restore lost packages from 0.2.3 + fix overwritten 0.2.4 files

- Restore 29 recipe symlinks (libdrm, qtbase, dbus, sddm, pipewire, etc.)
- Restore 33 patches (KDE, libdrm, mesa, pipewire, sddm, wireplumber)
- Restore 20+ local/scripts (audit, lint, test, build helpers)
- Restore src/cook/scheduler.rs, status.rs, gnu-config/
- Restore scripts/patch-inclusion-gate.sh, run_mini1.sh, validate-collision-log.sh
- Recover TLC source from HEAD (was overwritten by 0.2.3 checkout)
- Recover 11 local/docs plans from HEAD (were overwritten)
- Recover qt6-wayland-smoke symlink from HEAD
- Fix MOTD: remove garbled ASCII art, use clean text
- Update version: 0.2.0 -> 0.2.4 in os-release, motd, config
- Reduce filesystem_size: 1536 -> 512 MiB
- Add ABSOLUTE RULE to AGENTS.md: never delete/ignore packages
- Reduce pcid scheme log verbosity: info -> debug
This commit is contained in:
2026-06-19 12:39:14 +03:00
parent ffbe098ef8
commit dc68054305
6418 changed files with 7066233 additions and 8670 deletions
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Definitions for PCI support.
*/
#define FL_BASE_MASK 0x0007
#define FL_BASE0 0x0000
#define FL_BASE1 0x0001
#define FL_BASE2 0x0002
#define FL_BASE3 0x0003
#define FL_BASE4 0x0004
#define FL_GET_BASE(x) (x & FL_BASE_MASK)
/* Use successive BARs (PCI base address registers),
else use offset into some specified BAR */
#define FL_BASE_BARS 0x0008
/* do not assign an irq */
#define FL_NOIRQ 0x0080
/* Use the Base address register size to cap number of ports */
#define FL_REGION_SZ_CAP 0x0100
struct pciserial_board {
unsigned int flags;
unsigned int num_ports;
unsigned int base_baud;
unsigned int uart_offset;
unsigned int reg_shift;
unsigned int first_offset;
};
struct serial_private;
struct serial_private *
pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board);
void pciserial_remove_ports(struct serial_private *priv);
void pciserial_suspend_ports(struct serial_private *priv);
void pciserial_resume_ports(struct serial_private *priv);
@@ -0,0 +1,102 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* BSD Process Accounting for Linux - Definitions
*
* Author: Marco van Wieringen (mvw@planets.elm.net)
*
* This header file contains the definitions needed to implement
* BSD-style process accounting. The kernel accounting code and all
* user-level programs that try to do something useful with the
* process accounting log must include this file.
*
* Copyright (C) 1995 - 1997 Marco van Wieringen - ELM Consultancy B.V.
*
*/
#ifndef _LINUX_ACCT_H
#define _LINUX_ACCT_H
#include <uapi/linux/acct.h>
#ifdef CONFIG_BSD_PROCESS_ACCT
struct pid_namespace;
extern void acct_collect(long exitcode, int group_dead);
extern void acct_process(void);
extern void acct_exit_ns(struct pid_namespace *);
#else
#define acct_collect(x,y) do { } while (0)
#define acct_process() do { } while (0)
#define acct_exit_ns(ns) do { } while (0)
#endif
/*
* ACCT_VERSION numbers as yet defined:
* 0: old format (until 2.6.7) with 16 bit uid/gid
* 1: extended variant (binary compatible on M68K)
* 2: extended variant (binary compatible on everything except M68K)
* 3: new binary incompatible format (64 bytes)
* 4: new binary incompatible format (128 bytes)
* 5: new binary incompatible format (128 bytes, second half)
*
*/
#undef ACCT_VERSION
#undef AHZ
#ifdef CONFIG_BSD_PROCESS_ACCT_V3
#define ACCT_VERSION 3
#define AHZ 100
typedef struct acct_v3 acct_t;
#else
#ifdef CONFIG_M68K
#define ACCT_VERSION 1
#else
#define ACCT_VERSION 2
#endif
#define AHZ (USER_HZ)
typedef struct acct acct_t;
#endif
#include <linux/jiffies.h>
/*
* Yet another set of HZ to *HZ helper functions.
* See <linux/jiffies.h> for the original.
*/
static inline u32 jiffies_to_AHZ(unsigned long x)
{
#if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0
# if HZ < AHZ
return x * (AHZ / HZ);
# else
return x / (HZ / AHZ);
# endif
#else
u64 tmp = (u64)x * TICK_NSEC;
do_div(tmp, (NSEC_PER_SEC / AHZ));
return (long)tmp;
#endif
}
static inline u64 nsec_to_AHZ(u64 x)
{
#if (NSEC_PER_SEC % AHZ) == 0
do_div(x, (NSEC_PER_SEC / AHZ));
#elif (AHZ % 512) == 0
x *= AHZ/512;
do_div(x, (NSEC_PER_SEC / 512));
#else
/*
* max relative error 5.7e-8 (1.8s per year) for AHZ <= 1024,
* overflow after 64.99 years.
* exact for AHZ=60, 72, 90, 120, 144, 180, 300, 600, 900, ...
*/
x *= 9;
do_div(x, (unsigned long)((9ull * NSEC_PER_SEC + (AHZ/2))
/ AHZ));
#endif
return x;
}
#endif /* _LINUX_ACCT_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,91 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Wifi Band Exclusion Interface (AMD ACPI Implementation)
* Copyright (C) 2023 Advanced Micro Devices
*/
#ifndef _ACPI_AMD_WBRF_H
#define _ACPI_AMD_WBRF_H
#include <linux/device.h>
#include <linux/notifier.h>
/* The maximum number of frequency band ranges */
#define MAX_NUM_OF_WBRF_RANGES 11
/* Record actions */
#define WBRF_RECORD_ADD 0x0
#define WBRF_RECORD_REMOVE 0x1
/**
* struct freq_band_range - Wifi frequency band range definition
* @start: start frequency point (in Hz)
* @end: end frequency point (in Hz)
*/
struct freq_band_range {
u64 start;
u64 end;
};
/**
* struct wbrf_ranges_in_out - wbrf ranges info
* @num_of_ranges: total number of band ranges in this struct
* @band_list: array of Wifi band ranges
*/
struct wbrf_ranges_in_out {
u64 num_of_ranges;
struct freq_band_range band_list[MAX_NUM_OF_WBRF_RANGES];
};
/**
* enum wbrf_notifier_actions - wbrf notifier actions index
* @WBRF_CHANGED: there was some frequency band updates. The consumers
* should retrieve the latest active frequency bands.
*/
enum wbrf_notifier_actions {
WBRF_CHANGED,
};
#if IS_ENABLED(CONFIG_AMD_WBRF)
bool acpi_amd_wbrf_supported_producer(struct device *dev);
int acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action, struct wbrf_ranges_in_out *in);
bool acpi_amd_wbrf_supported_consumer(struct device *dev);
int amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out);
int amd_wbrf_register_notifier(struct notifier_block *nb);
int amd_wbrf_unregister_notifier(struct notifier_block *nb);
#else
static inline
bool acpi_amd_wbrf_supported_consumer(struct device *dev)
{
return false;
}
static inline
int acpi_amd_wbrf_add_remove(struct device *dev, uint8_t action, struct wbrf_ranges_in_out *in)
{
return -ENODEV;
}
static inline
bool acpi_amd_wbrf_supported_producer(struct device *dev)
{
return false;
}
static inline
int amd_wbrf_retrieve_freq_band(struct device *dev, struct wbrf_ranges_in_out *out)
{
return -ENODEV;
}
static inline
int amd_wbrf_register_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
static inline
int amd_wbrf_unregister_notifier(struct notifier_block *nb)
{
return -ENODEV;
}
#endif /* CONFIG_AMD_WBRF */
#endif /* _ACPI_AMD_WBRF_H */
@@ -0,0 +1,115 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ACPI helpers for DMA request / controller
*
* Based on of_dma.h
*
* Copyright (C) 2013, Intel Corporation
* Author: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
*/
#ifndef __LINUX_ACPI_DMA_H
#define __LINUX_ACPI_DMA_H
#include <linux/err.h>
#include <linux/dmaengine.h>
#include <linux/types.h>
struct device;
/**
* struct acpi_dma_spec - slave device DMA resources
* @chan_id: channel unique id
* @slave_id: request line unique id
* @dev: struct device of the DMA controller to be used in the filter
* function
*/
struct acpi_dma_spec {
int chan_id;
int slave_id;
struct device *dev;
};
/**
* struct acpi_dma - representation of the registered DMAC
* @dma_controllers: linked list node
* @dev: struct device of this controller
* @acpi_dma_xlate: callback function to find a suitable channel
* @data: private data used by a callback function
* @base_request_line: first supported request line (CSRT)
* @end_request_line: last supported request line (CSRT)
*/
struct acpi_dma {
struct list_head dma_controllers;
struct device *dev;
struct dma_chan *(*acpi_dma_xlate)
(struct acpi_dma_spec *, struct acpi_dma *);
void *data;
unsigned short base_request_line;
unsigned short end_request_line;
};
/* Used with acpi_dma_simple_xlate() */
struct acpi_dma_filter_info {
dma_cap_mask_t dma_cap;
dma_filter_fn filter_fn;
};
#ifdef CONFIG_DMA_ACPI
int acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
(struct acpi_dma_spec *, struct acpi_dma *),
void *data);
int acpi_dma_controller_free(struct device *dev);
int devm_acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
(struct acpi_dma_spec *, struct acpi_dma *),
void *data);
struct dma_chan *acpi_dma_request_slave_chan_by_index(struct device *dev,
size_t index);
struct dma_chan *acpi_dma_request_slave_chan_by_name(struct device *dev,
const char *name);
struct dma_chan *acpi_dma_simple_xlate(struct acpi_dma_spec *dma_spec,
struct acpi_dma *adma);
#else
static inline int acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
(struct acpi_dma_spec *, struct acpi_dma *),
void *data)
{
return -ENODEV;
}
static inline int acpi_dma_controller_free(struct device *dev)
{
return -ENODEV;
}
static inline int devm_acpi_dma_controller_register(struct device *dev,
struct dma_chan *(*acpi_dma_xlate)
(struct acpi_dma_spec *, struct acpi_dma *),
void *data)
{
return -ENODEV;
}
static inline struct dma_chan *acpi_dma_request_slave_chan_by_index(
struct device *dev, size_t index)
{
return ERR_PTR(-ENODEV);
}
static inline struct dma_chan *acpi_dma_request_slave_chan_by_name(
struct device *dev, const char *name)
{
return ERR_PTR(-ENODEV);
}
#define acpi_dma_simple_xlate NULL
#endif
#define acpi_dma_request_slave_channel acpi_dma_request_slave_chan_by_index
#endif /* __LINUX_ACPI_DMA_H */
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2016, Semihalf
* Author: Tomasz Nowicki <tn@semihalf.com>
*/
#ifndef __ACPI_IORT_H__
#define __ACPI_IORT_H__
#include <linux/acpi.h>
#include <linux/fwnode.h>
#include <linux/irqdomain.h>
#define IORT_IRQ_MASK(irq) (irq & 0xffffffffULL)
#define IORT_IRQ_TRIGGER_MASK(irq) ((irq >> 32) & 0xffffffffULL)
/*
* PMCG model identifiers for use in smmu pmu driver. Please note
* that this is purely for the use of software and has nothing to
* do with hardware or with IORT specification.
*/
#define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
#define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */
int iort_register_domain_token(int trans_id, phys_addr_t base,
struct fwnode_handle *fw_node);
void iort_deregister_domain_token(int trans_id);
struct fwnode_handle *iort_find_domain_token(int trans_id);
struct fwnode_handle *iort_iwb_handle(u32 iwb_id);
#ifdef CONFIG_ACPI_IORT
u32 iort_msi_map_id(struct device *dev, u32 id);
u32 iort_msi_xlate(struct device *dev, u32 id, struct fwnode_handle **node);
int iort_its_translate_pa(struct fwnode_handle *node, phys_addr_t *base);
struct irq_domain *iort_get_device_domain(struct device *dev, u32 id,
enum irq_domain_bus_token bus_token);
int iort_pmsi_get_msi_info(struct device *dev, u32 *dev_id, phys_addr_t *pa);
void acpi_configure_pmsi_domain(struct device *dev);
void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode,
struct list_head *head);
void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode,
struct list_head *head);
/* IOMMU interface */
int iort_dma_get_ranges(struct device *dev, u64 *limit);
int iort_iommu_configure_id(struct device *dev, const u32 *id_in);
void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head);
phys_addr_t acpi_iort_dma_get_max_cpu_address(void);
#else
static inline u32 iort_msi_map_id(struct device *dev, u32 id)
{ return id; }
static inline u32 iort_msi_xlate(struct device *dev, u32 id, struct fwnode_handle **node)
{ return id; }
static inline int iort_its_translate_pa(struct fwnode_handle *node, phys_addr_t *base)
{ return -ENODEV; }
static inline struct irq_domain *iort_get_device_domain(
struct device *dev, u32 id, enum irq_domain_bus_token bus_token)
{ return NULL; }
static inline int iort_pmsi_get_msi_info(struct device *dev, u32 *dev_id, phys_addr_t *pa)
{ return -ENODEV; }
static inline void acpi_configure_pmsi_domain(struct device *dev) { }
static inline
void iort_get_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { }
static inline
void iort_put_rmr_sids(struct fwnode_handle *iommu_fwnode, struct list_head *head) { }
/* IOMMU interface */
static inline int iort_dma_get_ranges(struct device *dev, u64 *limit)
{ return -ENODEV; }
static inline int iort_iommu_configure_id(struct device *dev, const u32 *id_in)
{ return -ENODEV; }
static inline
void iort_iommu_get_resv_regions(struct device *dev, struct list_head *head)
{ }
static inline phys_addr_t acpi_iort_dma_get_max_cpu_address(void)
{ return PHYS_ADDR_MAX; }
#endif
#endif /* __ACPI_IORT_H__ */
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ACPI helper for the MDIO (Ethernet PHY) API
*/
#ifndef __LINUX_ACPI_MDIO_H
#define __LINUX_ACPI_MDIO_H
#include <linux/phy.h>
#if IS_ENABLED(CONFIG_ACPI_MDIO)
int __acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode,
struct module *owner);
static inline int
acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *handle)
{
return __acpi_mdiobus_register(mdio, handle, THIS_MODULE);
}
#else /* CONFIG_ACPI_MDIO */
static inline int
acpi_mdiobus_register(struct mii_bus *mdio, struct fwnode_handle *fwnode)
{
/*
* Fall back to mdiobus_register() function to register a bus.
* This way, we don't have to keep compat bits around in drivers.
*/
return mdiobus_register(mdio);
}
#endif
#endif /* __LINUX_ACPI_MDIO_H */
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ACPI_PMTMR_H_
#define _ACPI_PMTMR_H_
#include <linux/clocksource.h>
/* Number of PMTMR ticks expected during calibration run */
#define PMTMR_TICKS_PER_SEC 3579545
/* limit it to 24 bits */
#define ACPI_PM_MASK CLOCKSOURCE_MASK(24)
/* Overrun value */
#define ACPI_PM_OVRRUN (1<<24)
#ifdef CONFIG_X86_PM_TIMER
extern u32 acpi_pm_read_verified(void);
extern u32 pmtmr_ioport;
static inline u32 acpi_pm_read_early(void)
{
if (!pmtmr_ioport)
return 0;
/* mask the output to 24 bits */
return acpi_pm_read_verified() & ACPI_PM_MASK;
}
/**
* Register callback for suspend and resume event
*
* @cb Callback triggered on suspend and resume
* @data Data passed with the callback
*/
void acpi_pmtmr_register_suspend_resume_callback(void (*cb)(void *data, bool suspend), void *data);
/**
* Remove registered callback for suspend and resume event
*/
void acpi_pmtmr_unregister_suspend_resume_callback(void);
#else
static inline u32 acpi_pm_read_early(void)
{
return 0;
}
#endif
#endif
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2024-2025, Ventana Micro Systems Inc.
* Author: Sunil V L <sunilvl@ventanamicro.com>
*/
#ifndef _ACPI_RIMT_H
#define _ACPI_RIMT_H
#ifdef CONFIG_ACPI_RIMT
int rimt_iommu_register(struct device *dev);
#else
static inline int rimt_iommu_register(struct device *dev)
{
return -ENODEV;
}
#endif
#if defined(CONFIG_IOMMU_API) && defined(CONFIG_ACPI_RIMT)
int rimt_iommu_configure_id(struct device *dev, const u32 *id_in);
#else
static inline int rimt_iommu_configure_id(struct device *dev, const u32 *id_in)
{
return -ENODEV;
}
#endif
#endif /* _ACPI_RIMT_H */
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef __ACPI_VIOT_H__
#define __ACPI_VIOT_H__
#include <linux/acpi.h>
#ifdef CONFIG_ACPI_VIOT
void __init acpi_viot_early_init(void);
void __init acpi_viot_init(void);
int viot_iommu_configure(struct device *dev);
#else
static inline void acpi_viot_early_init(void) {}
static inline void acpi_viot_init(void) {}
static inline int viot_iommu_configure(struct device *dev)
{
return -ENODEV;
}
#endif
#endif /* __ACPI_VIOT_H__ */
@@ -0,0 +1,67 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Definitions for ADB (Apple Desktop Bus) support.
*/
#ifndef __ADB_H
#define __ADB_H
#include <uapi/linux/adb.h>
struct adb_request {
unsigned char data[32];
int nbytes;
unsigned char reply[32];
int reply_len;
unsigned char reply_expected;
unsigned char sent;
unsigned char complete;
void (*done)(struct adb_request *);
void *arg;
struct adb_request *next;
};
struct adb_ids {
int nids;
unsigned char id[16];
};
/* Structure which encapsulates a low-level ADB driver */
struct adb_driver {
char name[16];
int (*probe)(void);
int (*init)(void);
int (*send_request)(struct adb_request *req, int sync);
int (*autopoll)(int devs);
void (*poll)(void);
int (*reset_bus)(void);
};
/* Values for adb_request flags */
#define ADBREQ_REPLY 1 /* expect reply */
#define ADBREQ_SYNC 2 /* poll until done */
#define ADBREQ_NOSEND 4 /* build the request, but don't send it */
/* Messages sent thru the client_list notifier. You should NOT stop
the operation, at least not with this version */
enum adb_message {
ADB_MSG_POWERDOWN, /* Currently called before sleep only */
ADB_MSG_PRE_RESET, /* Called before resetting the bus */
ADB_MSG_POST_RESET /* Called after resetting the bus (re-do init & register) */
};
extern struct blocking_notifier_head adb_client_list;
int adb_request(struct adb_request *req, void (*done)(struct adb_request *),
int flags, int nbytes, ...);
int adb_register(int default_id,int handler_id,struct adb_ids *ids,
void (*handler)(unsigned char *, int, int));
int adb_unregister(int index);
void adb_poll(void);
void adb_input(unsigned char *, int, int);
int adb_reset_bus(void);
int adb_try_handler_change(int address, int new_id);
int adb_get_infos(int address, int *original_address, int *handler_id);
#endif /* __ADB_H */
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ADFS_FS_H
#define _ADFS_FS_H
#include <uapi/linux/adfs_fs.h>
/*
* Calculate the boot block checksum on an ADFS drive. Note that this will
* appear to be correct if the sector contains all zeros, so also check that
* the disk size is non-zero!!!
*/
static inline int adfs_checkbblk(unsigned char *ptr)
{
unsigned int result = 0;
unsigned char *p = ptr + 511;
do {
result = (result & 0xff) + (result >> 8);
result = result + *--p;
} while (p != ptr);
return (result & 0xff) != ptr[511];
}
#endif
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Analog Devices AXI common registers & definitions
*
* Copyright 2019 Analog Devices Inc.
*
* https://wiki.analog.com/resources/fpga/docs/axi_ip
* https://wiki.analog.com/resources/fpga/docs/hdl/regmap
*/
#include <linux/types.h>
#ifndef ADI_AXI_COMMON_H_
#define ADI_AXI_COMMON_H_
#define ADI_AXI_REG_VERSION 0x0000
#define ADI_AXI_REG_FPGA_INFO 0x001C
#define ADI_AXI_PCORE_VER(major, minor, patch) \
(((major) << 16) | ((minor) << 8) | (patch))
#define ADI_AXI_PCORE_VER_MAJOR(version) (((version) >> 16) & 0xff)
#define ADI_AXI_PCORE_VER_MINOR(version) (((version) >> 8) & 0xff)
#define ADI_AXI_PCORE_VER_PATCH(version) ((version) & 0xff)
/**
* adi_axi_pcore_ver_gteq() - check if a version is satisfied
* @version: the full version read from the hardware
* @major: the major version to compare against
* @minor: the minor version to compare against
*
* ADI AXI IP Cores use semantic versioning, so this can be used to check for
* feature availability.
*
* Return: true if the version is greater than or equal to the specified
* major and minor version, false otherwise.
*/
static inline bool adi_axi_pcore_ver_gteq(u32 version, u32 major, u32 minor)
{
return ADI_AXI_PCORE_VER_MAJOR(version) > (major) ||
(ADI_AXI_PCORE_VER_MAJOR(version) == (major) &&
ADI_AXI_PCORE_VER_MINOR(version) >= (minor));
}
#define ADI_AXI_INFO_FPGA_TECH(info) (((info) >> 24) & 0xff)
#define ADI_AXI_INFO_FPGA_FAMILY(info) (((info) >> 16) & 0xff)
#define ADI_AXI_INFO_FPGA_SPEED_GRADE(info) (((info) >> 8) & 0xff)
enum adi_axi_fpga_technology {
ADI_AXI_FPGA_TECH_UNKNOWN = 0,
ADI_AXI_FPGA_TECH_SERIES7,
ADI_AXI_FPGA_TECH_ULTRASCALE,
ADI_AXI_FPGA_TECH_ULTRASCALE_PLUS,
};
enum adi_axi_fpga_family {
ADI_AXI_FPGA_FAMILY_UNKNOWN = 0,
ADI_AXI_FPGA_FAMILY_ARTIX,
ADI_AXI_FPGA_FAMILY_KINTEX,
ADI_AXI_FPGA_FAMILY_VIRTEX,
ADI_AXI_FPGA_FAMILY_ZYNQ,
};
enum adi_axi_fpga_speed_grade {
ADI_AXI_FPGA_SPEED_UNKNOWN = 0,
ADI_AXI_FPGA_SPEED_1 = 10,
ADI_AXI_FPGA_SPEED_1L = 11,
ADI_AXI_FPGA_SPEED_1H = 12,
ADI_AXI_FPGA_SPEED_1HV = 13,
ADI_AXI_FPGA_SPEED_1LV = 14,
ADI_AXI_FPGA_SPEED_2 = 20,
ADI_AXI_FPGA_SPEED_2L = 21,
ADI_AXI_FPGA_SPEED_2LV = 22,
ADI_AXI_FPGA_SPEED_3 = 30,
};
#endif /* ADI_AXI_COMMON_H_ */
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2020 Google, Inc
*/
#ifndef __ADRENO_SMMU_PRIV_H
#define __ADRENO_SMMU_PRIV_H
#include <linux/io-pgtable.h>
/**
* struct adreno_smmu_fault_info - container for key fault information
*
* @far: The faulting IOVA from ARM_SMMU_CB_FAR
* @ttbr0: The current TTBR0 pagetable from ARM_SMMU_CB_TTBR0
* @contextidr: The value of ARM_SMMU_CB_CONTEXTIDR
* @fsr: The fault status from ARM_SMMU_CB_FSR
* @fsynr0: The value of FSYNR0 from ARM_SMMU_CB_FSYNR0
* @fsynr1: The value of FSYNR1 from ARM_SMMU_CB_FSYNR0
* @cbfrsynra: The value of CBFRSYNRA from ARM_SMMU_GR1_CBFRSYNRA(idx)
*
* This struct passes back key page fault information to the GPU driver
* through the get_fault_info function pointer.
* The GPU driver can use this information to print informative
* log messages and provide deeper GPU specific insight into the fault.
*/
struct adreno_smmu_fault_info {
u64 far;
u64 ttbr0;
u32 contextidr;
u32 fsr;
u32 fsynr0;
u32 fsynr1;
u32 cbfrsynra;
};
/**
* struct adreno_smmu_priv - private interface between adreno-smmu and GPU
*
* @cookie: An opque token provided by adreno-smmu and passed
* back into the callbacks
* @get_ttbr1_cfg: Get the TTBR1 config for the GPUs context-bank
* @set_ttbr0_cfg: Set the TTBR0 config for the GPUs context bank. A
* NULL config disables TTBR0 translation, otherwise
* TTBR0 translation is enabled with the specified cfg
* @get_fault_info: Called by the GPU fault handler to get information about
* the fault
* @set_stall: Configure whether stall on fault (CFCFG) is enabled. If
* stalling on fault is enabled, the GPU driver must call
* resume_translation()
* @resume_translation: Resume translation after a fault
*
* @set_prr_bit: [optional] Configure the GPU's Partially Resident
* Region (PRR) bit in the ACTLR register.
* @set_prr_addr: [optional] Configure the PRR_CFG_*ADDR register with
* the physical address of PRR page passed from GPU
* driver.
*
* The GPU driver (drm/msm) and adreno-smmu work together for controlling
* the GPU's SMMU instance. This is by necessity, as the GPU is directly
* updating the SMMU for context switches, while on the other hand we do
* not want to duplicate all of the initial setup logic from arm-smmu.
*
* This private interface is used for the two drivers to coordinate. The
* cookie and callback functions are populated when the GPU driver attaches
* it's domain.
*/
struct adreno_smmu_priv {
const void *cookie;
const struct io_pgtable_cfg *(*get_ttbr1_cfg)(const void *cookie);
int (*set_ttbr0_cfg)(const void *cookie, const struct io_pgtable_cfg *cfg);
void (*get_fault_info)(const void *cookie, struct adreno_smmu_fault_info *info);
void (*set_stall)(const void *cookie, bool enabled);
void (*resume_translation)(const void *cookie, bool terminate);
void (*set_prr_bit)(const void *cookie, bool set);
void (*set_prr_addr)(const void *cookie, phys_addr_t page_addr);
};
#endif /* __ADRENO_SMMU_PRIV_H */
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Address translation interface via ACPI DSM.
* Copyright (C) 2018 Intel Corporation
*/
#ifndef _LINUX_ADXL_H
#define _LINUX_ADXL_H
const char * const *adxl_get_component_names(void);
int adxl_decode(u64 addr, u64 component_values[]);
#endif /* _LINUX_ADXL_H */
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2006 Intel Corp.
* Tom Long Nguyen (tom.l.nguyen@intel.com)
* Zhang Yanmin (yanmin.zhang@intel.com)
*/
#ifndef _AER_H_
#define _AER_H_
#include <linux/errno.h>
#include <linux/types.h>
#define AER_NONFATAL 0
#define AER_FATAL 1
#define AER_CORRECTABLE 2
#define DPC_FATAL 3
/*
* AER and DPC capabilities TLP Logging register sizes (PCIe r6.2, sec 7.8.4
* & 7.9.14).
*/
#define PCIE_STD_NUM_TLP_HEADERLOG 4
#define PCIE_STD_MAX_TLP_PREFIXLOG 4
#define PCIE_STD_MAX_TLP_HEADERLOG (PCIE_STD_NUM_TLP_HEADERLOG + 10)
struct pci_dev;
struct pcie_tlp_log {
union {
u32 dw[PCIE_STD_MAX_TLP_HEADERLOG];
struct {
u32 _do_not_use[PCIE_STD_NUM_TLP_HEADERLOG];
u32 prefix[PCIE_STD_MAX_TLP_PREFIXLOG];
};
};
u8 header_len; /* Length of the Logged TLP Header in DWORDs */
bool flit; /* TLP was logged when in Flit mode */
};
struct aer_capability_regs {
u32 header;
u32 uncor_status;
u32 uncor_mask;
u32 uncor_severity;
u32 cor_status;
u32 cor_mask;
u32 cap_control;
struct pcie_tlp_log header_log;
u32 root_command;
u32 root_status;
u16 cor_err_source;
u16 uncor_err_source;
};
#if defined(CONFIG_PCIEAER)
int pci_aer_clear_nonfatal_status(struct pci_dev *dev);
int pcie_aer_is_native(struct pci_dev *dev);
void pci_aer_unmask_internal_errors(struct pci_dev *dev);
#else
static inline int pci_aer_clear_nonfatal_status(struct pci_dev *dev)
{
return -EINVAL;
}
static inline int pcie_aer_is_native(struct pci_dev *dev) { return 0; }
static inline void pci_aer_unmask_internal_errors(struct pci_dev *dev) { }
#endif
void pci_print_aer(struct pci_dev *dev, int aer_severity,
struct aer_capability_regs *aer);
int cper_severity_to_aer(int cper_severity);
void aer_recover_queue(int domain, unsigned int bus, unsigned int devfn,
int severity, struct aer_capability_regs *aer_regs);
#endif //_AER_H_
@@ -0,0 +1,109 @@
/*
* AGPGART backend specific includes. Not for userspace consumption.
*
* Copyright (C) 2004 Silicon Graphics, Inc.
* Copyright (C) 2002-2003 Dave Jones
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _AGP_BACKEND_H
#define _AGP_BACKEND_H 1
#include <linux/list.h>
enum chipset_type {
NOT_SUPPORTED,
SUPPORTED,
};
struct agp_version {
u16 major;
u16 minor;
};
struct agp_kern_info {
struct agp_version version;
struct pci_dev *device;
enum chipset_type chipset;
unsigned long mode;
unsigned long aper_base;
size_t aper_size;
int max_memory; /* In pages */
int current_memory;
bool cant_use_aperture;
unsigned long page_mask;
const struct vm_operations_struct *vm_ops;
};
/*
* The agp_memory structure has information about the block of agp memory
* allocated. A caller may manipulate the next and prev pointers to link
* each allocated item into a list. These pointers are ignored by the backend.
* Everything else should never be written to, but the caller may read any of
* the items to determine the status of this block of agp memory.
*/
struct agp_bridge_data;
struct agp_memory {
struct agp_memory *next;
struct agp_memory *prev;
struct agp_bridge_data *bridge;
struct page **pages;
size_t page_count;
int key;
int num_scratch_pages;
off_t pg_start;
u32 type;
u32 physical;
bool is_bound;
bool is_flushed;
/* list of agp_memory mapped to the aperture */
struct list_head mapped_list;
/* DMA-mapped addresses */
struct scatterlist *sg_list;
int num_sg;
};
#define AGP_NORMAL_MEMORY 0
#define AGP_USER_TYPES (1 << 16)
#define AGP_USER_MEMORY (AGP_USER_TYPES)
#define AGP_USER_CACHED_MEMORY (AGP_USER_TYPES + 1)
extern struct agp_bridge_data *agp_bridge;
extern struct list_head agp_bridges;
extern struct agp_bridge_data *(*agp_find_bridge)(struct pci_dev *);
extern void agp_free_memory(struct agp_memory *);
extern struct agp_memory *agp_allocate_memory(struct agp_bridge_data *, size_t, u32);
extern int agp_copy_info(struct agp_bridge_data *, struct agp_kern_info *);
extern int agp_bind_memory(struct agp_memory *, off_t);
extern int agp_unbind_memory(struct agp_memory *);
extern void agp_enable(struct agp_bridge_data *, u32);
extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *);
extern void agp_backend_release(struct agp_bridge_data *);
#endif /* _AGP_BACKEND_H */
@@ -0,0 +1,128 @@
/*
* AGPGART module version 0.99
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _AGP_H
#define _AGP_H 1
#include <linux/mutex.h>
#include <linux/agp_backend.h>
#include <uapi/linux/agpgart.h>
struct agp_info {
struct agp_version version; /* version of the driver */
u32 bridge_id; /* bridge vendor/device */
u32 agp_mode; /* mode info of bridge */
unsigned long aper_base;/* base of aperture */
size_t aper_size; /* size of aperture */
size_t pg_total; /* max pages (swap + system) */
size_t pg_system; /* max pages (system) */
size_t pg_used; /* current pages used */
};
struct agp_setup {
u32 agp_mode; /* mode info of bridge */
};
/*
* The "prot" down below needs still a "sleep" flag somehow ...
*/
struct agp_segment {
off_t pg_start; /* starting page to populate */
size_t pg_count; /* number of pages */
int prot; /* prot flags for mmap */
};
struct agp_segment_priv {
off_t pg_start;
size_t pg_count;
pgprot_t prot;
};
struct agp_region {
pid_t pid; /* pid of process */
size_t seg_count; /* number of segments */
struct agp_segment *seg_list;
};
struct agp_allocate {
int key; /* tag of allocation */
size_t pg_count; /* number of pages */
u32 type; /* 0 == normal, other devspec */
u32 physical; /* device specific (some devices
* need a phys address of the
* actual page behind the gatt
* table) */
};
struct agp_bind {
int key; /* tag of allocation */
off_t pg_start; /* starting page to populate */
};
struct agp_unbind {
int key; /* tag of allocation */
u32 priority; /* priority for paging out */
};
struct agp_client {
struct agp_client *next;
struct agp_client *prev;
pid_t pid;
int num_segments;
struct agp_segment_priv **segments;
};
struct agp_controller {
struct agp_controller *next;
struct agp_controller *prev;
pid_t pid;
int num_clients;
struct agp_memory *pool;
struct agp_client *clients;
};
#define AGP_FF_ALLOW_CLIENT 0
#define AGP_FF_ALLOW_CONTROLLER 1
#define AGP_FF_IS_CLIENT 2
#define AGP_FF_IS_CONTROLLER 3
#define AGP_FF_IS_VALID 4
struct agp_file_private {
struct agp_file_private *next;
struct agp_file_private *prev;
pid_t my_pid;
unsigned long access_flags; /* long req'd for set_bit --RR */
};
struct agp_front_data {
struct mutex agp_mutex;
struct agp_controller *current_controller;
struct agp_controller *controllers;
struct agp_file_private *file_priv_list;
bool used_by_controller;
bool backend_acquired;
};
#endif /* _AGP_H */
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_AHCI_REMAP_H
#define _LINUX_AHCI_REMAP_H
#include <linux/sizes.h>
#define AHCI_VSCAP 0xa4
#define AHCI_REMAP_CAP 0x800
/* device class code */
#define AHCI_REMAP_N_DCC 0x880
/* remap-device base relative to ahci-bar */
#define AHCI_REMAP_N_OFFSET SZ_16K
#define AHCI_REMAP_N_SIZE SZ_16K
#define AHCI_MAX_REMAP 3
static inline unsigned int ahci_remap_dcc(int i)
{
return AHCI_REMAP_N_DCC + i * 0x80;
}
static inline unsigned int ahci_remap_base(int i)
{
return AHCI_REMAP_N_OFFSET + i * AHCI_REMAP_N_SIZE;
}
#endif /* _LINUX_AHCI_REMAP_H */
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* AHCI SATA platform driver
*
* Copyright 2004-2005 Red Hat, Inc.
* Jeff Garzik <jgarzik@pobox.com>
* Copyright 2010 MontaVista Software, LLC.
* Anton Vorontsov <avorontsov@ru.mvista.com>
*/
#ifndef _AHCI_PLATFORM_H
#define _AHCI_PLATFORM_H
#include <linux/compiler.h>
struct clk;
struct device;
struct ata_port_info;
struct ahci_host_priv;
struct platform_device;
struct scsi_host_template;
int ahci_platform_enable_phys(struct ahci_host_priv *hpriv);
void ahci_platform_disable_phys(struct ahci_host_priv *hpriv);
struct clk *ahci_platform_find_clk(struct ahci_host_priv *hpriv,
const char *con_id);
int ahci_platform_enable_clks(struct ahci_host_priv *hpriv);
void ahci_platform_disable_clks(struct ahci_host_priv *hpriv);
int ahci_platform_deassert_rsts(struct ahci_host_priv *hpriv);
int ahci_platform_assert_rsts(struct ahci_host_priv *hpriv);
int ahci_platform_enable_regulators(struct ahci_host_priv *hpriv);
void ahci_platform_disable_regulators(struct ahci_host_priv *hpriv);
int ahci_platform_enable_resources(struct ahci_host_priv *hpriv);
void ahci_platform_disable_resources(struct ahci_host_priv *hpriv);
struct ahci_host_priv *ahci_platform_get_resources(
struct platform_device *pdev, unsigned int flags);
int ahci_platform_init_host(struct platform_device *pdev,
struct ahci_host_priv *hpriv,
const struct ata_port_info *pi_template,
const struct scsi_host_template *sht);
void ahci_platform_shutdown(struct platform_device *pdev);
int ahci_platform_suspend_host(struct device *dev);
int ahci_platform_resume_host(struct device *dev);
int ahci_platform_suspend(struct device *dev);
int ahci_platform_resume(struct device *dev);
#define AHCI_PLATFORM_GET_RESETS BIT(0)
#define AHCI_PLATFORM_RST_TRIGGER BIT(1)
#endif /* _AHCI_PLATFORM_H */
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX__AIO_H
#define __LINUX__AIO_H
#include <linux/aio_abi.h>
struct kioctx;
struct kiocb;
struct mm_struct;
typedef int (kiocb_cancel_fn)(struct kiocb *);
/* prototypes */
#ifdef CONFIG_AIO
extern void exit_aio(struct mm_struct *mm);
void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel);
#else
static inline void exit_aio(struct mm_struct *mm) { }
static inline void kiocb_set_cancel_fn(struct kiocb *req,
kiocb_cancel_fn *cancel) { }
#endif /* CONFIG_AIO */
#endif /* __LINUX__AIO_H */
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ALARMTIMER_H
#define _LINUX_ALARMTIMER_H
#include <linux/time.h>
#include <linux/hrtimer.h>
#include <linux/timerqueue.h>
struct rtc_device;
enum alarmtimer_type {
ALARM_REALTIME,
ALARM_BOOTTIME,
/* Supported types end here */
ALARM_NUMTYPE,
/* Used for tracing information. No usable types. */
ALARM_REALTIME_FREEZER,
ALARM_BOOTTIME_FREEZER,
};
#define ALARMTIMER_STATE_INACTIVE 0x00
#define ALARMTIMER_STATE_ENQUEUED 0x01
/**
* struct alarm - Alarm timer structure
* @node: timerqueue node for adding to the event list this value
* also includes the expiration time.
* @timer: hrtimer used to schedule events while running
* @function: Function pointer to be executed when the timer fires.
* @type: Alarm type (BOOTTIME/REALTIME).
* @state: Flag that represents if the alarm is set to fire or not.
* @data: Internal data value.
*/
struct alarm {
struct timerqueue_node node;
struct hrtimer timer;
void (*function)(struct alarm *, ktime_t now);
enum alarmtimer_type type;
int state;
void *data;
};
void alarm_init(struct alarm *alarm, enum alarmtimer_type type,
void (*function)(struct alarm *, ktime_t));
void alarm_start(struct alarm *alarm, ktime_t start);
void alarm_start_relative(struct alarm *alarm, ktime_t start);
void alarm_restart(struct alarm *alarm);
int alarm_try_to_cancel(struct alarm *alarm);
int alarm_cancel(struct alarm *alarm);
u64 alarm_forward(struct alarm *alarm, ktime_t now, ktime_t interval);
u64 alarm_forward_now(struct alarm *alarm, ktime_t interval);
ktime_t alarm_expires_remaining(const struct alarm *alarm);
#ifdef CONFIG_RTC_CLASS
/* Provide way to access the rtc device being used by alarmtimers */
struct rtc_device *alarmtimer_get_rtcdev(void);
#else
static inline struct rtc_device *alarmtimer_get_rtcdev(void) { return NULL; }
#endif
#endif
@@ -0,0 +1,281 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Oleksij Rempel <linux@rempel-privat.de>
*
* Driver for Alcor Micro AU6601 and AU6621 controllers
*/
#ifndef __ALCOR_PCI_H
#define __ALCOR_PCI_H
#define ALCOR_SD_CARD 0
#define ALCOR_MS_CARD 1
#define DRV_NAME_ALCOR_PCI "alcor_pci"
#define DRV_NAME_ALCOR_PCI_SDMMC "alcor_sdmmc"
#define DRV_NAME_ALCOR_PCI_MS "alcor_ms"
#define PCI_ID_ALCOR_MICRO 0x1AEA
#define PCI_ID_AU6601 0x6601
#define PCI_ID_AU6621 0x6621
#define PCI_ID_AU6625 0x6625
#define MHZ_TO_HZ(freq) ((freq) * 1000 * 1000)
#define AU6601_BASE_CLOCK 31000000
#define AU6601_MIN_CLOCK 150000
#define AU6601_MAX_CLOCK 208000000
#define AU6601_MAX_DMA_SEGMENTS 64
#define AU6601_MAX_PIO_SEGMENTS 1
#define AU6601_MAX_DMA_BLOCK_SIZE 0x1000
#define AU6601_MAX_PIO_BLOCK_SIZE 0x200
#define AU6601_MAX_DMA_BLOCKS 1
#define AU6601_DMA_LOCAL_SEGMENTS 1
/* registers spotter by reverse engineering but still
* with unknown functionality:
* 0x10 - ADMA phy address. AU6621 only?
* 0x51 - LED ctrl?
* 0x52 - unknown
* 0x61 - LED related? Always toggled BIT0
* 0x63 - Same as 0x61?
* 0x77 - unknown
*/
/* SDMA phy address. Higher then 0x0800.0000?
* The au6601 and au6621 have different DMA engines with different issues. One
* For example au6621 engine is triggered by addr change. No other interaction
* is needed. This means, if we get two buffers with same address, then engine
* will stall.
*/
#define AU6601_REG_SDMA_ADDR 0x00
#define AU6601_SDMA_MASK 0xffffffff
#define AU6601_DMA_BOUNDARY 0x05
#define AU6621_DMA_PAGE_CNT 0x05
/* PIO */
#define AU6601_REG_BUFFER 0x08
/* ADMA ctrl? AU6621 only. */
#define AU6621_DMA_CTRL 0x0c
#define AU6621_DMA_ENABLE BIT(0)
/* CMD index */
#define AU6601_REG_CMD_OPCODE 0x23
/* CMD parametr */
#define AU6601_REG_CMD_ARG 0x24
/* CMD response 4x4 Bytes */
#define AU6601_REG_CMD_RSP0 0x30
#define AU6601_REG_CMD_RSP1 0x34
#define AU6601_REG_CMD_RSP2 0x38
#define AU6601_REG_CMD_RSP3 0x3C
/* default timeout set to 125: 125 * 40ms = 5 sec
* how exactly it is calculated?
*/
#define AU6601_TIME_OUT_CTRL 0x69
/* Block size for SDMA or PIO */
#define AU6601_REG_BLOCK_SIZE 0x6c
/* Some power related reg, used together with AU6601_OUTPUT_ENABLE */
#define AU6601_POWER_CONTROL 0x70
/* PLL ctrl */
#define AU6601_CLK_SELECT 0x72
#define AU6601_CLK_OVER_CLK 0x80
#define AU6601_CLK_384_MHZ 0x30
#define AU6601_CLK_125_MHZ 0x20
#define AU6601_CLK_48_MHZ 0x10
#define AU6601_CLK_EXT_PLL 0x04
#define AU6601_CLK_X2_MODE 0x02
#define AU6601_CLK_ENABLE 0x01
#define AU6601_CLK_31_25_MHZ 0x00
#define AU6601_CLK_DIVIDER 0x73
#define AU6601_INTERFACE_MODE_CTRL 0x74
#define AU6601_DLINK_MODE 0x80
#define AU6601_INTERRUPT_DELAY_TIME 0x40
#define AU6601_SIGNAL_REQ_CTRL 0x30
#define AU6601_MS_CARD_WP BIT(3)
#define AU6601_SD_CARD_WP BIT(0)
/* same register values are used for:
* - AU6601_OUTPUT_ENABLE
* - AU6601_POWER_CONTROL
*/
#define AU6601_ACTIVE_CTRL 0x75
#define AU6601_XD_CARD BIT(4)
/* AU6601_MS_CARD_ACTIVE - will cativate MS card section? */
#define AU6601_MS_CARD BIT(3)
#define AU6601_SD_CARD BIT(0)
/* card slot state. It should automatically detect type of
* the card
*/
#define AU6601_DETECT_STATUS 0x76
#define AU6601_DETECT_EN BIT(7)
#define AU6601_MS_DETECTED BIT(3)
#define AU6601_SD_DETECTED BIT(0)
#define AU6601_DETECT_STATUS_M 0xf
#define AU6601_REG_SW_RESET 0x79
#define AU6601_BUF_CTRL_RESET BIT(7)
#define AU6601_RESET_DATA BIT(3)
#define AU6601_RESET_CMD BIT(0)
#define AU6601_OUTPUT_ENABLE 0x7a
#define AU6601_PAD_DRIVE0 0x7b
#define AU6601_PAD_DRIVE1 0x7c
#define AU6601_PAD_DRIVE2 0x7d
/* read EEPROM? */
#define AU6601_FUNCTION 0x7f
#define AU6601_CMD_XFER_CTRL 0x81
#define AU6601_CMD_17_BYTE_CRC 0xc0
#define AU6601_CMD_6_BYTE_WO_CRC 0x80
#define AU6601_CMD_6_BYTE_CRC 0x40
#define AU6601_CMD_START_XFER 0x20
#define AU6601_CMD_STOP_WAIT_RDY 0x10
#define AU6601_CMD_NO_RESP 0x00
#define AU6601_REG_BUS_CTRL 0x82
#define AU6601_BUS_WIDTH_4BIT 0x20
#define AU6601_BUS_WIDTH_8BIT 0x10
#define AU6601_BUS_WIDTH_1BIT 0x00
#define AU6601_DATA_XFER_CTRL 0x83
#define AU6601_DATA_WRITE BIT(7)
#define AU6601_DATA_DMA_MODE BIT(6)
#define AU6601_DATA_START_XFER BIT(0)
#define AU6601_DATA_PIN_STATE 0x84
#define AU6601_BUS_STAT_CMD BIT(15)
/* BIT(4) - BIT(7) are permanently 1.
* May be reserved or not attached DAT4-DAT7
*/
#define AU6601_BUS_STAT_DAT3 BIT(3)
#define AU6601_BUS_STAT_DAT2 BIT(2)
#define AU6601_BUS_STAT_DAT1 BIT(1)
#define AU6601_BUS_STAT_DAT0 BIT(0)
#define AU6601_BUS_STAT_DAT_MASK 0xf
#define AU6601_OPT 0x85
#define AU6601_OPT_CMD_LINE_LEVEL 0x80
#define AU6601_OPT_NCRC_16_CLK BIT(4)
#define AU6601_OPT_CMD_NWT BIT(3)
#define AU6601_OPT_STOP_CLK BIT(2)
#define AU6601_OPT_DDR_MODE BIT(1)
#define AU6601_OPT_SD_18V BIT(0)
#define AU6601_CLK_DELAY 0x86
#define AU6601_CLK_DATA_POSITIVE_EDGE 0x80
#define AU6601_CLK_CMD_POSITIVE_EDGE 0x40
#define AU6601_CLK_POSITIVE_EDGE_ALL (AU6601_CLK_CMD_POSITIVE_EDGE \
| AU6601_CLK_DATA_POSITIVE_EDGE)
#define AU6601_REG_INT_STATUS 0x90
#define AU6601_REG_INT_ENABLE 0x94
#define AU6601_INT_DATA_END_BIT_ERR BIT(22)
#define AU6601_INT_DATA_CRC_ERR BIT(21)
#define AU6601_INT_DATA_TIMEOUT_ERR BIT(20)
#define AU6601_INT_CMD_INDEX_ERR BIT(19)
#define AU6601_INT_CMD_END_BIT_ERR BIT(18)
#define AU6601_INT_CMD_CRC_ERR BIT(17)
#define AU6601_INT_CMD_TIMEOUT_ERR BIT(16)
#define AU6601_INT_ERROR BIT(15)
#define AU6601_INT_OVER_CURRENT_ERR BIT(8)
#define AU6601_INT_CARD_INSERT BIT(7)
#define AU6601_INT_CARD_REMOVE BIT(6)
#define AU6601_INT_READ_BUF_RDY BIT(5)
#define AU6601_INT_WRITE_BUF_RDY BIT(4)
#define AU6601_INT_DMA_END BIT(3)
#define AU6601_INT_DATA_END BIT(1)
#define AU6601_INT_CMD_END BIT(0)
#define AU6601_INT_NORMAL_MASK 0x00007FFF
#define AU6601_INT_ERROR_MASK 0xFFFF8000
#define AU6601_INT_CMD_MASK (AU6601_INT_CMD_END | \
AU6601_INT_CMD_TIMEOUT_ERR | AU6601_INT_CMD_CRC_ERR | \
AU6601_INT_CMD_END_BIT_ERR | AU6601_INT_CMD_INDEX_ERR)
#define AU6601_INT_DATA_MASK (AU6601_INT_DATA_END | AU6601_INT_DMA_END | \
AU6601_INT_READ_BUF_RDY | AU6601_INT_WRITE_BUF_RDY | \
AU6601_INT_DATA_TIMEOUT_ERR | AU6601_INT_DATA_CRC_ERR | \
AU6601_INT_DATA_END_BIT_ERR)
#define AU6601_INT_ALL_MASK ((u32)-1)
/* MS_CARD mode registers */
#define AU6601_MS_STATUS 0xa0
#define AU6601_MS_BUS_MODE_CTRL 0xa1
#define AU6601_MS_BUS_8BIT_MODE 0x03
#define AU6601_MS_BUS_4BIT_MODE 0x01
#define AU6601_MS_BUS_1BIT_MODE 0x00
#define AU6601_MS_TPC_CMD 0xa2
#define AU6601_MS_TPC_READ_PAGE_DATA 0x02
#define AU6601_MS_TPC_READ_REG 0x04
#define AU6601_MS_TPC_GET_INT 0x07
#define AU6601_MS_TPC_WRITE_PAGE_DATA 0x0D
#define AU6601_MS_TPC_WRITE_REG 0x0B
#define AU6601_MS_TPC_SET_RW_REG_ADRS 0x08
#define AU6601_MS_TPC_SET_CMD 0x0E
#define AU6601_MS_TPC_EX_SET_CMD 0x09
#define AU6601_MS_TPC_READ_SHORT_DATA 0x03
#define AU6601_MS_TPC_WRITE_SHORT_DATA 0x0C
#define AU6601_MS_TRANSFER_MODE 0xa3
#define AU6601_MS_XFER_INT_TIMEOUT_CHK BIT(2)
#define AU6601_MS_XFER_DMA_ENABLE BIT(1)
#define AU6601_MS_XFER_START BIT(0)
#define AU6601_MS_DATA_PIN_STATE 0xa4
#define AU6601_MS_INT_STATUS 0xb0
#define AU6601_MS_INT_ENABLE 0xb4
#define AU6601_MS_INT_OVER_CURRENT_ERROR BIT(23)
#define AU6601_MS_INT_DATA_CRC_ERROR BIT(21)
#define AU6601_MS_INT_INT_TIMEOUT BIT(20)
#define AU6601_MS_INT_INT_RESP_ERROR BIT(19)
#define AU6601_MS_INT_CED_ERROR BIT(18)
#define AU6601_MS_INT_TPC_TIMEOUT BIT(16)
#define AU6601_MS_INT_ERROR BIT(15)
#define AU6601_MS_INT_CARD_INSERT BIT(7)
#define AU6601_MS_INT_CARD_REMOVE BIT(6)
#define AU6601_MS_INT_BUF_READ_RDY BIT(5)
#define AU6601_MS_INT_BUF_WRITE_RDY BIT(4)
#define AU6601_MS_INT_DMA_END BIT(3)
#define AU6601_MS_INT_TPC_END BIT(1)
#define AU6601_MS_INT_DATA_MASK 0x00000038
#define AU6601_MS_INT_TPC_MASK 0x003d8002
#define AU6601_MS_INT_TPC_ERROR 0x003d0000
#define ALCOR_PCIE_LINK_CTRL_OFFSET 0x10
#define ALCOR_PCIE_LINK_CAP_OFFSET 0x0c
#define ALCOR_CAP_START_OFFSET 0x34
struct alcor_dev_cfg {
u8 dma;
};
struct alcor_pci_priv {
struct pci_dev *pdev;
struct pci_dev *parent_pdev;
struct device *dev;
void __iomem *iobase;
unsigned int irq;
unsigned long id; /* idr id */
struct alcor_dev_cfg *cfg;
};
void alcor_write8(struct alcor_pci_priv *priv, u8 val, unsigned int addr);
void alcor_write16(struct alcor_pci_priv *priv, u16 val, unsigned int addr);
void alcor_write32(struct alcor_pci_priv *priv, u32 val, unsigned int addr);
void alcor_write32be(struct alcor_pci_priv *priv, u32 val, unsigned int addr);
u8 alcor_read8(struct alcor_pci_priv *priv, unsigned int addr);
u32 alcor_read32(struct alcor_pci_priv *priv, unsigned int addr);
u32 alcor_read32be(struct alcor_pci_priv *priv, unsigned int addr);
#endif
@@ -0,0 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ALIGN_H
#define _LINUX_ALIGN_H
#include <vdso/align.h>
#endif /* _LINUX_ALIGN_H */
@@ -0,0 +1,270 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* allocation tagging
*/
#ifndef _LINUX_ALLOC_TAG_H
#define _LINUX_ALLOC_TAG_H
#include <linux/bug.h>
#include <linux/codetag.h>
#include <linux/container_of.h>
#include <linux/preempt.h>
#include <asm/percpu.h>
#include <linux/cpumask.h>
#include <linux/smp.h>
#include <linux/static_key.h>
#include <linux/irqflags.h>
struct alloc_tag_counters {
u64 bytes;
u64 calls;
};
/*
* An instance of this structure is created in a special ELF section at every
* allocation callsite. At runtime, the special section is treated as
* an array of these. Embedded codetag utilizes codetag framework.
*/
struct alloc_tag {
struct codetag ct;
struct alloc_tag_counters __percpu *counters;
} __aligned(8);
struct alloc_tag_kernel_section {
struct alloc_tag *first_tag;
unsigned long count;
};
struct alloc_tag_module_section {
union {
unsigned long start_addr;
struct alloc_tag *first_tag;
};
unsigned long end_addr;
/* used size */
unsigned long size;
};
#ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG
#define CODETAG_EMPTY ((void *)1)
static inline bool is_codetag_empty(union codetag_ref *ref)
{
return ref->ct == CODETAG_EMPTY;
}
static inline void set_codetag_empty(union codetag_ref *ref)
{
if (ref)
ref->ct = CODETAG_EMPTY;
}
#else /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
static inline bool is_codetag_empty(union codetag_ref *ref) { return false; }
static inline void set_codetag_empty(union codetag_ref *ref)
{
if (ref)
ref->ct = NULL;
}
#endif /* CONFIG_MEM_ALLOC_PROFILING_DEBUG */
#ifdef CONFIG_MEM_ALLOC_PROFILING
#define ALLOC_TAG_SECTION_NAME "alloc_tags"
struct codetag_bytes {
struct codetag *ct;
s64 bytes;
};
size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep);
static inline struct alloc_tag *ct_to_alloc_tag(struct codetag *ct)
{
return container_of(ct, struct alloc_tag, ct);
}
#if defined(CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU) && defined(MODULE)
/*
* When percpu variables are required to be defined as weak, static percpu
* variables can't be used inside a function (see comments for DECLARE_PER_CPU_SECTION).
* Instead we will account all module allocations to a single counter.
*/
DECLARE_PER_CPU(struct alloc_tag_counters, _shared_alloc_tag);
#define DEFINE_ALLOC_TAG(_alloc_tag) \
static struct alloc_tag _alloc_tag __used __aligned(8) \
__section(ALLOC_TAG_SECTION_NAME) = { \
.ct = CODE_TAG_INIT, \
.counters = &_shared_alloc_tag };
#else /* CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU && MODULE */
#ifdef MODULE
#define DEFINE_ALLOC_TAG(_alloc_tag) \
static struct alloc_tag _alloc_tag __used __aligned(8) \
__section(ALLOC_TAG_SECTION_NAME) = { \
.ct = CODE_TAG_INIT, \
.counters = NULL };
#else /* MODULE */
#define DEFINE_ALLOC_TAG(_alloc_tag) \
static DEFINE_PER_CPU(struct alloc_tag_counters, _alloc_tag_cntr); \
static struct alloc_tag _alloc_tag __used __aligned(8) \
__section(ALLOC_TAG_SECTION_NAME) = { \
.ct = CODE_TAG_INIT, \
.counters = &_alloc_tag_cntr };
#endif /* MODULE */
#endif /* CONFIG_ARCH_MODULE_NEEDS_WEAK_PER_CPU && MODULE */
DECLARE_STATIC_KEY_MAYBE(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
mem_alloc_profiling_key);
static inline bool mem_alloc_profiling_enabled(void)
{
return static_branch_maybe(CONFIG_MEM_ALLOC_PROFILING_ENABLED_BY_DEFAULT,
&mem_alloc_profiling_key);
}
static inline struct alloc_tag_counters alloc_tag_read(struct alloc_tag *tag)
{
struct alloc_tag_counters v = { 0, 0 };
struct alloc_tag_counters *counter;
int cpu;
for_each_possible_cpu(cpu) {
counter = per_cpu_ptr(tag->counters, cpu);
v.bytes += counter->bytes;
v.calls += counter->calls;
}
return v;
}
#ifdef CONFIG_MEM_ALLOC_PROFILING_DEBUG
static inline void alloc_tag_add_check(union codetag_ref *ref, struct alloc_tag *tag)
{
WARN_ONCE(ref && ref->ct && !is_codetag_empty(ref),
"alloc_tag was not cleared (got tag for %s:%u)\n",
ref->ct->filename, ref->ct->lineno);
WARN_ONCE(!tag, "current->alloc_tag not set\n");
}
static inline void alloc_tag_sub_check(union codetag_ref *ref)
{
WARN_ONCE(ref && !ref->ct, "alloc_tag was not set\n");
}
void alloc_tag_add_early_pfn(unsigned long pfn);
#else
static inline void alloc_tag_add_check(union codetag_ref *ref, struct alloc_tag *tag) {}
static inline void alloc_tag_sub_check(union codetag_ref *ref) {}
static inline void alloc_tag_add_early_pfn(unsigned long pfn) {}
#endif
/* Caller should verify both ref and tag to be valid */
static inline bool __alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag)
{
alloc_tag_add_check(ref, tag);
if (!ref || !tag)
return false;
ref->ct = &tag->ct;
return true;
}
static inline bool alloc_tag_ref_set(union codetag_ref *ref, struct alloc_tag *tag)
{
if (unlikely(!__alloc_tag_ref_set(ref, tag)))
return false;
/*
* We need in increment the call counter every time we have a new
* allocation or when we split a large allocation into smaller ones.
* Each new reference for every sub-allocation needs to increment call
* counter because when we free each part the counter will be decremented.
*/
this_cpu_inc(tag->counters->calls);
return true;
}
static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag, size_t bytes)
{
if (likely(alloc_tag_ref_set(ref, tag)))
this_cpu_add(tag->counters->bytes, bytes);
}
static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes)
{
struct alloc_tag *tag;
alloc_tag_sub_check(ref);
if (!ref || !ref->ct)
return;
if (is_codetag_empty(ref)) {
ref->ct = NULL;
return;
}
tag = ct_to_alloc_tag(ref->ct);
this_cpu_sub(tag->counters->bytes, bytes);
this_cpu_dec(tag->counters->calls);
ref->ct = NULL;
}
static inline void alloc_tag_set_inaccurate(struct alloc_tag *tag)
{
tag->ct.flags |= CODETAG_FLAG_INACCURATE;
}
static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag)
{
return !!(tag->ct.flags & CODETAG_FLAG_INACCURATE);
}
#define alloc_tag_record(p) ((p) = current->alloc_tag)
#else /* CONFIG_MEM_ALLOC_PROFILING */
#define DEFINE_ALLOC_TAG(_alloc_tag)
static inline bool mem_alloc_profiling_enabled(void) { return false; }
static inline void alloc_tag_add(union codetag_ref *ref, struct alloc_tag *tag,
size_t bytes) {}
static inline void alloc_tag_sub(union codetag_ref *ref, size_t bytes) {}
static inline void alloc_tag_set_inaccurate(struct alloc_tag *tag) {}
static inline bool alloc_tag_is_inaccurate(struct alloc_tag *tag) { return false; }
#define alloc_tag_record(p) do {} while (0)
#endif /* CONFIG_MEM_ALLOC_PROFILING */
#define alloc_hooks_tag(_tag, _do_alloc) \
({ \
typeof(_do_alloc) _res; \
if (mem_alloc_profiling_enabled()) { \
struct alloc_tag * __maybe_unused _old; \
_old = alloc_tag_save(_tag); \
_res = _do_alloc; \
alloc_tag_restore(_tag, _old); \
} else \
_res = _do_alloc; \
_res; \
})
#define alloc_hooks(_do_alloc) \
({ \
DEFINE_ALLOC_TAG(_alloc_tag); \
alloc_hooks_tag(&_alloc_tag, _do_alloc); \
})
#endif /* _LINUX_ALLOC_TAG_H */
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* altera_jtaguart.h -- Altera JTAG UART driver defines.
*/
#ifndef __ALTJUART_H
#define __ALTJUART_H
#define ALTERA_JTAGUART_MAJOR 204
#define ALTERA_JTAGUART_MINOR 186
struct altera_jtaguart_platform_uart {
unsigned long mapbase; /* Physical address base */
unsigned int irq; /* Interrupt vector */
};
#endif /* __ALTJUART_H */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* altera_uart.h -- Altera UART driver defines.
*/
#ifndef __ALTUART_H
#define __ALTUART_H
struct altera_uart_platform_uart {
unsigned long mapbase; /* Physical address base */
unsigned int irq; /* Interrupt vector */
unsigned int uartclk; /* UART clock rate */
unsigned int bus_shift; /* Bus shift (address stride) */
};
#endif /* __ALTUART_H */
@@ -0,0 +1,209 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/include/amba/bus.h
*
* This device type deals with ARM PrimeCells and anything else that
* presents a proper CID (0xB105F00D) at the end of the I/O register
* region or that is derived from a PrimeCell.
*
* Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
*/
#ifndef ASMARM_AMBA_H
#define ASMARM_AMBA_H
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/err.h>
#include <linux/resource.h>
#include <linux/regulator/consumer.h>
#define AMBA_NR_IRQS 9
#define AMBA_CID 0xb105f00d
#define CORESIGHT_CID 0xb105900d
/*
* CoreSight Architecture specification updates the ID specification
* for components on the AMBA bus. (ARM IHI 0029E)
*
* Bits 15:12 of the CID are the device class.
*
* Class 0xF remains for PrimeCell and legacy components. (AMBA_CID above)
* Class 0x9 defines the component as CoreSight (CORESIGHT_CID above)
* Class 0x0, 0x1, 0xB, 0xE define components that do not have driver support
* at present.
* Class 0x2-0x8,0xA and 0xD-0xD are presently reserved.
*
* Remaining CID bits stay as 0xb105-00d
*/
/**
* Class 0x9 components use additional values to form a Unique Component
* Identifier (UCI), where peripheral ID values are identical for different
* components. Passed to the amba bus code from the component driver via
* the amba_id->data pointer.
* @devarch : coresight devarch register value
* @devarch_mask: mask bits used for matching. 0 indicates UCI not used.
* @devtype : coresight device type value
* @data : additional driver data. As we have usurped the original
* pointer some devices may still need additional data
*/
struct amba_cs_uci_id {
unsigned int devarch;
unsigned int devarch_mask;
unsigned int devtype;
void *data;
};
/* define offsets for registers used by UCI */
#define UCI_REG_DEVTYPE_OFFSET 0xFCC
#define UCI_REG_DEVARCH_OFFSET 0xFBC
struct clk;
struct amba_device {
struct device dev;
struct resource res;
struct clk *pclk;
struct device_dma_parameters dma_parms;
unsigned int periphid;
struct mutex periphid_lock;
unsigned int cid;
struct amba_cs_uci_id uci;
unsigned int irq[AMBA_NR_IRQS];
/*
* Driver name to force a match. Do not set directly, because core
* frees it. Use driver_set_override() to set or clear it.
*/
const char *driver_override;
};
struct amba_driver {
struct device_driver drv;
int (*probe)(struct amba_device *, const struct amba_id *);
void (*remove)(struct amba_device *);
void (*shutdown)(struct amba_device *);
const struct amba_id *id_table;
/*
* For most device drivers, no need to care about this flag as long as
* all DMAs are handled through the kernel DMA API. For some special
* ones, for example VFIO drivers, they know how to manage the DMA
* themselves and set this flag so that the IOMMU layer will allow them
* to setup and manage their own I/O address space.
*/
bool driver_managed_dma;
};
/*
* Constants for the designer field of the Peripheral ID register. When bit 7
* is set to '1', bits [6:0] should be the JEP106 manufacturer identity code.
*/
enum amba_vendor {
AMBA_VENDOR_ARM = 0x41,
AMBA_VENDOR_ST = 0x80,
AMBA_VENDOR_QCOM = 0x51,
AMBA_VENDOR_LSI = 0xb6,
};
extern const struct bus_type amba_bustype;
#define to_amba_device(d) container_of_const(d, struct amba_device, dev)
#define amba_get_drvdata(d) dev_get_drvdata(&d->dev)
#define amba_set_drvdata(d,p) dev_set_drvdata(&d->dev, p)
/*
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define amba_driver_register(drv) \
__amba_driver_register(drv, THIS_MODULE)
#ifdef CONFIG_ARM_AMBA
int __amba_driver_register(struct amba_driver *, struct module *);
void amba_driver_unregister(struct amba_driver *);
bool dev_is_amba(const struct device *dev);
#else
static inline int __amba_driver_register(struct amba_driver *drv,
struct module *owner)
{
return -EINVAL;
}
static inline void amba_driver_unregister(struct amba_driver *drv)
{
}
static inline bool dev_is_amba(const struct device *dev)
{
return false;
}
#endif
struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
void amba_device_put(struct amba_device *);
int amba_device_add(struct amba_device *, struct resource *);
int amba_device_register(struct amba_device *, struct resource *);
void amba_device_unregister(struct amba_device *);
int amba_request_regions(struct amba_device *, const char *);
void amba_release_regions(struct amba_device *);
/* Some drivers don't use the struct amba_device */
#define AMBA_CONFIG_BITS(a) (((a) >> 24) & 0xff)
#define AMBA_REV_BITS(a) (((a) >> 20) & 0x0f)
#define AMBA_MANF_BITS(a) (((a) >> 12) & 0xff)
#define AMBA_PART_BITS(a) ((a) & 0xfff)
#define amba_config(d) AMBA_CONFIG_BITS((d)->periphid)
#define amba_rev(d) AMBA_REV_BITS((d)->periphid)
#define amba_manf(d) AMBA_MANF_BITS((d)->periphid)
#define amba_part(d) AMBA_PART_BITS((d)->periphid)
#define __AMBA_DEV(busid, data, mask) \
{ \
.coherent_dma_mask = mask, \
.init_name = busid, \
.platform_data = data, \
}
/*
* APB devices do not themselves have the ability to address memory,
* so DMA masks should be zero (much like USB peripheral devices.)
* The DMA controller DMA masks should be used instead (much like
* USB host controllers in conventional PCs.)
*/
#define AMBA_APB_DEVICE(name, busid, id, base, irqs, data) \
struct amba_device name##_device = { \
.dev = __AMBA_DEV(busid, data, 0), \
.res = DEFINE_RES_MEM(base, SZ_4K), \
.irq = irqs, \
.periphid = id, \
}
/*
* AHB devices are DMA capable, so set their DMA masks
*/
#define AMBA_AHB_DEVICE(name, busid, id, base, irqs, data) \
struct amba_device name##_device = { \
.dev = __AMBA_DEV(busid, data, ~0ULL), \
.res = DEFINE_RES_MEM(base, SZ_4K), \
.irq = irqs, \
.periphid = id, \
}
/*
* module_amba_driver() - Helper macro for drivers that don't do anything
* special in module init/exit. This eliminates a lot of boilerplate. Each
* module may only use this macro once, and calling it replaces module_init()
* and module_exit()
*/
#define module_amba_driver(__amba_drv) \
module_driver(__amba_drv, amba_driver_register, amba_driver_unregister)
/*
* builtin_amba_driver() - Helper macro for drivers that don't do anything
* special in driver initcall. This eliminates a lot of boilerplate. Each
* driver may only use this macro once, and calling it replaces the instance
* device_initcall().
*/
#define builtin_amba_driver(__amba_drv) \
builtin_driver(__amba_drv, amba_driver_register)
#endif
@@ -0,0 +1,78 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* linux/include/asm-arm/hardware/amba_kmi.h
*
* Internal header file for AMBA KMI ports
*
* Copyright (C) 2000 Deep Blue Solutions Ltd.
*
* ---------------------------------------------------------------------------
* From ARM PrimeCell(tm) PS2 Keyboard/Mouse Interface (PL050) Technical
* Reference Manual - ARM DDI 0143B - see http://www.arm.com/
* ---------------------------------------------------------------------------
*/
#ifndef ASM_ARM_HARDWARE_AMBA_KMI_H
#define ASM_ARM_HARDWARE_AMBA_KMI_H
/*
* KMI control register:
* KMICR_TYPE 0 = PS2/AT mode, 1 = No line control bit mode
* KMICR_RXINTREN 1 = enable RX interrupts
* KMICR_TXINTREN 1 = enable TX interrupts
* KMICR_EN 1 = enable KMI
* KMICR_FD 1 = force KMI data low
* KMICR_FC 1 = force KMI clock low
*/
#define KMICR (KMI_BASE + 0x00)
#define KMICR_TYPE (1 << 5)
#define KMICR_RXINTREN (1 << 4)
#define KMICR_TXINTREN (1 << 3)
#define KMICR_EN (1 << 2)
#define KMICR_FD (1 << 1)
#define KMICR_FC (1 << 0)
/*
* KMI status register:
* KMISTAT_TXEMPTY 1 = transmitter register empty
* KMISTAT_TXBUSY 1 = currently sending data
* KMISTAT_RXFULL 1 = receiver register ready to be read
* KMISTAT_RXBUSY 1 = currently receiving data
* KMISTAT_RXPARITY parity of last databyte received
* KMISTAT_IC current level of KMI clock input
* KMISTAT_ID current level of KMI data input
*/
#define KMISTAT (KMI_BASE + 0x04)
#define KMISTAT_TXEMPTY (1 << 6)
#define KMISTAT_TXBUSY (1 << 5)
#define KMISTAT_RXFULL (1 << 4)
#define KMISTAT_RXBUSY (1 << 3)
#define KMISTAT_RXPARITY (1 << 2)
#define KMISTAT_IC (1 << 1)
#define KMISTAT_ID (1 << 0)
/*
* KMI data register
*/
#define KMIDATA (KMI_BASE + 0x08)
/*
* KMI clock divisor: to generate 8MHz internal clock
* div = (ref / 8MHz) - 1; 0 <= div <= 15
*/
#define KMICLKDIV (KMI_BASE + 0x0c)
/*
* KMI interrupt register:
* KMIIR_TXINTR 1 = transmit interrupt asserted
* KMIIR_RXINTR 1 = receive interrupt asserted
*/
#define KMIIR (KMI_BASE + 0x10)
#define KMIIR_TXINTR (1 << 1)
#define KMIIR_RXINTR (1 << 0)
/*
* The size of the KMI primecell
*/
#define KMI_SIZE (0x100)
#endif
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/linux/amba/mmci.h
*/
#ifndef AMBA_MMCI_H
#define AMBA_MMCI_H
#include <linux/mmc/host.h>
/**
* struct mmci_platform_data - platform configuration for the MMCI
* (also known as PL180) block.
* @ocr_mask: available voltages on the 4 pins from the block, this
* is ignored if a regulator is used, see the MMC_VDD_* masks in
* mmc/host.h
* @status: if no GPIO line was given to the block in this function will
* be called to determine whether a card is present in the MMC slot or not
*/
struct mmci_platform_data {
unsigned int ocr_mask;
unsigned int (*status)(struct device *);
};
#endif
@@ -0,0 +1,278 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* include/linux/amba/pl022.h
*
* Copyright (C) 2008-2009 ST-Ericsson AB
* Copyright (C) 2006 STMicroelectronics Pvt. Ltd.
*
* Author: Linus Walleij <linus.walleij@stericsson.com>
*
* Initial version inspired by:
* linux-2.6.17-rc3-mm1/drivers/spi/pxa2xx_spi.c
* Initial adoption to PL022 by:
* Sachin Verma <sachin.verma@st.com>
*/
#ifndef _SSP_PL022_H
#define _SSP_PL022_H
#include <linux/dmaengine.h>
#include <linux/types.h>
/**
* whether SSP is in loopback mode or not
*/
enum ssp_loopback {
LOOPBACK_DISABLED,
LOOPBACK_ENABLED
};
/**
* enum ssp_interface - interfaces allowed for this SSP Controller
* @SSP_INTERFACE_MOTOROLA_SPI: Motorola Interface
* @SSP_INTERFACE_TI_SYNC_SERIAL: Texas Instrument Synchronous Serial
* interface
* @SSP_INTERFACE_NATIONAL_MICROWIRE: National Semiconductor Microwire
* interface
* @SSP_INTERFACE_UNIDIRECTIONAL: Unidirectional interface (STn8810
* &STn8815 only)
*/
enum ssp_interface {
SSP_INTERFACE_MOTOROLA_SPI,
SSP_INTERFACE_TI_SYNC_SERIAL,
SSP_INTERFACE_NATIONAL_MICROWIRE,
SSP_INTERFACE_UNIDIRECTIONAL
};
/**
* enum ssp_hierarchy - whether SSP is configured as Master or Slave
*/
enum ssp_hierarchy {
SSP_MASTER,
SSP_SLAVE
};
/**
* enum ssp_clock_params - clock parameters, to set SSP clock at a
* desired freq
*/
struct ssp_clock_params {
u8 cpsdvsr; /* value from 2 to 254 (even only!) */
u8 scr; /* value from 0 to 255 */
};
/**
* enum ssp_rx_endian - endianess of Rx FIFO Data
* this feature is only available in ST versionf of PL022
*/
enum ssp_rx_endian {
SSP_RX_MSB,
SSP_RX_LSB
};
/**
* enum ssp_tx_endian - endianess of Tx FIFO Data
*/
enum ssp_tx_endian {
SSP_TX_MSB,
SSP_TX_LSB
};
/**
* enum ssp_data_size - number of bits in one data element
*/
enum ssp_data_size {
SSP_DATA_BITS_4 = 0x03, SSP_DATA_BITS_5, SSP_DATA_BITS_6,
SSP_DATA_BITS_7, SSP_DATA_BITS_8, SSP_DATA_BITS_9,
SSP_DATA_BITS_10, SSP_DATA_BITS_11, SSP_DATA_BITS_12,
SSP_DATA_BITS_13, SSP_DATA_BITS_14, SSP_DATA_BITS_15,
SSP_DATA_BITS_16, SSP_DATA_BITS_17, SSP_DATA_BITS_18,
SSP_DATA_BITS_19, SSP_DATA_BITS_20, SSP_DATA_BITS_21,
SSP_DATA_BITS_22, SSP_DATA_BITS_23, SSP_DATA_BITS_24,
SSP_DATA_BITS_25, SSP_DATA_BITS_26, SSP_DATA_BITS_27,
SSP_DATA_BITS_28, SSP_DATA_BITS_29, SSP_DATA_BITS_30,
SSP_DATA_BITS_31, SSP_DATA_BITS_32
};
/**
* enum ssp_mode - SSP mode of operation (Communication modes)
*/
enum ssp_mode {
INTERRUPT_TRANSFER,
POLLING_TRANSFER,
DMA_TRANSFER
};
/**
* enum ssp_rx_level_trig - receive FIFO watermark level which triggers
* IT: Interrupt fires when _N_ or more elements in RX FIFO.
*/
enum ssp_rx_level_trig {
SSP_RX_1_OR_MORE_ELEM,
SSP_RX_4_OR_MORE_ELEM,
SSP_RX_8_OR_MORE_ELEM,
SSP_RX_16_OR_MORE_ELEM,
SSP_RX_32_OR_MORE_ELEM
};
/**
* Transmit FIFO watermark level which triggers (IT Interrupt fires
* when _N_ or more empty locations in TX FIFO)
*/
enum ssp_tx_level_trig {
SSP_TX_1_OR_MORE_EMPTY_LOC,
SSP_TX_4_OR_MORE_EMPTY_LOC,
SSP_TX_8_OR_MORE_EMPTY_LOC,
SSP_TX_16_OR_MORE_EMPTY_LOC,
SSP_TX_32_OR_MORE_EMPTY_LOC
};
/**
* enum SPI Clock Phase - clock phase (Motorola SPI interface only)
* @SSP_CLK_FIRST_EDGE: Receive data on first edge transition (actual direction depends on polarity)
* @SSP_CLK_SECOND_EDGE: Receive data on second edge transition (actual direction depends on polarity)
*/
enum ssp_spi_clk_phase {
SSP_CLK_FIRST_EDGE,
SSP_CLK_SECOND_EDGE
};
/**
* enum SPI Clock Polarity - clock polarity (Motorola SPI interface only)
* @SSP_CLK_POL_IDLE_LOW: Low inactive level
* @SSP_CLK_POL_IDLE_HIGH: High inactive level
*/
enum ssp_spi_clk_pol {
SSP_CLK_POL_IDLE_LOW,
SSP_CLK_POL_IDLE_HIGH
};
/**
* Microwire Conrol Lengths Command size in microwire format
*/
enum ssp_microwire_ctrl_len {
SSP_BITS_4 = 0x03, SSP_BITS_5, SSP_BITS_6,
SSP_BITS_7, SSP_BITS_8, SSP_BITS_9,
SSP_BITS_10, SSP_BITS_11, SSP_BITS_12,
SSP_BITS_13, SSP_BITS_14, SSP_BITS_15,
SSP_BITS_16, SSP_BITS_17, SSP_BITS_18,
SSP_BITS_19, SSP_BITS_20, SSP_BITS_21,
SSP_BITS_22, SSP_BITS_23, SSP_BITS_24,
SSP_BITS_25, SSP_BITS_26, SSP_BITS_27,
SSP_BITS_28, SSP_BITS_29, SSP_BITS_30,
SSP_BITS_31, SSP_BITS_32
};
/**
* enum Microwire Wait State
* @SSP_MWIRE_WAIT_ZERO: No wait state inserted after last command bit
* @SSP_MWIRE_WAIT_ONE: One wait state inserted after last command bit
*/
enum ssp_microwire_wait_state {
SSP_MWIRE_WAIT_ZERO,
SSP_MWIRE_WAIT_ONE
};
/**
* enum ssp_duplex - whether Full/Half Duplex on microwire, only
* available in the ST Micro variant.
* @SSP_MICROWIRE_CHANNEL_FULL_DUPLEX: SSPTXD becomes bi-directional,
* SSPRXD not used
* @SSP_MICROWIRE_CHANNEL_HALF_DUPLEX: SSPTXD is an output, SSPRXD is
* an input.
*/
enum ssp_duplex {
SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
SSP_MICROWIRE_CHANNEL_HALF_DUPLEX
};
/**
* enum ssp_clkdelay - an optional clock delay on the feedback clock
* only available in the ST Micro PL023 variant.
* @SSP_FEEDBACK_CLK_DELAY_NONE: no delay, the data coming in from the
* slave is sampled directly
* @SSP_FEEDBACK_CLK_DELAY_1T: the incoming slave data is sampled with
* a delay of T-dt
* @SSP_FEEDBACK_CLK_DELAY_2T: dito with a delay if 2T-dt
* @SSP_FEEDBACK_CLK_DELAY_3T: dito with a delay if 3T-dt
* @SSP_FEEDBACK_CLK_DELAY_4T: dito with a delay if 4T-dt
* @SSP_FEEDBACK_CLK_DELAY_5T: dito with a delay if 5T-dt
* @SSP_FEEDBACK_CLK_DELAY_6T: dito with a delay if 6T-dt
* @SSP_FEEDBACK_CLK_DELAY_7T: dito with a delay if 7T-dt
*/
enum ssp_clkdelay {
SSP_FEEDBACK_CLK_DELAY_NONE,
SSP_FEEDBACK_CLK_DELAY_1T,
SSP_FEEDBACK_CLK_DELAY_2T,
SSP_FEEDBACK_CLK_DELAY_3T,
SSP_FEEDBACK_CLK_DELAY_4T,
SSP_FEEDBACK_CLK_DELAY_5T,
SSP_FEEDBACK_CLK_DELAY_6T,
SSP_FEEDBACK_CLK_DELAY_7T
};
/**
* CHIP select/deselect commands
*/
enum ssp_chip_select {
SSP_CHIP_SELECT,
SSP_CHIP_DESELECT
};
struct dma_chan;
/**
* struct pl022_ssp_master - device.platform_data for SPI controller devices.
* @bus_id: identifier for this bus
* @enable_dma: if true enables DMA driven transfers.
* @dma_filter: callback filter for dma_request_channel.
* @dma_rx_param: parameter to locate an RX DMA channel.
* @dma_tx_param: parameter to locate a TX DMA channel.
* @autosuspend_delay: delay in ms following transfer completion before the
* runtime power management system suspends the device. A setting of 0
* indicates no delay and the device will be suspended immediately.
* @rt: indicates the controller should run the message pump with realtime
* priority to minimise the transfer latency on the bus.
*/
struct pl022_ssp_controller {
u16 bus_id;
u8 enable_dma:1;
dma_filter_fn dma_filter;
void *dma_rx_param;
void *dma_tx_param;
int autosuspend_delay;
bool rt;
};
/**
* struct ssp_config_chip - spi_board_info.controller_data for SPI
* slave devices, copied to spi_device.controller_data.
*
* @iface: Interface type(Motorola, TI, Microwire, Universal)
* @hierarchy: sets whether interface is master or slave
* @slave_tx_disable: SSPTXD is disconnected (in slave mode only)
* @clk_freq: Tune freq parameters of SSP(when in master mode)
* @com_mode: communication mode: polling, Interrupt or DMA
* @rx_lev_trig: Rx FIFO watermark level (for IT & DMA mode)
* @tx_lev_trig: Tx FIFO watermark level (for IT & DMA mode)
* @ctrl_len: Microwire interface: Control length
* @wait_state: Microwire interface: Wait state
* @duplex: Microwire interface: Full/Half duplex
* @clkdelay: on the PL023 variant, the delay in feeback clock cycles
* before sampling the incoming line
*/
struct pl022_config_chip {
enum ssp_interface iface;
enum ssp_hierarchy hierarchy;
bool slave_tx_disable;
struct ssp_clock_params clk_freq;
enum ssp_mode com_mode;
enum ssp_rx_level_trig rx_lev_trig;
enum ssp_tx_level_trig tx_lev_trig;
enum ssp_microwire_ctrl_len ctrl_len;
enum ssp_microwire_wait_state wait_state;
enum ssp_duplex duplex;
enum ssp_clkdelay clkdelay;
};
#endif /* _SSP_PL022_H */
@@ -0,0 +1,217 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* include/linux/amba/pl080.h
*
* Copyright 2008 Openmoko, Inc.
* Copyright 2008 Simtec Electronics
* http://armlinux.simtec.co.uk/
* Ben Dooks <ben@simtec.co.uk>
*
* ARM PrimeCell PL080 DMA controller
*/
/* Note, there are some Samsung updates to this controller block which
* make it not entierly compatible with the PL080 specification from
* ARM. When in doubt, check the Samsung documentation first.
*
* The Samsung defines are PL080S, and add an extra control register,
* the ability to move more than 2^11 counts of data and some extra
* OneNAND features.
*/
#ifndef ASM_PL080_H
#define ASM_PL080_H
#define PL080_INT_STATUS (0x00)
#define PL080_TC_STATUS (0x04)
#define PL080_TC_CLEAR (0x08)
#define PL080_ERR_STATUS (0x0C)
#define PL080_ERR_CLEAR (0x10)
#define PL080_RAW_TC_STATUS (0x14)
#define PL080_RAW_ERR_STATUS (0x18)
#define PL080_EN_CHAN (0x1c)
#define PL080_SOFT_BREQ (0x20)
#define PL080_SOFT_SREQ (0x24)
#define PL080_SOFT_LBREQ (0x28)
#define PL080_SOFT_LSREQ (0x2C)
#define PL080_CONFIG (0x30)
#define PL080_CONFIG_M2_BE BIT(2)
#define PL080_CONFIG_M1_BE BIT(1)
#define PL080_CONFIG_ENABLE BIT(0)
#define PL080_SYNC (0x34)
/* The Faraday Technology FTDMAC020 variant registers */
#define FTDMAC020_CH_BUSY (0x20)
/* Identical to PL080_CONFIG */
#define FTDMAC020_CSR (0x24)
/* Identical to PL080_SYNC */
#define FTDMAC020_SYNC (0x2C)
#define FTDMAC020_REVISION (0x30)
#define FTDMAC020_FEATURE (0x34)
/* Per channel configuration registers */
#define PL080_Cx_BASE(x) ((0x100 + (x * 0x20)))
#define PL080_CH_SRC_ADDR (0x00)
#define PL080_CH_DST_ADDR (0x04)
#define PL080_CH_LLI (0x08)
#define PL080_CH_CONTROL (0x0C)
#define PL080_CH_CONFIG (0x10)
#define PL080S_CH_CONTROL2 (0x10)
#define PL080S_CH_CONFIG (0x14)
/* The Faraday FTDMAC020 derivative shuffles the registers around */
#define FTDMAC020_CH_CSR (0x00)
#define FTDMAC020_CH_CFG (0x04)
#define FTDMAC020_CH_SRC_ADDR (0x08)
#define FTDMAC020_CH_DST_ADDR (0x0C)
#define FTDMAC020_CH_LLP (0x10)
#define FTDMAC020_CH_SIZE (0x14)
#define PL080_LLI_ADDR_MASK GENMASK(31, 2)
#define PL080_LLI_ADDR_SHIFT (2)
#define PL080_LLI_LM_AHB2 BIT(0)
#define PL080_CONTROL_TC_IRQ_EN BIT(31)
#define PL080_CONTROL_PROT_MASK GENMASK(30, 28)
#define PL080_CONTROL_PROT_SHIFT (28)
#define PL080_CONTROL_PROT_CACHE BIT(30)
#define PL080_CONTROL_PROT_BUFF BIT(29)
#define PL080_CONTROL_PROT_SYS BIT(28)
#define PL080_CONTROL_DST_INCR BIT(27)
#define PL080_CONTROL_SRC_INCR BIT(26)
#define PL080_CONTROL_DST_AHB2 BIT(25)
#define PL080_CONTROL_SRC_AHB2 BIT(24)
#define PL080_CONTROL_DWIDTH_MASK GENMASK(23, 21)
#define PL080_CONTROL_DWIDTH_SHIFT (21)
#define PL080_CONTROL_SWIDTH_MASK GENMASK(20, 18)
#define PL080_CONTROL_SWIDTH_SHIFT (18)
#define PL080_CONTROL_DB_SIZE_MASK GENMASK(17, 15)
#define PL080_CONTROL_DB_SIZE_SHIFT (15)
#define PL080_CONTROL_SB_SIZE_MASK GENMASK(14, 12)
#define PL080_CONTROL_SB_SIZE_SHIFT (12)
#define PL080_CONTROL_TRANSFER_SIZE_MASK GENMASK(11, 0)
#define PL080S_CONTROL_TRANSFER_SIZE_MASK GENMASK(24, 0)
#define PL080_CONTROL_TRANSFER_SIZE_SHIFT (0)
#define PL080_BSIZE_1 (0x0)
#define PL080_BSIZE_4 (0x1)
#define PL080_BSIZE_8 (0x2)
#define PL080_BSIZE_16 (0x3)
#define PL080_BSIZE_32 (0x4)
#define PL080_BSIZE_64 (0x5)
#define PL080_BSIZE_128 (0x6)
#define PL080_BSIZE_256 (0x7)
#define PL080_WIDTH_8BIT (0x0)
#define PL080_WIDTH_16BIT (0x1)
#define PL080_WIDTH_32BIT (0x2)
#define PL080N_CONFIG_ITPROT BIT(20)
#define PL080N_CONFIG_SECPROT BIT(19)
#define PL080_CONFIG_HALT BIT(18)
#define PL080_CONFIG_ACTIVE BIT(17) /* RO */
#define PL080_CONFIG_LOCK BIT(16)
#define PL080_CONFIG_TC_IRQ_MASK BIT(15)
#define PL080_CONFIG_ERR_IRQ_MASK BIT(14)
#define PL080_CONFIG_FLOW_CONTROL_MASK GENMASK(13, 11)
#define PL080_CONFIG_FLOW_CONTROL_SHIFT (11)
#define PL080_CONFIG_DST_SEL_MASK GENMASK(9, 6)
#define PL080_CONFIG_DST_SEL_SHIFT (6)
#define PL080_CONFIG_SRC_SEL_MASK GENMASK(4, 1)
#define PL080_CONFIG_SRC_SEL_SHIFT (1)
#define PL080_CONFIG_ENABLE BIT(0)
#define PL080_FLOW_MEM2MEM (0x0)
#define PL080_FLOW_MEM2PER (0x1)
#define PL080_FLOW_PER2MEM (0x2)
#define PL080_FLOW_SRC2DST (0x3)
#define PL080_FLOW_SRC2DST_DST (0x4)
#define PL080_FLOW_MEM2PER_PER (0x5)
#define PL080_FLOW_PER2MEM_PER (0x6)
#define PL080_FLOW_SRC2DST_SRC (0x7)
#define FTDMAC020_CH_CSR_TC_MSK BIT(31)
/* Later versions have a threshold in bits 24..26, */
#define FTDMAC020_CH_CSR_FIFOTH_MSK GENMASK(26, 24)
#define FTDMAC020_CH_CSR_FIFOTH_SHIFT (24)
#define FTDMAC020_CH_CSR_CHPR1_MSK GENMASK(23, 22)
#define FTDMAC020_CH_CSR_PROT3 BIT(21)
#define FTDMAC020_CH_CSR_PROT2 BIT(20)
#define FTDMAC020_CH_CSR_PROT1 BIT(19)
#define FTDMAC020_CH_CSR_SRC_SIZE_MSK GENMASK(18, 16)
#define FTDMAC020_CH_CSR_SRC_SIZE_SHIFT (16)
#define FTDMAC020_CH_CSR_ABT BIT(15)
#define FTDMAC020_CH_CSR_SRC_WIDTH_MSK GENMASK(13, 11)
#define FTDMAC020_CH_CSR_SRC_WIDTH_SHIFT (11)
#define FTDMAC020_CH_CSR_DST_WIDTH_MSK GENMASK(10, 8)
#define FTDMAC020_CH_CSR_DST_WIDTH_SHIFT (8)
#define FTDMAC020_CH_CSR_MODE BIT(7)
/* 00 = increase, 01 = decrease, 10 = fix */
#define FTDMAC020_CH_CSR_SRCAD_CTL_MSK GENMASK(6, 5)
#define FTDMAC020_CH_CSR_SRCAD_CTL_SHIFT (5)
#define FTDMAC020_CH_CSR_DSTAD_CTL_MSK GENMASK(4, 3)
#define FTDMAC020_CH_CSR_DSTAD_CTL_SHIFT (3)
#define FTDMAC020_CH_CSR_SRC_SEL BIT(2)
#define FTDMAC020_CH_CSR_DST_SEL BIT(1)
#define FTDMAC020_CH_CSR_EN BIT(0)
/* FIFO threshold setting */
#define FTDMAC020_CH_CSR_FIFOTH_1 (0x0)
#define FTDMAC020_CH_CSR_FIFOTH_2 (0x1)
#define FTDMAC020_CH_CSR_FIFOTH_4 (0x2)
#define FTDMAC020_CH_CSR_FIFOTH_8 (0x3)
#define FTDMAC020_CH_CSR_FIFOTH_16 (0x4)
/* The FTDMAC020 supports 64bit wide transfers */
#define FTDMAC020_WIDTH_64BIT (0x3)
/* Address can be increased, decreased or fixed */
#define FTDMAC020_CH_CSR_SRCAD_CTL_INC (0x0)
#define FTDMAC020_CH_CSR_SRCAD_CTL_DEC (0x1)
#define FTDMAC020_CH_CSR_SRCAD_CTL_FIXED (0x2)
#define FTDMAC020_CH_CFG_LLP_CNT_MASK GENMASK(19, 16)
#define FTDMAC020_CH_CFG_LLP_CNT_SHIFT (16)
#define FTDMAC020_CH_CFG_BUSY BIT(8)
#define FTDMAC020_CH_CFG_INT_ABT_MASK BIT(2)
#define FTDMAC020_CH_CFG_INT_ERR_MASK BIT(1)
#define FTDMAC020_CH_CFG_INT_TC_MASK BIT(0)
/* Inside the LLIs, the applicable CSR fields are mapped differently */
#define FTDMAC020_LLI_TC_MSK BIT(28)
#define FTDMAC020_LLI_SRC_WIDTH_MSK GENMASK(27, 25)
#define FTDMAC020_LLI_SRC_WIDTH_SHIFT (25)
#define FTDMAC020_LLI_DST_WIDTH_MSK GENMASK(24, 22)
#define FTDMAC020_LLI_DST_WIDTH_SHIFT (22)
#define FTDMAC020_LLI_SRCAD_CTL_MSK GENMASK(21, 20)
#define FTDMAC020_LLI_SRCAD_CTL_SHIFT (20)
#define FTDMAC020_LLI_DSTAD_CTL_MSK GENMASK(19, 18)
#define FTDMAC020_LLI_DSTAD_CTL_SHIFT (18)
#define FTDMAC020_LLI_SRC_SEL BIT(17)
#define FTDMAC020_LLI_DST_SEL BIT(16)
#define FTDMAC020_LLI_TRANSFER_SIZE_MASK GENMASK(11, 0)
#define FTDMAC020_LLI_TRANSFER_SIZE_SHIFT (0)
#define FTDMAC020_CFG_LLP_CNT_MASK GENMASK(19, 16)
#define FTDMAC020_CFG_LLP_CNT_SHIFT (16)
#define FTDMAC020_CFG_BUSY BIT(8)
#define FTDMAC020_CFG_INT_ABT_MSK BIT(2)
#define FTDMAC020_CFG_INT_ERR_MSK BIT(1)
#define FTDMAC020_CFG_INT_TC_MSK BIT(0)
/* DMA linked list chain structure */
struct pl080_lli {
u32 src_addr;
u32 dst_addr;
u32 next_lli;
u32 control0;
};
struct pl080s_lli {
u32 src_addr;
u32 dst_addr;
u32 next_lli;
u32 control0;
u32 control1;
};
#endif /* ASM_PL080_H */
@@ -0,0 +1,130 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* linux/amba/pl08x.h - ARM PrimeCell DMA Controller driver
*
* Copyright (C) 2005 ARM Ltd
* Copyright (C) 2010 ST-Ericsson SA
*
* pl08x information required by platform code
*
* Please credit ARM.com
* Documentation: ARM DDI 0196D
*/
#ifndef AMBA_PL08X_H
#define AMBA_PL08X_H
/* We need sizes of structs from this header */
#include <linux/dmaengine.h>
#include <linux/interrupt.h>
struct pl08x_driver_data;
struct pl08x_phy_chan;
struct pl08x_txd;
/* Bitmasks for selecting AHB ports for DMA transfers */
enum {
PL08X_AHB1 = (1 << 0),
PL08X_AHB2 = (1 << 1)
};
/**
* struct pl08x_channel_data - data structure to pass info between
* platform and PL08x driver regarding channel configuration
* @bus_id: name of this device channel, not just a device name since
* devices may have more than one channel e.g. "foo_tx"
* @min_signal: the minimum DMA signal number to be muxed in for this
* channel (for platforms supporting muxed signals). If you have
* static assignments, make sure this is set to the assigned signal
* number, PL08x have 16 possible signals in number 0 thru 15 so
* when these are not enough they often get muxed (in hardware)
* disabling simultaneous use of the same channel for two devices.
* @max_signal: the maximum DMA signal number to be muxed in for
* the channel. Set to the same as min_signal for
* devices with static assignments
* @muxval: a number usually used to poke into some mux regiser to
* mux in the signal to this channel
* @addr: source/target address in physical memory for this DMA channel,
* can be the address of a FIFO register for burst requests for example.
* This can be left undefined if the PrimeCell API is used for configuring
* this.
* @single: the device connected to this channel will request single DMA
* transfers, not bursts. (Bursts are default.)
* @periph_buses: the device connected to this channel is accessible via
* these buses (use PL08X_AHB1 | PL08X_AHB2).
*/
struct pl08x_channel_data {
const char *bus_id;
int min_signal;
int max_signal;
u32 muxval;
dma_addr_t addr;
bool single;
u8 periph_buses;
};
enum pl08x_burst_size {
PL08X_BURST_SZ_1,
PL08X_BURST_SZ_4,
PL08X_BURST_SZ_8,
PL08X_BURST_SZ_16,
PL08X_BURST_SZ_32,
PL08X_BURST_SZ_64,
PL08X_BURST_SZ_128,
PL08X_BURST_SZ_256,
};
enum pl08x_bus_width {
PL08X_BUS_WIDTH_8_BITS,
PL08X_BUS_WIDTH_16_BITS,
PL08X_BUS_WIDTH_32_BITS,
};
/**
* struct pl08x_platform_data - the platform configuration for the PL08x
* PrimeCells.
* @slave_channels: the channels defined for the different devices on the
* platform, all inclusive, including multiplexed channels. The available
* physical channels will be multiplexed around these signals as they are
* requested, just enumerate all possible channels.
* @num_slave_channels: number of elements in the slave channel array
* @memcpy_burst_size: the appropriate burst size for memcpy operations
* @memcpy_bus_width: memory bus width
* @memcpy_prot_buff: whether memcpy DMA is bufferable
* @memcpy_prot_cache: whether memcpy DMA is cacheable
* @get_xfer_signal: request a physical signal to be used for a DMA transfer
* immediately: if there is some multiplexing or similar blocking the use
* of the channel the transfer can be denied by returning less than zero,
* else it returns the allocated signal number
* @put_xfer_signal: indicate to the platform that this physical signal is not
* running any DMA transfer and multiplexing can be recycled
* @lli_buses: buses which LLIs can be fetched from: PL08X_AHB1 | PL08X_AHB2
* @mem_buses: buses which memory can be accessed from: PL08X_AHB1 | PL08X_AHB2
* @slave_map: DMA slave matching table
* @slave_map_len: number of elements in @slave_map
*/
struct pl08x_platform_data {
struct pl08x_channel_data *slave_channels;
unsigned int num_slave_channels;
enum pl08x_burst_size memcpy_burst_size;
enum pl08x_bus_width memcpy_bus_width;
bool memcpy_prot_buff;
bool memcpy_prot_cache;
int (*get_xfer_signal)(const struct pl08x_channel_data *);
void (*put_xfer_signal)(const struct pl08x_channel_data *, int);
u8 lli_buses;
u8 mem_buses;
const struct dma_slave_map *slave_map;
int slave_map_len;
};
#ifdef CONFIG_AMBA_PL08X
bool pl08x_filter_id(struct dma_chan *chan, void *chan_id);
#else
static inline bool pl08x_filter_id(struct dma_chan *chan, void *chan_id)
{
return false;
}
#endif
#endif /* AMBA_PL08X_H */
@@ -0,0 +1,237 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* linux/include/asm-arm/hardware/serial_amba.h
*
* Internal header file for AMBA serial ports
*
* Copyright (C) ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd.
*/
#ifndef ASM_ARM_HARDWARE_SERIAL_AMBA_H
#define ASM_ARM_HARDWARE_SERIAL_AMBA_H
#ifndef __ASSEMBLY__
#include <linux/bitfield.h>
#include <linux/bits.h>
#endif
#include <linux/types.h>
/* -------------------------------------------------------------------------------
* From AMBA UART (PL010) Block Specification
* -------------------------------------------------------------------------------
* UART Register Offsets.
*/
#define UART01x_DR 0x00 /* Data read or written from the interface. */
#define UART01x_RSR 0x04 /* Receive status register (Read). */
#define UART01x_ECR 0x04 /* Error clear register (Write). */
#define UART010_LCRH 0x08 /* Line control register, high byte. */
#define ST_UART011_DMAWM 0x08 /* DMA watermark configure register. */
#define UART010_LCRM 0x0C /* Line control register, middle byte. */
#define ST_UART011_TIMEOUT 0x0C /* Timeout period register. */
#define UART010_LCRL 0x10 /* Line control register, low byte. */
#define UART010_CR 0x14 /* Control register. */
#define UART01x_FR 0x18 /* Flag register (Read only). */
#define UART010_IIR 0x1C /* Interrupt identification register (Read). */
#define UART010_ICR 0x1C /* Interrupt clear register (Write). */
#define ST_UART011_LCRH_RX 0x1C /* Rx line control register. */
#define UART01x_ILPR 0x20 /* IrDA low power counter register. */
#define UART011_IBRD 0x24 /* Integer baud rate divisor register. */
#define UART011_FBRD 0x28 /* Fractional baud rate divisor register. */
#define UART011_LCRH 0x2c /* Line control register. */
#define ST_UART011_LCRH_TX 0x2c /* Tx Line control register. */
#define UART011_CR 0x30 /* Control register. */
#define UART011_IFLS 0x34 /* Interrupt fifo level select. */
#define UART011_IMSC 0x38 /* Interrupt mask. */
#define UART011_RIS 0x3c /* Raw interrupt status. */
#define UART011_MIS 0x40 /* Masked interrupt status. */
#define UART011_ICR 0x44 /* Interrupt clear register. */
#define UART011_DMACR 0x48 /* DMA control register. */
#define ST_UART011_XFCR 0x50 /* XON/XOFF control register. */
#define ST_UART011_XON1 0x54 /* XON1 register. */
#define ST_UART011_XON2 0x58 /* XON2 register. */
#define ST_UART011_XOFF1 0x5C /* XON1 register. */
#define ST_UART011_XOFF2 0x60 /* XON2 register. */
#define ST_UART011_ITCR 0x80 /* Integration test control register. */
#define ST_UART011_ITIP 0x84 /* Integration test input register. */
#define ST_UART011_ABCR 0x100 /* Autobaud control register. */
#define ST_UART011_ABIMSC 0x15C /* Autobaud interrupt mask/clear register. */
/*
* ZTE UART register offsets. This UART has a radically different address
* allocation from the ARM and ST variants, so we list all registers here.
* We assume unlisted registers do not exist.
*/
#define ZX_UART011_DR 0x04
#define ZX_UART011_FR 0x14
#define ZX_UART011_IBRD 0x24
#define ZX_UART011_FBRD 0x28
#define ZX_UART011_LCRH 0x30
#define ZX_UART011_CR 0x34
#define ZX_UART011_IFLS 0x38
#define ZX_UART011_IMSC 0x40
#define ZX_UART011_RIS 0x44
#define ZX_UART011_MIS 0x48
#define ZX_UART011_ICR 0x4c
#define ZX_UART011_DMACR 0x50
#define UART011_DR_OE BIT(11)
#define UART011_DR_BE BIT(10)
#define UART011_DR_PE BIT(9)
#define UART011_DR_FE BIT(8)
#define UART01x_RSR_OE BIT(3)
#define UART01x_RSR_BE BIT(2)
#define UART01x_RSR_PE BIT(1)
#define UART01x_RSR_FE BIT(0)
#define UART011_FR_RI BIT(8)
#define UART011_FR_TXFE BIT(7)
#define UART011_FR_RXFF BIT(6)
#define UART01x_FR_TXFF (1 << 5) /* used in ASM */
#define UART01x_FR_RXFE BIT(4)
#define UART01x_FR_BUSY (1 << 3) /* used in ASM */
#define UART01x_FR_DCD BIT(2)
#define UART01x_FR_DSR BIT(1)
#define UART01x_FR_CTS BIT(0)
#define UART01x_FR_TMSK (UART01x_FR_TXFF + UART01x_FR_BUSY)
/*
* Some bits of Flag Register on ZTE device have different position from
* standard ones.
*/
#define ZX_UART01x_FR_BUSY BIT(8)
#define ZX_UART01x_FR_DSR BIT(3)
#define ZX_UART01x_FR_CTS BIT(1)
#define ZX_UART011_FR_RI BIT(0)
#define UART011_CR_CTSEN BIT(15) /* CTS hardware flow control */
#define UART011_CR_RTSEN BIT(14) /* RTS hardware flow control */
#define UART011_CR_OUT2 BIT(13) /* OUT2 */
#define UART011_CR_OUT1 BIT(12) /* OUT1 */
#define UART011_CR_RTS BIT(11) /* RTS */
#define UART011_CR_DTR BIT(10) /* DTR */
#define UART011_CR_RXE BIT(9) /* receive enable */
#define UART011_CR_TXE BIT(8) /* transmit enable */
#define UART011_CR_LBE BIT(7) /* loopback enable */
#define UART010_CR_RTIE BIT(6)
#define UART010_CR_TIE BIT(5)
#define UART010_CR_RIE BIT(4)
#define UART010_CR_MSIE BIT(3)
#define ST_UART011_CR_OVSFACT BIT(3) /* Oversampling factor */
#define UART01x_CR_IIRLP BIT(2) /* SIR low power mode */
#define UART01x_CR_SIREN BIT(1) /* SIR enable */
#define UART01x_CR_UARTEN BIT(0) /* UART enable */
#define UART011_LCRH_SPS BIT(7)
#define UART01x_LCRH_WLEN_8 0x60
#define UART01x_LCRH_WLEN_7 0x40
#define UART01x_LCRH_WLEN_6 0x20
#define UART01x_LCRH_WLEN_5 0x00
#define UART01x_LCRH_FEN BIT(4)
#define UART01x_LCRH_STP2 BIT(3)
#define UART01x_LCRH_EPS BIT(2)
#define UART01x_LCRH_PEN BIT(1)
#define UART01x_LCRH_BRK BIT(0)
#define ST_UART011_DMAWM_RX GENMASK(5, 3)
#define ST_UART011_DMAWM_RX_1 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 0)
#define ST_UART011_DMAWM_RX_2 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 1)
#define ST_UART011_DMAWM_RX_4 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 2)
#define ST_UART011_DMAWM_RX_8 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 3)
#define ST_UART011_DMAWM_RX_16 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 4)
#define ST_UART011_DMAWM_RX_32 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 5)
#define ST_UART011_DMAWM_RX_48 FIELD_PREP_CONST(ST_UART011_DMAWM_RX, 6)
#define ST_UART011_DMAWM_TX GENMASK(2, 0)
#define ST_UART011_DMAWM_TX_1 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 0)
#define ST_UART011_DMAWM_TX_2 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 1)
#define ST_UART011_DMAWM_TX_4 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 2)
#define ST_UART011_DMAWM_TX_8 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 3)
#define ST_UART011_DMAWM_TX_16 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 4)
#define ST_UART011_DMAWM_TX_32 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 5)
#define ST_UART011_DMAWM_TX_48 FIELD_PREP_CONST(ST_UART011_DMAWM_TX, 6)
#define UART010_IIR_RTIS BIT(3)
#define UART010_IIR_TIS BIT(2)
#define UART010_IIR_RIS BIT(1)
#define UART010_IIR_MIS BIT(0)
#define UART011_IFLS_RXIFLSEL GENMASK(5, 3)
#define UART011_IFLS_RX1_8 FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 0)
#define UART011_IFLS_RX2_8 FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 1)
#define UART011_IFLS_RX4_8 FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 2)
#define UART011_IFLS_RX6_8 FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 3)
#define UART011_IFLS_RX7_8 FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 4)
#define UART011_IFLS_TXIFLSEL GENMASK(2, 0)
#define UART011_IFLS_TX1_8 FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 0)
#define UART011_IFLS_TX2_8 FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 1)
#define UART011_IFLS_TX4_8 FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 2)
#define UART011_IFLS_TX6_8 FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 3)
#define UART011_IFLS_TX7_8 FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 4)
/* special values for ST vendor with deeper fifo */
#define UART011_IFLS_RX_HALF FIELD_PREP_CONST(UART011_IFLS_RXIFLSEL, 5)
#define UART011_IFLS_TX_HALF FIELD_PREP_CONST(UART011_IFLS_TXIFLSEL, 5)
#define UART011_OEIM BIT(10) /* overrun error interrupt mask */
#define UART011_BEIM BIT(9) /* break error interrupt mask */
#define UART011_PEIM BIT(8) /* parity error interrupt mask */
#define UART011_FEIM BIT(7) /* framing error interrupt mask */
#define UART011_RTIM BIT(6) /* receive timeout interrupt mask */
#define UART011_TXIM BIT(5) /* transmit interrupt mask */
#define UART011_RXIM BIT(4) /* receive interrupt mask */
#define UART011_DSRMIM BIT(3) /* DSR interrupt mask */
#define UART011_DCDMIM BIT(2) /* DCD interrupt mask */
#define UART011_CTSMIM BIT(1) /* CTS interrupt mask */
#define UART011_RIMIM BIT(0) /* RI interrupt mask */
#define UART011_OEIS BIT(10) /* overrun error interrupt status */
#define UART011_BEIS BIT(9) /* break error interrupt status */
#define UART011_PEIS BIT(8) /* parity error interrupt status */
#define UART011_FEIS BIT(7) /* framing error interrupt status */
#define UART011_RTIS BIT(6) /* receive timeout interrupt status */
#define UART011_TXIS BIT(5) /* transmit interrupt status */
#define UART011_RXIS BIT(4) /* receive interrupt status */
#define UART011_DSRMIS BIT(3) /* DSR interrupt status */
#define UART011_DCDMIS BIT(2) /* DCD interrupt status */
#define UART011_CTSMIS BIT(1) /* CTS interrupt status */
#define UART011_RIMIS BIT(0) /* RI interrupt status */
#define UART011_OEIC BIT(10) /* overrun error interrupt clear */
#define UART011_BEIC BIT(9) /* break error interrupt clear */
#define UART011_PEIC BIT(8) /* parity error interrupt clear */
#define UART011_FEIC BIT(7) /* framing error interrupt clear */
#define UART011_RTIC BIT(6) /* receive timeout interrupt clear */
#define UART011_TXIC BIT(5) /* transmit interrupt clear */
#define UART011_RXIC BIT(4) /* receive interrupt clear */
#define UART011_DSRMIC BIT(3) /* DSR interrupt clear */
#define UART011_DCDMIC BIT(2) /* DCD interrupt clear */
#define UART011_CTSMIC BIT(1) /* CTS interrupt clear */
#define UART011_RIMIC BIT(0) /* RI interrupt clear */
#define UART011_DMAONERR BIT(2) /* disable dma on error */
#define UART011_TXDMAE BIT(1) /* enable transmit dma */
#define UART011_RXDMAE BIT(0) /* enable receive dma */
#define UART01x_RSR_ANY (UART01x_RSR_OE | UART01x_RSR_BE | UART01x_RSR_PE | UART01x_RSR_FE)
#define UART01x_FR_MODEM_ANY (UART01x_FR_DCD | UART01x_FR_DSR | UART01x_FR_CTS)
#ifndef __ASSEMBLY__
struct amba_device; /* in uncompress this is included but amba/bus.h is not */
struct amba_pl010_data {
void (*set_mctrl)(struct amba_device *dev, void __iomem *base, unsigned int mctrl);
};
struct dma_chan;
struct amba_pl011_data {
bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
void *dma_rx_param;
void *dma_tx_param;
bool dma_rx_poll_enable;
unsigned int dma_rx_poll_rate;
unsigned int dma_rx_poll_timeout;
void (*init)(void);
void (*exit)(void);
};
#endif
#endif
@@ -0,0 +1,62 @@
/*
* ARM PrimeXsys System Controller SP810 header file
*
* Copyright (C) 2009 ST Microelectronics
* Viresh Kumar <vireshk@kernel.org>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#ifndef __AMBA_SP810_H
#define __AMBA_SP810_H
#include <linux/io.h>
/* sysctl registers offset */
#define SCCTRL 0x000
#define SCSYSSTAT 0x004
#define SCIMCTRL 0x008
#define SCIMSTAT 0x00C
#define SCXTALCTRL 0x010
#define SCPLLCTRL 0x014
#define SCPLLFCTRL 0x018
#define SCPERCTRL0 0x01C
#define SCPERCTRL1 0x020
#define SCPEREN 0x024
#define SCPERDIS 0x028
#define SCPERCLKEN 0x02C
#define SCPERSTAT 0x030
#define SCSYSID0 0xEE0
#define SCSYSID1 0xEE4
#define SCSYSID2 0xEE8
#define SCSYSID3 0xEEC
#define SCITCR 0xF00
#define SCITIR0 0xF04
#define SCITIR1 0xF08
#define SCITOR 0xF0C
#define SCCNTCTRL 0xF10
#define SCCNTDATA 0xF14
#define SCCNTSTEP 0xF18
#define SCPERIPHID0 0xFE0
#define SCPERIPHID1 0xFE4
#define SCPERIPHID2 0xFE8
#define SCPERIPHID3 0xFEC
#define SCPCELLID0 0xFF0
#define SCPCELLID1 0xFF4
#define SCPCELLID2 0xFF8
#define SCPCELLID3 0xFFC
#define SCCTRL_TIMERENnSEL_SHIFT(n) (15 + ((n) * 2))
static inline void sysctl_soft_reset(void __iomem *base)
{
/* switch to slow mode */
writel(0x2, base + SCCTRL);
/* writing any value to SCSYSSTAT reg will reset system */
writel(0, base + SCSYSSTAT);
}
#endif /* __AMBA_SP810_H */
@@ -0,0 +1,79 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2007-2010 Advanced Micro Devices, Inc.
* Author: Joerg Roedel <joerg.roedel@amd.com>
* Leo Duran <leo.duran@amd.com>
*/
#ifndef _ASM_X86_AMD_IOMMU_H
#define _ASM_X86_AMD_IOMMU_H
#include <linux/types.h>
struct amd_iommu;
#ifdef CONFIG_AMD_IOMMU
struct task_struct;
struct pci_dev;
extern void amd_iommu_detect(void);
#else /* CONFIG_AMD_IOMMU */
static inline void amd_iommu_detect(void) { }
#endif /* CONFIG_AMD_IOMMU */
#if defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP)
/* IOMMU AVIC Function */
extern int amd_iommu_register_ga_log_notifier(int (*notifier)(u32));
extern int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr);
extern int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr);
extern int amd_iommu_deactivate_guest_mode(void *data);
#else /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
static inline int
amd_iommu_register_ga_log_notifier(int (*notifier)(u32))
{
return 0;
}
static inline int amd_iommu_update_ga(void *data, int cpu, bool ga_log_intr)
{
return 0;
}
static inline int amd_iommu_activate_guest_mode(void *data, int cpu, bool ga_log_intr)
{
return 0;
}
static inline int amd_iommu_deactivate_guest_mode(void *data)
{
return 0;
}
#endif /* defined(CONFIG_AMD_IOMMU) && defined(CONFIG_IRQ_REMAP) */
int amd_iommu_get_num_iommus(void);
bool amd_iommu_pc_supported(void);
u8 amd_iommu_pc_get_max_banks(unsigned int idx);
u8 amd_iommu_pc_get_max_counters(unsigned int idx);
int amd_iommu_pc_set_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn,
u64 *value);
int amd_iommu_pc_get_reg(struct amd_iommu *iommu, u8 bank, u8 cntr, u8 fxn,
u64 *value);
struct amd_iommu *get_amd_iommu(unsigned int idx);
#ifdef CONFIG_KVM_AMD_SEV
int amd_iommu_snp_disable(void);
extern bool amd_iommu_sev_tio_supported(void);
#else
static inline int amd_iommu_snp_disable(void) { return 0; }
static inline bool amd_iommu_sev_tio_supported(void) { return false; }
#endif
#endif /* _ASM_X86_AMD_IOMMU_H */
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* AMD Platform Management Framework Interface
*
* Copyright (c) 2023, Advanced Micro Devices, Inc.
* All Rights Reserved.
*
* Authors: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
* Basavaraj Natikar <Basavaraj.Natikar@amd.com>
*/
#ifndef AMD_PMF_IO_H
#define AMD_PMF_IO_H
#include <linux/types.h>
/**
* enum sfh_message_type - Query the SFH message type
* @MT_HPD: Message ID to know the Human presence info from MP2 FW
* @MT_ALS: Message ID to know the Ambient light info from MP2 FW
* @MT_SRA: Message ID to know the SRA data from MP2 FW
*/
enum sfh_message_type {
MT_HPD,
MT_ALS,
MT_SRA,
};
/**
* enum sfh_hpd_info - Query the Human presence information
* @SFH_NOT_DETECTED: Check the HPD connection information from MP2 FW
* @SFH_USER_PRESENT: Check if the user is present from HPD sensor
* @SFH_USER_AWAY: Check if the user is away from HPD sensor
*/
enum sfh_hpd_info {
SFH_NOT_DETECTED,
SFH_USER_PRESENT,
SFH_USER_AWAY,
};
/**
* struct amd_sfh_info - get HPD sensor info from MP2 FW
* @ambient_light: Populates the ambient light information
* @user_present: Populates the user presence information
* @platform_type: Operating modes (clamshell, flat, tent, etc.)
* @laptop_placement: Device states (ontable, onlap, outbag)
*/
struct amd_sfh_info {
u32 ambient_light;
u8 user_present;
u32 platform_type;
u32 laptop_placement;
};
enum laptop_placement {
LP_UNKNOWN = 0,
ON_TABLE,
ON_LAP_MOTION,
IN_BAG,
OUT_OF_BAG,
LP_UNDEFINED,
};
/**
* struct amd_pmf_npu_metrics: Get NPU metrics data from PMF driver
* @npuclk_freq: NPU clock frequency [MHz]
* @npu_busy: NPU busy % [0-100]
* @npu_power: NPU power [mW]
* @mpnpuclk_freq: MPNPU [MHz]
* @npu_reads: NPU read bandwidth [MB/sec]
* @npu_writes: NPU write bandwidth [MB/sec]
*/
struct amd_pmf_npu_metrics {
u16 npuclk_freq;
u16 npu_busy[8];
u16 npu_power;
u16 mpnpuclk_freq;
u16 npu_reads;
u16 npu_writes;
};
int amd_get_sfh_info(struct amd_sfh_info *sfh_info, enum sfh_message_type op);
/* AMD PMF and NPU interface */
int amd_pmf_get_npu_data(struct amd_pmf_npu_metrics *info);
#endif
@@ -0,0 +1,127 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ANNOTATE_H
#define _LINUX_ANNOTATE_H
#include <linux/objtool_types.h>
#ifdef CONFIG_OBJTOOL
#define __ASM_ANNOTATE(section, label, type) \
.pushsection section, "M", @progbits, 8; \
.long label - ., type; \
.popsection
#ifndef __ASSEMBLY__
#define ASM_ANNOTATE_LABEL(label, type) \
__stringify(__ASM_ANNOTATE(.discard.annotate_insn, label, type))
#define ASM_ANNOTATE(type) \
"911: " \
__stringify(__ASM_ANNOTATE(.discard.annotate_insn, 911b, type))
#define ASM_ANNOTATE_DATA(type) \
"912: " \
__stringify(__ASM_ANNOTATE(.discard.annotate_data, 912b, type))
#else /* __ASSEMBLY__ */
.macro ANNOTATE type
.Lhere_\@:
__ASM_ANNOTATE(.discard.annotate_insn, .Lhere_\@, \type)
.endm
.macro ANNOTATE_DATA type
.Lhere_\@:
__ASM_ANNOTATE(.discard.annotate_data, .Lhere_\@, \type)
.endm
#endif /* __ASSEMBLY__ */
#else /* !CONFIG_OBJTOOL */
#ifndef __ASSEMBLY__
#define ASM_ANNOTATE_LABEL(label, type) ""
#define ASM_ANNOTATE(type)
#define ASM_ANNOTATE_DATA(type)
#else /* __ASSEMBLY__ */
.macro ANNOTATE type
.endm
.macro ANNOTATE_DATA type
.endm
#endif /* __ASSEMBLY__ */
#endif /* !CONFIG_OBJTOOL */
#ifndef __ASSEMBLY__
/*
* Annotate away the various 'relocation to !ENDBR` complaints; knowing that
* these relocations will never be used for indirect calls.
*/
#define ANNOTATE_NOENDBR ASM_ANNOTATE(ANNOTYPE_NOENDBR)
#define ANNOTATE_NOENDBR_SYM(sym) asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_NOENDBR))
/*
* This should be used immediately before an indirect jump/call. It tells
* objtool the subsequent indirect jump/call is vouched safe for retpoline
* builds.
*/
#define ANNOTATE_RETPOLINE_SAFE ASM_ANNOTATE(ANNOTYPE_RETPOLINE_SAFE)
/*
* See linux/instrumentation.h
*/
#define ANNOTATE_INSTR_BEGIN(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_BEGIN)
#define ANNOTATE_INSTR_END(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_INSTR_END)
/*
* objtool annotation to ignore the alternatives and only consider the original
* instruction(s).
*/
#define ANNOTATE_IGNORE_ALTERNATIVE ASM_ANNOTATE(ANNOTYPE_IGNORE_ALTS)
/*
* This macro indicates that the following intra-function call is valid.
* Any non-annotated intra-function call will cause objtool to issue a warning.
*/
#define ANNOTATE_INTRA_FUNCTION_CALL ASM_ANNOTATE(ANNOTYPE_INTRA_FUNCTION_CALL)
/*
* Use objtool to validate the entry requirement that all code paths do
* VALIDATE_UNRET_END before RET.
*
* NOTE: The macro must be used at the beginning of a global symbol, otherwise
* it will be ignored.
*/
#define ANNOTATE_UNRET_BEGIN ASM_ANNOTATE(ANNOTYPE_UNRET_BEGIN)
/*
* This should be used to refer to an instruction that is considered
* terminating, like a noreturn CALL or UD2 when we know they are not -- eg
* WARN using UD2.
*/
#define ANNOTATE_REACHABLE(label) ASM_ANNOTATE_LABEL(label, ANNOTYPE_REACHABLE)
/*
* This should not be used; it annotates away CFI violations. There are a few
* valid use cases like kexec handover to the next kernel image, and there is
* no security concern there.
*
* There are also a few real issues annotated away, like EFI because we can't
* control the EFI code.
*/
#define ANNOTATE_NOCFI_SYM(sym) asm(ASM_ANNOTATE_LABEL(sym, ANNOTYPE_NOCFI))
/*
* Annotate a special section entry. This emables livepatch module generation
* to find and extract individual special section entries as needed.
*/
#define ANNOTATE_DATA_SPECIAL ASM_ANNOTATE_DATA(ANNOTYPE_DATA_SPECIAL)
#else /* __ASSEMBLY__ */
#define ANNOTATE_NOENDBR ANNOTATE type=ANNOTYPE_NOENDBR
#define ANNOTATE_RETPOLINE_SAFE ANNOTATE type=ANNOTYPE_RETPOLINE_SAFE
/* ANNOTATE_INSTR_BEGIN ANNOTATE type=ANNOTYPE_INSTR_BEGIN */
/* ANNOTATE_INSTR_END ANNOTATE type=ANNOTYPE_INSTR_END */
#define ANNOTATE_IGNORE_ALTERNATIVE ANNOTATE type=ANNOTYPE_IGNORE_ALTS
#define ANNOTATE_INTRA_FUNCTION_CALL ANNOTATE type=ANNOTYPE_INTRA_FUNCTION_CALL
#define ANNOTATE_UNRET_BEGIN ANNOTATE type=ANNOTYPE_UNRET_BEGIN
#define ANNOTATE_REACHABLE ANNOTATE type=ANNOTYPE_REACHABLE
#define ANNOTATE_NOCFI_SYM ANNOTATE type=ANNOTYPE_NOCFI
#define ANNOTATE_DATA_SPECIAL ANNOTATE_DATA type=ANNOTYPE_DATA_SPECIAL
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_ANNOTATE_H */
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/linux/anon_inodes.h
*
* Copyright (C) 2007 Davide Libenzi <davidel@xmailserver.org>
*
*/
#ifndef _LINUX_ANON_INODES_H
#define _LINUX_ANON_INODES_H
#include <linux/types.h>
struct file_operations;
struct inode;
struct file *anon_inode_getfile(const char *name,
const struct file_operations *fops,
void *priv, int flags);
struct file *anon_inode_getfile_fmode(const char *name,
const struct file_operations *fops,
void *priv, int flags, fmode_t f_mode);
struct file *anon_inode_create_getfile(const char *name,
const struct file_operations *fops,
void *priv, int flags,
const struct inode *context_inode);
int anon_inode_getfd(const char *name, const struct file_operations *fops,
void *priv, int flags);
int anon_inode_create_getfd(const char *name,
const struct file_operations *fops,
void *priv, int flags,
const struct inode *context_inode);
#endif /* _LINUX_ANON_INODES_H */
@@ -0,0 +1,62 @@
/* SPDX-License-Identifier: MIT */
#ifndef _LINUX_APERTURE_H_
#define _LINUX_APERTURE_H_
#include <linux/types.h>
struct pci_dev;
struct platform_device;
#if defined(CONFIG_APERTURE_HELPERS)
int devm_aperture_acquire_for_platform_device(struct platform_device *pdev,
resource_size_t base,
resource_size_t size);
int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
const char *name);
int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev);
int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name);
#else
static inline int devm_aperture_acquire_for_platform_device(struct platform_device *pdev,
resource_size_t base,
resource_size_t size)
{
return 0;
}
static inline int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size,
const char *name)
{
return 0;
}
static inline int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev)
{
return 0;
}
static inline int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name)
{
return 0;
}
#endif
/**
* aperture_remove_all_conflicting_devices - remove all existing framebuffers
* @name: a descriptive name of the requesting driver
*
* This function removes all graphics device drivers. Use this function on systems
* that can have their framebuffer located anywhere in memory.
*
* Returns:
* 0 on success, or a negative errno code otherwise
*/
static inline int aperture_remove_all_conflicting_devices(const char *name)
{
return aperture_remove_conflicting_devices(0, (resource_size_t)-1, name);
}
#endif
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* -*- linux-c -*-
*
* (C) 2003 zecke@handhelds.org
*
* based on arch/arm/kernel/apm.c
* factor out the information needed by architectures to provide
* apm status
*/
#ifndef __LINUX_APM_EMULATION_H
#define __LINUX_APM_EMULATION_H
#include <linux/apm_bios.h>
/*
* This structure gets filled in by the machine specific 'get_power_status'
* implementation. Any fields which are not set default to a safe value.
*/
struct apm_power_info {
unsigned char ac_line_status;
#define APM_AC_OFFLINE 0
#define APM_AC_ONLINE 1
#define APM_AC_BACKUP 2
#define APM_AC_UNKNOWN 0xff
unsigned char battery_status;
#define APM_BATTERY_STATUS_HIGH 0
#define APM_BATTERY_STATUS_LOW 1
#define APM_BATTERY_STATUS_CRITICAL 2
#define APM_BATTERY_STATUS_CHARGING 3
#define APM_BATTERY_STATUS_NOT_PRESENT 4
#define APM_BATTERY_STATUS_UNKNOWN 0xff
unsigned char battery_flag;
#define APM_BATTERY_FLAG_HIGH (1 << 0)
#define APM_BATTERY_FLAG_LOW (1 << 1)
#define APM_BATTERY_FLAG_CRITICAL (1 << 2)
#define APM_BATTERY_FLAG_CHARGING (1 << 3)
#define APM_BATTERY_FLAG_NOT_PRESENT (1 << 7)
#define APM_BATTERY_FLAG_UNKNOWN 0xff
int battery_life;
int time;
int units;
#define APM_UNITS_MINS 0
#define APM_UNITS_SECS 1
#define APM_UNITS_UNKNOWN -1
};
/*
* This allows machines to provide their own "apm get power status" function.
*/
extern void (*apm_get_power_status)(struct apm_power_info *);
/*
* Queue an event (APM_SYS_SUSPEND or APM_CRITICAL_SUSPEND)
*/
void apm_queue_event(apm_event_t event);
#endif /* __LINUX_APM_EMULATION_H */
@@ -0,0 +1,92 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Include file for the interface to an APM BIOS
* Copyright 1994-2001 Stephen Rothwell (sfr@canb.auug.org.au)
*/
#ifndef _LINUX_APM_H
#define _LINUX_APM_H
#include <uapi/linux/apm_bios.h>
#define APM_CS (GDT_ENTRY_APMBIOS_BASE * 8)
#define APM_CS_16 (APM_CS + 8)
#define APM_DS (APM_CS_16 + 8)
/* Results of APM Installation Check */
#define APM_16_BIT_SUPPORT 0x0001
#define APM_32_BIT_SUPPORT 0x0002
#define APM_IDLE_SLOWS_CLOCK 0x0004
#define APM_BIOS_DISABLED 0x0008
#define APM_BIOS_DISENGAGED 0x0010
/*
* Data for APM that is persistent across module unload/load
*/
struct apm_info {
struct apm_bios_info bios;
unsigned short connection_version;
int get_power_status_broken;
int get_power_status_swabinminutes;
int allow_ints;
int forbid_idle;
int realmode_power_off;
int disabled;
};
/*
* The APM function codes
*/
#define APM_FUNC_INST_CHECK 0x5300
#define APM_FUNC_REAL_CONN 0x5301
#define APM_FUNC_16BIT_CONN 0x5302
#define APM_FUNC_32BIT_CONN 0x5303
#define APM_FUNC_DISCONN 0x5304
#define APM_FUNC_IDLE 0x5305
#define APM_FUNC_BUSY 0x5306
#define APM_FUNC_SET_STATE 0x5307
#define APM_FUNC_ENABLE_PM 0x5308
#define APM_FUNC_RESTORE_BIOS 0x5309
#define APM_FUNC_GET_STATUS 0x530a
#define APM_FUNC_GET_EVENT 0x530b
#define APM_FUNC_GET_STATE 0x530c
#define APM_FUNC_ENABLE_DEV_PM 0x530d
#define APM_FUNC_VERSION 0x530e
#define APM_FUNC_ENGAGE_PM 0x530f
#define APM_FUNC_GET_CAP 0x5310
#define APM_FUNC_RESUME_TIMER 0x5311
#define APM_FUNC_RESUME_ON_RING 0x5312
#define APM_FUNC_TIMER 0x5313
/*
* Function code for APM_FUNC_RESUME_TIMER
*/
#define APM_FUNC_DISABLE_TIMER 0
#define APM_FUNC_GET_TIMER 1
#define APM_FUNC_SET_TIMER 2
/*
* Function code for APM_FUNC_RESUME_ON_RING
*/
#define APM_FUNC_DISABLE_RING 0
#define APM_FUNC_ENABLE_RING 1
#define APM_FUNC_GET_RING 2
/*
* Function code for APM_FUNC_TIMER_STATUS
*/
#define APM_FUNC_TIMER_DISABLE 0
#define APM_FUNC_TIMER_ENABLE 1
#define APM_FUNC_TIMER_GET 2
/*
* in arch/i386/kernel/setup.c
*/
extern struct apm_info apm_info;
/*
* This is the "All Devices" ID communicated to the BIOS
*/
#define APM_DEVICE_BALL ((apm_info.connection_version > 0x0100) ? \
APM_DEVICE_ALL : APM_DEVICE_OLD_ALL)
#endif /* LINUX_APM_H */
@@ -0,0 +1,180 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* apple-gmux.h - microcontroller built into dual GPU MacBook Pro & Mac Pro
* Copyright (C) 2015 Lukas Wunner <lukas@wunner.de>
*/
#ifndef LINUX_APPLE_GMUX_H
#define LINUX_APPLE_GMUX_H
#include <linux/acpi.h>
#include <linux/io.h>
#include <linux/pnp.h>
#define GMUX_ACPI_HID "APP000B"
/*
* gmux port offsets. Many of these are not yet used, but may be in the
* future, and it's useful to have them documented here anyhow.
*/
#define GMUX_PORT_VERSION_MAJOR 0x04
#define GMUX_PORT_VERSION_MINOR 0x05
#define GMUX_PORT_VERSION_RELEASE 0x06
#define GMUX_PORT_SWITCH_DISPLAY 0x10
#define GMUX_PORT_SWITCH_GET_DISPLAY 0x11
#define GMUX_PORT_INTERRUPT_ENABLE 0x14
#define GMUX_PORT_INTERRUPT_STATUS 0x16
#define GMUX_PORT_SWITCH_DDC 0x28
#define GMUX_PORT_SWITCH_EXTERNAL 0x40
#define GMUX_PORT_SWITCH_GET_EXTERNAL 0x41
#define GMUX_PORT_DISCRETE_POWER 0x50
#define GMUX_PORT_MAX_BRIGHTNESS 0x70
#define GMUX_PORT_BRIGHTNESS 0x74
#define GMUX_PORT_VALUE 0xc2
#define GMUX_PORT_READ 0xd0
#define GMUX_PORT_WRITE 0xd4
#define GMUX_MMIO_PORT_SELECT 0x0e
#define GMUX_MMIO_COMMAND_SEND 0x0f
#define GMUX_MMIO_READ 0x00
#define GMUX_MMIO_WRITE 0x40
#define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4)
enum apple_gmux_type {
APPLE_GMUX_TYPE_PIO,
APPLE_GMUX_TYPE_INDEXED,
APPLE_GMUX_TYPE_MMIO,
};
#if IS_ENABLED(CONFIG_APPLE_GMUX)
static inline bool apple_gmux_is_indexed(unsigned long iostart)
{
u16 val;
outb(0xaa, iostart + 0xcc);
outb(0x55, iostart + 0xcd);
outb(0x00, iostart + 0xce);
val = inb(iostart + 0xcc) | (inb(iostart + 0xcd) << 8);
if (val == 0x55aa)
return true;
return false;
}
static inline bool apple_gmux_is_mmio(unsigned long iostart)
{
u8 __iomem *iomem_base = ioremap(iostart, 16);
u8 val;
if (!iomem_base)
return false;
/*
* If this is 0xff, then gmux must not be present, as the gmux would
* reset it to 0x00, or it would be one of 0x1, 0x4, 0x41, 0x44 if a
* command is currently being processed.
*/
val = ioread8(iomem_base + GMUX_MMIO_COMMAND_SEND);
iounmap(iomem_base);
return (val != 0xff);
}
/**
* apple_gmux_detect() - detect if gmux is built into the machine
*
* @pnp_dev: Device to probe or NULL to use the first matching device
* @type_ret: Returns (by reference) the apple_gmux_type of the device
*
* Detect if a supported gmux device is present by actually probing it.
* This avoids the false positives returned on some models by
* apple_gmux_present().
*
* Return: %true if a supported gmux ACPI device is detected and the kernel
* was configured with CONFIG_APPLE_GMUX, %false otherwise.
*/
static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, enum apple_gmux_type *type_ret)
{
u8 ver_major, ver_minor, ver_release;
struct device *dev = NULL;
struct acpi_device *adev;
struct resource *res;
enum apple_gmux_type type = APPLE_GMUX_TYPE_PIO;
bool ret = false;
if (!pnp_dev) {
adev = acpi_dev_get_first_match_dev(GMUX_ACPI_HID, NULL, -1);
if (!adev)
return false;
dev = get_device(acpi_get_first_physical_node(adev));
acpi_dev_put(adev);
if (!dev)
return false;
pnp_dev = to_pnp_dev(dev);
}
res = pnp_get_resource(pnp_dev, IORESOURCE_IO, 0);
if (res && resource_size(res) >= GMUX_MIN_IO_LEN) {
/*
* Invalid version information may indicate either that the gmux
* device isn't present or that it's a new one that uses indexed io.
*/
ver_major = inb(res->start + GMUX_PORT_VERSION_MAJOR);
ver_minor = inb(res->start + GMUX_PORT_VERSION_MINOR);
ver_release = inb(res->start + GMUX_PORT_VERSION_RELEASE);
if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) {
if (apple_gmux_is_indexed(res->start))
type = APPLE_GMUX_TYPE_INDEXED;
else
goto out;
}
} else {
res = pnp_get_resource(pnp_dev, IORESOURCE_MEM, 0);
if (res && apple_gmux_is_mmio(res->start))
type = APPLE_GMUX_TYPE_MMIO;
else
goto out;
}
if (type_ret)
*type_ret = type;
ret = true;
out:
put_device(dev);
return ret;
}
/**
* apple_gmux_present() - check if gmux ACPI device is present
*
* Drivers may use this to activate quirks specific to dual GPU MacBook Pros
* and Mac Pros, e.g. for deferred probing, runtime pm and backlight.
*
* Return: %true if gmux ACPI device is present and the kernel was configured
* with CONFIG_APPLE_GMUX, %false otherwise.
*/
static inline bool apple_gmux_present(void)
{
return acpi_dev_found(GMUX_ACPI_HID);
}
#else /* !CONFIG_APPLE_GMUX */
static inline bool apple_gmux_present(void)
{
return false;
}
static inline bool apple_gmux_detect(struct pnp_dev *pnp_dev, bool *indexed_ret)
{
return false;
}
#endif /* !CONFIG_APPLE_GMUX */
#endif /* LINUX_APPLE_GMUX_H */
@@ -0,0 +1,114 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/linux/arch_topology.h - arch specific cpu topology information
*/
#ifndef _LINUX_ARCH_TOPOLOGY_H_
#define _LINUX_ARCH_TOPOLOGY_H_
#include <linux/types.h>
#include <linux/percpu.h>
void topology_normalize_cpu_scale(void);
int topology_update_cpu_topology(void);
struct device_node;
bool topology_parse_cpu_capacity(struct device_node *cpu_node, int cpu);
DECLARE_PER_CPU(unsigned long, capacity_freq_ref);
static inline unsigned long topology_get_freq_ref(int cpu)
{
return per_cpu(capacity_freq_ref, cpu);
}
DECLARE_PER_CPU(unsigned long, arch_freq_scale);
static inline unsigned long topology_get_freq_scale(int cpu)
{
return per_cpu(arch_freq_scale, cpu);
}
void topology_set_freq_scale(const struct cpumask *cpus, unsigned long cur_freq,
unsigned long max_freq);
bool topology_scale_freq_invariant(void);
enum scale_freq_source {
SCALE_FREQ_SOURCE_CPUFREQ = 0,
SCALE_FREQ_SOURCE_ARCH,
SCALE_FREQ_SOURCE_CPPC,
SCALE_FREQ_SOURCE_VIRT,
};
struct scale_freq_data {
enum scale_freq_source source;
void (*set_freq_scale)(void);
};
void topology_scale_freq_tick(void);
void topology_set_scale_freq_source(struct scale_freq_data *data, const struct cpumask *cpus);
void topology_clear_scale_freq_source(enum scale_freq_source source, const struct cpumask *cpus);
DECLARE_PER_CPU(unsigned long, hw_pressure);
static inline unsigned long topology_get_hw_pressure(int cpu)
{
return per_cpu(hw_pressure, cpu);
}
void topology_update_hw_pressure(const struct cpumask *cpus,
unsigned long capped_freq);
struct cpu_topology {
int thread_id;
int core_id;
int cluster_id;
int package_id;
cpumask_t thread_sibling;
cpumask_t core_sibling;
cpumask_t cluster_sibling;
cpumask_t llc_sibling;
};
#ifdef CONFIG_GENERIC_ARCH_TOPOLOGY
extern struct cpu_topology cpu_topology[NR_CPUS];
#define topology_physical_package_id(cpu) (cpu_topology[cpu].package_id)
#define topology_cluster_id(cpu) (cpu_topology[cpu].cluster_id)
#define topology_core_id(cpu) (cpu_topology[cpu].core_id)
#define topology_core_cpumask(cpu) (&cpu_topology[cpu].core_sibling)
#define topology_sibling_cpumask(cpu) (&cpu_topology[cpu].thread_sibling)
#define topology_cluster_cpumask(cpu) (&cpu_topology[cpu].cluster_sibling)
#define topology_llc_cpumask(cpu) (&cpu_topology[cpu].llc_sibling)
#ifndef arch_cpu_is_threaded
#define arch_cpu_is_threaded() (0)
#endif
void init_cpu_topology(void);
void store_cpu_topology(unsigned int cpuid);
const struct cpumask *cpu_coregroup_mask(int cpu);
const struct cpumask *cpu_clustergroup_mask(int cpu);
void update_siblings_masks(unsigned int cpu);
void remove_cpu_topology(unsigned int cpuid);
void reset_cpu_topology(void);
int parse_acpi_topology(void);
void freq_inv_set_max_ratio(int cpu, u64 max_rate);
/*
* Architectures like ARM64 don't have reliable architectural way to get SMT
* information and depend on the firmware (ACPI/OF) report. Non-SMT core won't
* initialize thread_id so we can use this to detect the SMT implementation.
*/
static inline bool topology_core_has_smt(int cpu)
{
return cpu_topology[cpu].thread_id != -1;
}
#else
static inline bool topology_core_has_smt(int cpu) { return false; }
#endif /* CONFIG_GENERIC_ARCH_TOPOLOGY */
#endif /* _LINUX_ARCH_TOPOLOGY_H_ */
@@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ARGS_H
#define _LINUX_ARGS_H
/*
* How do these macros work?
*
* In __COUNT_ARGS() _0 to _15 are just placeholders from the start
* in order to make sure _n is positioned over the correct number
* from 15 to 0 (depending on X, which is a variadic argument list).
* They serve no purpose other than occupying a position. Since each
* macro parameter must have a distinct identifier, those identifiers
* are as good as any.
*
* In COUNT_ARGS() we use actual integers, so __COUNT_ARGS() returns
* that as _n.
*/
/* This counts to 15. Any more, it will return 16th argument. */
#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _n, X...) _n
#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
/* Concatenate two parameters, but allow them to be expanded beforehand. */
#define __CONCAT(a, b) a ## b
#define CONCATENATE(a, b) __CONCAT(a, b)
#endif /* _LINUX_ARGS_H */
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* CCI cache coherent interconnect support
*
* Copyright (C) 2013 ARM Ltd.
*/
#ifndef __LINUX_ARM_CCI_H
#define __LINUX_ARM_CCI_H
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/arm-cci.h>
struct device_node;
#ifdef CONFIG_ARM_CCI
extern bool cci_probed(void);
#else
static inline bool cci_probed(void) { return false; }
#endif
#ifdef CONFIG_ARM_CCI400_PORT_CTRL
extern int cci_ace_get_port(struct device_node *dn);
extern int cci_disable_port_by_cpu(u64 mpidr);
extern int __cci_control_port_by_device(struct device_node *dn, bool enable);
extern int __cci_control_port_by_index(u32 port, bool enable);
#else
static inline int cci_ace_get_port(struct device_node *dn)
{
return -ENODEV;
}
static inline int cci_disable_port_by_cpu(u64 mpidr) { return -ENODEV; }
static inline int __cci_control_port_by_device(struct device_node *dn,
bool enable)
{
return -ENODEV;
}
static inline int __cci_control_port_by_index(u32 port, bool enable)
{
return -ENODEV;
}
#endif
void cci_enable_port_for_self(void);
#define cci_disable_port_by_device(dev) \
__cci_control_port_by_device(dev, false)
#define cci_enable_port_by_device(dev) \
__cci_control_port_by_device(dev, true)
#define cci_disable_port_by_index(dev) \
__cci_control_port_by_index(dev, false)
#define cci_enable_port_by_index(dev) \
__cci_control_port_by_index(dev, true)
#endif
@@ -0,0 +1,760 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015, Linaro Limited
*/
#ifndef __LINUX_ARM_SMCCC_H
#define __LINUX_ARM_SMCCC_H
#include <linux/args.h>
#include <linux/init.h>
#ifndef __ASSEMBLY__
#include <linux/uuid.h>
#endif
#include <uapi/linux/const.h>
/*
* This file provides common defines for ARM SMC Calling Convention as
* specified in
* https://developer.arm.com/docs/den0028/latest
*
* This code is up-to-date with version DEN 0028 C
*/
#define ARM_SMCCC_STD_CALL _AC(0,U)
#define ARM_SMCCC_FAST_CALL _AC(1,U)
#define ARM_SMCCC_TYPE_SHIFT 31
#define ARM_SMCCC_SMC_32 0
#define ARM_SMCCC_SMC_64 1
#define ARM_SMCCC_CALL_CONV_SHIFT 30
#define ARM_SMCCC_OWNER_MASK 0x3F
#define ARM_SMCCC_OWNER_SHIFT 24
#define ARM_SMCCC_FUNC_MASK 0xFFFF
#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
#define ARM_SMCCC_IS_64(smc_val) \
((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
#define ARM_SMCCC_OWNER_NUM(smc_val) \
(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
(((type) << ARM_SMCCC_TYPE_SHIFT) | \
((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
((func_num) & ARM_SMCCC_FUNC_MASK))
#define ARM_SMCCC_OWNER_ARCH 0
#define ARM_SMCCC_OWNER_CPU 1
#define ARM_SMCCC_OWNER_SIP 2
#define ARM_SMCCC_OWNER_OEM 3
#define ARM_SMCCC_OWNER_STANDARD 4
#define ARM_SMCCC_OWNER_STANDARD_HYP 5
#define ARM_SMCCC_OWNER_VENDOR_HYP 6
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
#define ARM_SMCCC_FUNC_QUERY_CALL_UID 0xff01
#define ARM_SMCCC_QUIRK_NONE 0
#define ARM_SMCCC_QUIRK_QCOM_A6 1 /* Save/restore register a6 */
#define ARM_SMCCC_VERSION_1_0 0x10000
#define ARM_SMCCC_VERSION_1_1 0x10001
#define ARM_SMCCC_VERSION_1_2 0x10002
#define ARM_SMCCC_VERSION_1_3 0x10003
#define ARM_SMCCC_1_3_SVE_HINT 0x10000
#define ARM_SMCCC_CALL_HINTS ARM_SMCCC_1_3_SVE_HINT
#define ARM_SMCCC_VERSION_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 0)
#define ARM_SMCCC_ARCH_FEATURES_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 1)
#define ARM_SMCCC_ARCH_SOC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 2)
#define ARM_SMCCC_ARCH_WORKAROUND_1 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 0x8000)
#define ARM_SMCCC_ARCH_WORKAROUND_2 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 0x7fff)
#define ARM_SMCCC_ARCH_WORKAROUND_3 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
0, 0x3fff)
/* C1-Pro erratum 4193714: SME DVMSync early acknowledgement */
#define ARM_SMCCC_CPU_WORKAROUND_4193714 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_CPU, 0x10)
#define ARM_SMCCC_VENDOR_HYP_CALL_UID_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_FUNC_QUERY_CALL_UID)
/* KVM UID value: 28b46fb6-2ec5-11e9-a9ca-4b564d003a74 */
#define ARM_SMCCC_VENDOR_HYP_UID_KVM UUID_INIT(\
0x28b46fb6, 0x2ec5, 0x11e9, \
0xa9, 0xca, 0x4b, 0x56, \
0x4d, 0x00, 0x3a, 0x74)
/* KVM "vendor specific" services */
#define ARM_SMCCC_KVM_FUNC_FEATURES 0
#define ARM_SMCCC_KVM_FUNC_PTP 1
/* Start of pKVM hypercall range */
#define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2
#define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3
#define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6
#define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62
#define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63
/* End of pKVM hypercall range */
#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER 64
#define ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS 65
#define ARM_SMCCC_KVM_FUNC_FEATURES_2 127
#define ARM_SMCCC_KVM_NUM_FUNCS 128
#define ARM_SMCCC_VENDOR_HYP_KVM_FEATURES_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_FEATURES)
#define SMCCC_ARCH_WORKAROUND_RET_UNAFFECTED 1
/*
* ptp_kvm is a feature used for time sync between vm and host.
* ptp_kvm module in guest kernel will get service from host using
* this hypercall ID.
*/
#define ARM_SMCCC_VENDOR_HYP_KVM_PTP_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_PTP)
#define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_HYP_MEMINFO)
#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_MEM_SHARE)
#define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_MEM_UNSHARE)
#define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_MMIO_GUARD)
#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_VER)
#define ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_VENDOR_HYP, \
ARM_SMCCC_KVM_FUNC_DISCOVER_IMPL_CPUS)
/* ptp_kvm counter type ID */
#define KVM_PTP_VIRT_COUNTER 0
#define KVM_PTP_PHYS_COUNTER 1
/* Paravirtualised time calls (defined by ARM DEN0057A) */
#define ARM_SMCCC_HV_PV_TIME_FEATURES \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_STANDARD_HYP, \
0x20)
#define ARM_SMCCC_HV_PV_TIME_ST \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_STANDARD_HYP, \
0x21)
/* TRNG entropy source calls (defined by ARM DEN0098) */
#define ARM_SMCCC_TRNG_VERSION \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_STANDARD, \
0x50)
#define ARM_SMCCC_TRNG_FEATURES \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_STANDARD, \
0x51)
#define ARM_SMCCC_TRNG_GET_UUID \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_STANDARD, \
0x52)
#define ARM_SMCCC_TRNG_RND32 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_STANDARD, \
0x53)
#define ARM_SMCCC_TRNG_RND64 \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \
ARM_SMCCC_SMC_64, \
ARM_SMCCC_OWNER_STANDARD, \
0x53)
/*
* Return codes defined in ARM DEN 0070A
* ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C
*/
#define SMCCC_RET_SUCCESS 0
#define SMCCC_RET_NOT_SUPPORTED -1
#define SMCCC_RET_NOT_REQUIRED -2
#define SMCCC_RET_INVALID_PARAMETER -3
#ifndef __ASSEMBLY__
#include <linux/linkage.h>
#include <linux/types.h>
enum arm_smccc_conduit {
SMCCC_CONDUIT_NONE,
SMCCC_CONDUIT_SMC,
SMCCC_CONDUIT_HVC,
};
/**
* arm_smccc_1_1_get_conduit()
*
* Returns the conduit to be used for SMCCCv1.1 or later.
*
* When SMCCCv1.1 is not present, returns SMCCC_CONDUIT_NONE.
*/
enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void);
/**
* arm_smccc_get_version()
*
* Returns the version to be used for SMCCCv1.1 or later.
*
* When SMCCCv1.1 or above is not present, returns SMCCCv1.0, but this
* does not imply the presence of firmware or a valid conduit. Caller
* handling SMCCCv1.0 must determine the conduit by other means.
*/
u32 arm_smccc_get_version(void);
void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit);
/**
* arm_smccc_get_soc_id_version()
*
* Returns the SOC ID version.
*
* When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
*/
s32 arm_smccc_get_soc_id_version(void);
/**
* arm_smccc_get_soc_id_revision()
*
* Returns the SOC ID revision.
*
* When ARM_SMCCC_ARCH_SOC_ID is not present, returns SMCCC_RET_NOT_SUPPORTED.
*/
s32 arm_smccc_get_soc_id_revision(void);
#ifndef __ASSEMBLY__
/*
* Returns whether a specific hypervisor UUID is advertised for the
* Vendor Specific Hypervisor Service range.
*/
bool arm_smccc_hypervisor_has_uuid(const uuid_t *uuid);
static inline uuid_t smccc_res_to_uuid(u32 r0, u32 r1, u32 r2, u32 r3)
{
uuid_t uuid = {
.b = {
[0] = (r0 >> 0) & 0xff,
[1] = (r0 >> 8) & 0xff,
[2] = (r0 >> 16) & 0xff,
[3] = (r0 >> 24) & 0xff,
[4] = (r1 >> 0) & 0xff,
[5] = (r1 >> 8) & 0xff,
[6] = (r1 >> 16) & 0xff,
[7] = (r1 >> 24) & 0xff,
[8] = (r2 >> 0) & 0xff,
[9] = (r2 >> 8) & 0xff,
[10] = (r2 >> 16) & 0xff,
[11] = (r2 >> 24) & 0xff,
[12] = (r3 >> 0) & 0xff,
[13] = (r3 >> 8) & 0xff,
[14] = (r3 >> 16) & 0xff,
[15] = (r3 >> 24) & 0xff,
},
};
return uuid;
}
static inline u32 smccc_uuid_to_reg(const uuid_t *uuid, int reg)
{
u32 val = 0;
val |= (u32)(uuid->b[4 * reg + 0] << 0);
val |= (u32)(uuid->b[4 * reg + 1] << 8);
val |= (u32)(uuid->b[4 * reg + 2] << 16);
val |= (u32)(uuid->b[4 * reg + 3] << 24);
return val;
}
#endif /* !__ASSEMBLY__ */
/**
* struct arm_smccc_res - Result from SMC/HVC call
* @a0-a3 result values from registers 0 to 3
*/
struct arm_smccc_res {
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
};
#ifdef CONFIG_ARM64
/**
* struct arm_smccc_1_2_regs - Arguments for or Results from SMC/HVC call
* @a0-a17 argument values from registers 0 to 17
*/
struct arm_smccc_1_2_regs {
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
unsigned long a4;
unsigned long a5;
unsigned long a6;
unsigned long a7;
unsigned long a8;
unsigned long a9;
unsigned long a10;
unsigned long a11;
unsigned long a12;
unsigned long a13;
unsigned long a14;
unsigned long a15;
unsigned long a16;
unsigned long a17;
};
/**
* arm_smccc_1_2_hvc() - make HVC calls
* @args: arguments passed via struct arm_smccc_1_2_regs
* @res: result values via struct arm_smccc_1_2_regs
*
* This function is used to make HVC calls following SMC Calling Convention
* v1.2 or above. The content of the supplied param are copied from the
* structure to registers prior to the HVC instruction. The return values
* are updated with the content from registers on return from the HVC
* instruction.
*/
asmlinkage void arm_smccc_1_2_hvc(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
/**
* arm_smccc_1_2_smc() - make SMC calls
* @args: arguments passed via struct arm_smccc_1_2_regs
* @res: result values via struct arm_smccc_1_2_regs
*
* This function is used to make SMC calls following SMC Calling Convention
* v1.2 or above. The content of the supplied param are copied from the
* structure to registers prior to the SMC instruction. The return values
* are updated with the content from registers on return from the SMC
* instruction.
*/
asmlinkage void arm_smccc_1_2_smc(const struct arm_smccc_1_2_regs *args,
struct arm_smccc_1_2_regs *res);
#endif
/**
* struct arm_smccc_quirk - Contains quirk information
* @id: quirk identification
* @state: quirk specific information
* @a6: Qualcomm quirk entry for returning post-smc call contents of a6
*/
struct arm_smccc_quirk {
int id;
union {
unsigned long a6;
} state;
};
/**
* __arm_smccc_smc() - make SMC calls
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
* @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
*
* This function is used to make SMC calls following SMC Calling Convention.
* The content of the supplied param are copied to registers 0 to 7 prior
* to the SMC instruction. The return values are updated with the content
* from register 0 to 3 on return from the SMC instruction. An optional
* quirk structure provides vendor specific behavior.
*/
#ifdef CONFIG_HAVE_ARM_SMCCC
asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, unsigned long a6, unsigned long a7,
struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
#else
static inline void __arm_smccc_smc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, unsigned long a6, unsigned long a7,
struct arm_smccc_res *res, struct arm_smccc_quirk *quirk)
{
*res = (struct arm_smccc_res){};
}
#endif
/**
* __arm_smccc_hvc() - make HVC calls
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
* @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required.
*
* This function is used to make HVC calls following SMC Calling
* Convention. The content of the supplied param are copied to registers 0
* to 7 prior to the HVC instruction. The return values are updated with
* the content from register 0 to 3 on return from the HVC instruction. An
* optional quirk structure provides vendor specific behavior.
*/
asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, unsigned long a6, unsigned long a7,
struct arm_smccc_res *res, struct arm_smccc_quirk *quirk);
#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL)
#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__)
#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL)
#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__)
/* SMCCC v1.1 implementation madness follows */
#ifdef CONFIG_ARM64
#define SMCCC_SMC_INST "smc #0"
#define SMCCC_HVC_INST "hvc #0"
#elif defined(CONFIG_ARM)
#include <asm/opcodes-sec.h>
#include <asm/opcodes-virt.h>
#define SMCCC_SMC_INST __SMC(0)
#define SMCCC_HVC_INST __HVC(0)
#endif
#define __constraint_read_2 "r" (arg0)
#define __constraint_read_3 __constraint_read_2, "r" (arg1)
#define __constraint_read_4 __constraint_read_3, "r" (arg2)
#define __constraint_read_5 __constraint_read_4, "r" (arg3)
#define __constraint_read_6 __constraint_read_5, "r" (arg4)
#define __constraint_read_7 __constraint_read_6, "r" (arg5)
#define __constraint_read_8 __constraint_read_7, "r" (arg6)
#define __constraint_read_9 __constraint_read_8, "r" (arg7)
#define __declare_arg_2(a0, res) \
struct arm_smccc_res *___res = res; \
register unsigned long arg0 asm("r0") = (u32)a0
#define __declare_arg_3(a0, a1, res) \
typeof(a1) __a1 = a1; \
struct arm_smccc_res *___res = res; \
register unsigned long arg0 asm("r0") = (u32)a0; \
register typeof(a1) arg1 asm("r1") = __a1
#define __declare_arg_4(a0, a1, a2, res) \
typeof(a1) __a1 = a1; \
typeof(a2) __a2 = a2; \
struct arm_smccc_res *___res = res; \
register unsigned long arg0 asm("r0") = (u32)a0; \
register typeof(a1) arg1 asm("r1") = __a1; \
register typeof(a2) arg2 asm("r2") = __a2
#define __declare_arg_5(a0, a1, a2, a3, res) \
typeof(a1) __a1 = a1; \
typeof(a2) __a2 = a2; \
typeof(a3) __a3 = a3; \
struct arm_smccc_res *___res = res; \
register unsigned long arg0 asm("r0") = (u32)a0; \
register typeof(a1) arg1 asm("r1") = __a1; \
register typeof(a2) arg2 asm("r2") = __a2; \
register typeof(a3) arg3 asm("r3") = __a3
#define __declare_arg_6(a0, a1, a2, a3, a4, res) \
typeof(a4) __a4 = a4; \
__declare_arg_5(a0, a1, a2, a3, res); \
register typeof(a4) arg4 asm("r4") = __a4
#define __declare_arg_7(a0, a1, a2, a3, a4, a5, res) \
typeof(a5) __a5 = a5; \
__declare_arg_6(a0, a1, a2, a3, a4, res); \
register typeof(a5) arg5 asm("r5") = __a5
#define __declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res) \
typeof(a6) __a6 = a6; \
__declare_arg_7(a0, a1, a2, a3, a4, a5, res); \
register typeof(a6) arg6 asm("r6") = __a6
#define __declare_arg_9(a0, a1, a2, a3, a4, a5, a6, a7, res) \
typeof(a7) __a7 = a7; \
__declare_arg_8(a0, a1, a2, a3, a4, a5, a6, res); \
register typeof(a7) arg7 asm("r7") = __a7
/*
* We have an output list that is not necessarily used, and GCC feels
* entitled to optimise the whole sequence away. "volatile" is what
* makes it stick.
*/
#define __arm_smccc_1_1(inst, ...) \
do { \
register unsigned long r0 asm("r0"); \
register unsigned long r1 asm("r1"); \
register unsigned long r2 asm("r2"); \
register unsigned long r3 asm("r3"); \
CONCATENATE(__declare_arg_, \
COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
asm volatile(inst "\n" : \
"=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \
: CONCATENATE(__constraint_read_, \
COUNT_ARGS(__VA_ARGS__)) \
: "memory"); \
if (___res) \
*___res = (typeof(*___res)){r0, r1, r2, r3}; \
} while (0)
/*
* arm_smccc_1_1_smc() - make an SMCCC v1.1 compliant SMC call
*
* This is a variadic macro taking one to eight source arguments, and
* an optional return structure.
*
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
*
* This macro is used to make SMC calls following SMC Calling Convention v1.1.
* The content of the supplied param are copied to registers 0 to 7 prior
* to the SMC instruction. The return values are updated with the content
* from register 0 to 3 on return from the SMC instruction if not NULL.
*/
#define arm_smccc_1_1_smc(...) __arm_smccc_1_1(SMCCC_SMC_INST, __VA_ARGS__)
/*
* arm_smccc_1_1_hvc() - make an SMCCC v1.1 compliant HVC call
*
* This is a variadic macro taking one to eight source arguments, and
* an optional return structure.
*
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
*
* This macro is used to make HVC calls following SMC Calling Convention v1.1.
* The content of the supplied param are copied to registers 0 to 7 prior
* to the HVC instruction. The return values are updated with the content
* from register 0 to 3 on return from the HVC instruction if not NULL.
*/
#define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__)
/*
* Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED.
* Used when the SMCCC conduit is not defined. The empty asm statement
* avoids compiler warnings about unused variables.
*/
#define __fail_smccc_1_1(...) \
do { \
CONCATENATE(__declare_arg_, \
COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__); \
asm ("" : \
: CONCATENATE(__constraint_read_, \
COUNT_ARGS(__VA_ARGS__)) \
: "memory"); \
if (___res) \
___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
} while (0)
/*
* arm_smccc_1_1_invoke() - make an SMCCC v1.1 compliant call
*
* This is a variadic macro taking one to eight source arguments, and
* an optional return structure.
*
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
*
* This macro will make either an HVC call or an SMC call depending on the
* current SMCCC conduit. If no valid conduit is available then -1
* (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
*
* The return value also provides the conduit that was used.
*/
#define arm_smccc_1_1_invoke(...) ({ \
int method = arm_smccc_1_1_get_conduit(); \
switch (method) { \
case SMCCC_CONDUIT_HVC: \
arm_smccc_1_1_hvc(__VA_ARGS__); \
break; \
case SMCCC_CONDUIT_SMC: \
arm_smccc_1_1_smc(__VA_ARGS__); \
break; \
default: \
__fail_smccc_1_1(__VA_ARGS__); \
method = SMCCC_CONDUIT_NONE; \
break; \
} \
method; \
})
#ifdef CONFIG_ARM64
#define __fail_smccc_1_2(___res) \
do { \
if (___res) \
___res->a0 = SMCCC_RET_NOT_SUPPORTED; \
} while (0)
/*
* arm_smccc_1_2_invoke() - make an SMCCC v1.2 compliant call
*
* @args: SMC args are in the a0..a17 fields of the arm_smcc_1_2_regs structure
* @res: result values from registers 0 to 17
*
* This macro will make either an HVC call or an SMC call depending on the
* current SMCCC conduit. If no valid conduit is available then -1
* (SMCCC_RET_NOT_SUPPORTED) is returned in @res.a0 (if supplied).
*
* The return value also provides the conduit that was used.
*/
#define arm_smccc_1_2_invoke(args, res) ({ \
struct arm_smccc_1_2_regs *__args = args; \
struct arm_smccc_1_2_regs *__res = res; \
int method = arm_smccc_1_1_get_conduit(); \
switch (method) { \
case SMCCC_CONDUIT_HVC: \
arm_smccc_1_2_hvc(__args, __res); \
break; \
case SMCCC_CONDUIT_SMC: \
arm_smccc_1_2_smc(__args, __res); \
break; \
default: \
__fail_smccc_1_2(__res); \
method = SMCCC_CONDUIT_NONE; \
break; \
} \
method; \
})
#endif /*CONFIG_ARM64*/
#endif /*__ASSEMBLY__*/
#endif /*__LINUX_ARM_SMCCC_H*/
@@ -0,0 +1,515 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2021 ARM Ltd.
*/
#ifndef _LINUX_ARM_FFA_H
#define _LINUX_ARM_FFA_H
#include <linux/bitfield.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/uuid.h>
#define FFA_SMC(calling_convention, func_num) \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, (calling_convention), \
ARM_SMCCC_OWNER_STANDARD, (func_num))
#define FFA_SMC_32(func_num) FFA_SMC(ARM_SMCCC_SMC_32, (func_num))
#define FFA_SMC_64(func_num) FFA_SMC(ARM_SMCCC_SMC_64, (func_num))
#define FFA_ERROR FFA_SMC_32(0x60)
#define FFA_SUCCESS FFA_SMC_32(0x61)
#define FFA_FN64_SUCCESS FFA_SMC_64(0x61)
#define FFA_INTERRUPT FFA_SMC_32(0x62)
#define FFA_VERSION FFA_SMC_32(0x63)
#define FFA_FEATURES FFA_SMC_32(0x64)
#define FFA_RX_RELEASE FFA_SMC_32(0x65)
#define FFA_RXTX_MAP FFA_SMC_32(0x66)
#define FFA_FN64_RXTX_MAP FFA_SMC_64(0x66)
#define FFA_RXTX_UNMAP FFA_SMC_32(0x67)
#define FFA_PARTITION_INFO_GET FFA_SMC_32(0x68)
#define FFA_ID_GET FFA_SMC_32(0x69)
#define FFA_MSG_POLL FFA_SMC_32(0x6A)
#define FFA_MSG_WAIT FFA_SMC_32(0x6B)
#define FFA_YIELD FFA_SMC_32(0x6C)
#define FFA_RUN FFA_SMC_32(0x6D)
#define FFA_MSG_SEND FFA_SMC_32(0x6E)
#define FFA_MSG_SEND_DIRECT_REQ FFA_SMC_32(0x6F)
#define FFA_FN64_MSG_SEND_DIRECT_REQ FFA_SMC_64(0x6F)
#define FFA_MSG_SEND_DIRECT_RESP FFA_SMC_32(0x70)
#define FFA_FN64_MSG_SEND_DIRECT_RESP FFA_SMC_64(0x70)
#define FFA_MEM_DONATE FFA_SMC_32(0x71)
#define FFA_FN64_MEM_DONATE FFA_SMC_64(0x71)
#define FFA_MEM_LEND FFA_SMC_32(0x72)
#define FFA_FN64_MEM_LEND FFA_SMC_64(0x72)
#define FFA_MEM_SHARE FFA_SMC_32(0x73)
#define FFA_FN64_MEM_SHARE FFA_SMC_64(0x73)
#define FFA_MEM_RETRIEVE_REQ FFA_SMC_32(0x74)
#define FFA_FN64_MEM_RETRIEVE_REQ FFA_SMC_64(0x74)
#define FFA_MEM_RETRIEVE_RESP FFA_SMC_32(0x75)
#define FFA_MEM_RELINQUISH FFA_SMC_32(0x76)
#define FFA_MEM_RECLAIM FFA_SMC_32(0x77)
#define FFA_MEM_OP_PAUSE FFA_SMC_32(0x78)
#define FFA_MEM_OP_RESUME FFA_SMC_32(0x79)
#define FFA_MEM_FRAG_RX FFA_SMC_32(0x7A)
#define FFA_MEM_FRAG_TX FFA_SMC_32(0x7B)
#define FFA_NORMAL_WORLD_RESUME FFA_SMC_32(0x7C)
#define FFA_NOTIFICATION_BITMAP_CREATE FFA_SMC_32(0x7D)
#define FFA_NOTIFICATION_BITMAP_DESTROY FFA_SMC_32(0x7E)
#define FFA_NOTIFICATION_BIND FFA_SMC_32(0x7F)
#define FFA_NOTIFICATION_UNBIND FFA_SMC_32(0x80)
#define FFA_NOTIFICATION_SET FFA_SMC_32(0x81)
#define FFA_NOTIFICATION_GET FFA_SMC_32(0x82)
#define FFA_NOTIFICATION_INFO_GET FFA_SMC_32(0x83)
#define FFA_FN64_NOTIFICATION_INFO_GET FFA_SMC_64(0x83)
#define FFA_RX_ACQUIRE FFA_SMC_32(0x84)
#define FFA_SPM_ID_GET FFA_SMC_32(0x85)
#define FFA_MSG_SEND2 FFA_SMC_32(0x86)
#define FFA_SECONDARY_EP_REGISTER FFA_SMC_32(0x87)
#define FFA_FN64_SECONDARY_EP_REGISTER FFA_SMC_64(0x87)
#define FFA_MEM_PERM_GET FFA_SMC_32(0x88)
#define FFA_FN64_MEM_PERM_GET FFA_SMC_64(0x88)
#define FFA_MEM_PERM_SET FFA_SMC_32(0x89)
#define FFA_FN64_MEM_PERM_SET FFA_SMC_64(0x89)
#define FFA_CONSOLE_LOG FFA_SMC_32(0x8A)
#define FFA_PARTITION_INFO_GET_REGS FFA_SMC_64(0x8B)
#define FFA_EL3_INTR_HANDLE FFA_SMC_32(0x8C)
#define FFA_MSG_SEND_DIRECT_REQ2 FFA_SMC_64(0x8D)
#define FFA_MSG_SEND_DIRECT_RESP2 FFA_SMC_64(0x8E)
/*
* For some calls it is necessary to use SMC64 to pass or return 64-bit values.
* For such calls FFA_FN_NATIVE(name) will choose the appropriate
* (native-width) function ID.
*/
#ifdef CONFIG_64BIT
#define FFA_FN_NATIVE(name) FFA_FN64_##name
#else
#define FFA_FN_NATIVE(name) FFA_##name
#endif
/* FFA error codes. */
#define FFA_RET_SUCCESS (0)
#define FFA_RET_NOT_SUPPORTED (-1)
#define FFA_RET_INVALID_PARAMETERS (-2)
#define FFA_RET_NO_MEMORY (-3)
#define FFA_RET_BUSY (-4)
#define FFA_RET_INTERRUPTED (-5)
#define FFA_RET_DENIED (-6)
#define FFA_RET_RETRY (-7)
#define FFA_RET_ABORTED (-8)
#define FFA_RET_NO_DATA (-9)
/* FFA version encoding */
#define FFA_MAJOR_VERSION_MASK GENMASK(30, 16)
#define FFA_MINOR_VERSION_MASK GENMASK(15, 0)
#define FFA_MAJOR_VERSION(x) ((u16)(FIELD_GET(FFA_MAJOR_VERSION_MASK, (x))))
#define FFA_MINOR_VERSION(x) ((u16)(FIELD_GET(FFA_MINOR_VERSION_MASK, (x))))
#define FFA_PACK_VERSION_INFO(major, minor) \
(FIELD_PREP(FFA_MAJOR_VERSION_MASK, (major)) | \
FIELD_PREP(FFA_MINOR_VERSION_MASK, (minor)))
#define FFA_VERSION_1_0 FFA_PACK_VERSION_INFO(1, 0)
#define FFA_VERSION_1_1 FFA_PACK_VERSION_INFO(1, 1)
#define FFA_VERSION_1_2 FFA_PACK_VERSION_INFO(1, 2)
/**
* FF-A specification mentions explicitly about '4K pages'. This should
* not be confused with the kernel PAGE_SIZE, which is the translation
* granule kernel is configured and may be one among 4K, 16K and 64K.
*/
#define FFA_PAGE_SIZE SZ_4K
/*
* Minimum buffer size/alignment encodings returned by an FFA_FEATURES
* query for FFA_RXTX_MAP.
*/
#define FFA_FEAT_RXTX_MIN_SZ_4K 0
#define FFA_FEAT_RXTX_MIN_SZ_64K 1
#define FFA_FEAT_RXTX_MIN_SZ_16K 2
#define FFA_FEAT_RXTX_MIN_SZ_MASK GENMASK(1, 0)
/* FFA Bus/Device/Driver related */
struct ffa_device {
u32 id;
u32 properties;
int vm_id;
bool mode_32bit;
uuid_t uuid;
struct device dev;
const struct ffa_ops *ops;
};
#define to_ffa_dev(d) container_of(d, struct ffa_device, dev)
struct ffa_device_id {
uuid_t uuid;
};
struct ffa_driver {
const char *name;
int (*probe)(struct ffa_device *sdev);
void (*remove)(struct ffa_device *sdev);
const struct ffa_device_id *id_table;
struct device_driver driver;
};
#define to_ffa_driver(d) container_of_const(d, struct ffa_driver, driver)
static inline void ffa_dev_set_drvdata(struct ffa_device *fdev, void *data)
{
dev_set_drvdata(&fdev->dev, data);
}
static inline void *ffa_dev_get_drvdata(struct ffa_device *fdev)
{
return dev_get_drvdata(&fdev->dev);
}
struct ffa_partition_info;
#if IS_REACHABLE(CONFIG_ARM_FFA_TRANSPORT)
struct ffa_device *
ffa_device_register(const struct ffa_partition_info *part_info,
const struct ffa_ops *ops);
void ffa_device_unregister(struct ffa_device *ffa_dev);
int ffa_driver_register(struct ffa_driver *driver, struct module *owner,
const char *mod_name);
void ffa_driver_unregister(struct ffa_driver *driver);
void ffa_devices_unregister(void);
bool ffa_device_is_valid(struct ffa_device *ffa_dev);
#else
static inline struct ffa_device *
ffa_device_register(const struct ffa_partition_info *part_info,
const struct ffa_ops *ops)
{
return NULL;
}
static inline void ffa_device_unregister(struct ffa_device *dev) {}
static inline void ffa_devices_unregister(void) {}
static inline int
ffa_driver_register(struct ffa_driver *driver, struct module *owner,
const char *mod_name)
{
return -EINVAL;
}
static inline void ffa_driver_unregister(struct ffa_driver *driver) {}
static inline
bool ffa_device_is_valid(struct ffa_device *ffa_dev) { return false; }
#endif /* CONFIG_ARM_FFA_TRANSPORT */
#define ffa_register(driver) \
ffa_driver_register(driver, THIS_MODULE, KBUILD_MODNAME)
#define ffa_unregister(driver) \
ffa_driver_unregister(driver)
/**
* module_ffa_driver() - Helper macro for registering a psa_ffa driver
* @__ffa_driver: ffa_driver structure
*
* Helper macro for psa_ffa drivers to set up proper module init / exit
* functions. Replaces module_init() and module_exit() and keeps people from
* printing pointless things to the kernel log when their driver is loaded.
*/
#define module_ffa_driver(__ffa_driver) \
module_driver(__ffa_driver, ffa_register, ffa_unregister)
extern const struct bus_type ffa_bus_type;
/* The FF-A 1.0 partition structure lacks the uuid[4] */
#define FFA_1_0_PARTITON_INFO_SZ (8)
/* FFA transport related */
struct ffa_partition_info {
u16 id;
u16 exec_ctxt;
/* partition supports receipt of direct requests */
#define FFA_PARTITION_DIRECT_RECV BIT(0)
/* partition can send direct requests. */
#define FFA_PARTITION_DIRECT_SEND BIT(1)
/* partition can send and receive indirect messages. */
#define FFA_PARTITION_INDIRECT_MSG BIT(2)
/* partition can receive notifications */
#define FFA_PARTITION_NOTIFICATION_RECV BIT(3)
/* partition runs in the AArch64 execution state. */
#define FFA_PARTITION_AARCH64_EXEC BIT(8)
/* partition supports receipt of direct request2 */
#define FFA_PARTITION_DIRECT_REQ2_RECV BIT(9)
/* partition can send direct request2. */
#define FFA_PARTITION_DIRECT_REQ2_SEND BIT(10)
u32 properties;
uuid_t uuid;
};
static inline
bool ffa_partition_check_property(struct ffa_device *dev, u32 property)
{
return dev->properties & property;
}
#define ffa_partition_supports_notify_recv(dev) \
ffa_partition_check_property(dev, FFA_PARTITION_NOTIFICATION_RECV)
#define ffa_partition_supports_indirect_msg(dev) \
ffa_partition_check_property(dev, FFA_PARTITION_INDIRECT_MSG)
#define ffa_partition_supports_direct_recv(dev) \
ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_RECV)
#define ffa_partition_supports_direct_req2_recv(dev) \
(ffa_partition_check_property(dev, FFA_PARTITION_DIRECT_REQ2_RECV) && \
!dev->mode_32bit)
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
struct ffa_send_direct_data {
unsigned long data0; /* w3/x3 */
unsigned long data1; /* w4/x4 */
unsigned long data2; /* w5/x5 */
unsigned long data3; /* w6/x6 */
unsigned long data4; /* w7/x7 */
};
struct ffa_indirect_msg_hdr {
u32 flags;
u32 res0;
u32 offset;
u32 send_recv_id;
u32 size;
u32 res1;
uuid_t uuid;
};
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP}2 which pass data via registers */
struct ffa_send_direct_data2 {
unsigned long data[14]; /* x4-x17 */
};
struct ffa_mem_region_addr_range {
/* The base IPA of the constituent memory region, aligned to 4 kiB */
u64 address;
/* The number of 4 kiB pages in the constituent memory region. */
u32 pg_cnt;
u32 reserved;
};
struct ffa_composite_mem_region {
/*
* The total number of 4 kiB pages included in this memory region. This
* must be equal to the sum of page counts specified in each
* `struct ffa_mem_region_addr_range`.
*/
u32 total_pg_cnt;
/* The number of constituents included in this memory region range */
u32 addr_range_cnt;
u64 reserved;
/** An array of `addr_range_cnt` memory region constituents. */
struct ffa_mem_region_addr_range constituents[];
};
struct ffa_mem_region_attributes {
/* The ID of the VM to which the memory is being given or shared. */
u16 receiver;
/*
* The permissions with which the memory region should be mapped in the
* receiver's page table.
*/
#define FFA_MEM_EXEC BIT(3)
#define FFA_MEM_NO_EXEC BIT(2)
#define FFA_MEM_RW BIT(1)
#define FFA_MEM_RO BIT(0)
u8 attrs;
/*
* Flags used during FFA_MEM_RETRIEVE_REQ and FFA_MEM_RETRIEVE_RESP
* for memory regions with multiple borrowers.
*/
#define FFA_MEM_RETRIEVE_SELF_BORROWER BIT(0)
u8 flag;
/*
* Offset in bytes from the start of the outer `ffa_memory_region` to
* an `struct ffa_mem_region_addr_range`.
*/
u32 composite_off;
u8 impdef_val[16];
u64 reserved;
};
struct ffa_mem_region {
/* The ID of the VM/owner which originally sent the memory region */
u16 sender_id;
#define FFA_MEM_NORMAL BIT(5)
#define FFA_MEM_DEVICE BIT(4)
#define FFA_MEM_WRITE_BACK (3 << 2)
#define FFA_MEM_NON_CACHEABLE (1 << 2)
#define FFA_DEV_nGnRnE (0 << 2)
#define FFA_DEV_nGnRE (1 << 2)
#define FFA_DEV_nGRE (2 << 2)
#define FFA_DEV_GRE (3 << 2)
#define FFA_MEM_NON_SHAREABLE (0)
#define FFA_MEM_OUTER_SHAREABLE (2)
#define FFA_MEM_INNER_SHAREABLE (3)
/* Memory region attributes, upper byte MBZ pre v1.1 */
u16 attributes;
/*
* Clear memory region contents after unmapping it from the sender and
* before mapping it for any receiver.
*/
#define FFA_MEM_CLEAR BIT(0)
/*
* Whether the hypervisor may time slice the memory sharing or retrieval
* operation.
*/
#define FFA_TIME_SLICE_ENABLE BIT(1)
#define FFA_MEM_RETRIEVE_TYPE_IN_RESP (0 << 3)
#define FFA_MEM_RETRIEVE_TYPE_SHARE (1 << 3)
#define FFA_MEM_RETRIEVE_TYPE_LEND (2 << 3)
#define FFA_MEM_RETRIEVE_TYPE_DONATE (3 << 3)
#define FFA_MEM_RETRIEVE_ADDR_ALIGN_HINT BIT(9)
#define FFA_MEM_RETRIEVE_ADDR_ALIGN(x) ((x) << 5)
/* Flags to control behaviour of the transaction. */
u32 flags;
#define HANDLE_LOW_MASK GENMASK_ULL(31, 0)
#define HANDLE_HIGH_MASK GENMASK_ULL(63, 32)
#define HANDLE_LOW(x) ((u32)(FIELD_GET(HANDLE_LOW_MASK, (x))))
#define HANDLE_HIGH(x) ((u32)(FIELD_GET(HANDLE_HIGH_MASK, (x))))
#define PACK_HANDLE(l, h) \
(FIELD_PREP(HANDLE_LOW_MASK, (l)) | FIELD_PREP(HANDLE_HIGH_MASK, (h)))
/*
* A globally-unique ID assigned by the hypervisor for a region
* of memory being sent between VMs.
*/
u64 handle;
/*
* An implementation defined value associated with the receiver and the
* memory region.
*/
u64 tag;
/* Size of each endpoint memory access descriptor, MBZ pre v1.1 */
u32 ep_mem_size;
/*
* The number of `ffa_mem_region_attributes` entries included in this
* transaction.
*/
u32 ep_count;
/*
* 16-byte aligned offset from the base address of this descriptor
* to the first element of the endpoint memory access descriptor array
* Valid only from v1.1
*/
u32 ep_mem_offset;
/* MBZ, valid only from v1.1 */
u32 reserved[3];
};
#define CONSTITUENTS_OFFSET(x) \
(offsetof(struct ffa_composite_mem_region, constituents[x]))
#define FFA_EMAD_HAS_IMPDEF_FIELD(version) ((version) >= FFA_VERSION_1_2)
#define FFA_MEM_REGION_HAS_EP_MEM_OFFSET(version) ((version) > FFA_VERSION_1_0)
static inline u32 ffa_emad_size_get(u32 ffa_version)
{
u32 sz;
struct ffa_mem_region_attributes *ep_mem_access;
if (FFA_EMAD_HAS_IMPDEF_FIELD(ffa_version))
sz = sizeof(*ep_mem_access);
else
sz = sizeof(*ep_mem_access) - sizeof(ep_mem_access->impdef_val);
return sz;
}
static inline u32
ffa_mem_desc_offset(struct ffa_mem_region *buf, int count, u32 ffa_version)
{
u32 offset = count * ffa_emad_size_get(ffa_version);
/*
* Earlier to v1.1, the endpoint memory descriptor array started at
* offset 32(i.e. offset of ep_mem_offset in the current structure)
*/
if (!FFA_MEM_REGION_HAS_EP_MEM_OFFSET(ffa_version))
offset += offsetof(struct ffa_mem_region, ep_mem_offset);
else
offset += sizeof(struct ffa_mem_region);
return offset;
}
struct ffa_mem_ops_args {
bool use_txbuf;
u32 nattrs;
u32 flags;
u64 tag;
u64 g_handle;
struct scatterlist *sg;
struct ffa_mem_region_attributes *attrs;
};
struct ffa_info_ops {
u32 (*api_version_get)(void);
int (*partition_info_get)(const char *uuid_str,
struct ffa_partition_info *buffer);
};
struct ffa_msg_ops {
void (*mode_32bit_set)(struct ffa_device *dev);
int (*sync_send_receive)(struct ffa_device *dev,
struct ffa_send_direct_data *data);
int (*indirect_send)(struct ffa_device *dev, void *buf, size_t sz);
int (*sync_send_receive2)(struct ffa_device *dev,
struct ffa_send_direct_data2 *data);
};
struct ffa_mem_ops {
int (*memory_reclaim)(u64 g_handle, u32 flags);
int (*memory_share)(struct ffa_mem_ops_args *args);
int (*memory_lend)(struct ffa_mem_ops_args *args);
};
struct ffa_cpu_ops {
int (*run)(struct ffa_device *dev, u16 vcpu);
};
typedef void (*ffa_sched_recv_cb)(u16 vcpu, bool is_per_vcpu, void *cb_data);
typedef void (*ffa_notifier_cb)(int notify_id, void *cb_data);
typedef void (*ffa_fwk_notifier_cb)(int notify_id, void *cb_data, void *buf);
struct ffa_notifier_ops {
int (*sched_recv_cb_register)(struct ffa_device *dev,
ffa_sched_recv_cb cb, void *cb_data);
int (*sched_recv_cb_unregister)(struct ffa_device *dev);
int (*notify_request)(struct ffa_device *dev, bool per_vcpu,
ffa_notifier_cb cb, void *cb_data, int notify_id);
int (*notify_relinquish)(struct ffa_device *dev, int notify_id);
int (*fwk_notify_request)(struct ffa_device *dev,
ffa_fwk_notifier_cb cb, void *cb_data,
int notify_id);
int (*fwk_notify_relinquish)(struct ffa_device *dev, int notify_id);
int (*notify_send)(struct ffa_device *dev, int notify_id, bool per_vcpu,
u16 vcpu);
};
struct ffa_ops {
const struct ffa_info_ops *info_ops;
const struct ffa_msg_ops *msg_ops;
const struct ffa_mem_ops *mem_ops;
const struct ffa_cpu_ops *cpu_ops;
const struct ffa_notifier_ops *notifier_ops;
};
#endif /* _LINUX_ARM_FFA_H */
@@ -0,0 +1,98 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2025 Arm Ltd. */
#ifndef __LINUX_ARM_MPAM_H
#define __LINUX_ARM_MPAM_H
#include <linux/acpi.h>
#include <linux/resctrl_types.h>
#include <linux/types.h>
struct mpam_msc;
enum mpam_msc_iface {
MPAM_IFACE_MMIO, /* a real MPAM MSC */
MPAM_IFACE_PCC, /* a fake MPAM MSC */
};
enum mpam_class_types {
MPAM_CLASS_CACHE, /* Caches, e.g. L2, L3 */
MPAM_CLASS_MEMORY, /* Main memory */
MPAM_CLASS_UNKNOWN, /* Everything else, e.g. SMMU */
};
#define MPAM_CLASS_ID_DEFAULT 255
#ifdef CONFIG_ACPI_MPAM
int acpi_mpam_parse_resources(struct mpam_msc *msc,
struct acpi_mpam_msc_node *tbl_msc);
int acpi_mpam_count_msc(void);
#else
static inline int acpi_mpam_parse_resources(struct mpam_msc *msc,
struct acpi_mpam_msc_node *tbl_msc)
{
return -EINVAL;
}
static inline int acpi_mpam_count_msc(void) { return -EINVAL; }
#endif
#ifdef CONFIG_ARM64_MPAM_DRIVER
int mpam_ris_create(struct mpam_msc *msc, u8 ris_idx,
enum mpam_class_types type, u8 class_id, int component_id);
#else
static inline int mpam_ris_create(struct mpam_msc *msc, u8 ris_idx,
enum mpam_class_types type, u8 class_id,
int component_id)
{
return -EINVAL;
}
#endif
bool resctrl_arch_alloc_capable(void);
bool resctrl_arch_mon_capable(void);
void resctrl_arch_set_cpu_default_closid(int cpu, u32 closid);
void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid);
void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid);
void resctrl_arch_sched_in(struct task_struct *tsk);
bool resctrl_arch_match_closid(struct task_struct *tsk, u32 closid);
bool resctrl_arch_match_rmid(struct task_struct *tsk, u32 closid, u32 rmid);
u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid);
void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid);
u32 resctrl_arch_system_num_rmid_idx(void);
struct rdt_resource;
void *resctrl_arch_mon_ctx_alloc(struct rdt_resource *r, enum resctrl_event_id evtid);
void resctrl_arch_mon_ctx_free(struct rdt_resource *r, enum resctrl_event_id evtid, void *ctx);
/*
* The CPU configuration for MPAM is cheap to write, and is only written if it
* has changed. No need for fine grained enables.
*/
static inline void resctrl_arch_enable_mon(void) { }
static inline void resctrl_arch_disable_mon(void) { }
static inline void resctrl_arch_enable_alloc(void) { }
static inline void resctrl_arch_disable_alloc(void) { }
static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
{
return val;
}
/**
* mpam_register_requestor() - Register a requestor with the MPAM driver
* @partid_max: The maximum PARTID value the requestor can generate.
* @pmg_max: The maximum PMG value the requestor can generate.
*
* Registers a requestor with the MPAM driver to ensure the chosen system-wide
* minimum PARTID and PMG values will allow the requestors features to be used.
*
* Returns an error if the registration is too late, and a larger PARTID/PMG
* value has been advertised to user-space. In this case the requestor should
* not use its MPAM features. Returns 0 on success.
*/
int mpam_register_requestor(u16 partid_max, u8 pmg_max);
#endif /* __LINUX_ARM_MPAM_H */
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (C) 2017 Arm Ltd.
#ifndef __LINUX_ARM_SDEI_H
#define __LINUX_ARM_SDEI_H
#include <uapi/linux/arm_sdei.h>
#include <acpi/ghes.h>
#ifdef CONFIG_ARM_SDE_INTERFACE
#include <asm/sdei.h>
#endif
/* Arch code should override this to set the entry point from firmware... */
#ifndef sdei_arch_get_entry_point
#define sdei_arch_get_entry_point(conduit) (0)
#endif
/*
* When an event occurs sdei_event_handler() will call a user-provided callback
* like this in NMI context on the CPU that received the event.
*/
typedef int (sdei_event_callback)(u32 event, struct pt_regs *regs, void *arg);
/*
* Register your callback to claim an event. The event must be described
* by firmware.
*/
int sdei_event_register(u32 event_num, sdei_event_callback *cb, void *arg);
/*
* Calls to sdei_event_unregister() may return EINPROGRESS. Keep calling
* it until it succeeds.
*/
int sdei_event_unregister(u32 event_num);
int sdei_event_enable(u32 event_num);
int sdei_event_disable(u32 event_num);
/* GHES register/unregister helpers */
int sdei_register_ghes(struct ghes *ghes, sdei_event_callback *normal_cb,
sdei_event_callback *critical_cb);
int sdei_unregister_ghes(struct ghes *ghes);
#ifdef CONFIG_ARM_SDE_INTERFACE
/* For use by arch code when CPU hotplug notifiers are not appropriate. */
int sdei_mask_local_cpu(void);
int sdei_unmask_local_cpu(void);
void __init acpi_sdei_init(void);
void sdei_handler_abort(void);
#else
static inline int sdei_mask_local_cpu(void) { return 0; }
static inline int sdei_unmask_local_cpu(void) { return 0; }
static inline void acpi_sdei_init(void) { }
static inline void sdei_handler_abort(void) { }
#endif /* CONFIG_ARM_SDE_INTERFACE */
/*
* This struct represents an event that has been registered. The driver
* maintains a list of all events, and which ones are registered. (Private
* events have one entry in the list, but are registered on each CPU).
* A pointer to this struct is passed to firmware, and back to the event
* handler. The event handler can then use this to invoke the registered
* callback, without having to walk the list.
*
* For CPU private events, this structure is per-cpu.
*/
struct sdei_registered_event {
/* For use by arch code: */
struct pt_regs interrupted_regs;
sdei_event_callback *callback;
void *callback_arg;
u32 event_num;
u8 priority;
};
/* The arch code entry point should then call this when an event arrives. */
int notrace sdei_event_handler(struct pt_regs *regs,
struct sdei_registered_event *arg);
/* arch code may use this to retrieve the extra registers. */
int sdei_api_event_context(u32 query, u64 *result);
#endif /* __LINUX_ARM_SDEI_H */
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* rWTM BIU Mailbox driver for Armada 37xx
*
* Author: Marek Behún <kabel@kernel.org>
*/
#ifndef _LINUX_ARMADA_37XX_RWTM_MAILBOX_H_
#define _LINUX_ARMADA_37XX_RWTM_MAILBOX_H_
#include <linux/types.h>
struct armada_37xx_rwtm_tx_msg {
u16 command;
u32 args[16];
};
struct armada_37xx_rwtm_rx_msg {
u32 retval;
u32 status[16];
};
#endif /* _LINUX_ARMADA_37XX_RWTM_MAILBOX_H_ */
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_ARRAY_SIZE_H
#define _LINUX_ARRAY_SIZE_H
#include <linux/compiler.h>
/**
* ARRAY_SIZE - get the number of elements in array @arr
* @arr: array to be sized
*/
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
/**
* ARRAY_END - get a pointer to one past the last element in array @arr
* @arr: array
*/
#define ARRAY_END(arr) (&(arr)[ARRAY_SIZE(arr)])
#endif /* _LINUX_ARRAY_SIZE_H */
@@ -0,0 +1,39 @@
/*
* SPDX-License-Identifier: GPL-2.0
*
* Copyright (c) 2008 Intel Corporation
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
*/
#ifndef _ASCII85_H_
#define _ASCII85_H_
#include <linux/math.h>
#include <linux/types.h>
#define ASCII85_BUFSZ 6
static inline long
ascii85_encode_len(long len)
{
return DIV_ROUND_UP(len, 4);
}
static inline const char *
ascii85_encode(u32 in, char *out)
{
int i;
if (in == 0)
return "z";
out[5] = '\0';
for (i = 5; i--; ) {
out[i] = '!' + in % 85;
in /= 85;
}
return out;
}
#endif
@@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* ASN.1 BER/DER/CER encoding definitions
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASN1_H
#define _LINUX_ASN1_H
/* Class */
enum asn1_class {
ASN1_UNIV = 0, /* Universal */
ASN1_APPL = 1, /* Application */
ASN1_CONT = 2, /* Context */
ASN1_PRIV = 3 /* Private */
};
#define ASN1_CLASS_BITS 0xc0
enum asn1_method {
ASN1_PRIM = 0, /* Primitive */
ASN1_CONS = 1 /* Constructed */
};
#define ASN1_CONS_BIT 0x20
/* Tag */
enum asn1_tag {
ASN1_EOC = 0, /* End Of Contents or N/A */
ASN1_BOOL = 1, /* Boolean */
ASN1_INT = 2, /* Integer */
ASN1_BTS = 3, /* Bit String */
ASN1_OTS = 4, /* Octet String */
ASN1_NULL = 5, /* Null */
ASN1_OID = 6, /* Object Identifier */
ASN1_ODE = 7, /* Object Description */
ASN1_EXT = 8, /* External */
ASN1_REAL = 9, /* Real float */
ASN1_ENUM = 10, /* Enumerated */
ASN1_EPDV = 11, /* Embedded PDV */
ASN1_UTF8STR = 12, /* UTF8 String */
ASN1_RELOID = 13, /* Relative OID */
/* 14 - Reserved */
/* 15 - Reserved */
ASN1_SEQ = 16, /* Sequence and Sequence of */
ASN1_SET = 17, /* Set and Set of */
ASN1_NUMSTR = 18, /* Numerical String */
ASN1_PRNSTR = 19, /* Printable String */
ASN1_TEXSTR = 20, /* T61 String / Teletext String */
ASN1_VIDSTR = 21, /* Videotex String */
ASN1_IA5STR = 22, /* IA5 String */
ASN1_UNITIM = 23, /* Universal Time */
ASN1_GENTIM = 24, /* General Time */
ASN1_GRASTR = 25, /* Graphic String */
ASN1_VISSTR = 26, /* Visible String */
ASN1_GENSTR = 27, /* General String */
ASN1_UNISTR = 28, /* Universal String */
ASN1_CHRSTR = 29, /* Character String */
ASN1_BMPSTR = 30, /* BMP String */
ASN1_LONG_TAG = 31 /* Long form tag */
};
#define ASN1_INDEFINITE_LENGTH 0x80
#endif /* _LINUX_ASN1_H */
@@ -0,0 +1,89 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* ASN.1 BER/DER/CER parsing state machine internal definitions
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASN1_BER_BYTECODE_H
#define _LINUX_ASN1_BER_BYTECODE_H
#ifdef __KERNEL__
#include <linux/types.h>
#endif
#include <linux/asn1.h>
typedef int (*asn1_action_t)(void *context,
size_t hdrlen, /* In case of ANY type */
unsigned char tag, /* In case of ANY type */
const void *value, size_t vlen);
struct asn1_decoder {
const unsigned char *machine;
size_t machlen;
const asn1_action_t *actions;
};
enum asn1_opcode {
/* The tag-matching ops come first and the odd-numbered slots
* are for OR_SKIP ops.
*/
#define ASN1_OP_MATCH__SKIP 0x01
#define ASN1_OP_MATCH__ACT 0x02
#define ASN1_OP_MATCH__JUMP 0x04
#define ASN1_OP_MATCH__ANY 0x08
#define ASN1_OP_MATCH__COND 0x10
ASN1_OP_MATCH = 0x00,
ASN1_OP_MATCH_OR_SKIP = 0x01,
ASN1_OP_MATCH_ACT = 0x02,
ASN1_OP_MATCH_ACT_OR_SKIP = 0x03,
ASN1_OP_MATCH_JUMP = 0x04,
ASN1_OP_MATCH_JUMP_OR_SKIP = 0x05,
ASN1_OP_MATCH_ANY = 0x08,
ASN1_OP_MATCH_ANY_OR_SKIP = 0x09,
ASN1_OP_MATCH_ANY_ACT = 0x0a,
ASN1_OP_MATCH_ANY_ACT_OR_SKIP = 0x0b,
/* Everything before here matches unconditionally */
ASN1_OP_COND_MATCH_OR_SKIP = 0x11,
ASN1_OP_COND_MATCH_ACT_OR_SKIP = 0x13,
ASN1_OP_COND_MATCH_JUMP_OR_SKIP = 0x15,
ASN1_OP_COND_MATCH_ANY = 0x18,
ASN1_OP_COND_MATCH_ANY_OR_SKIP = 0x19,
ASN1_OP_COND_MATCH_ANY_ACT = 0x1a,
ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP = 0x1b,
/* Everything before here will want a tag from the data */
#define ASN1_OP__MATCHES_TAG ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP
/* These are here to help fill up space */
ASN1_OP_COND_FAIL = 0x1c,
ASN1_OP_COMPLETE = 0x1d,
ASN1_OP_ACT = 0x1e,
ASN1_OP_MAYBE_ACT = 0x1f,
/* The following eight have bit 0 -> SET, 1 -> OF, 2 -> ACT */
ASN1_OP_END_SEQ = 0x20,
ASN1_OP_END_SET = 0x21,
ASN1_OP_END_SEQ_OF = 0x22,
ASN1_OP_END_SET_OF = 0x23,
ASN1_OP_END_SEQ_ACT = 0x24,
ASN1_OP_END_SET_ACT = 0x25,
ASN1_OP_END_SEQ_OF_ACT = 0x26,
ASN1_OP_END_SET_OF_ACT = 0x27,
#define ASN1_OP_END__SET 0x01
#define ASN1_OP_END__OF 0x02
#define ASN1_OP_END__ACT 0x04
ASN1_OP_RETURN = 0x28,
ASN1_OP__NR
};
#define _tag(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | ASN1_##TAG)
#define _tagn(CLASS, CP, TAG) ((ASN1_##CLASS << 6) | (ASN1_##CP << 5) | TAG)
#define _jump_target(N) (N)
#define _action(N) (N)
#endif /* _LINUX_ASN1_BER_BYTECODE_H */
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* ASN.1 decoder
*
* Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASN1_DECODER_H
#define _LINUX_ASN1_DECODER_H
#include <linux/asn1.h>
#include <linux/types.h>
struct asn1_decoder;
extern int asn1_ber_decoder(const struct asn1_decoder *decoder,
void *context,
const unsigned char *data,
size_t datalen);
#endif /* _LINUX_ASN1_DECODER_H */
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _LINUX_ASN1_ENCODER_H
#define _LINUX_ASN1_ENCODER_H
#include <linux/types.h>
#include <linux/asn1.h>
#include <linux/asn1_ber_bytecode.h>
#define asn1_oid_len(oid) (sizeof(oid)/sizeof(u32))
unsigned char *
asn1_encode_integer(unsigned char *data, const unsigned char *end_data,
s64 integer);
unsigned char *
asn1_encode_oid(unsigned char *data, const unsigned char *end_data,
u32 oid[], int oid_len);
unsigned char *
asn1_encode_tag(unsigned char *data, const unsigned char *end_data,
u32 tag, const unsigned char *string, int len);
unsigned char *
asn1_encode_octet_string(unsigned char *data,
const unsigned char *end_data,
const unsigned char *string, u32 len);
unsigned char *
asn1_encode_sequence(unsigned char *data, const unsigned char *end_data,
const unsigned char *seq, int len);
unsigned char *
asn1_encode_boolean(unsigned char *data, const unsigned char *end_data,
bool val);
#endif
@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Generic associative array implementation.
*
* See Documentation/core-api/assoc_array.rst for information.
*
* Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASSOC_ARRAY_H
#define _LINUX_ASSOC_ARRAY_H
#ifdef CONFIG_ASSOCIATIVE_ARRAY
#include <linux/types.h>
#define ASSOC_ARRAY_KEY_CHUNK_SIZE BITS_PER_LONG /* Key data retrieved in chunks of this size */
/*
* Generic associative array.
*/
struct assoc_array {
struct assoc_array_ptr *root; /* The node at the root of the tree */
unsigned long nr_leaves_on_tree;
};
/*
* Operations on objects and index keys for use by array manipulation routines.
*/
struct assoc_array_ops {
/* Method to get a chunk of an index key from caller-supplied data */
unsigned long (*get_key_chunk)(const void *index_key, int level);
/* Method to get a piece of an object's index key */
unsigned long (*get_object_key_chunk)(const void *object, int level);
/* Is this the object we're looking for? */
bool (*compare_object)(const void *object, const void *index_key);
/* How different is an object from an index key, to a bit position in
* their keys? (or -1 if they're the same)
*/
int (*diff_objects)(const void *object, const void *index_key);
/* Method to free an object. */
void (*free_object)(void *object);
};
/*
* Access and manipulation functions.
*/
struct assoc_array_edit;
static inline void assoc_array_init(struct assoc_array *array)
{
array->root = NULL;
array->nr_leaves_on_tree = 0;
}
extern int assoc_array_iterate(const struct assoc_array *array,
int (*iterator)(const void *object,
void *iterator_data),
void *iterator_data);
extern void *assoc_array_find(const struct assoc_array *array,
const struct assoc_array_ops *ops,
const void *index_key);
extern void assoc_array_destroy(struct assoc_array *array,
const struct assoc_array_ops *ops);
extern struct assoc_array_edit *assoc_array_insert(struct assoc_array *array,
const struct assoc_array_ops *ops,
const void *index_key,
void *object);
extern void assoc_array_insert_set_object(struct assoc_array_edit *edit,
void *object);
extern struct assoc_array_edit *assoc_array_delete(struct assoc_array *array,
const struct assoc_array_ops *ops,
const void *index_key);
extern struct assoc_array_edit *assoc_array_clear(struct assoc_array *array,
const struct assoc_array_ops *ops);
extern void assoc_array_apply_edit(struct assoc_array_edit *edit);
extern void assoc_array_cancel_edit(struct assoc_array_edit *edit);
extern int assoc_array_gc(struct assoc_array *array,
const struct assoc_array_ops *ops,
bool (*iterator)(void *object, void *iterator_data),
void *iterator_data);
#endif /* CONFIG_ASSOCIATIVE_ARRAY */
#endif /* _LINUX_ASSOC_ARRAY_H */
@@ -0,0 +1,178 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Private definitions for the generic associative array implementation.
*
* See Documentation/core-api/assoc_array.rst for information.
*
* Copyright (C) 2013 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*/
#ifndef _LINUX_ASSOC_ARRAY_PRIV_H
#define _LINUX_ASSOC_ARRAY_PRIV_H
#ifdef CONFIG_ASSOCIATIVE_ARRAY
#include <linux/assoc_array.h>
#define ASSOC_ARRAY_FAN_OUT 16 /* Number of slots per node */
#define ASSOC_ARRAY_FAN_MASK (ASSOC_ARRAY_FAN_OUT - 1)
#define ASSOC_ARRAY_LEVEL_STEP (ilog2(ASSOC_ARRAY_FAN_OUT))
#define ASSOC_ARRAY_LEVEL_STEP_MASK (ASSOC_ARRAY_LEVEL_STEP - 1)
#define ASSOC_ARRAY_KEY_CHUNK_MASK (ASSOC_ARRAY_KEY_CHUNK_SIZE - 1)
#define ASSOC_ARRAY_KEY_CHUNK_SHIFT (ilog2(BITS_PER_LONG))
/*
* Undefined type representing a pointer with type information in the bottom
* two bits.
*/
struct assoc_array_ptr;
/*
* An N-way node in the tree.
*
* Each slot contains one of four things:
*
* (1) Nothing (NULL).
*
* (2) A leaf object (pointer types 0).
*
* (3) A next-level node (pointer type 1, subtype 0).
*
* (4) A shortcut (pointer type 1, subtype 1).
*
* The tree is optimised for search-by-ID, but permits reasonable iteration
* also.
*
* The tree is navigated by constructing an index key consisting of an array of
* segments, where each segment is ilog2(ASSOC_ARRAY_FAN_OUT) bits in size.
*
* The segments correspond to levels of the tree (the first segment is used at
* level 0, the second at level 1, etc.).
*/
struct assoc_array_node {
struct assoc_array_ptr *back_pointer;
u8 parent_slot;
struct assoc_array_ptr *slots[ASSOC_ARRAY_FAN_OUT];
unsigned long nr_leaves_on_branch;
};
/*
* A shortcut through the index space out to where a collection of nodes/leaves
* with the same IDs live.
*/
struct assoc_array_shortcut {
struct assoc_array_ptr *back_pointer;
int parent_slot;
int skip_to_level;
struct assoc_array_ptr *next_node;
unsigned long index_key[];
};
/*
* Preallocation cache.
*/
struct assoc_array_edit {
struct rcu_head rcu;
struct assoc_array *array;
const struct assoc_array_ops *ops;
const struct assoc_array_ops *ops_for_excised_subtree;
struct assoc_array_ptr *leaf;
struct assoc_array_ptr **leaf_p;
struct assoc_array_ptr *dead_leaf;
struct assoc_array_ptr *new_meta[3];
struct assoc_array_ptr *excised_meta[1];
struct assoc_array_ptr *excised_subtree;
struct assoc_array_ptr **set_backpointers[ASSOC_ARRAY_FAN_OUT];
struct assoc_array_ptr *set_backpointers_to;
struct assoc_array_node *adjust_count_on;
long adjust_count_by;
struct {
struct assoc_array_ptr **ptr;
struct assoc_array_ptr *to;
} set[2];
struct {
u8 *p;
u8 to;
} set_parent_slot[1];
u8 segment_cache[ASSOC_ARRAY_FAN_OUT + 1];
};
/*
* Internal tree member pointers are marked in the bottom one or two bits to
* indicate what type they are so that we don't have to look behind every
* pointer to see what it points to.
*
* We provide functions to test type annotations and to create and translate
* the annotated pointers.
*/
#define ASSOC_ARRAY_PTR_TYPE_MASK 0x1UL
#define ASSOC_ARRAY_PTR_LEAF_TYPE 0x0UL /* Points to leaf (or nowhere) */
#define ASSOC_ARRAY_PTR_META_TYPE 0x1UL /* Points to node or shortcut */
#define ASSOC_ARRAY_PTR_SUBTYPE_MASK 0x2UL
#define ASSOC_ARRAY_PTR_NODE_SUBTYPE 0x0UL
#define ASSOC_ARRAY_PTR_SHORTCUT_SUBTYPE 0x2UL
static inline bool assoc_array_ptr_is_meta(const struct assoc_array_ptr *x)
{
return (unsigned long)x & ASSOC_ARRAY_PTR_TYPE_MASK;
}
static inline bool assoc_array_ptr_is_leaf(const struct assoc_array_ptr *x)
{
return !assoc_array_ptr_is_meta(x);
}
static inline bool assoc_array_ptr_is_shortcut(const struct assoc_array_ptr *x)
{
return (unsigned long)x & ASSOC_ARRAY_PTR_SUBTYPE_MASK;
}
static inline bool assoc_array_ptr_is_node(const struct assoc_array_ptr *x)
{
return !assoc_array_ptr_is_shortcut(x);
}
static inline void *assoc_array_ptr_to_leaf(const struct assoc_array_ptr *x)
{
return (void *)((unsigned long)x & ~ASSOC_ARRAY_PTR_TYPE_MASK);
}
static inline
unsigned long __assoc_array_ptr_to_meta(const struct assoc_array_ptr *x)
{
return (unsigned long)x &
~(ASSOC_ARRAY_PTR_SUBTYPE_MASK | ASSOC_ARRAY_PTR_TYPE_MASK);
}
static inline
struct assoc_array_node *assoc_array_ptr_to_node(const struct assoc_array_ptr *x)
{
return (struct assoc_array_node *)__assoc_array_ptr_to_meta(x);
}
static inline
struct assoc_array_shortcut *assoc_array_ptr_to_shortcut(const struct assoc_array_ptr *x)
{
return (struct assoc_array_shortcut *)__assoc_array_ptr_to_meta(x);
}
static inline
struct assoc_array_ptr *__assoc_array_x_to_ptr(const void *p, unsigned long t)
{
return (struct assoc_array_ptr *)((unsigned long)p | t);
}
static inline
struct assoc_array_ptr *assoc_array_leaf_to_ptr(const void *p)
{
return __assoc_array_x_to_ptr(p, ASSOC_ARRAY_PTR_LEAF_TYPE);
}
static inline
struct assoc_array_ptr *assoc_array_node_to_ptr(const struct assoc_array_node *p)
{
return __assoc_array_x_to_ptr(
p, ASSOC_ARRAY_PTR_META_TYPE | ASSOC_ARRAY_PTR_NODE_SUBTYPE);
}
static inline
struct assoc_array_ptr *assoc_array_shortcut_to_ptr(const struct assoc_array_shortcut *p)
{
return __assoc_array_x_to_ptr(
p, ASSOC_ARRAY_PTR_META_TYPE | ASSOC_ARRAY_PTR_SHORTCUT_SUBTYPE);
}
#endif /* CONFIG_ASSOCIATIVE_ARRAY */
#endif /* _LINUX_ASSOC_ARRAY_PRIV_H */
@@ -0,0 +1,124 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* async.h: Asynchronous function calls for boot performance
*
* (C) Copyright 2009 Intel Corporation
* Author: Arjan van de Ven <arjan@linux.intel.com>
*/
#ifndef __ASYNC_H__
#define __ASYNC_H__
#include <linux/types.h>
#include <linux/list.h>
#include <linux/numa.h>
#include <linux/device.h>
typedef u64 async_cookie_t;
typedef void (*async_func_t) (void *data, async_cookie_t cookie);
struct async_domain {
struct list_head pending;
unsigned registered:1;
};
/*
* domain participates in global async_synchronize_full
*/
#define ASYNC_DOMAIN(_name) \
struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \
.registered = 1 }
/*
* domain is free to go out of scope as soon as all pending work is
* complete, this domain does not participate in async_synchronize_full
*/
#define ASYNC_DOMAIN_EXCLUSIVE(_name) \
struct async_domain _name = { .pending = LIST_HEAD_INIT(_name.pending), \
.registered = 0 }
async_cookie_t async_schedule_node(async_func_t func, void *data,
int node);
async_cookie_t async_schedule_node_domain(async_func_t func, void *data,
int node,
struct async_domain *domain);
/**
* async_schedule - schedule a function for asynchronous execution
* @func: function to execute asynchronously
* @data: data pointer to pass to the function
*
* Returns an async_cookie_t that may be used for checkpointing later.
* Note: This function may be called from atomic or non-atomic contexts.
*/
static inline async_cookie_t async_schedule(async_func_t func, void *data)
{
return async_schedule_node(func, data, NUMA_NO_NODE);
}
/**
* async_schedule_domain - schedule a function for asynchronous execution within a certain domain
* @func: function to execute asynchronously
* @data: data pointer to pass to the function
* @domain: the domain
*
* Returns an async_cookie_t that may be used for checkpointing later.
* @domain may be used in the async_synchronize_*_domain() functions to
* wait within a certain synchronization domain rather than globally.
* Note: This function may be called from atomic or non-atomic contexts.
*/
static inline async_cookie_t
async_schedule_domain(async_func_t func, void *data,
struct async_domain *domain)
{
return async_schedule_node_domain(func, data, NUMA_NO_NODE, domain);
}
/**
* async_schedule_dev - A device specific version of async_schedule
* @func: function to execute asynchronously
* @dev: device argument to be passed to function
*
* Returns an async_cookie_t that may be used for checkpointing later.
* @dev is used as both the argument for the function and to provide NUMA
* context for where to run the function. By doing this we can try to
* provide for the best possible outcome by operating on the device on the
* CPUs closest to the device.
* Note: This function may be called from atomic or non-atomic contexts.
*/
static inline async_cookie_t
async_schedule_dev(async_func_t func, struct device *dev)
{
return async_schedule_node(func, dev, dev_to_node(dev));
}
bool async_schedule_dev_nocall(async_func_t func, struct device *dev);
/**
* async_schedule_dev_domain - A device specific version of async_schedule_domain
* @func: function to execute asynchronously
* @dev: device argument to be passed to function
* @domain: the domain
*
* Returns an async_cookie_t that may be used for checkpointing later.
* @dev is used as both the argument for the function and to provide NUMA
* context for where to run the function. By doing this we can try to
* provide for the best possible outcome by operating on the device on the
* CPUs closest to the device.
* @domain may be used in the async_synchronize_*_domain() functions to
* wait within a certain synchronization domain rather than globally.
* Note: This function may be called from atomic or non-atomic contexts.
*/
static inline async_cookie_t
async_schedule_dev_domain(async_func_t func, struct device *dev,
struct async_domain *domain)
{
return async_schedule_node_domain(func, dev, dev_to_node(dev), domain);
}
extern void async_synchronize_full(void);
extern void async_synchronize_full_domain(struct async_domain *domain);
extern void async_synchronize_cookie(async_cookie_t cookie);
extern void async_synchronize_cookie_domain(async_cookie_t cookie,
struct async_domain *domain);
extern bool current_is_async(void);
extern void async_init(void);
#endif
@@ -0,0 +1,203 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright © 2006, Intel Corporation.
*/
#ifndef _ASYNC_TX_H_
#define _ASYNC_TX_H_
#include <linux/dmaengine.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
/* on architectures without dma-mapping capabilities we need to ensure
* that the asynchronous path compiles away
*/
#ifdef CONFIG_HAS_DMA
#define __async_inline
#else
#define __async_inline __always_inline
#endif
/**
* dma_chan_ref - object used to manage dma channels received from the
* dmaengine core.
* @chan - the channel being tracked
* @node - node for the channel to be placed on async_tx_master_list
* @rcu - for list_del_rcu
* @count - number of times this channel is listed in the pool
* (for channels with multiple capabiities)
*/
struct dma_chan_ref {
struct dma_chan *chan;
struct list_head node;
struct rcu_head rcu;
atomic_t count;
};
/**
* async_tx_flags - modifiers for the async_* calls
* @ASYNC_TX_XOR_ZERO_DST: this flag must be used for xor operations where the
* destination address is not a source. The asynchronous case handles this
* implicitly, the synchronous case needs to zero the destination block.
* @ASYNC_TX_XOR_DROP_DST: this flag must be used if the destination address is
* also one of the source addresses. In the synchronous case the destination
* address is an implied source, whereas the asynchronous case it must be listed
* as a source. The destination address must be the first address in the source
* array.
* @ASYNC_TX_ACK: immediately ack the descriptor, precludes setting up a
* dependency chain
* @ASYNC_TX_FENCE: specify that the next operation in the dependency
* chain uses this operation's result as an input
* @ASYNC_TX_PQ_XOR_DST: do not overwrite the syndrome but XOR it with the
* input data. Required for rmw case.
*/
enum async_tx_flags {
ASYNC_TX_XOR_ZERO_DST = (1 << 0),
ASYNC_TX_XOR_DROP_DST = (1 << 1),
ASYNC_TX_ACK = (1 << 2),
ASYNC_TX_FENCE = (1 << 3),
ASYNC_TX_PQ_XOR_DST = (1 << 4),
};
/**
* struct async_submit_ctl - async_tx submission/completion modifiers
* @flags: submission modifiers
* @depend_tx: parent dependency of the current operation being submitted
* @cb_fn: callback routine to run at operation completion
* @cb_param: parameter for the callback routine
* @scribble: caller provided space for dma/page address conversions
*/
struct async_submit_ctl {
enum async_tx_flags flags;
struct dma_async_tx_descriptor *depend_tx;
dma_async_tx_callback cb_fn;
void *cb_param;
void *scribble;
};
#if defined(CONFIG_DMA_ENGINE) && !defined(CONFIG_ASYNC_TX_CHANNEL_SWITCH)
#define async_tx_issue_pending_all dma_issue_pending_all
/**
* async_tx_issue_pending - send pending descriptor to the hardware channel
* @tx: descriptor handle to retrieve hardware context
*
* Note: any dependent operations will have already been issued by
* async_tx_channel_switch, or (in the case of no channel switch) will
* be already pending on this channel.
*/
static inline void async_tx_issue_pending(struct dma_async_tx_descriptor *tx)
{
if (likely(tx)) {
struct dma_chan *chan = tx->chan;
struct dma_device *dma = chan->device;
dma->device_issue_pending(chan);
}
}
#ifdef CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL
#include <asm/async_tx.h>
#else
#define async_tx_find_channel(dep, type, dst, dst_count, src, src_count, len) \
__async_tx_find_channel(dep, type)
struct dma_chan *
__async_tx_find_channel(struct async_submit_ctl *submit,
enum dma_transaction_type tx_type);
#endif /* CONFIG_ARCH_HAS_ASYNC_TX_FIND_CHANNEL */
#else
static inline void async_tx_issue_pending_all(void)
{
do { } while (0);
}
static inline void async_tx_issue_pending(struct dma_async_tx_descriptor *tx)
{
do { } while (0);
}
static inline struct dma_chan *
async_tx_find_channel(struct async_submit_ctl *submit,
enum dma_transaction_type tx_type, struct page **dst,
int dst_count, struct page **src, int src_count,
size_t len)
{
return NULL;
}
#endif
/**
* async_tx_sync_epilog - actions to take if an operation is run synchronously
* @cb_fn: function to call when the transaction completes
* @cb_fn_param: parameter to pass to the callback routine
*/
static inline void
async_tx_sync_epilog(struct async_submit_ctl *submit)
{
if (submit->cb_fn)
submit->cb_fn(submit->cb_param);
}
typedef union {
unsigned long addr;
struct page *page;
dma_addr_t dma;
} addr_conv_t;
static inline void
init_async_submit(struct async_submit_ctl *args, enum async_tx_flags flags,
struct dma_async_tx_descriptor *tx,
dma_async_tx_callback cb_fn, void *cb_param,
addr_conv_t *scribble)
{
args->flags = flags;
args->depend_tx = tx;
args->cb_fn = cb_fn;
args->cb_param = cb_param;
args->scribble = scribble;
}
void async_tx_submit(struct dma_chan *chan, struct dma_async_tx_descriptor *tx,
struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_xor(struct page *dest, struct page **src_list, unsigned int offset,
int src_cnt, size_t len, struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_xor_offs(struct page *dest, unsigned int offset,
struct page **src_list, unsigned int *src_offset,
int src_cnt, size_t len, struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_xor_val_offs(struct page *dest, unsigned int offset,
struct page **src_list, unsigned int *src_offset,
int src_cnt, size_t len, enum sum_check_flags *result,
struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_memcpy(struct page *dest, struct page *src, unsigned int dest_offset,
unsigned int src_offset, size_t len,
struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *async_trigger_callback(struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_gen_syndrome(struct page **blocks, unsigned int *offsets, int src_cnt,
size_t len, struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_syndrome_val(struct page **blocks, unsigned int *offsets, int src_cnt,
size_t len, enum sum_check_flags *pqres, struct page *spare,
unsigned int s_off, struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_raid6_2data_recov(int src_num, size_t bytes, int faila, int failb,
struct page **ptrs, unsigned int *offs,
struct async_submit_ctl *submit);
struct dma_async_tx_descriptor *
async_raid6_datap_recov(int src_num, size_t bytes, int faila,
struct page **ptrs, unsigned int *offs,
struct async_submit_ctl *submit);
void async_tx_quiesce(struct dma_async_tx_descriptor **tx);
#endif /* _ASYNC_TX_H_ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_ATA_PLATFORM_H
#define __LINUX_ATA_PLATFORM_H
struct pata_platform_info {
/*
* I/O port shift, for platforms with ports that are
* constantly spaced and need larger than the 1-byte
* spacing used by ata_std_ports().
*/
unsigned int ioport_shift;
};
struct scsi_host_template;
extern int __pata_platform_probe(struct device *dev,
struct resource *io_res,
struct resource *ctl_res,
struct resource *irq_res,
unsigned int ioport_shift,
int __pio_mask,
const struct scsi_host_template *sht,
bool use16bit);
/*
* Marvell SATA private data
*/
struct mv_sata_platform_data {
int n_ports; /* number of sata ports */
};
#endif /* __LINUX_ATA_PLATFORM_H */
@@ -0,0 +1,186 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_ATALK_H__
#define __LINUX_ATALK_H__
#include <net/sock.h>
#include <uapi/linux/atalk.h>
struct atalk_route {
struct net_device *dev;
struct atalk_addr target;
struct atalk_addr gateway;
int flags;
struct atalk_route *next;
};
/**
* struct atalk_iface - AppleTalk Interface
* @dev - Network device associated with this interface
* @address - Our address
* @status - What are we doing?
* @nets - Associated direct netrange
* @next - next element in the list of interfaces
*/
struct atalk_iface {
struct net_device *dev;
struct atalk_addr address;
int status;
#define ATIF_PROBE 1 /* Probing for an address */
#define ATIF_PROBE_FAIL 2 /* Probe collided */
struct atalk_netrange nets;
struct atalk_iface *next;
};
struct atalk_sock {
/* struct sock has to be the first member of atalk_sock */
struct sock sk;
__be16 dest_net;
__be16 src_net;
unsigned char dest_node;
unsigned char src_node;
unsigned char dest_port;
unsigned char src_port;
};
static inline struct atalk_sock *at_sk(struct sock *sk)
{
return (struct atalk_sock *)sk;
}
struct ddpehdr {
__be16 deh_len_hops; /* lower 10 bits are length, next 4 - hops */
__be16 deh_sum;
__be16 deh_dnet;
__be16 deh_snet;
__u8 deh_dnode;
__u8 deh_snode;
__u8 deh_dport;
__u8 deh_sport;
/* And netatalk apps expect to stick the type in themselves */
};
static __inline__ struct ddpehdr *ddp_hdr(struct sk_buff *skb)
{
return (struct ddpehdr *)skb_transport_header(skb);
}
/* AppleTalk AARP headers */
struct elapaarp {
__be16 hw_type;
#define AARP_HW_TYPE_ETHERNET 1
#define AARP_HW_TYPE_TOKENRING 2
__be16 pa_type;
__u8 hw_len;
__u8 pa_len;
#define AARP_PA_ALEN 4
__be16 function;
#define AARP_REQUEST 1
#define AARP_REPLY 2
#define AARP_PROBE 3
__u8 hw_src[ETH_ALEN];
__u8 pa_src_zero;
__be16 pa_src_net;
__u8 pa_src_node;
__u8 hw_dst[ETH_ALEN];
__u8 pa_dst_zero;
__be16 pa_dst_net;
__u8 pa_dst_node;
} __attribute__ ((packed));
static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb)
{
return (struct elapaarp *)skb_transport_header(skb);
}
/* Not specified - how long till we drop a resolved entry */
#define AARP_EXPIRY_TIME (5 * 60 * HZ)
/* Size of hash table */
#define AARP_HASH_SIZE 16
/* Fast retransmission timer when resolving */
#define AARP_TICK_TIME (HZ / 5)
/* Send 10 requests then give up (2 seconds) */
#define AARP_RETRANSMIT_LIMIT 10
/*
* Some value bigger than total retransmit time + a bit for last reply to
* appear and to stop continual requests
*/
#define AARP_RESOLVE_TIME (10 * HZ)
extern struct datalink_proto *ddp_dl, *aarp_dl;
extern int aarp_proto_init(void);
/* Inter module exports */
/* Give a device find its atif control structure */
#if IS_ENABLED(CONFIG_ATALK)
static inline struct atalk_iface *atalk_find_dev(struct net_device *dev)
{
return dev->atalk_ptr;
}
#endif
extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev);
extern struct net_device *atrtr_get_dev(struct atalk_addr *sa);
extern int aarp_send_ddp(struct net_device *dev,
struct sk_buff *skb,
struct atalk_addr *sa, void *hwaddr);
extern void aarp_device_down(struct net_device *dev);
extern void aarp_probe_network(struct atalk_iface *atif);
extern int aarp_proxy_probe_network(struct atalk_iface *atif,
struct atalk_addr *sa);
extern void aarp_proxy_remove(struct net_device *dev,
struct atalk_addr *sa);
extern void aarp_cleanup_module(void);
extern struct hlist_head atalk_sockets;
extern rwlock_t atalk_sockets_lock;
extern struct atalk_route *atalk_routes;
extern rwlock_t atalk_routes_lock;
extern struct atalk_iface *atalk_interfaces;
extern rwlock_t atalk_interfaces_lock;
extern struct atalk_route atrtr_default;
struct aarp_iter_state {
int bucket;
struct aarp_entry **table;
};
extern const struct seq_operations aarp_seq_ops;
extern int sysctl_aarp_expiry_time;
extern int sysctl_aarp_tick_time;
extern int sysctl_aarp_retransmit_limit;
extern int sysctl_aarp_resolve_time;
#ifdef CONFIG_SYSCTL
extern int atalk_register_sysctl(void);
extern void atalk_unregister_sysctl(void);
#else
static inline int atalk_register_sysctl(void)
{
return 0;
}
static inline void atalk_unregister_sysctl(void)
{
}
#endif
#ifdef CONFIG_PROC_FS
extern int atalk_proc_init(void);
extern void atalk_proc_exit(void);
#else
static inline int atalk_proc_init(void)
{
return 0;
}
static inline void atalk_proc_exit(void)
{
}
#endif /* CONFIG_PROC_FS */
#endif /* __LINUX_ATALK_H__ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* atm.h - general ATM declarations */
#ifndef _LINUX_ATM_H
#define _LINUX_ATM_H
#include <uapi/linux/atm.h>
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
struct compat_atmif_sioc {
int number;
int length;
compat_uptr_t arg;
};
#endif
#endif
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* atm_tcp.h - Driver-specific declarations of the ATMTCP driver (for use by
driver-specific utilities) */
/* Written 1997-2000 by Werner Almesberger, EPFL LRC/ICA */
#ifndef LINUX_ATM_TCP_H
#define LINUX_ATM_TCP_H
#include <uapi/linux/atm_tcp.h>
struct atm_vcc;
struct module;
struct atm_tcp_ops {
int (*attach)(struct atm_vcc *vcc,int itf);
int (*create_persistent)(int itf);
int (*remove_persistent)(int itf);
struct module *owner;
};
extern struct atm_tcp_ops atm_tcp_ops;
#endif
@@ -0,0 +1,335 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* atmdev.h - ATM device driver declarations and various related items */
#ifndef LINUX_ATMDEV_H
#define LINUX_ATMDEV_H
#include <linux/wait.h> /* wait_queue_head_t */
#include <linux/time.h> /* struct timeval */
#include <linux/net.h>
#include <linux/bug.h>
#include <linux/skbuff.h> /* struct sk_buff */
#include <linux/uio.h>
#include <net/sock.h>
#include <linux/atomic.h>
#include <linux/refcount.h>
#include <uapi/linux/atmdev.h>
#ifdef CONFIG_PROC_FS
#include <linux/proc_fs.h>
extern struct proc_dir_entry *atm_proc_root;
#endif
#ifdef CONFIG_COMPAT
#include <linux/compat.h>
struct compat_atm_iobuf {
int length;
compat_uptr_t buffer;
};
#endif
struct k_atm_aal_stats {
#define __HANDLE_ITEM(i) atomic_t i
__AAL_STAT_ITEMS
#undef __HANDLE_ITEM
};
struct k_atm_dev_stats {
struct k_atm_aal_stats aal0;
struct k_atm_aal_stats aal34;
struct k_atm_aal_stats aal5;
};
struct device;
enum {
ATM_VF_ADDR, /* Address is in use. Set by anybody, cleared
by device driver. */
ATM_VF_READY, /* VC is ready to transfer data. Set by device
driver, cleared by anybody. */
ATM_VF_PARTIAL, /* resources are bound to PVC (partial PVC
setup), controlled by socket layer */
ATM_VF_REGIS, /* registered with demon, controlled by SVC
socket layer */
ATM_VF_BOUND, /* local SAP is set, controlled by SVC socket
layer */
ATM_VF_RELEASED, /* demon has indicated/requested release,
controlled by SVC socket layer */
ATM_VF_HASQOS, /* QOS parameters have been set */
ATM_VF_LISTEN, /* socket is used for listening */
ATM_VF_META, /* SVC socket isn't used for normal data
traffic and doesn't depend on signaling
to be available */
ATM_VF_SESSION, /* VCC is p2mp session control descriptor */
ATM_VF_HASSAP, /* SAP has been set */
ATM_VF_CLOSE, /* asynchronous close - treat like VF_RELEASED*/
ATM_VF_WAITING, /* waiting for reply from sigd */
ATM_VF_IS_CLIP, /* in use by CLIP protocol */
};
#define ATM_VF2VS(flags) \
(test_bit(ATM_VF_READY,&(flags)) ? ATM_VS_CONNECTED : \
test_bit(ATM_VF_RELEASED,&(flags)) ? ATM_VS_CLOSING : \
test_bit(ATM_VF_LISTEN,&(flags)) ? ATM_VS_LISTEN : \
test_bit(ATM_VF_REGIS,&(flags)) ? ATM_VS_INUSE : \
test_bit(ATM_VF_BOUND,&(flags)) ? ATM_VS_BOUND : ATM_VS_IDLE)
enum {
ATM_DF_REMOVED, /* device was removed from atm_devs list */
};
#define ATM_PHY_SIG_LOST 0 /* no carrier/light */
#define ATM_PHY_SIG_UNKNOWN 1 /* carrier/light status is unknown */
#define ATM_PHY_SIG_FOUND 2 /* carrier/light okay */
#define ATM_ATMOPT_CLP 1 /* set CLP bit */
struct atm_vcc {
/* struct sock has to be the first member of atm_vcc */
struct sock sk;
unsigned long flags; /* VCC flags (ATM_VF_*) */
short vpi; /* VPI and VCI (types must be equal */
/* with sockaddr) */
int vci;
unsigned long aal_options; /* AAL layer options */
unsigned long atm_options; /* ATM layer options */
struct atm_dev *dev; /* device back pointer */
struct atm_qos qos; /* QOS */
struct atm_sap sap; /* SAP */
void (*release_cb)(struct atm_vcc *vcc); /* release_sock callback */
void (*push)(struct atm_vcc *vcc,struct sk_buff *skb);
void (*pop)(struct atm_vcc *vcc,struct sk_buff *skb); /* optional */
int (*push_oam)(struct atm_vcc *vcc,void *cell);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
void *dev_data; /* per-device data */
void *proto_data; /* per-protocol data */
struct k_atm_aal_stats *stats; /* pointer to AAL stats group */
struct module *owner; /* owner of ->push function */
/* SVC part --- may move later ------------------------------------- */
short itf; /* interface number */
struct sockaddr_atmsvc local;
struct sockaddr_atmsvc remote;
/* Multipoint part ------------------------------------------------- */
struct atm_vcc *session; /* session VCC descriptor */
/* Other stuff ----------------------------------------------------- */
void *user_back; /* user backlink - not touched by */
/* native ATM stack. Currently used */
/* by CLIP and sch_atm. */
};
static inline struct atm_vcc *atm_sk(struct sock *sk)
{
return (struct atm_vcc *)sk;
}
static inline struct atm_vcc *ATM_SD(struct socket *sock)
{
return atm_sk(sock->sk);
}
static inline struct sock *sk_atm(struct atm_vcc *vcc)
{
return (struct sock *)vcc;
}
struct atm_dev_addr {
struct sockaddr_atmsvc addr; /* ATM address */
struct list_head entry; /* next address */
};
enum atm_addr_type_t { ATM_ADDR_LOCAL, ATM_ADDR_LECS };
struct atm_dev {
const struct atmdev_ops *ops; /* device operations; NULL if unused */
const struct atmphy_ops *phy; /* PHY operations, may be undefined */
/* (NULL) */
const char *type; /* device type name */
int number; /* device index */
void *dev_data; /* per-device data */
void *phy_data; /* private PHY data */
unsigned long flags; /* device flags (ATM_DF_*) */
struct list_head local; /* local ATM addresses */
struct list_head lecs; /* LECS ATM addresses learned via ILMI */
unsigned char esi[ESI_LEN]; /* ESI ("MAC" addr) */
struct atm_cirange ci_range; /* VPI/VCI range */
struct k_atm_dev_stats stats; /* statistics */
char signal; /* signal status (ATM_PHY_SIG_*) */
int link_rate; /* link rate (default: OC3) */
refcount_t refcnt; /* reference count */
spinlock_t lock; /* protect internal members */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry; /* proc entry */
char *proc_name; /* proc entry name */
#endif
struct device class_dev; /* sysfs device */
struct list_head dev_list; /* linkage */
};
/* OF: send_Oam Flags */
#define ATM_OF_IMMED 1 /* Attempt immediate delivery */
#define ATM_OF_INRATE 2 /* Attempt in-rate delivery */
struct atmdev_ops { /* only send is required */
void (*dev_close)(struct atm_dev *dev);
int (*open)(struct atm_vcc *vcc);
void (*close)(struct atm_vcc *vcc);
int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
#ifdef CONFIG_COMPAT
int (*compat_ioctl)(struct atm_dev *dev,unsigned int cmd,
void __user *arg);
#endif
int (*pre_send)(struct atm_vcc *vcc, struct sk_buff *skb);
int (*send)(struct atm_vcc *vcc,struct sk_buff *skb);
int (*send_bh)(struct atm_vcc *vcc, struct sk_buff *skb);
int (*send_oam)(struct atm_vcc *vcc,void *cell,int flags);
void (*phy_put)(struct atm_dev *dev,unsigned char value,
unsigned long addr);
unsigned char (*phy_get)(struct atm_dev *dev,unsigned long addr);
int (*change_qos)(struct atm_vcc *vcc,struct atm_qos *qos,int flags);
int (*proc_read)(struct atm_dev *dev,loff_t *pos,char *page);
struct module *owner;
};
struct atmphy_ops {
int (*start)(struct atm_dev *dev);
int (*ioctl)(struct atm_dev *dev,unsigned int cmd,void __user *arg);
void (*interrupt)(struct atm_dev *dev);
int (*stop)(struct atm_dev *dev);
};
struct atm_skb_data {
struct atm_vcc *vcc; /* ATM VCC */
unsigned long atm_options; /* ATM layer options */
unsigned int acct_truesize; /* truesize accounted to vcc */
} __packed;
#define VCC_HTABLE_SIZE 32
extern struct hlist_head vcc_hash[VCC_HTABLE_SIZE];
extern rwlock_t vcc_sklist_lock;
#define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb))
struct atm_dev *atm_dev_register(const char *type, struct device *parent,
const struct atmdev_ops *ops,
int number, /* -1 == pick first available */
unsigned long *flags);
struct atm_dev *atm_dev_lookup(int number);
void atm_dev_deregister(struct atm_dev *dev);
/* atm_dev_signal_change
*
* Propagate lower layer signal change in atm_dev->signal to netdevice.
* The event will be sent via a notifier call chain.
*/
void atm_dev_signal_change(struct atm_dev *dev, char signal);
void vcc_insert_socket(struct sock *sk);
void atm_dev_release_vccs(struct atm_dev *dev);
static inline void atm_account_tx(struct atm_vcc *vcc, struct sk_buff *skb)
{
/*
* Because ATM skbs may not belong to a sock (and we don't
* necessarily want to), skb->truesize may be adjusted,
* escaping the hack in pskb_expand_head() which avoids
* doing so for some cases. So stash the value of truesize
* at the time we accounted it, and atm_pop_raw() can use
* that value later, in case it changes.
*/
refcount_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
ATM_SKB(skb)->acct_truesize = skb->truesize;
ATM_SKB(skb)->atm_options = vcc->atm_options;
}
static inline void atm_return_tx(struct atm_vcc *vcc, struct sk_buff *skb)
{
WARN_ON_ONCE(refcount_sub_and_test(ATM_SKB(skb)->acct_truesize,
&sk_atm(vcc)->sk_wmem_alloc));
}
static inline void atm_force_charge(struct atm_vcc *vcc,int truesize)
{
atomic_add(truesize, &sk_atm(vcc)->sk_rmem_alloc);
}
static inline void atm_return(struct atm_vcc *vcc,int truesize)
{
atomic_sub(truesize, &sk_atm(vcc)->sk_rmem_alloc);
}
static inline int atm_may_send(struct atm_vcc *vcc,unsigned int size)
{
return (size + refcount_read(&sk_atm(vcc)->sk_wmem_alloc)) <
sk_atm(vcc)->sk_sndbuf;
}
static inline void atm_dev_hold(struct atm_dev *dev)
{
refcount_inc(&dev->refcnt);
}
static inline void atm_dev_put(struct atm_dev *dev)
{
if (refcount_dec_and_test(&dev->refcnt)) {
BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
if (dev->ops->dev_close)
dev->ops->dev_close(dev);
put_device(&dev->class_dev);
}
}
int atm_charge(struct atm_vcc *vcc,int truesize);
struct sk_buff *atm_alloc_charge(struct atm_vcc *vcc,int pdu_size,
gfp_t gfp_flags);
int atm_pcr_goal(const struct atm_trafprm *tp);
void vcc_release_async(struct atm_vcc *vcc, int reply);
struct atm_ioctl {
struct module *owner;
/* A module reference is kept if appropriate over this call.
* Return -ENOIOCTLCMD if you don't handle it. */
int (*ioctl)(struct socket *, unsigned int cmd, unsigned long arg);
struct list_head list;
};
/**
* register_atm_ioctl - register handler for ioctl operations
* @ioctl: ioctl handler to register
*
* Special (non-device) handlers of ioctl's should
* register here. If you're a normal device, you should
* set .ioctl in your atmdev_ops instead.
*/
void register_atm_ioctl(struct atm_ioctl *ioctl);
/**
* deregister_atm_ioctl - remove the ioctl handler
* @ioctl: ioctl handler to deregister
*/
void deregister_atm_ioctl(struct atm_ioctl *ioctl);
/* register_atmdevice_notifier - register atm_dev notify events
*
* Clients like br2684 will register notify events
* Currently we notify of signal found/lost
*/
int register_atmdevice_notifier(struct notifier_block *nb);
void unregister_atmdevice_notifier(struct notifier_block *nb);
#endif
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries
*
* Author: Eugen Hristev <eugen.hristev@microchip.com>
*/
#ifndef __LINUX_ATMEL_ISC_MEDIA_H__
#define __LINUX_ATMEL_ISC_MEDIA_H__
/*
* There are 8 controls available:
* 4 gain controls, sliders, for each of the BAYER components: R, B, GR, GB.
* These gains are multipliers for each component, in format unsigned 0:4:9 with
* a default value of 512 (1.0 multiplier).
* 4 offset controls, sliders, for each of the BAYER components: R, B, GR, GB.
* These offsets are added/substracted from each component, in format signed
* 1:12:0 with a default value of 0 (+/- 0)
*
* To expose this to userspace, added 8 custom controls, in an auto cluster.
*
* To summarize the functionality:
* The auto cluster switch is the auto white balance control, and it works
* like this:
* AWB == 1: autowhitebalance is on, the do_white_balance button is inactive,
* the gains/offsets are inactive, but volatile and readable.
* Thus, the results of the whitebalance algorithm are available to userspace to
* read at any time.
* AWB == 0: autowhitebalance is off, cluster is in manual mode, user can
* configure the gain/offsets directly.
* More than that, if the do_white_balance button is
* pressed, the driver will perform one-time-adjustment, (preferably with color
* checker card) and the userspace can read again the new values.
*
* With this feature, the userspace can save the coefficients and reinstall them
* for example after reboot or reprobing the driver.
*/
enum atmel_isc_ctrl_id {
/* Red component gain control */
ISC_CID_R_GAIN = (V4L2_CID_USER_ATMEL_ISC_BASE + 0),
/* Blue component gain control */
ISC_CID_B_GAIN,
/* Green Red component gain control */
ISC_CID_GR_GAIN,
/* Green Blue gain control */
ISC_CID_GB_GAIN,
/* Red component offset control */
ISC_CID_R_OFFSET,
/* Blue component offset control */
ISC_CID_B_OFFSET,
/* Green Red component offset control */
ISC_CID_GR_OFFSET,
/* Green Blue component offset control */
ISC_CID_GB_OFFSET,
};
#endif
@@ -0,0 +1,335 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __INCLUDE_ATMEL_SSC_H
#define __INCLUDE_ATMEL_SSC_H
#include <linux/platform_device.h>
#include <linux/list.h>
#include <linux/io.h>
struct atmel_ssc_platform_data {
int use_dma;
int has_fslen_ext;
};
struct ssc_device {
struct list_head list;
dma_addr_t phybase;
void __iomem *regs;
struct platform_device *pdev;
struct atmel_ssc_platform_data *pdata;
struct clk *clk;
int user;
int irq;
bool clk_from_rk_pin;
bool sound_dai;
};
struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
void ssc_free(struct ssc_device *ssc);
/* SSC register offsets */
/* SSC Control Register */
#define SSC_CR 0x00000000
#define SSC_CR_RXDIS_SIZE 1
#define SSC_CR_RXDIS_OFFSET 1
#define SSC_CR_RXEN_SIZE 1
#define SSC_CR_RXEN_OFFSET 0
#define SSC_CR_SWRST_SIZE 1
#define SSC_CR_SWRST_OFFSET 15
#define SSC_CR_TXDIS_SIZE 1
#define SSC_CR_TXDIS_OFFSET 9
#define SSC_CR_TXEN_SIZE 1
#define SSC_CR_TXEN_OFFSET 8
/* SSC Clock Mode Register */
#define SSC_CMR 0x00000004
#define SSC_CMR_DIV_SIZE 12
#define SSC_CMR_DIV_OFFSET 0
/* SSC Receive Clock Mode Register */
#define SSC_RCMR 0x00000010
#define SSC_RCMR_CKG_SIZE 2
#define SSC_RCMR_CKG_OFFSET 6
#define SSC_RCMR_CKI_SIZE 1
#define SSC_RCMR_CKI_OFFSET 5
#define SSC_RCMR_CKO_SIZE 3
#define SSC_RCMR_CKO_OFFSET 2
#define SSC_RCMR_CKS_SIZE 2
#define SSC_RCMR_CKS_OFFSET 0
#define SSC_RCMR_PERIOD_SIZE 8
#define SSC_RCMR_PERIOD_OFFSET 24
#define SSC_RCMR_START_SIZE 4
#define SSC_RCMR_START_OFFSET 8
#define SSC_RCMR_STOP_SIZE 1
#define SSC_RCMR_STOP_OFFSET 12
#define SSC_RCMR_STTDLY_SIZE 8
#define SSC_RCMR_STTDLY_OFFSET 16
/* SSC Receive Frame Mode Register */
#define SSC_RFMR 0x00000014
#define SSC_RFMR_DATLEN_SIZE 5
#define SSC_RFMR_DATLEN_OFFSET 0
#define SSC_RFMR_DATNB_SIZE 4
#define SSC_RFMR_DATNB_OFFSET 8
#define SSC_RFMR_FSEDGE_SIZE 1
#define SSC_RFMR_FSEDGE_OFFSET 24
/*
* The FSLEN_EXT exist on at91sam9rl, at91sam9g10,
* at91sam9g20, and at91sam9g45 and newer SoCs
*/
#define SSC_RFMR_FSLEN_EXT_SIZE 4
#define SSC_RFMR_FSLEN_EXT_OFFSET 28
#define SSC_RFMR_FSLEN_SIZE 4
#define SSC_RFMR_FSLEN_OFFSET 16
#define SSC_RFMR_FSOS_SIZE 4
#define SSC_RFMR_FSOS_OFFSET 20
#define SSC_RFMR_LOOP_SIZE 1
#define SSC_RFMR_LOOP_OFFSET 5
#define SSC_RFMR_MSBF_SIZE 1
#define SSC_RFMR_MSBF_OFFSET 7
/* SSC Transmit Clock Mode Register */
#define SSC_TCMR 0x00000018
#define SSC_TCMR_CKG_SIZE 2
#define SSC_TCMR_CKG_OFFSET 6
#define SSC_TCMR_CKI_SIZE 1
#define SSC_TCMR_CKI_OFFSET 5
#define SSC_TCMR_CKO_SIZE 3
#define SSC_TCMR_CKO_OFFSET 2
#define SSC_TCMR_CKS_SIZE 2
#define SSC_TCMR_CKS_OFFSET 0
#define SSC_TCMR_PERIOD_SIZE 8
#define SSC_TCMR_PERIOD_OFFSET 24
#define SSC_TCMR_START_SIZE 4
#define SSC_TCMR_START_OFFSET 8
#define SSC_TCMR_STTDLY_SIZE 8
#define SSC_TCMR_STTDLY_OFFSET 16
/* SSC Transmit Frame Mode Register */
#define SSC_TFMR 0x0000001c
#define SSC_TFMR_DATDEF_SIZE 1
#define SSC_TFMR_DATDEF_OFFSET 5
#define SSC_TFMR_DATLEN_SIZE 5
#define SSC_TFMR_DATLEN_OFFSET 0
#define SSC_TFMR_DATNB_SIZE 4
#define SSC_TFMR_DATNB_OFFSET 8
#define SSC_TFMR_FSDEN_SIZE 1
#define SSC_TFMR_FSDEN_OFFSET 23
#define SSC_TFMR_FSEDGE_SIZE 1
#define SSC_TFMR_FSEDGE_OFFSET 24
/*
* The FSLEN_EXT exist on at91sam9rl, at91sam9g10,
* at91sam9g20, and at91sam9g45 and newer SoCs
*/
#define SSC_TFMR_FSLEN_EXT_SIZE 4
#define SSC_TFMR_FSLEN_EXT_OFFSET 28
#define SSC_TFMR_FSLEN_SIZE 4
#define SSC_TFMR_FSLEN_OFFSET 16
#define SSC_TFMR_FSOS_SIZE 3
#define SSC_TFMR_FSOS_OFFSET 20
#define SSC_TFMR_MSBF_SIZE 1
#define SSC_TFMR_MSBF_OFFSET 7
/* SSC Receive Hold Register */
#define SSC_RHR 0x00000020
#define SSC_RHR_RDAT_SIZE 32
#define SSC_RHR_RDAT_OFFSET 0
/* SSC Transmit Hold Register */
#define SSC_THR 0x00000024
#define SSC_THR_TDAT_SIZE 32
#define SSC_THR_TDAT_OFFSET 0
/* SSC Receive Sync. Holding Register */
#define SSC_RSHR 0x00000030
#define SSC_RSHR_RSDAT_SIZE 16
#define SSC_RSHR_RSDAT_OFFSET 0
/* SSC Transmit Sync. Holding Register */
#define SSC_TSHR 0x00000034
#define SSC_TSHR_TSDAT_SIZE 16
#define SSC_TSHR_RSDAT_OFFSET 0
/* SSC Receive Compare 0 Register */
#define SSC_RC0R 0x00000038
#define SSC_RC0R_CP0_SIZE 16
#define SSC_RC0R_CP0_OFFSET 0
/* SSC Receive Compare 1 Register */
#define SSC_RC1R 0x0000003c
#define SSC_RC1R_CP1_SIZE 16
#define SSC_RC1R_CP1_OFFSET 0
/* SSC Status Register */
#define SSC_SR 0x00000040
#define SSC_SR_CP0_SIZE 1
#define SSC_SR_CP0_OFFSET 8
#define SSC_SR_CP1_SIZE 1
#define SSC_SR_CP1_OFFSET 9
#define SSC_SR_ENDRX_SIZE 1
#define SSC_SR_ENDRX_OFFSET 6
#define SSC_SR_ENDTX_SIZE 1
#define SSC_SR_ENDTX_OFFSET 2
#define SSC_SR_OVRUN_SIZE 1
#define SSC_SR_OVRUN_OFFSET 5
#define SSC_SR_RXBUFF_SIZE 1
#define SSC_SR_RXBUFF_OFFSET 7
#define SSC_SR_RXEN_SIZE 1
#define SSC_SR_RXEN_OFFSET 17
#define SSC_SR_RXRDY_SIZE 1
#define SSC_SR_RXRDY_OFFSET 4
#define SSC_SR_RXSYN_SIZE 1
#define SSC_SR_RXSYN_OFFSET 11
#define SSC_SR_TXBUFE_SIZE 1
#define SSC_SR_TXBUFE_OFFSET 3
#define SSC_SR_TXEMPTY_SIZE 1
#define SSC_SR_TXEMPTY_OFFSET 1
#define SSC_SR_TXEN_SIZE 1
#define SSC_SR_TXEN_OFFSET 16
#define SSC_SR_TXRDY_SIZE 1
#define SSC_SR_TXRDY_OFFSET 0
#define SSC_SR_TXSYN_SIZE 1
#define SSC_SR_TXSYN_OFFSET 10
/* SSC Interrupt Enable Register */
#define SSC_IER 0x00000044
#define SSC_IER_CP0_SIZE 1
#define SSC_IER_CP0_OFFSET 8
#define SSC_IER_CP1_SIZE 1
#define SSC_IER_CP1_OFFSET 9
#define SSC_IER_ENDRX_SIZE 1
#define SSC_IER_ENDRX_OFFSET 6
#define SSC_IER_ENDTX_SIZE 1
#define SSC_IER_ENDTX_OFFSET 2
#define SSC_IER_OVRUN_SIZE 1
#define SSC_IER_OVRUN_OFFSET 5
#define SSC_IER_RXBUFF_SIZE 1
#define SSC_IER_RXBUFF_OFFSET 7
#define SSC_IER_RXRDY_SIZE 1
#define SSC_IER_RXRDY_OFFSET 4
#define SSC_IER_RXSYN_SIZE 1
#define SSC_IER_RXSYN_OFFSET 11
#define SSC_IER_TXBUFE_SIZE 1
#define SSC_IER_TXBUFE_OFFSET 3
#define SSC_IER_TXEMPTY_SIZE 1
#define SSC_IER_TXEMPTY_OFFSET 1
#define SSC_IER_TXRDY_SIZE 1
#define SSC_IER_TXRDY_OFFSET 0
#define SSC_IER_TXSYN_SIZE 1
#define SSC_IER_TXSYN_OFFSET 10
/* SSC Interrupt Disable Register */
#define SSC_IDR 0x00000048
#define SSC_IDR_CP0_SIZE 1
#define SSC_IDR_CP0_OFFSET 8
#define SSC_IDR_CP1_SIZE 1
#define SSC_IDR_CP1_OFFSET 9
#define SSC_IDR_ENDRX_SIZE 1
#define SSC_IDR_ENDRX_OFFSET 6
#define SSC_IDR_ENDTX_SIZE 1
#define SSC_IDR_ENDTX_OFFSET 2
#define SSC_IDR_OVRUN_SIZE 1
#define SSC_IDR_OVRUN_OFFSET 5
#define SSC_IDR_RXBUFF_SIZE 1
#define SSC_IDR_RXBUFF_OFFSET 7
#define SSC_IDR_RXRDY_SIZE 1
#define SSC_IDR_RXRDY_OFFSET 4
#define SSC_IDR_RXSYN_SIZE 1
#define SSC_IDR_RXSYN_OFFSET 11
#define SSC_IDR_TXBUFE_SIZE 1
#define SSC_IDR_TXBUFE_OFFSET 3
#define SSC_IDR_TXEMPTY_SIZE 1
#define SSC_IDR_TXEMPTY_OFFSET 1
#define SSC_IDR_TXRDY_SIZE 1
#define SSC_IDR_TXRDY_OFFSET 0
#define SSC_IDR_TXSYN_SIZE 1
#define SSC_IDR_TXSYN_OFFSET 10
/* SSC Interrupt Mask Register */
#define SSC_IMR 0x0000004c
#define SSC_IMR_CP0_SIZE 1
#define SSC_IMR_CP0_OFFSET 8
#define SSC_IMR_CP1_SIZE 1
#define SSC_IMR_CP1_OFFSET 9
#define SSC_IMR_ENDRX_SIZE 1
#define SSC_IMR_ENDRX_OFFSET 6
#define SSC_IMR_ENDTX_SIZE 1
#define SSC_IMR_ENDTX_OFFSET 2
#define SSC_IMR_OVRUN_SIZE 1
#define SSC_IMR_OVRUN_OFFSET 5
#define SSC_IMR_RXBUFF_SIZE 1
#define SSC_IMR_RXBUFF_OFFSET 7
#define SSC_IMR_RXRDY_SIZE 1
#define SSC_IMR_RXRDY_OFFSET 4
#define SSC_IMR_RXSYN_SIZE 1
#define SSC_IMR_RXSYN_OFFSET 11
#define SSC_IMR_TXBUFE_SIZE 1
#define SSC_IMR_TXBUFE_OFFSET 3
#define SSC_IMR_TXEMPTY_SIZE 1
#define SSC_IMR_TXEMPTY_OFFSET 1
#define SSC_IMR_TXRDY_SIZE 1
#define SSC_IMR_TXRDY_OFFSET 0
#define SSC_IMR_TXSYN_SIZE 1
#define SSC_IMR_TXSYN_OFFSET 10
/* SSC PDC Receive Pointer Register */
#define SSC_PDC_RPR 0x00000100
/* SSC PDC Receive Counter Register */
#define SSC_PDC_RCR 0x00000104
/* SSC PDC Transmit Pointer Register */
#define SSC_PDC_TPR 0x00000108
/* SSC PDC Receive Next Pointer Register */
#define SSC_PDC_RNPR 0x00000110
/* SSC PDC Receive Next Counter Register */
#define SSC_PDC_RNCR 0x00000114
/* SSC PDC Transmit Counter Register */
#define SSC_PDC_TCR 0x0000010c
/* SSC PDC Transmit Next Pointer Register */
#define SSC_PDC_TNPR 0x00000118
/* SSC PDC Transmit Next Counter Register */
#define SSC_PDC_TNCR 0x0000011c
/* SSC PDC Transfer Control Register */
#define SSC_PDC_PTCR 0x00000120
#define SSC_PDC_PTCR_RXTDIS_SIZE 1
#define SSC_PDC_PTCR_RXTDIS_OFFSET 1
#define SSC_PDC_PTCR_RXTEN_SIZE 1
#define SSC_PDC_PTCR_RXTEN_OFFSET 0
#define SSC_PDC_PTCR_TXTDIS_SIZE 1
#define SSC_PDC_PTCR_TXTDIS_OFFSET 9
#define SSC_PDC_PTCR_TXTEN_SIZE 1
#define SSC_PDC_PTCR_TXTEN_OFFSET 8
/* SSC PDC Transfer Status Register */
#define SSC_PDC_PTSR 0x00000124
#define SSC_PDC_PTSR_RXTEN_SIZE 1
#define SSC_PDC_PTSR_RXTEN_OFFSET 0
#define SSC_PDC_PTSR_TXTEN_SIZE 1
#define SSC_PDC_PTSR_TXTEN_OFFSET 8
/* Bit manipulation macros */
#define SSC_BIT(name) \
(1 << SSC_##name##_OFFSET)
#define SSC_BF(name, value) \
(((value) & ((1 << SSC_##name##_SIZE) - 1)) \
<< SSC_##name##_OFFSET)
#define SSC_BFEXT(name, value) \
(((value) >> SSC_##name##_OFFSET) \
& ((1 << SSC_##name##_SIZE) - 1))
#define SSC_BFINS(name, value, old) \
(((old) & ~(((1 << SSC_##name##_SIZE) - 1) \
<< SSC_##name##_OFFSET)) | SSC_BF(name, value))
/* Register access macros */
#define ssc_readl(base, reg) __raw_readl(base + SSC_##reg)
#define ssc_writel(base, reg, value) __raw_writel((value), base + SSC_##reg)
#endif /* __INCLUDE_ATMEL_SSC_H */
@@ -0,0 +1,34 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* include/linux/atmel_pdc.h
*
* Copyright (C) 2005 Ivan Kokshaysky
* Copyright (C) SAN People
*
* Peripheral Data Controller (PDC) registers.
* Based on AT91RM9200 datasheet revision E.
*/
#ifndef ATMEL_PDC_H
#define ATMEL_PDC_H
#define ATMEL_PDC_RPR 0x100 /* Receive Pointer Register */
#define ATMEL_PDC_RCR 0x104 /* Receive Counter Register */
#define ATMEL_PDC_TPR 0x108 /* Transmit Pointer Register */
#define ATMEL_PDC_TCR 0x10c /* Transmit Counter Register */
#define ATMEL_PDC_RNPR 0x110 /* Receive Next Pointer Register */
#define ATMEL_PDC_RNCR 0x114 /* Receive Next Counter Register */
#define ATMEL_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
#define ATMEL_PDC_TNCR 0x11c /* Transmit Next Counter Register */
#define ATMEL_PDC_PTCR 0x120 /* Transfer Control Register */
#define ATMEL_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
#define ATMEL_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
#define ATMEL_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
#define ATMEL_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
#define ATMEL_PDC_PTSR 0x124 /* Transfer Status Register */
#define ATMEL_PDC_SCND_BUF_OFF 0x10 /* Offset between first and second buffer registers */
#endif
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Atomic operations usable in machine independent code */
#ifndef _LINUX_ATOMIC_H
#define _LINUX_ATOMIC_H
#include <linux/types.h>
#include <asm/atomic.h>
#include <asm/barrier.h>
/*
* Relaxed variants of xchg, cmpxchg and some atomic operations.
*
* We support four variants:
*
* - Fully ordered: The default implementation, no suffix required.
* - Acquire: Provides ACQUIRE semantics, _acquire suffix.
* - Release: Provides RELEASE semantics, _release suffix.
* - Relaxed: No ordering guarantees, _relaxed suffix.
*
* For compound atomics performing both a load and a store, ACQUIRE
* semantics apply only to the load and RELEASE semantics only to the
* store portion of the operation. Note that a failed cmpxchg_acquire
* does -not- imply any memory ordering constraints.
*
* See Documentation/memory-barriers.txt for ACQUIRE/RELEASE definitions.
*/
#define atomic_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
#define atomic_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
#define atomic64_cond_read_acquire(v, c) smp_cond_load_acquire(&(v)->counter, (c))
#define atomic64_cond_read_relaxed(v, c) smp_cond_load_relaxed(&(v)->counter, (c))
/*
* The idea here is to build acquire/release variants by adding explicit
* barriers on top of the relaxed variant. In the case where the relaxed
* variant is already fully ordered, no additional barriers are needed.
*
* If an architecture overrides __atomic_acquire_fence() it will probably
* want to define smp_mb__after_spinlock().
*/
#ifndef __atomic_acquire_fence
#define __atomic_acquire_fence smp_mb__after_atomic
#endif
#ifndef __atomic_release_fence
#define __atomic_release_fence smp_mb__before_atomic
#endif
#ifndef __atomic_pre_full_fence
#define __atomic_pre_full_fence smp_mb__before_atomic
#endif
#ifndef __atomic_post_full_fence
#define __atomic_post_full_fence smp_mb__after_atomic
#endif
#define __atomic_op_acquire(op, args...) \
({ \
typeof(op##_relaxed(args)) __ret = op##_relaxed(args); \
__atomic_acquire_fence(); \
__ret; \
})
#define __atomic_op_release(op, args...) \
({ \
__atomic_release_fence(); \
op##_relaxed(args); \
})
#define __atomic_op_fence(op, args...) \
({ \
typeof(op##_relaxed(args)) __ret; \
__atomic_pre_full_fence(); \
__ret = op##_relaxed(args); \
__atomic_post_full_fence(); \
__ret; \
})
#include <linux/atomic/atomic-arch-fallback.h>
#include <linux/atomic/atomic-long.h>
#include <linux/atomic/atomic-instrumented.h>
#endif /* _LINUX_ATOMIC_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* attribute_container.h - a generic container for all classes
*
* Copyright (c) 2005 - James Bottomley <James.Bottomley@steeleye.com>
*/
#ifndef _ATTRIBUTE_CONTAINER_H_
#define _ATTRIBUTE_CONTAINER_H_
#include <linux/list.h>
#include <linux/klist.h>
struct device;
struct attribute_container {
struct list_head node;
struct klist containers;
struct class *class;
const struct attribute_group *grp;
struct device_attribute **attrs;
int (*match)(struct attribute_container *, struct device *);
#define ATTRIBUTE_CONTAINER_NO_CLASSDEVS 0x01
unsigned long flags;
};
static inline int
attribute_container_no_classdevs(struct attribute_container *atc)
{
return atc->flags & ATTRIBUTE_CONTAINER_NO_CLASSDEVS;
}
static inline void
attribute_container_set_no_classdevs(struct attribute_container *atc)
{
atc->flags |= ATTRIBUTE_CONTAINER_NO_CLASSDEVS;
}
void attribute_container_register(struct attribute_container *cont);
int __must_check attribute_container_unregister(struct attribute_container *cont);
void attribute_container_create_device(struct device *dev,
int (*fn)(struct attribute_container *,
struct device *,
struct device *));
void attribute_container_add_device(struct device *dev,
int (*fn)(struct attribute_container *,
struct device *,
struct device *));
void attribute_container_remove_device(struct device *dev,
void (*fn)(struct attribute_container *,
struct device *,
struct device *));
void attribute_container_device_trigger(struct device *dev,
int (*fn)(struct attribute_container *,
struct device *,
struct device *));
int attribute_container_device_trigger_safe(struct device *dev,
int (*fn)(struct attribute_container *,
struct device *,
struct device *),
int (*undo)(struct attribute_container *,
struct device *,
struct device *));
int attribute_container_add_attrs(struct device *classdev);
int attribute_container_add_class_device(struct device *classdev);
void attribute_container_remove_attrs(struct device *classdev);
void attribute_container_class_device_del(struct device *classdev);
struct attribute_container *attribute_container_classdev_to_container(struct device *);
struct device *attribute_container_find_class_device(struct attribute_container *, struct device *);
struct device_attribute **attribute_container_classdev_to_attrs(const struct device *classdev);
#endif
@@ -0,0 +1,742 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* audit.h -- Auditing support
*
* Copyright 2003-2004 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* Written by Rickard E. (Rik) Faith <faith@redhat.com>
*/
#ifndef _LINUX_AUDIT_H_
#define _LINUX_AUDIT_H_
#include <linux/sched.h>
#include <linux/ptrace.h>
#include <linux/audit_arch.h>
#include <uapi/linux/audit.h>
#include <uapi/linux/fanotify.h>
#define AUDIT_STATUS_ALL (AUDIT_STATUS_ENABLED | \
AUDIT_STATUS_FAILURE | \
AUDIT_STATUS_PID | \
AUDIT_STATUS_RATE_LIMIT | \
AUDIT_STATUS_BACKLOG_LIMIT | \
AUDIT_STATUS_BACKLOG_WAIT_TIME | \
AUDIT_STATUS_LOST | \
AUDIT_STATUS_BACKLOG_WAIT_TIME_ACTUAL)
#define AUDIT_INO_UNSET ((u64)-1)
#define AUDIT_DEV_UNSET ((dev_t)-1)
struct audit_sig_info {
uid_t uid;
pid_t pid;
char ctx[];
};
struct audit_buffer;
struct audit_context;
struct inode;
struct netlink_skb_parms;
struct path;
struct linux_binprm;
struct mq_attr;
struct mqstat;
struct audit_watch;
struct audit_tree;
struct sk_buff;
struct kern_ipc_perm;
struct lsm_id;
struct lsm_prop;
struct audit_krule {
u32 pflags;
u32 flags;
u32 listnr;
u32 action;
u32 mask[AUDIT_BITMASK_SIZE];
u32 buflen; /* for data alloc on list rules */
u32 field_count;
char *filterkey; /* ties events to rules */
struct audit_field *fields;
struct audit_field *arch_f; /* quick access to arch field */
struct audit_field *inode_f; /* quick access to an inode field */
struct audit_watch *watch; /* associated watch */
struct audit_tree *tree; /* associated watched tree */
struct audit_fsnotify_mark *exe;
struct list_head rlist; /* entry in audit_{watch,tree}.rules list */
struct list_head list; /* for AUDIT_LIST* purposes only */
u64 prio;
};
/* Flag to indicate legacy AUDIT_LOGINUID unset usage */
#define AUDIT_LOGINUID_LEGACY 0x1
struct audit_field {
u32 type;
union {
u32 val;
kuid_t uid;
kgid_t gid;
struct {
char *lsm_str;
void *lsm_rule;
};
};
u32 op;
};
enum audit_ntp_type {
AUDIT_NTP_OFFSET,
AUDIT_NTP_FREQ,
AUDIT_NTP_STATUS,
AUDIT_NTP_TAI,
AUDIT_NTP_TICK,
AUDIT_NTP_ADJUST,
AUDIT_NTP_NVALS /* count */
};
#ifdef CONFIG_AUDITSYSCALL
struct audit_ntp_val {
long long oldval, newval;
};
struct audit_ntp_data {
struct audit_ntp_val vals[AUDIT_NTP_NVALS];
};
#else
struct audit_ntp_data {};
#endif
enum audit_nfcfgop {
AUDIT_XT_OP_REGISTER,
AUDIT_XT_OP_REPLACE,
AUDIT_XT_OP_UNREGISTER,
AUDIT_NFT_OP_TABLE_REGISTER,
AUDIT_NFT_OP_TABLE_UNREGISTER,
AUDIT_NFT_OP_CHAIN_REGISTER,
AUDIT_NFT_OP_CHAIN_UNREGISTER,
AUDIT_NFT_OP_RULE_REGISTER,
AUDIT_NFT_OP_RULE_UNREGISTER,
AUDIT_NFT_OP_SET_REGISTER,
AUDIT_NFT_OP_SET_UNREGISTER,
AUDIT_NFT_OP_SETELEM_REGISTER,
AUDIT_NFT_OP_SETELEM_UNREGISTER,
AUDIT_NFT_OP_GEN_REGISTER,
AUDIT_NFT_OP_OBJ_REGISTER,
AUDIT_NFT_OP_OBJ_UNREGISTER,
AUDIT_NFT_OP_OBJ_RESET,
AUDIT_NFT_OP_FLOWTABLE_REGISTER,
AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
AUDIT_NFT_OP_SETELEM_RESET,
AUDIT_NFT_OP_RULE_RESET,
AUDIT_NFT_OP_INVALID,
};
extern int __init audit_register_class(int class, unsigned *list);
extern int audit_classify_syscall(int abi, unsigned syscall);
extern int audit_classify_arch(int arch);
/* audit_names->type values */
#define AUDIT_TYPE_UNKNOWN 0 /* we don't know yet */
#define AUDIT_TYPE_NORMAL 1 /* a "normal" audit record */
#define AUDIT_TYPE_PARENT 2 /* a parent audit record */
#define AUDIT_TYPE_CHILD_DELETE 3 /* a child being deleted */
#define AUDIT_TYPE_CHILD_CREATE 4 /* a child being created */
/* maximized args number that audit_socketcall can process */
#define AUDITSC_ARGS 6
/* bit values for ->signal->audit_tty */
#define AUDIT_TTY_ENABLE BIT(0)
#define AUDIT_TTY_LOG_PASSWD BIT(1)
/* bit values for audit_cfg_lsm */
#define AUDIT_CFG_LSM_SECCTX_SUBJECT BIT(0)
#define AUDIT_CFG_LSM_SECCTX_OBJECT BIT(1)
struct filename;
#define AUDIT_OFF 0
#define AUDIT_ON 1
#define AUDIT_LOCKED 2
#ifdef CONFIG_AUDIT
/* These are defined in audit.c */
/* Public API */
extern __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...);
extern struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type);
extern __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...);
extern void audit_log_end(struct audit_buffer *ab);
extern bool audit_string_contains_control(const char *string,
size_t len);
extern void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf,
size_t len);
extern void audit_log_n_string(struct audit_buffer *ab,
const char *buf,
size_t n);
extern void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string,
size_t n);
extern void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string);
extern void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path);
extern void audit_log_key(struct audit_buffer *ab,
char *key);
extern void audit_log_path_denied(int type,
const char *operation);
extern void audit_log_lost(const char *message);
extern int audit_log_subj_ctx(struct audit_buffer *ab, struct lsm_prop *prop);
extern int audit_log_obj_ctx(struct audit_buffer *ab, struct lsm_prop *prop);
extern int audit_log_task_context(struct audit_buffer *ab);
extern void audit_log_task_info(struct audit_buffer *ab);
extern int audit_log_nf_skb(struct audit_buffer *ab,
const struct sk_buff *skb, u8 nfproto);
extern int audit_update_lsm_rules(void);
/* Private API (for audit.c only) */
extern int audit_rule_change(int type, int seq, void *data, size_t datasz);
extern int audit_list_rules_send(struct sk_buff *request_skb, int seq);
extern int audit_set_loginuid(kuid_t loginuid);
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
{
return tsk->loginuid;
}
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
{
return tsk->sessionid;
}
extern u32 audit_enabled;
extern int audit_signal_info(int sig, struct task_struct *t);
extern void audit_cfg_lsm(const struct lsm_id *lsmid, int flags);
#else /* CONFIG_AUDIT */
static inline __printf(4, 5)
void audit_log(struct audit_context *ctx, gfp_t gfp_mask, int type,
const char *fmt, ...)
{ }
static inline struct audit_buffer *audit_log_start(struct audit_context *ctx,
gfp_t gfp_mask, int type)
{
return NULL;
}
static inline __printf(2, 3)
void audit_log_format(struct audit_buffer *ab, const char *fmt, ...)
{ }
static inline void audit_log_end(struct audit_buffer *ab)
{ }
static inline void audit_log_n_hex(struct audit_buffer *ab,
const unsigned char *buf, size_t len)
{ }
static inline void audit_log_n_string(struct audit_buffer *ab,
const char *buf, size_t n)
{ }
static inline void audit_log_n_untrustedstring(struct audit_buffer *ab,
const char *string, size_t n)
{ }
static inline void audit_log_untrustedstring(struct audit_buffer *ab,
const char *string)
{ }
static inline void audit_log_d_path(struct audit_buffer *ab,
const char *prefix,
const struct path *path)
{ }
static inline void audit_log_key(struct audit_buffer *ab, char *key)
{ }
static inline void audit_log_path_denied(int type, const char *operation)
{ }
static inline int audit_log_subj_ctx(struct audit_buffer *ab,
struct lsm_prop *prop)
{
return 0;
}
static inline int audit_log_obj_ctx(struct audit_buffer *ab,
struct lsm_prop *prop)
{
return 0;
}
static inline int audit_log_task_context(struct audit_buffer *ab)
{
return 0;
}
static inline void audit_log_task_info(struct audit_buffer *ab)
{ }
static inline int audit_log_nf_skb(struct audit_buffer *ab,
const struct sk_buff *skb, u8 nfproto)
{
return 0;
}
static inline kuid_t audit_get_loginuid(struct task_struct *tsk)
{
return INVALID_UID;
}
static inline unsigned int audit_get_sessionid(struct task_struct *tsk)
{
return AUDIT_SID_UNSET;
}
#define audit_enabled AUDIT_OFF
static inline int audit_signal_info(int sig, struct task_struct *t)
{
return 0;
}
static inline void audit_cfg_lsm(const struct lsm_id *lsmid, int flags)
{ }
#endif /* CONFIG_AUDIT */
#ifdef CONFIG_AUDIT_COMPAT_GENERIC
#define audit_is_compat(arch) (!((arch) & __AUDIT_ARCH_64BIT))
#else
#define audit_is_compat(arch) false
#endif
#define AUDIT_INODE_PARENT 1 /* dentry represents the parent */
#define AUDIT_INODE_HIDDEN 2 /* audit record should be hidden */
#define AUDIT_INODE_NOEVAL 4 /* audit record incomplete */
#ifdef CONFIG_AUDITSYSCALL
#include <asm/syscall.h> /* for syscall_get_arch() */
/* These are defined in auditsc.c */
/* Public API */
extern int audit_alloc(struct task_struct *task);
extern void __audit_free(struct task_struct *task);
extern void __audit_uring_entry(u8 op);
extern void __audit_uring_exit(int success, long code);
extern void __audit_syscall_entry(int major, unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3);
extern void __audit_syscall_exit(int ret_success, long ret_value);
extern void __audit_getname(struct filename *name);
extern void __audit_inode(struct filename *name, const struct dentry *dentry,
unsigned int flags);
extern void __audit_file(const struct file *);
extern void __audit_inode_child(struct inode *parent,
const struct dentry *dentry,
const unsigned char type);
extern void audit_seccomp(unsigned long syscall, long signr, int code);
extern void audit_seccomp_actions_logged(const char *names,
const char *old_names, int res);
extern void __audit_ptrace(struct task_struct *t);
static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
{
task->audit_context = ctx;
}
static inline struct audit_context *audit_context(void)
{
return current->audit_context;
}
static inline bool audit_dummy_context(void)
{
void *p = audit_context();
return !p || *(int *)p;
}
static inline void audit_free(struct task_struct *task)
{
if (unlikely(task->audit_context))
__audit_free(task);
}
static inline void audit_uring_entry(u8 op)
{
/*
* We intentionally check audit_context() before audit_enabled as most
* Linux systems (as of ~2021) rely on systemd which forces audit to
* be enabled regardless of the user's audit configuration.
*/
if (unlikely(audit_context() && audit_enabled))
__audit_uring_entry(op);
}
static inline void audit_uring_exit(int success, long code)
{
if (unlikely(audit_context()))
__audit_uring_exit(success, code);
}
static inline void audit_syscall_entry(int major, unsigned long a0,
unsigned long a1, unsigned long a2,
unsigned long a3)
{
if (unlikely(audit_context()))
__audit_syscall_entry(major, a0, a1, a2, a3);
}
static inline void audit_syscall_exit(void *pt_regs)
{
if (unlikely(audit_context())) {
int success = is_syscall_success(pt_regs);
long return_code = regs_return_value(pt_regs);
__audit_syscall_exit(success, return_code);
}
}
static inline void audit_getname(struct filename *name)
{
if (unlikely(!audit_dummy_context()))
__audit_getname(name);
}
static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags) {
if (unlikely(!audit_dummy_context()))
__audit_inode(name, dentry, aflags);
}
static inline void audit_file(struct file *file)
{
if (unlikely(!audit_dummy_context()))
__audit_file(file);
}
static inline void audit_inode_parent_hidden(struct filename *name,
const struct dentry *dentry)
{
if (unlikely(!audit_dummy_context()))
__audit_inode(name, dentry,
AUDIT_INODE_PARENT | AUDIT_INODE_HIDDEN);
}
static inline void audit_inode_child(struct inode *parent,
const struct dentry *dentry,
const unsigned char type) {
if (unlikely(!audit_dummy_context()))
__audit_inode_child(parent, dentry, type);
}
void audit_core_dumps(long signr);
static inline void audit_ptrace(struct task_struct *t)
{
if (unlikely(!audit_dummy_context()))
__audit_ptrace(t);
}
/* Private API (for audit.c only) */
extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern void __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode);
extern void __audit_bprm(struct linux_binprm *bprm);
extern int __audit_socketcall(int nargs, unsigned long *args);
extern int __audit_sockaddr(int len, void *addr);
extern void __audit_fd_pair(int fd1, int fd2);
extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout);
extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
const struct cred *new,
const struct cred *old);
extern void __audit_log_capset(const struct cred *new, const struct cred *old);
extern void __audit_mmap_fd(int fd, int flags);
extern void __audit_openat2_how(struct open_how *how);
extern void __audit_log_kern_module(const char *name);
extern void __audit_fanotify(u32 response, struct fanotify_response_info_audit_rule *friar);
extern void __audit_tk_injoffset(struct timespec64 offset);
extern void __audit_ntp_log(const struct audit_ntp_data *ad);
extern void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries,
enum audit_nfcfgop op, gfp_t gfp);
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
if (unlikely(!audit_dummy_context()))
__audit_ipc_obj(ipcp);
}
static inline void audit_fd_pair(int fd1, int fd2)
{
if (unlikely(!audit_dummy_context()))
__audit_fd_pair(fd1, fd2);
}
static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, umode_t mode)
{
if (unlikely(!audit_dummy_context()))
__audit_ipc_set_perm(qbytes, uid, gid, mode);
}
static inline void audit_bprm(struct linux_binprm *bprm)
{
if (unlikely(!audit_dummy_context()))
__audit_bprm(bprm);
}
static inline int audit_socketcall(int nargs, unsigned long *args)
{
if (unlikely(!audit_dummy_context()))
return __audit_socketcall(nargs, args);
return 0;
}
static inline int audit_socketcall_compat(int nargs, u32 *args)
{
unsigned long a[AUDITSC_ARGS];
int i;
if (audit_dummy_context())
return 0;
for (i = 0; i < nargs; i++)
a[i] = (unsigned long)args[i];
return __audit_socketcall(nargs, a);
}
static inline int audit_sockaddr(int len, void *addr)
{
if (unlikely(!audit_dummy_context()))
return __audit_sockaddr(len, addr);
return 0;
}
static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
{
if (unlikely(!audit_dummy_context()))
__audit_mq_open(oflag, mode, attr);
}
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout)
{
if (unlikely(!audit_dummy_context()))
__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
}
static inline void audit_mq_notify(mqd_t mqdes, const struct sigevent *notification)
{
if (unlikely(!audit_dummy_context()))
__audit_mq_notify(mqdes, notification);
}
static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
{
if (unlikely(!audit_dummy_context()))
__audit_mq_getsetattr(mqdes, mqstat);
}
static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
const struct cred *new,
const struct cred *old)
{
if (unlikely(!audit_dummy_context()))
return __audit_log_bprm_fcaps(bprm, new, old);
return 0;
}
static inline void audit_log_capset(const struct cred *new,
const struct cred *old)
{
if (unlikely(!audit_dummy_context()))
__audit_log_capset(new, old);
}
static inline void audit_mmap_fd(int fd, int flags)
{
if (unlikely(!audit_dummy_context()))
__audit_mmap_fd(fd, flags);
}
static inline void audit_openat2_how(struct open_how *how)
{
if (unlikely(!audit_dummy_context()))
__audit_openat2_how(how);
}
static inline void audit_log_kern_module(const char *name)
{
if (!audit_dummy_context())
__audit_log_kern_module(name);
}
static inline void audit_fanotify(u32 response, struct fanotify_response_info_audit_rule *friar)
{
if (audit_enabled)
__audit_fanotify(response, friar);
}
static inline void audit_tk_injoffset(struct timespec64 offset)
{
/* ignore no-op events */
if (offset.tv_sec == 0 && offset.tv_nsec == 0)
return;
if (!audit_dummy_context())
__audit_tk_injoffset(offset);
}
static inline void audit_ntp_init(struct audit_ntp_data *ad)
{
memset(ad, 0, sizeof(*ad));
}
static inline void audit_ntp_set_old(struct audit_ntp_data *ad,
enum audit_ntp_type type, long long val)
{
ad->vals[type].oldval = val;
}
static inline void audit_ntp_set_new(struct audit_ntp_data *ad,
enum audit_ntp_type type, long long val)
{
ad->vals[type].newval = val;
}
static inline void audit_ntp_log(const struct audit_ntp_data *ad)
{
if (!audit_dummy_context())
__audit_ntp_log(ad);
}
static inline void audit_log_nfcfg(const char *name, u8 af,
unsigned int nentries,
enum audit_nfcfgop op, gfp_t gfp)
{
if (audit_enabled)
__audit_log_nfcfg(name, af, nentries, op, gfp);
}
extern int audit_n_rules;
extern int audit_signals;
#else /* CONFIG_AUDITSYSCALL */
static inline int audit_alloc(struct task_struct *task)
{
return 0;
}
static inline void audit_free(struct task_struct *task)
{ }
static inline void audit_uring_entry(u8 op)
{ }
static inline void audit_uring_exit(int success, long code)
{ }
static inline void audit_syscall_entry(int major, unsigned long a0,
unsigned long a1, unsigned long a2,
unsigned long a3)
{ }
static inline void audit_syscall_exit(void *pt_regs)
{ }
static inline bool audit_dummy_context(void)
{
return true;
}
static inline void audit_set_context(struct task_struct *task, struct audit_context *ctx)
{ }
static inline struct audit_context *audit_context(void)
{
return NULL;
}
static inline void audit_getname(struct filename *name)
{ }
static inline void audit_inode(struct filename *name,
const struct dentry *dentry,
unsigned int aflags)
{ }
static inline void audit_file(struct file *file)
{
}
static inline void audit_inode_parent_hidden(struct filename *name,
const struct dentry *dentry)
{ }
static inline void audit_inode_child(struct inode *parent,
const struct dentry *dentry,
const unsigned char type)
{ }
static inline void audit_core_dumps(long signr)
{ }
static inline void audit_seccomp(unsigned long syscall, long signr, int code)
{ }
static inline void audit_seccomp_actions_logged(const char *names,
const char *old_names, int res)
{ }
static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
{ }
static inline void audit_ipc_set_perm(unsigned long qbytes, uid_t uid,
gid_t gid, umode_t mode)
{ }
static inline void audit_bprm(struct linux_binprm *bprm)
{ }
static inline int audit_socketcall(int nargs, unsigned long *args)
{
return 0;
}
static inline int audit_socketcall_compat(int nargs, u32 *args)
{
return 0;
}
static inline void audit_fd_pair(int fd1, int fd2)
{ }
static inline int audit_sockaddr(int len, void *addr)
{
return 0;
}
static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
{ }
static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
unsigned int msg_prio,
const struct timespec64 *abs_timeout)
{ }
static inline void audit_mq_notify(mqd_t mqdes,
const struct sigevent *notification)
{ }
static inline void audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
{ }
static inline int audit_log_bprm_fcaps(struct linux_binprm *bprm,
const struct cred *new,
const struct cred *old)
{
return 0;
}
static inline void audit_log_capset(const struct cred *new,
const struct cred *old)
{ }
static inline void audit_mmap_fd(int fd, int flags)
{ }
static inline void audit_openat2_how(struct open_how *how)
{ }
static inline void audit_log_kern_module(const char *name)
{ }
static inline void audit_fanotify(u32 response, struct fanotify_response_info_audit_rule *friar)
{ }
static inline void audit_tk_injoffset(struct timespec64 offset)
{ }
static inline void audit_ntp_init(struct audit_ntp_data *ad)
{ }
static inline void audit_ntp_set_old(struct audit_ntp_data *ad,
enum audit_ntp_type type, long long val)
{ }
static inline void audit_ntp_set_new(struct audit_ntp_data *ad,
enum audit_ntp_type type, long long val)
{ }
static inline void audit_ntp_log(const struct audit_ntp_data *ad)
{ }
static inline void audit_ptrace(struct task_struct *t)
{ }
static inline void audit_log_nfcfg(const char *name, u8 af,
unsigned int nentries,
enum audit_nfcfgop op, gfp_t gfp)
{ }
#define audit_n_rules 0
#define audit_signals 0
#endif /* CONFIG_AUDITSYSCALL */
static inline bool audit_loginuid_set(struct task_struct *tsk)
{
return uid_valid(audit_get_loginuid(tsk));
}
#endif
@@ -0,0 +1,33 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/* audit_arch.h -- Arch layer specific support for audit
*
* Copyright 2021 Red Hat Inc., Durham, North Carolina.
* All Rights Reserved.
*
* Author: Richard Guy Briggs <rgb@redhat.com>
*/
#ifndef _LINUX_AUDIT_ARCH_H_
#define _LINUX_AUDIT_ARCH_H_
enum auditsc_class_t {
AUDITSC_NATIVE = 0,
AUDITSC_COMPAT,
AUDITSC_OPEN,
AUDITSC_OPENAT,
AUDITSC_SOCKETCALL,
AUDITSC_EXECVE,
AUDITSC_OPENAT2,
AUDITSC_NVALS /* count */
};
extern int audit_classify_compat_syscall(int abi, unsigned syscall);
/* only for compat system calls */
extern unsigned compat_write_class[];
extern unsigned compat_read_class[];
extern unsigned compat_dir_class[];
extern unsigned compat_chattr_class[];
extern unsigned compat_signal_class[];
#endif
@@ -0,0 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 2008 Red Hat, Inc. All rights reserved.
* Copyright 2008 Ian Kent <raven@themaw.net>
*/
#ifndef _LINUX_AUTO_DEV_IOCTL_H
#define _LINUX_AUTO_DEV_IOCTL_H
#include <uapi/linux/auto_dev-ioctl.h>
#endif /* _LINUX_AUTO_DEV_IOCTL_H */
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 1997 Transmeta Corporation - All Rights Reserved
*/
#ifndef _LINUX_AUTO_FS_H
#define _LINUX_AUTO_FS_H
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <uapi/linux/auto_fs.h>
#endif /* _LINUX_AUTO_FS_H */
@@ -0,0 +1,291 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019-2020 Intel Corporation
*
* Please see Documentation/driver-api/auxiliary_bus.rst for more information.
*/
#ifndef _AUXILIARY_BUS_H_
#define _AUXILIARY_BUS_H_
#include <linux/device.h>
#include <linux/mod_devicetable.h>
/**
* DOC: DEVICE_LIFESPAN
*
* The registering driver is the entity that allocates memory for the
* auxiliary_device and registers it on the auxiliary bus. It is important to
* note that, as opposed to the platform bus, the registering driver is wholly
* responsible for the management of the memory used for the device object.
*
* To be clear the memory for the auxiliary_device is freed in the release()
* callback defined by the registering driver. The registering driver should
* only call auxiliary_device_delete() and then auxiliary_device_uninit() when
* it is done with the device. The release() function is then automatically
* called if and when other code releases their reference to the devices.
*
* A parent object, defined in the shared header file, contains the
* auxiliary_device. It also contains a pointer to the shared object(s), which
* also is defined in the shared header. Both the parent object and the shared
* object(s) are allocated by the registering driver. This layout allows the
* auxiliary_driver's registering module to perform a container_of() call to go
* from the pointer to the auxiliary_device, that is passed during the call to
* the auxiliary_driver's probe function, up to the parent object, and then
* have access to the shared object(s).
*
* The memory for the shared object(s) must have a lifespan equal to, or
* greater than, the lifespan of the memory for the auxiliary_device. The
* auxiliary_driver should only consider that the shared object is valid as
* long as the auxiliary_device is still registered on the auxiliary bus. It
* is up to the registering driver to manage (e.g. free or keep available) the
* memory for the shared object beyond the life of the auxiliary_device.
*
* The registering driver must unregister all auxiliary devices before its own
* driver.remove() is completed. An easy way to ensure this is to use the
* devm_add_action_or_reset() call to register a function against the parent
* device which unregisters the auxiliary device object(s).
*
* Finally, any operations which operate on the auxiliary devices must continue
* to function (if only to return an error) after the registering driver
* unregisters the auxiliary device.
*/
/**
* struct auxiliary_device - auxiliary device object.
* @dev: Device,
* The release and parent fields of the device structure must be filled
* in
* @name: Match name found by the auxiliary device driver,
* @id: unique identitier if multiple devices of the same name are exported,
* @sysfs: embedded struct which hold all sysfs related fields,
* @sysfs.irqs: irqs xarray contains irq indices which are used by the device,
* @sysfs.lock: Synchronize irq sysfs creation,
* @sysfs.irq_dir_exists: whether "irqs" directory exists,
*
* An auxiliary_device represents a part of its parent device's functionality.
* It is given a name that, combined with the registering drivers
* KBUILD_MODNAME, creates a match_name that is used for driver binding, and an
* id that combined with the match_name provide a unique name to register with
* the bus subsystem. For example, a driver registering an auxiliary device is
* named 'foo_mod.ko' and the subdevice is named 'foo_dev'. The match name is
* therefore 'foo_mod.foo_dev'.
*
* Registering an auxiliary_device is a three-step process.
*
* First, a 'struct auxiliary_device' needs to be defined or allocated for each
* sub-device desired. The name, id, dev.release, and dev.parent fields of
* this structure must be filled in as follows.
*
* The 'name' field is to be given a name that is recognized by the auxiliary
* driver. If two auxiliary_devices with the same match_name, eg
* "foo_mod.foo_dev", are registered onto the bus, they must have unique id
* values (e.g. "x" and "y") so that the registered devices names are
* "foo_mod.foo_dev.x" and "foo_mod.foo_dev.y". If match_name + id are not
* unique, then the device_add fails and generates an error message.
*
* The auxiliary_device.dev.type.release or auxiliary_device.dev.release must
* be populated with a non-NULL pointer to successfully register the
* auxiliary_device. This release call is where resources associated with the
* auxiliary device must be free'ed. Because once the device is placed on the
* bus the parent driver can not tell what other code may have a reference to
* this data.
*
* The auxiliary_device.dev.parent should be set. Typically to the registering
* drivers device.
*
* Second, call auxiliary_device_init(), which checks several aspects of the
* auxiliary_device struct and performs a device_initialize(). After this step
* completes, any error state must have a call to auxiliary_device_uninit() in
* its resolution path.
*
* The third and final step in registering an auxiliary_device is to perform a
* call to auxiliary_device_add(), which sets the name of the device and adds
* the device to the bus.
*
* .. code-block:: c
*
* #define MY_DEVICE_NAME "foo_dev"
*
* ...
*
* struct auxiliary_device *my_aux_dev = my_aux_dev_alloc(xxx);
*
* // Step 1:
* my_aux_dev->name = MY_DEVICE_NAME;
* my_aux_dev->id = my_unique_id_alloc(xxx);
* my_aux_dev->dev.release = my_aux_dev_release;
* my_aux_dev->dev.parent = my_dev;
*
* // Step 2:
* if (auxiliary_device_init(my_aux_dev))
* goto fail;
*
* // Step 3:
* if (auxiliary_device_add(my_aux_dev)) {
* auxiliary_device_uninit(my_aux_dev);
* goto fail;
* }
*
* ...
*
*
* Unregistering an auxiliary_device is a two-step process to mirror the
* register process. First call auxiliary_device_delete(), then call
* auxiliary_device_uninit().
*
* .. code-block:: c
*
* auxiliary_device_delete(my_dev->my_aux_dev);
* auxiliary_device_uninit(my_dev->my_aux_dev);
*/
struct auxiliary_device {
struct device dev;
const char *name;
u32 id;
struct {
struct xarray irqs;
struct mutex lock; /* Synchronize irq sysfs creation */
bool irq_dir_exists;
} sysfs;
};
/**
* struct auxiliary_driver - Definition of an auxiliary bus driver
* @probe: Called when a matching device is added to the bus.
* @remove: Called when device is removed from the bus.
* @shutdown: Called at shut-down time to quiesce the device.
* @suspend: Called to put the device to sleep mode. Usually to a power state.
* @resume: Called to bring a device from sleep mode.
* @name: Driver name.
* @driver: Core driver structure.
* @id_table: Table of devices this driver should match on the bus.
*
* Auxiliary drivers follow the standard driver model convention, where
* discovery/enumeration is handled by the core, and drivers provide probe()
* and remove() methods. They support power management and shutdown
* notifications using the standard conventions.
*
* Auxiliary drivers register themselves with the bus by calling
* auxiliary_driver_register(). The id_table contains the match_names of
* auxiliary devices that a driver can bind with.
*
* .. code-block:: c
*
* static const struct auxiliary_device_id my_auxiliary_id_table[] = {
* { .name = "foo_mod.foo_dev" },
* {},
* };
*
* MODULE_DEVICE_TABLE(auxiliary, my_auxiliary_id_table);
*
* struct auxiliary_driver my_drv = {
* .name = "myauxiliarydrv",
* .id_table = my_auxiliary_id_table,
* .probe = my_drv_probe,
* .remove = my_drv_remove
* };
*/
struct auxiliary_driver {
int (*probe)(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id);
void (*remove)(struct auxiliary_device *auxdev);
void (*shutdown)(struct auxiliary_device *auxdev);
int (*suspend)(struct auxiliary_device *auxdev, pm_message_t state);
int (*resume)(struct auxiliary_device *auxdev);
const char *name;
struct device_driver driver;
const struct auxiliary_device_id *id_table;
};
static inline void *auxiliary_get_drvdata(struct auxiliary_device *auxdev)
{
return dev_get_drvdata(&auxdev->dev);
}
static inline void auxiliary_set_drvdata(struct auxiliary_device *auxdev, void *data)
{
dev_set_drvdata(&auxdev->dev, data);
}
static inline struct auxiliary_device *to_auxiliary_dev(struct device *dev)
{
return container_of(dev, struct auxiliary_device, dev);
}
static inline const struct auxiliary_driver *to_auxiliary_drv(const struct device_driver *drv)
{
return container_of(drv, struct auxiliary_driver, driver);
}
int auxiliary_device_init(struct auxiliary_device *auxdev);
int __auxiliary_device_add(struct auxiliary_device *auxdev, const char *modname);
#define auxiliary_device_add(auxdev) __auxiliary_device_add(auxdev, KBUILD_MODNAME)
#ifdef CONFIG_SYSFS
int auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq);
void auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev,
int irq);
#else /* CONFIG_SYSFS */
static inline int
auxiliary_device_sysfs_irq_add(struct auxiliary_device *auxdev, int irq)
{
return 0;
}
static inline void
auxiliary_device_sysfs_irq_remove(struct auxiliary_device *auxdev, int irq) {}
#endif
static inline void auxiliary_device_uninit(struct auxiliary_device *auxdev)
{
mutex_destroy(&auxdev->sysfs.lock);
put_device(&auxdev->dev);
}
static inline void auxiliary_device_delete(struct auxiliary_device *auxdev)
{
device_del(&auxdev->dev);
}
int __auxiliary_driver_register(struct auxiliary_driver *auxdrv, struct module *owner,
const char *modname);
#define auxiliary_driver_register(auxdrv) \
__auxiliary_driver_register(auxdrv, THIS_MODULE, KBUILD_MODNAME)
void auxiliary_driver_unregister(struct auxiliary_driver *auxdrv);
struct auxiliary_device *auxiliary_device_create(struct device *dev,
const char *modname,
const char *devname,
void *platform_data,
int id);
void auxiliary_device_destroy(void *auxdev);
struct auxiliary_device *__devm_auxiliary_device_create(struct device *dev,
const char *modname,
const char *devname,
void *platform_data,
int id);
#define devm_auxiliary_device_create(dev, devname, platform_data) \
__devm_auxiliary_device_create(dev, KBUILD_MODNAME, devname, \
platform_data, 0)
bool dev_is_auxiliary(struct device *dev);
/**
* module_auxiliary_driver() - Helper macro for registering an auxiliary driver
* @__auxiliary_driver: auxiliary driver struct
*
* Helper macro for auxiliary drivers which do not do anything special in
* module init/exit. This eliminates a lot of boilerplate. Each module may only
* use this macro once, and calling it replaces module_init() and module_exit()
*
* .. code-block:: c
*
* module_auxiliary_driver(my_drv);
*/
#define module_auxiliary_driver(__auxiliary_driver) \
module_driver(__auxiliary_driver, auxiliary_driver_register, auxiliary_driver_unregister)
#endif /* _AUXILIARY_BUS_H_ */
@@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_AUXVEC_H
#define _LINUX_AUXVEC_H
#include <uapi/linux/auxvec.h>
#define AT_VECTOR_SIZE_BASE 24 /* NEW_AUX_ENT entries in auxiliary table */
/* number of "#define AT_.*" above, minus {AT_NULL, AT_IGNORE, AT_NOTELF} */
#endif /* _LINUX_AUXVEC_H */
@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_AVERAGE_H
#define _LINUX_AVERAGE_H
#include <linux/bug.h>
#include <linux/compiler.h>
#include <linux/log2.h>
/*
* Exponentially weighted moving average (EWMA)
*
* This implements a fixed-precision EWMA algorithm, with both the
* precision and fall-off coefficient determined at compile-time
* and built into the generated helper funtions.
*
* The first argument to the macro is the name that will be used
* for the struct and helper functions.
*
* The second argument, the precision, expresses how many bits are
* used for the fractional part of the fixed-precision values.
*
* The third argument, the weight reciprocal, determines how the
* new values will be weighed vs. the old state, new values will
* get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
* that this parameter must be a power of two for efficiency.
*/
#define DECLARE_EWMA(name, _precision, _weight_rcp) \
struct ewma_##name { \
unsigned long internal; \
}; \
static inline void ewma_##name##_init(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
/* \
* Even if you want to feed it just 0/1 you should have \
* some bits for the non-fractional part... \
*/ \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
e->internal = 0; \
} \
static inline unsigned long \
ewma_##name##_read(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
return e->internal >> (_precision); \
} \
static inline void ewma_##name##_add(struct ewma_##name *e, \
unsigned long val) \
{ \
unsigned long internal = READ_ONCE(e->internal); \
unsigned long weight_rcp = ilog2(_weight_rcp); \
unsigned long precision = _precision; \
\
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
\
WRITE_ONCE(e->internal, internal ? \
(((internal << weight_rcp) - internal) + \
(val << precision)) >> weight_rcp : \
(val << precision)); \
}
#endif /* _LINUX_AVERAGE_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,304 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_BACKING_DEV_DEFS_H
#define __LINUX_BACKING_DEV_DEFS_H
#include <linux/list.h>
#include <linux/radix-tree.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/percpu_counter.h>
#include <linux/percpu-refcount.h>
#include <linux/flex_proportions.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/kref.h>
#include <linux/refcount.h>
struct page;
struct device;
struct dentry;
/*
* Bits in bdi_writeback.state
*/
enum wb_state {
WB_registered, /* bdi_register() was done */
WB_writeback_running, /* Writeback is in progress */
WB_has_dirty_io, /* Dirty inodes on ->b_{dirty|io|more_io} */
WB_start_all, /* nr_pages == 0 (all) work pending */
};
enum wb_stat_item {
WB_RECLAIMABLE,
WB_WRITEBACK,
WB_DIRTIED,
WB_WRITTEN,
NR_WB_STAT_ITEMS
};
#define WB_STAT_BATCH (8*(1+ilog2(nr_cpu_ids)))
/*
* why some writeback work was initiated
*/
enum wb_reason {
WB_REASON_BACKGROUND,
WB_REASON_VMSCAN,
WB_REASON_SYNC,
WB_REASON_PERIODIC,
WB_REASON_FS_FREE_SPACE,
/*
* There is no bdi forker thread any more and works are done
* by emergency worker, however, this is TPs userland visible
* and we'll be exposing exactly the same information,
* so it has a mismatch name.
*/
WB_REASON_FORKER_THREAD,
WB_REASON_FOREIGN_FLUSH,
WB_REASON_MAX,
};
struct wb_completion {
atomic_t cnt;
wait_queue_head_t *waitq;
unsigned long progress_stamp; /* The jiffies when slow progress is detected */
unsigned long wait_start; /* The jiffies when waiting for the writeback work to finish */
};
#define __WB_COMPLETION_INIT(_waitq) \
(struct wb_completion){ .cnt = ATOMIC_INIT(1), .waitq = (_waitq) }
/*
* If one wants to wait for one or more wb_writeback_works, each work's
* ->done should be set to a wb_completion defined using the following
* macro. Once all work items are issued with wb_queue_work(), the caller
* can wait for the completion of all using wb_wait_for_completion(). Work
* items which are waited upon aren't freed automatically on completion.
*/
#define WB_COMPLETION_INIT(bdi) __WB_COMPLETION_INIT(&(bdi)->wb_waitq)
#define DEFINE_WB_COMPLETION(cmpl, bdi) \
struct wb_completion cmpl = WB_COMPLETION_INIT(bdi)
/*
* Each wb (bdi_writeback) can perform writeback operations, is measured
* and throttled, independently. Without cgroup writeback, each bdi
* (bdi_writeback) is served by its embedded bdi->wb.
*
* On the default hierarchy, blkcg implicitly enables memcg. This allows
* using memcg's page ownership for attributing writeback IOs, and every
* memcg - blkcg combination can be served by its own wb by assigning a
* dedicated wb to each memcg, which enables isolation across different
* cgroups and propagation of IO back pressure down from the IO layer upto
* the tasks which are generating the dirty pages to be written back.
*
* A cgroup wb is indexed on its bdi by the ID of the associated memcg,
* refcounted with the number of inodes attached to it, and pins the memcg
* and the corresponding blkcg. As the corresponding blkcg for a memcg may
* change as blkcg is disabled and enabled higher up in the hierarchy, a wb
* is tested for blkcg after lookup and removed from index on mismatch so
* that a new wb for the combination can be created.
*
* Each bdi_writeback that is not embedded into the backing_dev_info must hold
* a reference to the parent backing_dev_info. See cgwb_create() for details.
*/
struct bdi_writeback {
struct backing_dev_info *bdi; /* our parent bdi */
unsigned long state; /* Always use atomic bitops on this */
unsigned long last_old_flush; /* last old data flush */
struct list_head b_dirty; /* dirty inodes */
struct list_head b_io; /* parked for writeback */
struct list_head b_more_io; /* parked for more writeback */
struct list_head b_dirty_time; /* time stamps are dirty */
spinlock_t list_lock; /* protects the b_* lists */
atomic_t writeback_inodes; /* number of inodes under writeback */
struct percpu_counter stat[NR_WB_STAT_ITEMS];
unsigned long bw_time_stamp; /* last time write bw is updated */
unsigned long dirtied_stamp;
unsigned long written_stamp; /* pages written at bw_time_stamp */
unsigned long write_bandwidth; /* the estimated write bandwidth */
unsigned long avg_write_bandwidth; /* further smoothed write bw, > 0 */
/*
* The base dirty throttle rate, re-calculated on every 200ms.
* All the bdi tasks' dirty rate will be curbed under it.
* @dirty_ratelimit tracks the estimated @balanced_dirty_ratelimit
* in small steps and is much more smooth/stable than the latter.
*/
unsigned long dirty_ratelimit;
unsigned long balanced_dirty_ratelimit;
struct fprop_local_percpu completions;
int dirty_exceeded;
enum wb_reason start_all_reason;
spinlock_t work_lock; /* protects work_list & dwork scheduling */
struct list_head work_list;
struct delayed_work dwork; /* work item used for writeback */
struct delayed_work bw_dwork; /* work item used for bandwidth estimate */
struct list_head bdi_node; /* anchored at bdi->wb_list */
#ifdef CONFIG_CGROUP_WRITEBACK
struct percpu_ref refcnt; /* used only for !root wb's */
struct fprop_local_percpu memcg_completions;
struct cgroup_subsys_state *memcg_css; /* the associated memcg */
struct cgroup_subsys_state *blkcg_css; /* and blkcg */
struct list_head memcg_node; /* anchored at memcg->cgwb_list */
struct list_head blkcg_node; /* anchored at blkcg->cgwb_list */
struct list_head b_attached; /* attached inodes, protected by list_lock */
struct list_head offline_node; /* anchored at offline_cgwbs */
struct work_struct switch_work; /* work used to perform inode switching
* to this wb */
struct llist_head switch_wbs_ctxs; /* queued contexts for
* writeback switching */
union {
struct work_struct release_work;
struct rcu_head rcu;
};
#endif
};
struct backing_dev_info {
u64 id;
struct rb_node rb_node; /* keyed by ->id */
struct list_head bdi_list;
/* max readahead in PAGE_SIZE units */
unsigned long __data_racy ra_pages;
unsigned long io_pages; /* max allowed IO size */
struct kref refcnt; /* Reference counter for the structure */
unsigned int capabilities; /* Device capabilities */
unsigned int min_ratio;
unsigned int max_ratio, max_prop_frac;
/*
* Sum of avg_write_bw of wbs with dirty inodes. > 0 if there are
* any dirty wbs, which is depended upon by bdi_has_dirty().
*/
atomic_long_t tot_write_bandwidth;
/*
* Jiffies when last process was dirty throttled on this bdi. Used by
* blk-wbt.
*/
unsigned long last_bdp_sleep;
struct bdi_writeback wb; /* the root writeback info for this bdi */
struct list_head wb_list; /* list of all wbs */
#ifdef CONFIG_CGROUP_WRITEBACK
struct radix_tree_root cgwb_tree; /* radix tree of active cgroup wbs */
struct mutex cgwb_release_mutex; /* protect shutdown of wb structs */
struct rw_semaphore wb_switch_rwsem; /* no cgwb switch while syncing */
#endif
wait_queue_head_t wb_waitq;
struct device *dev;
char dev_name[64];
struct device *owner;
#ifdef CONFIG_DEBUG_FS
struct dentry *debug_dir;
#endif
};
struct wb_lock_cookie {
bool locked;
unsigned long flags;
};
#ifdef CONFIG_CGROUP_WRITEBACK
/**
* wb_tryget - try to increment a wb's refcount
* @wb: bdi_writeback to get
*/
static inline bool wb_tryget(struct bdi_writeback *wb)
{
if (wb != &wb->bdi->wb)
return percpu_ref_tryget(&wb->refcnt);
return true;
}
/**
* wb_get - increment a wb's refcount
* @wb: bdi_writeback to get
*/
static inline void wb_get(struct bdi_writeback *wb)
{
if (wb != &wb->bdi->wb)
percpu_ref_get(&wb->refcnt);
}
/**
* wb_put_many - decrement a wb's refcount
* @wb: bdi_writeback to put
* @nr: number of references to put
*/
static inline void wb_put_many(struct bdi_writeback *wb, unsigned long nr)
{
if (WARN_ON_ONCE(!wb->bdi)) {
/*
* A driver bug might cause a file to be removed before bdi was
* initialized.
*/
return;
}
if (wb != &wb->bdi->wb)
percpu_ref_put_many(&wb->refcnt, nr);
}
/**
* wb_put - decrement a wb's refcount
* @wb: bdi_writeback to put
*/
static inline void wb_put(struct bdi_writeback *wb)
{
wb_put_many(wb, 1);
}
/**
* wb_dying - is a wb dying?
* @wb: bdi_writeback of interest
*
* Returns whether @wb is unlinked and being drained.
*/
static inline bool wb_dying(struct bdi_writeback *wb)
{
return percpu_ref_is_dying(&wb->refcnt);
}
#else /* CONFIG_CGROUP_WRITEBACK */
static inline bool wb_tryget(struct bdi_writeback *wb)
{
return true;
}
static inline void wb_get(struct bdi_writeback *wb)
{
}
static inline void wb_put(struct bdi_writeback *wb)
{
}
static inline void wb_put_many(struct bdi_writeback *wb, unsigned long nr)
{
}
static inline bool wb_dying(struct bdi_writeback *wb)
{
return false;
}
#endif /* CONFIG_CGROUP_WRITEBACK */
#endif /* __LINUX_BACKING_DEV_DEFS_H */
@@ -0,0 +1,377 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* include/linux/backing-dev.h
*
* low-level device information and state which is propagated up through
* to high-level code.
*/
#ifndef _LINUX_BACKING_DEV_H
#define _LINUX_BACKING_DEV_H
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/device.h>
#include <linux/writeback.h>
#include <linux/backing-dev-defs.h>
#include <linux/slab.h>
static inline struct backing_dev_info *bdi_get(struct backing_dev_info *bdi)
{
kref_get(&bdi->refcnt);
return bdi;
}
struct backing_dev_info *bdi_get_by_id(u64 id);
void bdi_put(struct backing_dev_info *bdi);
__printf(2, 3)
int bdi_register(struct backing_dev_info *bdi, const char *fmt, ...);
__printf(2, 0)
int bdi_register_va(struct backing_dev_info *bdi, const char *fmt,
va_list args);
void bdi_set_owner(struct backing_dev_info *bdi, struct device *owner);
void bdi_unregister(struct backing_dev_info *bdi);
struct backing_dev_info *bdi_alloc(int node_id);
void wb_start_background_writeback(struct bdi_writeback *wb);
void wb_workfn(struct work_struct *work);
void wb_wait_for_completion(struct wb_completion *done);
extern spinlock_t bdi_lock;
extern struct list_head bdi_list;
extern struct workqueue_struct *bdi_wq;
static inline bool wb_has_dirty_io(struct bdi_writeback *wb)
{
return test_bit(WB_has_dirty_io, &wb->state);
}
static inline bool bdi_has_dirty_io(struct backing_dev_info *bdi)
{
/*
* @bdi->tot_write_bandwidth is guaranteed to be > 0 if there are
* any dirty wbs. See wb_update_write_bandwidth().
*/
return atomic_long_read(&bdi->tot_write_bandwidth);
}
static inline void wb_stat_mod(struct bdi_writeback *wb,
enum wb_stat_item item, s64 amount)
{
percpu_counter_add_batch(&wb->stat[item], amount, WB_STAT_BATCH);
}
static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
{
return percpu_counter_read_positive(&wb->stat[item]);
}
static inline s64 wb_stat_sum(struct bdi_writeback *wb, enum wb_stat_item item)
{
return percpu_counter_sum_positive(&wb->stat[item]);
}
extern void wb_writeout_inc(struct bdi_writeback *wb);
/*
* maximal error of a stat counter.
*/
static inline unsigned long wb_stat_error(void)
{
#ifdef CONFIG_SMP
return nr_cpu_ids * WB_STAT_BATCH;
#else
return 1;
#endif
}
/* BDI ratio is expressed as part per 1000000 for finer granularity. */
#define BDI_RATIO_SCALE 10000
u64 bdi_get_min_bytes(struct backing_dev_info *bdi);
u64 bdi_get_max_bytes(struct backing_dev_info *bdi);
int bdi_set_min_ratio(struct backing_dev_info *bdi, unsigned int min_ratio);
int bdi_set_max_ratio(struct backing_dev_info *bdi, unsigned int max_ratio);
int bdi_set_min_ratio_no_scale(struct backing_dev_info *bdi, unsigned int min_ratio);
int bdi_set_max_ratio_no_scale(struct backing_dev_info *bdi, unsigned int max_ratio);
int bdi_set_min_bytes(struct backing_dev_info *bdi, u64 min_bytes);
int bdi_set_max_bytes(struct backing_dev_info *bdi, u64 max_bytes);
int bdi_set_strict_limit(struct backing_dev_info *bdi, unsigned int strict_limit);
/*
* Flags in backing_dev_info::capability
*
* BDI_CAP_WRITEBACK: Supports dirty page writeback, and dirty pages
* should contribute to accounting
* BDI_CAP_STRICTLIMIT: Keep number of dirty pages below bdi threshold
*/
#define BDI_CAP_WRITEBACK (1 << 0)
#define BDI_CAP_STRICTLIMIT (1 << 1)
extern struct backing_dev_info noop_backing_dev_info;
int bdi_init(struct backing_dev_info *bdi);
/**
* writeback_in_progress - determine whether there is writeback in progress
* @wb: bdi_writeback of interest
*
* Determine whether there is writeback waiting to be handled against a
* bdi_writeback.
*/
static inline bool writeback_in_progress(struct bdi_writeback *wb)
{
return test_bit(WB_writeback_running, &wb->state);
}
struct backing_dev_info *inode_to_bdi(struct inode *inode);
static inline bool mapping_can_writeback(struct address_space *mapping)
{
return inode_to_bdi(mapping->host)->capabilities & BDI_CAP_WRITEBACK;
}
/* Must not be used by file systems that support cgroup writeback */
static inline int bdi_wb_dirty_exceeded(struct backing_dev_info *bdi)
{
return bdi->wb.dirty_exceeded;
}
/* Must not be used by file systems that support cgroup writeback */
static inline void bdi_wb_stat_mod(struct inode *inode, enum wb_stat_item item,
s64 amount)
{
wb_stat_mod(&inode_to_bdi(inode)->wb, item, amount);
}
#ifdef CONFIG_CGROUP_WRITEBACK
struct bdi_writeback *wb_get_lookup(struct backing_dev_info *bdi,
struct cgroup_subsys_state *memcg_css);
struct bdi_writeback *wb_get_create(struct backing_dev_info *bdi,
struct cgroup_subsys_state *memcg_css,
gfp_t gfp);
void wb_memcg_offline(struct mem_cgroup *memcg);
void wb_blkcg_offline(struct cgroup_subsys_state *css);
/**
* inode_cgwb_enabled - test whether cgroup writeback is enabled on an inode
* @inode: inode of interest
*
* Cgroup writeback requires support from the filesystem. Also, both memcg and
* iocg have to be on the default hierarchy. Test whether all conditions are
* met.
*
* Note that the test result may change dynamically on the same inode
* depending on how memcg and iocg are configured.
*/
static inline bool inode_cgwb_enabled(struct inode *inode)
{
struct backing_dev_info *bdi = inode_to_bdi(inode);
return cgroup_subsys_on_dfl(memory_cgrp_subsys) &&
cgroup_subsys_on_dfl(io_cgrp_subsys) &&
(bdi->capabilities & BDI_CAP_WRITEBACK) &&
(inode->i_sb->s_iflags & SB_I_CGROUPWB);
}
/**
* wb_find_current - find wb for %current on a bdi
* @bdi: bdi of interest
*
* Find the wb of @bdi which matches both the memcg and blkcg of %current.
* Must be called under rcu_read_lock() which protects the returend wb.
* NULL if not found.
*/
static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi)
{
struct cgroup_subsys_state *memcg_css;
struct bdi_writeback *wb;
memcg_css = task_css(current, memory_cgrp_id);
if (!memcg_css->parent)
return &bdi->wb;
wb = radix_tree_lookup(&bdi->cgwb_tree, memcg_css->id);
/*
* %current's blkcg equals the effective blkcg of its memcg. No
* need to use the relatively expensive cgroup_get_e_css().
*/
if (likely(wb && wb->blkcg_css == task_css(current, io_cgrp_id)))
return wb;
return NULL;
}
/**
* wb_get_create_current - get or create wb for %current on a bdi
* @bdi: bdi of interest
* @gfp: allocation mask
*
* Equivalent to wb_get_create() on %current's memcg. This function is
* called from a relatively hot path and optimizes the common cases using
* wb_find_current().
*/
static inline struct bdi_writeback *
wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp)
{
struct bdi_writeback *wb;
rcu_read_lock();
wb = wb_find_current(bdi);
if (wb && unlikely(!wb_tryget(wb)))
wb = NULL;
rcu_read_unlock();
if (unlikely(!wb)) {
struct cgroup_subsys_state *memcg_css;
memcg_css = task_get_css(current, memory_cgrp_id);
wb = wb_get_create(bdi, memcg_css, gfp);
css_put(memcg_css);
}
return wb;
}
/**
* inode_to_wb - determine the wb of an inode
* @inode: inode of interest
*
* Returns the wb @inode is currently associated with. The caller must be
* holding either @inode->i_lock, the i_pages lock, or the
* associated wb's list_lock.
*/
static inline struct bdi_writeback *inode_to_wb(const struct inode *inode)
{
#ifdef CONFIG_LOCKDEP
WARN_ON_ONCE(debug_locks &&
(inode->i_sb->s_iflags & SB_I_CGROUPWB) &&
(!lockdep_is_held(&inode->i_lock) &&
!lockdep_is_held(&inode->i_mapping->i_pages.xa_lock) &&
!lockdep_is_held(&inode->i_wb->list_lock)));
#endif
return inode->i_wb;
}
static inline struct bdi_writeback *inode_to_wb_wbc(
struct inode *inode,
struct writeback_control *wbc)
{
/*
* If wbc does not have inode attached, it means cgroup writeback was
* disabled when wbc started. Just use the default wb in that case.
*/
return wbc->wb ? wbc->wb : &inode_to_bdi(inode)->wb;
}
/**
* unlocked_inode_to_wb_begin - begin unlocked inode wb access transaction
* @inode: target inode
* @cookie: output param, to be passed to the end function
*
* The caller wants to access the wb associated with @inode but isn't
* holding inode->i_lock, the i_pages lock or wb->list_lock. This
* function determines the wb associated with @inode and ensures that the
* association doesn't change until the transaction is finished with
* unlocked_inode_to_wb_end().
*
* The caller must call unlocked_inode_to_wb_end() with *@cookie afterwards and
* can't sleep during the transaction. IRQs may or may not be disabled on
* return.
*/
static inline struct bdi_writeback *
unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
{
rcu_read_lock();
/*
* Paired with a release fence in inode_do_switch_wbs() and
* ensures that we see the new wb if we see cleared I_WB_SWITCH.
*/
cookie->locked = inode_state_read_once(inode) & I_WB_SWITCH;
smp_rmb();
if (unlikely(cookie->locked))
xa_lock_irqsave(&inode->i_mapping->i_pages, cookie->flags);
/*
* Protected by either !I_WB_SWITCH + rcu_read_lock() or the i_pages
* lock. inode_to_wb() will bark. Deref directly.
*/
return inode->i_wb;
}
/**
* unlocked_inode_to_wb_end - end inode wb access transaction
* @inode: target inode
* @cookie: @cookie from unlocked_inode_to_wb_begin()
*/
static inline void unlocked_inode_to_wb_end(struct inode *inode,
struct wb_lock_cookie *cookie)
{
if (unlikely(cookie->locked))
xa_unlock_irqrestore(&inode->i_mapping->i_pages, cookie->flags);
rcu_read_unlock();
}
#else /* CONFIG_CGROUP_WRITEBACK */
static inline bool inode_cgwb_enabled(struct inode *inode)
{
return false;
}
static inline struct bdi_writeback *wb_find_current(struct backing_dev_info *bdi)
{
return &bdi->wb;
}
static inline struct bdi_writeback *
wb_get_create_current(struct backing_dev_info *bdi, gfp_t gfp)
{
return &bdi->wb;
}
static inline struct bdi_writeback *inode_to_wb(struct inode *inode)
{
return &inode_to_bdi(inode)->wb;
}
static inline struct bdi_writeback *inode_to_wb_wbc(
struct inode *inode,
struct writeback_control *wbc)
{
return inode_to_wb(inode);
}
static inline struct bdi_writeback *
unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
{
return inode_to_wb(inode);
}
static inline void unlocked_inode_to_wb_end(struct inode *inode,
struct wb_lock_cookie *cookie)
{
}
static inline void wb_memcg_offline(struct mem_cgroup *memcg)
{
}
static inline void wb_blkcg_offline(struct cgroup_subsys_state *css)
{
}
#endif /* CONFIG_CGROUP_WRITEBACK */
const char *bdi_dev_name(struct backing_dev_info *bdi);
#endif /* _LINUX_BACKING_DEV_H */
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Common helpers for stackable filesystems and backing files.
*
* Copyright (C) 2023 CTERA Networks.
*/
#ifndef _LINUX_BACKING_FILE_H
#define _LINUX_BACKING_FILE_H
#include <linux/file.h>
#include <linux/uio.h>
#include <linux/fs.h>
struct backing_file_ctx {
const struct cred *cred;
void (*accessed)(struct file *file);
void (*end_write)(struct kiocb *iocb, ssize_t);
};
struct file *backing_file_open(const struct file *user_file, int flags,
const struct path *real_path,
const struct cred *cred);
struct file *backing_tmpfile_open(const struct file *user_file, int flags,
const struct path *real_parentpath,
umode_t mode, const struct cred *cred);
ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
struct kiocb *iocb, int flags,
struct backing_file_ctx *ctx);
ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
struct kiocb *iocb, int flags,
struct backing_file_ctx *ctx);
ssize_t backing_file_splice_read(struct file *in, struct kiocb *iocb,
struct pipe_inode_info *pipe, size_t len,
unsigned int flags,
struct backing_file_ctx *ctx);
ssize_t backing_file_splice_write(struct pipe_inode_info *pipe,
struct file *out, struct kiocb *iocb,
size_t len, unsigned int flags,
struct backing_file_ctx *ctx);
int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
struct backing_file_ctx *ctx);
#endif /* _LINUX_BACKING_FILE_H */
@@ -0,0 +1,451 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Backlight Lowlevel Control Abstraction
*
* Copyright (C) 2003,2004 Hewlett-Packard Company
*
*/
#ifndef _LINUX_BACKLIGHT_H
#define _LINUX_BACKLIGHT_H
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/types.h>
/**
* enum backlight_update_reason - what method was used to update backlight
*
* A driver indicates the method (reason) used for updating the backlight
* when calling backlight_force_update().
*/
enum backlight_update_reason {
/**
* @BACKLIGHT_UPDATE_HOTKEY: The backlight was updated using a hot-key.
*/
BACKLIGHT_UPDATE_HOTKEY,
/**
* @BACKLIGHT_UPDATE_SYSFS: The backlight was updated using sysfs.
*/
BACKLIGHT_UPDATE_SYSFS,
};
/**
* enum backlight_type - the type of backlight control
*
* The type of interface used to control the backlight.
*/
enum backlight_type {
/**
* @BACKLIGHT_RAW:
*
* The backlight is controlled using hardware registers.
*/
BACKLIGHT_RAW = 1,
/**
* @BACKLIGHT_PLATFORM:
*
* The backlight is controlled using a platform-specific interface.
*/
BACKLIGHT_PLATFORM,
/**
* @BACKLIGHT_FIRMWARE:
*
* The backlight is controlled using a standard firmware interface.
*/
BACKLIGHT_FIRMWARE,
/**
* @BACKLIGHT_TYPE_MAX: Number of entries.
*/
BACKLIGHT_TYPE_MAX,
};
/** enum backlight_scale - the type of scale used for brightness values
*
* The type of scale used for brightness values.
*/
enum backlight_scale {
/**
* @BACKLIGHT_SCALE_UNKNOWN: The scale is unknown.
*/
BACKLIGHT_SCALE_UNKNOWN = 0,
/**
* @BACKLIGHT_SCALE_LINEAR: The scale is linear.
*
* The linear scale will increase brightness the same for each step.
*/
BACKLIGHT_SCALE_LINEAR,
/**
* @BACKLIGHT_SCALE_NON_LINEAR: The scale is not linear.
*
* This is often used when the brightness values tries to adjust to
* the relative perception of the eye demanding a non-linear scale.
*/
BACKLIGHT_SCALE_NON_LINEAR,
};
struct backlight_device;
/**
* struct backlight_ops - backlight operations
*
* The backlight operations are specified when the backlight device is registered.
*/
struct backlight_ops {
/**
* @options: Configure how operations are called from the core.
*
* The options parameter is used to adjust the behaviour of the core.
* Set BL_CORE_SUSPENDRESUME to get the update_status() operation called
* upon suspend and resume.
*/
unsigned int options;
#define BL_CORE_SUSPENDRESUME (1 << 0)
/**
* @update_status: Operation called when properties have changed.
*
* Notify the backlight driver some property has changed.
* The update_status operation is protected by the update_lock.
*
* The backlight driver is expected to use backlight_is_blank()
* to check if the display is blanked and set brightness accordingly.
* update_status() is called when any of the properties has changed.
*
* RETURNS:
*
* 0 on success, negative error code if any failure occurred.
*/
int (*update_status)(struct backlight_device *);
/**
* @get_brightness: Return the current backlight brightness.
*
* The driver may implement this as a readback from the HW.
* This operation is optional and if not present then the current
* brightness property value is used.
*
* RETURNS:
*
* A brightness value which is 0 or a positive number.
* On failure a negative error code is returned.
*/
int (*get_brightness)(struct backlight_device *);
/**
* @controls_device: Check against the display device
*
* Check if the backlight controls the given display device. This
* operation is optional and if not implemented it is assumed that
* the display is always the one controlled by the backlight.
*
* RETURNS:
*
* If display_dev is NULL or display_dev matches the device controlled by
* the backlight, return true. Otherwise return false.
*/
bool (*controls_device)(struct backlight_device *bd, struct device *display_dev);
};
/**
* struct backlight_properties - backlight properties
*
* This structure defines all the properties of a backlight.
*/
struct backlight_properties {
/**
* @brightness: The current brightness requested by the user.
*
* The backlight core makes sure the range is (0 to max_brightness)
* when the brightness is set via the sysfs attribute:
* /sys/class/backlight/<backlight>/brightness.
*
* This value can be set in the backlight_properties passed
* to devm_backlight_device_register() to set a default brightness
* value.
*/
int brightness;
/**
* @max_brightness: The maximum brightness value.
*
* This value must be set in the backlight_properties passed to
* devm_backlight_device_register() and shall not be modified by the
* driver after registration.
*/
int max_brightness;
/**
* @power: The current power mode.
*
* User space can configure the power mode using the sysfs
* attribute: /sys/class/backlight/<backlight>/bl_power
* When the power property is updated update_status() is called.
*
* The possible values are: (0: full on, 4: full off), see
* BACKLIGHT_POWER constants.
*
* When the backlight device is enabled, @power is set to
* BACKLIGHT_POWER_ON. When the backlight device is disabled,
* @power is set to BACKLIGHT_POWER_OFF.
*/
int power;
#define BACKLIGHT_POWER_ON (0)
#define BACKLIGHT_POWER_OFF (4)
#define BACKLIGHT_POWER_REDUCED (1) // deprecated; don't use in new code
/**
* @type: The type of backlight supported.
*
* The backlight type allows userspace to make appropriate
* policy decisions based on the backlight type.
*
* This value must be set in the backlight_properties
* passed to devm_backlight_device_register().
*/
enum backlight_type type;
/**
* @state: The state of the backlight core.
*
* The state is a bitmask. BL_CORE_FBBLANK is set when the display
* is expected to be blank. BL_CORE_SUSPENDED is set when the
* driver is suspended.
*
* backlight drivers are expected to use backlight_is_blank()
* in their update_status() operation rather than reading the
* state property.
*
* The state is maintained by the core and drivers may not modify it.
*/
unsigned int state;
#define BL_CORE_SUSPENDED (1 << 0) /* backlight is suspended */
#define BL_CORE_FBBLANK (1 << 1) /* backlight is under an fb blank event */
/**
* @scale: The type of the brightness scale.
*/
enum backlight_scale scale;
};
/**
* struct backlight_device - backlight device data
*
* This structure holds all data required by a backlight device.
*/
struct backlight_device {
/**
* @props: Backlight properties
*/
struct backlight_properties props;
/**
* @update_lock: The lock used when calling the update_status() operation.
*
* update_lock is an internal backlight lock that serialise access
* to the update_status() operation. The backlight core holds the update_lock
* when calling the update_status() operation. The update_lock shall not
* be used by backlight drivers.
*/
struct mutex update_lock;
/**
* @ops_lock: The lock used around everything related to backlight_ops.
*
* ops_lock is an internal backlight lock that protects the ops pointer
* and is used around all accesses to ops and when the operations are
* invoked. The ops_lock shall not be used by backlight drivers.
*/
struct mutex ops_lock;
/**
* @ops: Pointer to the backlight operations.
*
* If ops is NULL, the driver that registered this device has been unloaded,
* and if class_get_devdata() points to something in the body of that driver,
* it is also invalid.
*/
const struct backlight_ops *ops;
/**
* @entry: List entry of all registered backlight devices
*/
struct list_head entry;
/**
* @dev: Parent device.
*/
struct device dev;
/**
* @use_count: The number of unblanked displays.
*/
int use_count;
};
/**
* backlight_update_status - force an update of the backlight device status
* @bd: the backlight device
*/
static inline int backlight_update_status(struct backlight_device *bd)
{
int ret = -ENOENT;
mutex_lock(&bd->update_lock);
if (bd->ops && bd->ops->update_status)
ret = bd->ops->update_status(bd);
mutex_unlock(&bd->update_lock);
return ret;
}
/**
* backlight_enable - Enable backlight
* @bd: the backlight device to enable
*/
static inline int backlight_enable(struct backlight_device *bd)
{
if (!bd)
return 0;
bd->props.power = BACKLIGHT_POWER_ON;
bd->props.state &= ~BL_CORE_FBBLANK;
return backlight_update_status(bd);
}
/**
* backlight_disable - Disable backlight
* @bd: the backlight device to disable
*/
static inline int backlight_disable(struct backlight_device *bd)
{
if (!bd)
return 0;
bd->props.power = BACKLIGHT_POWER_OFF;
bd->props.state |= BL_CORE_FBBLANK;
return backlight_update_status(bd);
}
/**
* backlight_is_blank - Return true if display is expected to be blank
* @bd: the backlight device
*
* Display is expected to be blank if any of these is true::
*
* 1) if power in not UNBLANK
* 2) if state indicate BLANK or SUSPENDED
*
* Returns true if display is expected to be blank, false otherwise.
*/
static inline bool backlight_is_blank(const struct backlight_device *bd)
{
return bd->props.power != BACKLIGHT_POWER_ON ||
bd->props.state & (BL_CORE_SUSPENDED | BL_CORE_FBBLANK);
}
/**
* backlight_get_brightness - Returns the current brightness value
* @bd: the backlight device
*
* Returns the current brightness value, taking in consideration the current
* state. If backlight_is_blank() returns true then return 0 as brightness
* otherwise return the current brightness property value.
*
* Backlight drivers are expected to use this function in their update_status()
* operation to get the brightness value.
*/
static inline int backlight_get_brightness(const struct backlight_device *bd)
{
if (backlight_is_blank(bd))
return 0;
else
return bd->props.brightness;
}
struct backlight_device *
backlight_device_register(const char *name, struct device *dev, void *devdata,
const struct backlight_ops *ops,
const struct backlight_properties *props);
struct backlight_device *
devm_backlight_device_register(struct device *dev, const char *name,
struct device *parent, void *devdata,
const struct backlight_ops *ops,
const struct backlight_properties *props);
void backlight_device_unregister(struct backlight_device *bd);
void devm_backlight_device_unregister(struct device *dev,
struct backlight_device *bd);
void backlight_force_update(struct backlight_device *bd,
enum backlight_update_reason reason);
struct backlight_device *backlight_device_get_by_name(const char *name);
struct backlight_device *backlight_device_get_by_type(enum backlight_type type);
int backlight_device_set_brightness(struct backlight_device *bd,
unsigned long brightness);
#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
void backlight_notify_blank(struct backlight_device *bd,
struct device *display_dev,
bool fb_on, bool prev_fb_on);
void backlight_notify_blank_all(struct device *display_dev,
bool fb_on, bool prev_fb_on);
#else
static inline void backlight_notify_blank(struct backlight_device *bd,
struct device *display_dev,
bool fb_on, bool prev_fb_on)
{ }
static inline void backlight_notify_blank_all(struct device *display_dev,
bool fb_on, bool prev_fb_on)
{ }
#endif
#define to_backlight_device(obj) container_of(obj, struct backlight_device, dev)
/**
* bl_get_data - access devdata
* @bl_dev: pointer to backlight device
*
* When a backlight device is registered the driver has the possibility
* to supply a void * devdata. bl_get_data() return a pointer to the
* devdata.
*
* RETURNS:
*
* pointer to devdata stored while registering the backlight device.
*/
static inline void * bl_get_data(struct backlight_device *bl_dev)
{
return dev_get_drvdata(&bl_dev->dev);
}
#ifdef CONFIG_OF
struct backlight_device *of_find_backlight_by_node(struct device_node *node);
#else
static inline struct backlight_device *
of_find_backlight_by_node(struct device_node *node)
{
return NULL;
}
#endif
#if IS_ENABLED(CONFIG_BACKLIGHT_CLASS_DEVICE)
struct backlight_device *devm_of_find_backlight(struct device *dev);
#else
static inline struct backlight_device *
devm_of_find_backlight(struct device *dev)
{
return NULL;
}
#endif
#endif
@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_BADBLOCKS_H
#define _LINUX_BADBLOCKS_H
#include <linux/seqlock.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
#include <linux/types.h>
#define BB_LEN_MASK (0x00000000000001FFULL)
#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL)
#define BB_ACK_MASK (0x8000000000000000ULL)
#define BB_MAX_LEN 512
#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9)
#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1)
#define BB_ACK(x) (!!((x) & BB_ACK_MASK))
#define BB_END(x) (BB_OFFSET(x) + BB_LEN(x))
#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63))
/* Bad block numbers are stored sorted in a single page.
* 64bits is used for each block or extent.
* 54 bits are sector number, 9 bits are extent size,
* 1 bit is an 'acknowledged' flag.
*/
#define MAX_BADBLOCKS (PAGE_SIZE/8)
struct badblocks {
struct device *dev; /* set by devm_init_badblocks */
int count; /* count of bad blocks */
int unacked_exist; /* there probably are unacknowledged
* bad blocks. This is only cleared
* when a read discovers none
*/
int shift; /* shift from sectors to block size
* a -ve shift means badblocks are
* disabled.*/
u64 *page; /* badblock list */
int changed;
seqlock_t lock;
sector_t sector;
sector_t size; /* in sectors */
};
struct badblocks_context {
sector_t start;
sector_t len;
int ack;
};
int badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
sector_t *first_bad, sector_t *bad_sectors);
bool badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
int acknowledged);
bool badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors);
void ack_all_badblocks(struct badblocks *bb);
ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,
int unack);
int badblocks_init(struct badblocks *bb, int enable);
void badblocks_exit(struct badblocks *bb);
struct device;
int devm_init_badblocks(struct device *dev, struct badblocks *bb);
static inline void devm_exit_badblocks(struct device *dev, struct badblocks *bb)
{
if (bb->dev != dev) {
dev_WARN_ONCE(dev, 1, "%s: badblocks instance not associated\n",
__func__);
return;
}
badblocks_exit(bb);
}
static inline int badblocks_full(struct badblocks *bb)
{
return (bb->count >= MAX_BADBLOCKS);
}
static inline int badblocks_empty(struct badblocks *bb)
{
return (bb->count == 0);
}
static inline void set_changed(struct badblocks *bb)
{
if (bb->changed != 1)
bb->changed = 1;
}
static inline void clear_changed(struct badblocks *bb)
{
if (bb->changed != 0)
bb->changed = 0;
}
#endif
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Common interface for implementing a memory balloon, including support
* for migration of pages inflated in a memory balloon.
*
* Balloon page migration makes use of the general "movable_ops page migration"
* feature.
*
* page->private is used to reference the responsible balloon device.
* That these pages have movable_ops, and which movable_ops apply,
* is derived from the page type (PageOffline()) combined with the
* PG_movable_ops flag (PageMovableOps()).
*
* Once the page type and the PG_movable_ops are set, migration code
* can initiate page isolation by invoking the
* movable_operations()->isolate_page() callback
*
* As long as page->private is set, the page is either on the balloon list
* or isolated for migration. If page->private is not set, the page is
* either still getting inflated, or was deflated to be freed by the balloon
* driver soon. Isolation is impossible in both cases.
*
* As the page isolation scanning step a compaction thread does is a lockless
* procedure (from a page standpoint), it might bring some racy situations while
* performing balloon page migration. In order to sort out these racy scenarios
* and safely perform balloon's page migration we must, always, ensure following
* these simple rules:
*
* i. Inflation/deflation must set/clear page->private under the
* balloon_pages_lock
*
* ii. isolation or dequeueing procedure must remove the page from balloon
* device page list under balloon_pages_lock
*
* Copyright (C) 2012, Red Hat, Inc. Rafael Aquini <aquini@redhat.com>
*/
#ifndef _LINUX_BALLOON_H
#define _LINUX_BALLOON_H
#include <linux/pagemap.h>
#include <linux/page-flags.h>
#include <linux/migrate.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/list.h>
/*
* Balloon device information descriptor.
* This struct is used to allow the common balloon page migration interface
* procedures to find the proper balloon device holding memory pages they'll
* have to cope for page migration, as well as it serves the balloon driver as
* a page book-keeper for its registered balloon devices.
*/
struct balloon_dev_info {
unsigned long isolated_pages; /* # of isolated pages for migration */
struct list_head pages; /* Pages enqueued & handled to Host */
int (*migratepage)(struct balloon_dev_info *, struct page *newpage,
struct page *page, enum migrate_mode mode);
bool adjust_managed_page_count;
};
struct page *balloon_page_alloc(void);
void balloon_page_enqueue(struct balloon_dev_info *b_dev_info,
struct page *page);
struct page *balloon_page_dequeue(struct balloon_dev_info *b_dev_info);
size_t balloon_page_list_enqueue(struct balloon_dev_info *b_dev_info,
struct list_head *pages);
size_t balloon_page_list_dequeue(struct balloon_dev_info *b_dev_info,
struct list_head *pages, size_t n_req_pages);
static inline void balloon_devinfo_init(struct balloon_dev_info *balloon)
{
balloon->isolated_pages = 0;
INIT_LIST_HEAD(&balloon->pages);
balloon->migratepage = NULL;
balloon->adjust_managed_page_count = false;
}
#endif /* _LINUX_BALLOON_H */
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-2.0
/*
* base64 encoding, lifted from fs/crypto/fname.c.
*/
#ifndef _LINUX_BASE64_H
#define _LINUX_BASE64_H
#include <linux/types.h>
enum base64_variant {
BASE64_STD, /* RFC 4648 (standard) */
BASE64_URLSAFE, /* RFC 4648 (base64url) */
BASE64_IMAP, /* RFC 3501 */
};
#define BASE64_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3)
int base64_encode(const u8 *src, int len, char *dst, bool padding, enum base64_variant variant);
int base64_decode(const char *src, int len, u8 *dst, bool padding, enum base64_variant variant);
#endif /* _LINUX_BASE64_H */
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _BCD_H
#define _BCD_H
#include <linux/compiler.h>
#define bcd2bin(x) \
(__builtin_constant_p((u8 )(x)) ? \
const_bcd2bin(x) : \
_bcd2bin(x))
#define bin2bcd(x) \
(__builtin_constant_p((u8 )(x)) ? \
const_bin2bcd(x) : \
_bin2bcd(x))
#define bcd_is_valid(x) \
const_bcd_is_valid(x)
#define const_bcd2bin(x) (((x) & 0x0f) + ((x) >> 4) * 10)
#define const_bin2bcd(x) ((((x) / 10) << 4) + (x) % 10)
#define const_bcd_is_valid(x) (((x) & 0x0f) < 10 && ((x) >> 4) < 10)
unsigned _bcd2bin(unsigned char val) __attribute_const__;
unsigned char _bin2bcd(unsigned val) __attribute_const__;
#endif /* _BCD_H */
@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Generic binary BCH encoding/decoding library
*
* Copyright © 2011 Parrot S.A.
*
* Author: Ivan Djelic <ivan.djelic@parrot.com>
*
* Description:
*
* This library provides runtime configurable encoding/decoding of binary
* Bose-Chaudhuri-Hocquenghem (BCH) codes.
*/
#ifndef _BCH_H
#define _BCH_H
#include <linux/types.h>
/**
* struct bch_control - BCH control structure
* @m: Galois field order
* @n: maximum codeword size in bits (= 2^m-1)
* @t: error correction capability in bits
* @ecc_bits: ecc exact size in bits, i.e. generator polynomial degree (<=m*t)
* @ecc_bytes: ecc max size (m*t bits) in bytes
* @a_pow_tab: Galois field GF(2^m) exponentiation lookup table
* @a_log_tab: Galois field GF(2^m) log lookup table
* @mod8_tab: remainder generator polynomial lookup tables
* @ecc_buf: ecc parity words buffer
* @ecc_buf2: ecc parity words buffer
* @xi_tab: GF(2^m) base for solving degree 2 polynomial roots
* @syn: syndrome buffer
* @cache: log-based polynomial representation buffer
* @elp: error locator polynomial
* @poly_2t: temporary polynomials of degree 2t
* @swap_bits: swap bits within data and syndrome bytes
*/
struct bch_control {
unsigned int m;
unsigned int n;
unsigned int t;
unsigned int ecc_bits;
unsigned int ecc_bytes;
/* private: */
uint16_t *a_pow_tab;
uint16_t *a_log_tab;
uint32_t *mod8_tab;
uint32_t *ecc_buf;
uint32_t *ecc_buf2;
unsigned int *xi_tab;
unsigned int *syn;
int *cache;
struct gf_poly *elp;
struct gf_poly *poly_2t[4];
bool swap_bits;
};
struct bch_control *bch_init(int m, int t, unsigned int prim_poly,
bool swap_bits);
void bch_free(struct bch_control *bch);
void bch_encode(struct bch_control *bch, const uint8_t *data,
unsigned int len, uint8_t *ecc);
int bch_decode(struct bch_control *bch, const uint8_t *data, unsigned int len,
const uint8_t *recv_ecc, const uint8_t *calc_ecc,
const unsigned int *syn, unsigned int *errloc);
#endif /* _BCH_H */
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
*/
#ifndef __BCM47XX_NVRAM_H
#define __BCM47XX_NVRAM_H
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
#ifdef CONFIG_BCM47XX_NVRAM
int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start, size_t res_size);
int bcm47xx_nvram_init_from_mem(u32 base, u32 lim);
int bcm47xx_nvram_getenv(const char *name, char *val, size_t val_len);
int bcm47xx_nvram_gpio_pin(const char *name);
char *bcm47xx_nvram_get_contents(size_t *val_len);
static inline void bcm47xx_nvram_release_contents(char *nvram)
{
vfree(nvram);
};
#else
static inline int bcm47xx_nvram_init_from_iomem(void __iomem *nvram_start,
size_t res_size)
{
return -ENOTSUPP;
}
static inline int bcm47xx_nvram_init_from_mem(u32 base, u32 lim)
{
return -ENOTSUPP;
};
static inline int bcm47xx_nvram_getenv(const char *name, char *val,
size_t val_len)
{
return -ENOTSUPP;
};
static inline int bcm47xx_nvram_gpio_pin(const char *name)
{
return -ENOTSUPP;
};
static inline char *bcm47xx_nvram_get_contents(size_t *val_len)
{
return NULL;
};
static inline void bcm47xx_nvram_release_contents(char *nvram)
{
};
#endif
#endif /* __BCM47XX_NVRAM_H */
@@ -0,0 +1,31 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
*/
#ifndef __BCM47XX_SPROM_H
#define __BCM47XX_SPROM_H
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/vmalloc.h>
struct ssb_sprom;
#ifdef CONFIG_BCM47XX_SPROM
void bcm47xx_fill_sprom(struct ssb_sprom *sprom, const char *prefix,
bool fallback);
int bcm47xx_sprom_register_fallbacks(void);
#else
static inline void bcm47xx_fill_sprom(struct ssb_sprom *sprom,
const char *prefix,
bool fallback)
{
}
static inline int bcm47xx_sprom_register_fallbacks(void)
{
return -ENOTSUPP;
};
#endif
#endif /* __BCM47XX_SPROM_H */
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_BCM47XX_WDT_H_
#define LINUX_BCM47XX_WDT_H_
#include <linux/timer.h>
#include <linux/types.h>
#include <linux/watchdog.h>
struct bcm47xx_wdt {
u32 (*timer_set)(struct bcm47xx_wdt *, u32);
u32 (*timer_set_ms)(struct bcm47xx_wdt *, u32);
u32 max_timer_ms;
void *driver_data;
struct watchdog_device wdd;
struct timer_list soft_timer;
atomic_t soft_ticks;
};
static inline void *bcm47xx_wdt_get_drvdata(struct bcm47xx_wdt *wdt)
{
return wdt->driver_data;
}
#endif /* LINUX_BCM47XX_WDT_H_ */
@@ -0,0 +1,109 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_BCM963XX_NVRAM_H__
#define __LINUX_BCM963XX_NVRAM_H__
#include <linux/crc32.h>
#include <linux/if_ether.h>
#include <linux/sizes.h>
#include <linux/types.h>
/*
* Broadcom BCM963xx SoC board nvram data structure.
*
* The nvram structure varies in size depending on the SoC board version. Use
* the appropriate minimum BCM963XX_NVRAM_*_SIZE define for the information
* you need instead of sizeof(struct bcm963xx_nvram) as this may change.
*/
#define BCM963XX_NVRAM_V4_SIZE 300
#define BCM963XX_NVRAM_V5_SIZE (1 * SZ_1K)
#define BCM963XX_DEFAULT_PSI_SIZE 64
enum bcm963xx_nvram_nand_part {
BCM963XX_NVRAM_NAND_PART_BOOT = 0,
BCM963XX_NVRAM_NAND_PART_ROOTFS_1,
BCM963XX_NVRAM_NAND_PART_ROOTFS_2,
BCM963XX_NVRAM_NAND_PART_DATA,
BCM963XX_NVRAM_NAND_PART_BBT,
__BCM963XX_NVRAM_NAND_NR_PARTS
};
struct bcm963xx_nvram {
u32 version;
char bootline[256];
char name[16];
u32 main_tp_number;
u32 psi_size;
u32 mac_addr_count;
u8 mac_addr_base[ETH_ALEN];
u8 __reserved1[2];
u32 checksum_v4;
u8 __reserved2[292];
u32 nand_part_offset[__BCM963XX_NVRAM_NAND_NR_PARTS];
u32 nand_part_size[__BCM963XX_NVRAM_NAND_NR_PARTS];
u8 __reserved3[388];
u32 checksum_v5;
};
#define BCM963XX_NVRAM_NAND_PART_OFFSET(nvram, part) \
bcm963xx_nvram_nand_part_offset(nvram, BCM963XX_NVRAM_NAND_PART_ ##part)
static inline u64 __pure bcm963xx_nvram_nand_part_offset(
const struct bcm963xx_nvram *nvram,
enum bcm963xx_nvram_nand_part part)
{
return nvram->nand_part_offset[part] * SZ_1K;
}
#define BCM963XX_NVRAM_NAND_PART_SIZE(nvram, part) \
bcm963xx_nvram_nand_part_size(nvram, BCM963XX_NVRAM_NAND_PART_ ##part)
static inline u64 __pure bcm963xx_nvram_nand_part_size(
const struct bcm963xx_nvram *nvram,
enum bcm963xx_nvram_nand_part part)
{
return nvram->nand_part_size[part] * SZ_1K;
}
/*
* bcm963xx_nvram_checksum - Verify nvram checksum
*
* @nvram: pointer to full size nvram data structure
* @expected_out: optional pointer to store expected checksum value
* @actual_out: optional pointer to store actual checksum value
*
* Return: 0 if the checksum is valid, otherwise -EINVAL
*/
static int __maybe_unused bcm963xx_nvram_checksum(
const struct bcm963xx_nvram *nvram,
u32 *expected_out, u32 *actual_out)
{
const u32 zero = 0;
u32 expected, actual;
size_t len;
if (nvram->version <= 4) {
expected = nvram->checksum_v4;
len = BCM963XX_NVRAM_V4_SIZE;
} else {
expected = nvram->checksum_v5;
len = BCM963XX_NVRAM_V5_SIZE;
}
/* Calculate the CRC32 of the nvram with the checksum field set to 0. */
actual = crc32_le(~0, nvram, len - sizeof(u32));
actual = crc32_le(actual, &zero, sizeof(u32));
if (expected_out)
*expected_out = expected;
if (actual_out)
*actual_out = actual;
return expected == actual ? 0 : -EINVAL;
};
#endif /* __LINUX_BCM963XX_NVRAM_H__ */
@@ -0,0 +1,103 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_BCM963XX_TAG_H__
#define __LINUX_BCM963XX_TAG_H__
#include <linux/types.h>
#define TAGVER_LEN 4 /* Length of Tag Version */
#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */
#define SIG1_LEN 20 /* Company Signature 1 Length */
#define SIG2_LEN 14 /* Company Signature 2 Length */
#define BOARDID_LEN 16 /* Length of BoardId */
#define ENDIANFLAG_LEN 2 /* Endian Flag Length */
#define CHIPID_LEN 6 /* Chip Id Length */
#define IMAGE_LEN 10 /* Length of Length Field */
#define ADDRESS_LEN 12 /* Length of Address field */
#define IMAGE_SEQUENCE_LEN 4 /* Image sequence Length */
#define RSASIG_LEN 20 /* Length of RSA Signature in tag */
#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */
#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */
#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */
#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */
#define NUM_PIRELLI 2
#define IMAGETAG_CRC_START 0xFFFFFFFF
#define PIRELLI_BOARDS { \
"AGPF-S0", \
"DWV-S0", \
}
/* Extended flash address, needs to be subtracted
* from bcm_tag flash image offsets.
*/
#define BCM963XX_EXTENDED_SIZE 0xBFC00000
/*
* The broadcom firmware assumes the rootfs starts the image,
* therefore uses the rootfs start (flash_image_address)
* to determine where to flash the image. Since we have the kernel first
* we have to give it the kernel address, but the crc uses the length
* associated with this address (root_length), which is added to the kernel
* length (kernel_length) to determine the length of image to flash and thus
* needs to be rootfs + deadcode (jffs2 EOF marker)
*/
struct bcm_tag {
/* 0-3: Version of the image tag */
char tag_version[TAGVER_LEN];
/* 4-23: Company Line 1 */
char sig_1[SIG1_LEN];
/* 24-37: Company Line 2 */
char sig_2[SIG2_LEN];
/* 38-43: Chip this image is for */
char chip_id[CHIPID_LEN];
/* 44-59: Board name */
char board_id[BOARDID_LEN];
/* 60-61: Map endianness -- 1 BE 0 LE */
char big_endian[ENDIANFLAG_LEN];
/* 62-71: Total length of image */
char total_length[IMAGE_LEN];
/* 72-83: Address in memory of CFE */
char cfe__address[ADDRESS_LEN];
/* 84-93: Size of CFE */
char cfe_length[IMAGE_LEN];
/* 94-105: Address in memory of image start
* (kernel for OpenWRT, rootfs for stock firmware)
*/
char flash_image_start[ADDRESS_LEN];
/* 106-115: Size of rootfs */
char root_length[IMAGE_LEN];
/* 116-127: Address in memory of kernel */
char kernel_address[ADDRESS_LEN];
/* 128-137: Size of kernel */
char kernel_length[IMAGE_LEN];
/* 138-141: Image sequence number
* (to be incremented when flashed with a new image)
*/
char image_sequence[IMAGE_SEQUENCE_LEN];
/* 142-161: RSA Signature (not used; some vendors may use this) */
char rsa_signature[RSASIG_LEN];
/* 162-191: Compilation and related information (not used in OpenWrt) */
char information1[TAGINFO1_LEN];
/* 192-195: Version flash layout */
char flash_layout_ver[FLASHLAYOUTVER_LEN];
/* 196-199: kernel+rootfs CRC32 */
__u32 fskernel_crc;
/* 200-215: Unused except on Alice Gate where it is information */
char information2[TAGINFO2_LEN];
/* 216-219: CRC32 of image less imagetag (kernel for Alice Gate) */
__u32 image_crc;
/* 220-223: CRC32 of rootfs partition */
__u32 rootfs_crc;
/* 224-227: CRC32 of kernel partition */
__u32 kernel_crc;
/* 228-235: Unused at present */
char reserved1[8];
/* 236-239: CRC32 of header excluding last 20 bytes */
__u32 header_crc;
/* 240-255: Unused at present */
char reserved2[16];
};
#endif /* __LINUX_BCM63XX_TAG_H__ */
@@ -0,0 +1,489 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_BCMA_H_
#define LINUX_BCMA_H_
#include <linux/pci.h>
#include <linux/mod_devicetable.h>
#include <linux/bcma/bcma_driver_arm_c9.h>
#include <linux/bcma/bcma_driver_chipcommon.h>
#include <linux/bcma/bcma_driver_pci.h>
#include <linux/bcma/bcma_driver_pcie2.h>
#include <linux/bcma/bcma_driver_mips.h>
#include <linux/bcma/bcma_driver_gmac_cmn.h>
#include <linux/ssb/ssb.h> /* SPROM sharing */
#include <linux/bcma/bcma_regs.h>
struct bcma_device;
struct bcma_bus;
enum bcma_hosttype {
BCMA_HOSTTYPE_PCI,
BCMA_HOSTTYPE_SDIO,
BCMA_HOSTTYPE_SOC,
};
struct bcma_chipinfo {
u16 id;
u8 rev;
u8 pkg;
};
struct bcma_boardinfo {
u16 vendor;
u16 type;
};
enum bcma_clkmode {
BCMA_CLKMODE_FAST,
BCMA_CLKMODE_DYNAMIC,
};
struct bcma_host_ops {
u8 (*read8)(struct bcma_device *core, u16 offset);
u16 (*read16)(struct bcma_device *core, u16 offset);
u32 (*read32)(struct bcma_device *core, u16 offset);
void (*write8)(struct bcma_device *core, u16 offset, u8 value);
void (*write16)(struct bcma_device *core, u16 offset, u16 value);
void (*write32)(struct bcma_device *core, u16 offset, u32 value);
#ifdef CONFIG_BCMA_BLOCKIO
void (*block_read)(struct bcma_device *core, void *buffer,
size_t count, u16 offset, u8 reg_width);
void (*block_write)(struct bcma_device *core, const void *buffer,
size_t count, u16 offset, u8 reg_width);
#endif
/* Agent ops */
u32 (*aread32)(struct bcma_device *core, u16 offset);
void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
};
/* Core manufacturers */
#define BCMA_MANUF_ARM 0x43B
#define BCMA_MANUF_MIPS 0x4A7
#define BCMA_MANUF_BCM 0x4BF
/* Core class values. */
#define BCMA_CL_SIM 0x0
#define BCMA_CL_EROM 0x1
#define BCMA_CL_CORESIGHT 0x9
#define BCMA_CL_VERIF 0xB
#define BCMA_CL_OPTIMO 0xD
#define BCMA_CL_GEN 0xE
#define BCMA_CL_PRIMECELL 0xF
/* Core-ID values. */
#define BCMA_CORE_OOB_ROUTER 0x367 /* Out of band */
#define BCMA_CORE_4706_CHIPCOMMON 0x500
#define BCMA_CORE_NS_PCIEG2 0x501
#define BCMA_CORE_NS_DMA 0x502
#define BCMA_CORE_NS_SDIO3 0x503
#define BCMA_CORE_NS_USB20 0x504
#define BCMA_CORE_NS_USB30 0x505
#define BCMA_CORE_NS_A9JTAG 0x506
#define BCMA_CORE_NS_DDR23 0x507
#define BCMA_CORE_NS_ROM 0x508
#define BCMA_CORE_NS_NAND 0x509
#define BCMA_CORE_NS_QSPI 0x50A
#define BCMA_CORE_NS_CHIPCOMMON_B 0x50B
#define BCMA_CORE_4706_SOC_RAM 0x50E
#define BCMA_CORE_ARMCA9 0x510
#define BCMA_CORE_4706_MAC_GBIT 0x52D
#define BCMA_CORE_AMEMC 0x52E /* DDR1/2 memory controller core */
#define BCMA_CORE_ALTA 0x534 /* I2S core */
#define BCMA_CORE_4706_MAC_GBIT_COMMON 0x5DC
#define BCMA_CORE_DDR23_PHY 0x5DD
#define BCMA_CORE_INVALID 0x700
#define BCMA_CORE_CHIPCOMMON 0x800
#define BCMA_CORE_ILINE20 0x801
#define BCMA_CORE_SRAM 0x802
#define BCMA_CORE_SDRAM 0x803
#define BCMA_CORE_PCI 0x804
#define BCMA_CORE_MIPS 0x805
#define BCMA_CORE_ETHERNET 0x806
#define BCMA_CORE_V90 0x807
#define BCMA_CORE_USB11_HOSTDEV 0x808
#define BCMA_CORE_ADSL 0x809
#define BCMA_CORE_ILINE100 0x80A
#define BCMA_CORE_IPSEC 0x80B
#define BCMA_CORE_UTOPIA 0x80C
#define BCMA_CORE_PCMCIA 0x80D
#define BCMA_CORE_INTERNAL_MEM 0x80E
#define BCMA_CORE_MEMC_SDRAM 0x80F
#define BCMA_CORE_OFDM 0x810
#define BCMA_CORE_EXTIF 0x811
#define BCMA_CORE_80211 0x812
#define BCMA_CORE_PHY_A 0x813
#define BCMA_CORE_PHY_B 0x814
#define BCMA_CORE_PHY_G 0x815
#define BCMA_CORE_MIPS_3302 0x816
#define BCMA_CORE_USB11_HOST 0x817
#define BCMA_CORE_USB11_DEV 0x818
#define BCMA_CORE_USB20_HOST 0x819
#define BCMA_CORE_USB20_DEV 0x81A
#define BCMA_CORE_SDIO_HOST 0x81B
#define BCMA_CORE_ROBOSWITCH 0x81C
#define BCMA_CORE_PARA_ATA 0x81D
#define BCMA_CORE_SATA_XORDMA 0x81E
#define BCMA_CORE_ETHERNET_GBIT 0x81F
#define BCMA_CORE_PCIE 0x820
#define BCMA_CORE_PHY_N 0x821
#define BCMA_CORE_SRAM_CTL 0x822
#define BCMA_CORE_MINI_MACPHY 0x823
#define BCMA_CORE_ARM_1176 0x824
#define BCMA_CORE_ARM_7TDMI 0x825
#define BCMA_CORE_PHY_LP 0x826
#define BCMA_CORE_PMU 0x827
#define BCMA_CORE_PHY_SSN 0x828
#define BCMA_CORE_SDIO_DEV 0x829
#define BCMA_CORE_ARM_CM3 0x82A
#define BCMA_CORE_PHY_HT 0x82B
#define BCMA_CORE_MIPS_74K 0x82C
#define BCMA_CORE_MAC_GBIT 0x82D
#define BCMA_CORE_DDR12_MEM_CTL 0x82E
#define BCMA_CORE_PCIE_RC 0x82F /* PCIe Root Complex */
#define BCMA_CORE_OCP_OCP_BRIDGE 0x830
#define BCMA_CORE_SHARED_COMMON 0x831
#define BCMA_CORE_OCP_AHB_BRIDGE 0x832
#define BCMA_CORE_SPI_HOST 0x833
#define BCMA_CORE_I2S 0x834
#define BCMA_CORE_SDR_DDR1_MEM_CTL 0x835 /* SDR/DDR1 memory controller core */
#define BCMA_CORE_SHIM 0x837 /* SHIM component in ubus/6362 */
#define BCMA_CORE_PHY_AC 0x83B
#define BCMA_CORE_PCIE2 0x83C /* PCI Express Gen2 */
#define BCMA_CORE_USB30_DEV 0x83D
#define BCMA_CORE_ARM_CR4 0x83E
#define BCMA_CORE_GCI 0x840
#define BCMA_CORE_CMEM 0x846 /* CNDS DDR2/3 memory controller */
#define BCMA_CORE_ARM_CA7 0x847
#define BCMA_CORE_SYS_MEM 0x849
#define BCMA_CORE_DEFAULT 0xFFF
#define BCMA_MAX_NR_CORES 16
#define BCMA_CORE_SIZE 0x1000
/* Chip IDs of PCIe devices */
#define BCMA_CHIP_ID_BCM4313 0x4313
#define BCMA_CHIP_ID_BCM43142 43142
#define BCMA_CHIP_ID_BCM43131 43131
#define BCMA_CHIP_ID_BCM43217 43217
#define BCMA_CHIP_ID_BCM43222 43222
#define BCMA_CHIP_ID_BCM43224 43224
#define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8
#define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa
#define BCMA_CHIP_ID_BCM43225 43225
#define BCMA_CHIP_ID_BCM43227 43227
#define BCMA_CHIP_ID_BCM43228 43228
#define BCMA_CHIP_ID_BCM43421 43421
#define BCMA_CHIP_ID_BCM43428 43428
#define BCMA_CHIP_ID_BCM43431 43431
#define BCMA_CHIP_ID_BCM43460 43460
#define BCMA_CHIP_ID_BCM4331 0x4331
#define BCMA_CHIP_ID_BCM6362 0x6362
#define BCMA_CHIP_ID_BCM4360 0x4360
#define BCMA_CHIP_ID_BCM4352 0x4352
/* Chip IDs of SoCs */
#define BCMA_CHIP_ID_BCM4706 0x5300
#define BCMA_PKG_ID_BCM4706L 1
#define BCMA_CHIP_ID_BCM4716 0x4716
#define BCMA_PKG_ID_BCM4716 8
#define BCMA_PKG_ID_BCM4717 9
#define BCMA_PKG_ID_BCM4718 10
#define BCMA_CHIP_ID_BCM47162 47162
#define BCMA_CHIP_ID_BCM4748 0x4748
#define BCMA_CHIP_ID_BCM4749 0x4749
#define BCMA_CHIP_ID_BCM5356 0x5356
#define BCMA_CHIP_ID_BCM5357 0x5357
#define BCMA_PKG_ID_BCM5358 9
#define BCMA_PKG_ID_BCM47186 10
#define BCMA_PKG_ID_BCM5357 11
#define BCMA_CHIP_ID_BCM53572 53572
#define BCMA_PKG_ID_BCM47188 9
#define BCMA_CHIP_ID_BCM4707 53010
#define BCMA_PKG_ID_BCM4707 1
#define BCMA_PKG_ID_BCM4708 2
#define BCMA_PKG_ID_BCM4709 0
#define BCMA_CHIP_ID_BCM47094 53030
#define BCMA_CHIP_ID_BCM53018 53018
#define BCMA_CHIP_ID_BCM53573 53573
#define BCMA_PKG_ID_BCM53573 0
#define BCMA_PKG_ID_BCM47189 1
/* Board types (on PCI usually equals to the subsystem dev id) */
/* BCM4313 */
#define BCMA_BOARD_TYPE_BCM94313BU 0X050F
#define BCMA_BOARD_TYPE_BCM94313HM 0X0510
#define BCMA_BOARD_TYPE_BCM94313EPA 0X0511
#define BCMA_BOARD_TYPE_BCM94313HMG 0X051C
/* BCM4716 */
#define BCMA_BOARD_TYPE_BCM94716NR2 0X04CD
/* BCM43224 */
#define BCMA_BOARD_TYPE_BCM943224X21 0X056E
#define BCMA_BOARD_TYPE_BCM943224X21_FCC 0X00D1
#define BCMA_BOARD_TYPE_BCM943224X21B 0X00E9
#define BCMA_BOARD_TYPE_BCM943224M93 0X008B
#define BCMA_BOARD_TYPE_BCM943224M93A 0X0090
#define BCMA_BOARD_TYPE_BCM943224X16 0X0093
#define BCMA_BOARD_TYPE_BCM94322X9 0X008D
#define BCMA_BOARD_TYPE_BCM94322M35E 0X008E
/* BCM43228 */
#define BCMA_BOARD_TYPE_BCM943228BU8 0X0540
#define BCMA_BOARD_TYPE_BCM943228BU9 0X0541
#define BCMA_BOARD_TYPE_BCM943228BU 0X0542
#define BCMA_BOARD_TYPE_BCM943227HM4L 0X0543
#define BCMA_BOARD_TYPE_BCM943227HMB 0X0544
#define BCMA_BOARD_TYPE_BCM943228HM4L 0X0545
#define BCMA_BOARD_TYPE_BCM943228SD 0X0573
/* BCM4331 */
#define BCMA_BOARD_TYPE_BCM94331X19 0X00D6
#define BCMA_BOARD_TYPE_BCM94331X28 0X00E4
#define BCMA_BOARD_TYPE_BCM94331X28B 0X010E
#define BCMA_BOARD_TYPE_BCM94331PCIEBT3AX 0X00E4
#define BCMA_BOARD_TYPE_BCM94331X12_2G 0X00EC
#define BCMA_BOARD_TYPE_BCM94331X12_5G 0X00ED
#define BCMA_BOARD_TYPE_BCM94331X29B 0X00EF
#define BCMA_BOARD_TYPE_BCM94331CSAX 0X00EF
#define BCMA_BOARD_TYPE_BCM94331X19C 0X00F5
#define BCMA_BOARD_TYPE_BCM94331X33 0X00F4
#define BCMA_BOARD_TYPE_BCM94331BU 0X0523
#define BCMA_BOARD_TYPE_BCM94331S9BU 0X0524
#define BCMA_BOARD_TYPE_BCM94331MC 0X0525
#define BCMA_BOARD_TYPE_BCM94331MCI 0X0526
#define BCMA_BOARD_TYPE_BCM94331PCIEBT4 0X0527
#define BCMA_BOARD_TYPE_BCM94331HM 0X0574
#define BCMA_BOARD_TYPE_BCM94331PCIEDUAL 0X059B
#define BCMA_BOARD_TYPE_BCM94331MCH5 0X05A9
#define BCMA_BOARD_TYPE_BCM94331CS 0X05C6
#define BCMA_BOARD_TYPE_BCM94331CD 0X05DA
/* BCM53572 */
#define BCMA_BOARD_TYPE_BCM953572BU 0X058D
#define BCMA_BOARD_TYPE_BCM953572NR2 0X058E
#define BCMA_BOARD_TYPE_BCM947188NR2 0X058F
#define BCMA_BOARD_TYPE_BCM953572SDRNR2 0X0590
/* BCM43142 */
#define BCMA_BOARD_TYPE_BCM943142HM 0X05E0
struct bcma_device {
struct bcma_bus *bus;
struct bcma_device_id id;
struct device dev;
struct device *dma_dev;
unsigned int irq;
bool dev_registered;
u8 core_index;
u8 core_unit;
u32 addr;
u32 addr_s[8];
u32 wrap;
void __iomem *io_addr;
void __iomem *io_wrap;
void *drvdata;
struct list_head list;
};
static inline void *bcma_get_drvdata(struct bcma_device *core)
{
return core->drvdata;
}
static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
{
core->drvdata = drvdata;
}
struct bcma_driver {
const char *name;
const struct bcma_device_id *id_table;
int (*probe)(struct bcma_device *dev);
void (*remove)(struct bcma_device *dev);
int (*suspend)(struct bcma_device *dev);
int (*resume)(struct bcma_device *dev);
void (*shutdown)(struct bcma_device *dev);
struct device_driver drv;
};
extern
int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
#define bcma_driver_register(drv) \
__bcma_driver_register(drv, THIS_MODULE)
extern void bcma_driver_unregister(struct bcma_driver *drv);
/* module_bcma_driver() - Helper macro for drivers that don't do
* anything special in module init/exit. This eliminates a lot of
* boilerplate. Each module may only use this macro once, and
* calling it replaces module_init() and module_exit()
*/
#define module_bcma_driver(__bcma_driver) \
module_driver(__bcma_driver, bcma_driver_register, \
bcma_driver_unregister)
/* Set a fallback SPROM.
* See kdoc at the function definition for complete documentation. */
extern int bcma_arch_register_fallback_sprom(
int (*sprom_callback)(struct bcma_bus *bus,
struct ssb_sprom *out));
struct bcma_bus {
struct device *dev;
/* The MMIO area. */
void __iomem *mmio;
const struct bcma_host_ops *ops;
enum bcma_hosttype hosttype;
bool host_is_pcie2; /* Used for BCMA_HOSTTYPE_PCI only */
struct pci_dev *host_pci; /* PCI bus pointer (BCMA_HOSTTYPE_PCI only) */
struct bcma_chipinfo chipinfo;
struct bcma_boardinfo boardinfo;
struct bcma_device *mapped_core;
struct list_head cores;
u8 nr_cores;
u8 num;
struct bcma_drv_cc drv_cc;
struct bcma_drv_cc_b drv_cc_b;
struct bcma_drv_pci drv_pci[2];
struct bcma_drv_pcie2 drv_pcie2;
struct bcma_drv_mips drv_mips;
struct bcma_drv_gmac_cmn drv_gmac_cmn;
/* We decided to share SPROM struct with SSB as long as we do not need
* any hacks for BCMA. This simplifies drivers code. */
struct ssb_sprom sprom;
};
static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
{
return core->bus->ops->read8(core, offset);
}
static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
{
return core->bus->ops->read16(core, offset);
}
static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
{
return core->bus->ops->read32(core, offset);
}
static inline
void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
{
core->bus->ops->write8(core, offset, value);
}
static inline
void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
{
core->bus->ops->write16(core, offset, value);
}
static inline
void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
{
core->bus->ops->write32(core, offset, value);
}
#ifdef CONFIG_BCMA_BLOCKIO
static inline void bcma_block_read(struct bcma_device *core, void *buffer,
size_t count, u16 offset, u8 reg_width)
{
core->bus->ops->block_read(core, buffer, count, offset, reg_width);
}
static inline void bcma_block_write(struct bcma_device *core,
const void *buffer, size_t count,
u16 offset, u8 reg_width)
{
core->bus->ops->block_write(core, buffer, count, offset, reg_width);
}
#endif
static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
{
return core->bus->ops->aread32(core, offset);
}
static inline
void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
{
core->bus->ops->awrite32(core, offset, value);
}
static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
{
bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
}
static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
{
bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
}
static inline void bcma_maskset32(struct bcma_device *cc,
u16 offset, u32 mask, u32 set)
{
bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
}
static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
{
bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
}
static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
{
bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
}
static inline void bcma_maskset16(struct bcma_device *cc,
u16 offset, u16 mask, u16 set)
{
bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
}
extern struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
u8 unit);
static inline struct bcma_device *bcma_find_core(struct bcma_bus *bus,
u16 coreid)
{
return bcma_find_core_unit(bus, coreid, 0);
}
#ifdef CONFIG_BCMA_HOST_PCI
extern void bcma_host_pci_up(struct bcma_bus *bus);
extern void bcma_host_pci_down(struct bcma_bus *bus);
extern int bcma_host_pci_irq_ctl(struct bcma_bus *bus,
struct bcma_device *core, bool enable);
#else
static inline void bcma_host_pci_up(struct bcma_bus *bus)
{
}
static inline void bcma_host_pci_down(struct bcma_bus *bus)
{
}
static inline int bcma_host_pci_irq_ctl(struct bcma_bus *bus,
struct bcma_device *core, bool enable)
{
if (bus->hosttype == BCMA_HOSTTYPE_PCI)
return -ENOTSUPP;
return 0;
}
#endif
extern bool bcma_core_is_enabled(struct bcma_device *core);
extern void bcma_core_disable(struct bcma_device *core, u32 flags);
extern int bcma_core_enable(struct bcma_device *core, u32 flags);
extern void bcma_core_set_clockmode(struct bcma_device *core,
enum bcma_clkmode clkmode);
extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
bool on);
extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset);
#define BCMA_DMA_TRANSLATION_MASK 0xC0000000
#define BCMA_DMA_TRANSLATION_NONE 0x00000000
#define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */
#define BCMA_DMA_TRANSLATION_DMA64_CMT 0x80000000 /* Client Mode Translation for 64-bit DMA */
extern u32 bcma_core_dma_translation(struct bcma_device *core);
extern unsigned int bcma_core_irq(struct bcma_device *core, int num);
#endif /* LINUX_BCMA_H_ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_BCMA_DRIVER_ARM_C9_H_
#define LINUX_BCMA_DRIVER_ARM_C9_H_
/* DMU (Device Management Unit) */
#define BCMA_DMU_CRU_USB2_CONTROL 0x0164
#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_MASK 0x00000FFC
#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_NDIV_SHIFT 2
#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_MASK 0x00007000
#define BCMA_DMU_CRU_USB2_CONTROL_USB_PLL_PDIV_SHIFT 12
#define BCMA_DMU_CRU_CLKSET_KEY 0x0180
#define BCMA_DMU_CRU_STRAPS_CTRL 0x02A0
#define BCMA_DMU_CRU_STRAPS_CTRL_USB3 0x00000010
#define BCMA_DMU_CRU_STRAPS_CTRL_4BYTE 0x00008000
#endif /* LINUX_BCMA_DRIVER_ARM_C9_H_ */
@@ -0,0 +1,722 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LINUX_BCMA_DRIVER_CC_H_
#define LINUX_BCMA_DRIVER_CC_H_
#include <linux/platform_device.h>
#include <linux/platform_data/brcmnand.h>
#include <linux/gpio/driver.h>
/** ChipCommon core registers. **/
#define BCMA_CC_ID 0x0000
#define BCMA_CC_ID_ID 0x0000FFFF
#define BCMA_CC_ID_ID_SHIFT 0
#define BCMA_CC_ID_REV 0x000F0000
#define BCMA_CC_ID_REV_SHIFT 16
#define BCMA_CC_ID_PKG 0x00F00000
#define BCMA_CC_ID_PKG_SHIFT 20
#define BCMA_CC_ID_NRCORES 0x0F000000
#define BCMA_CC_ID_NRCORES_SHIFT 24
#define BCMA_CC_ID_TYPE 0xF0000000
#define BCMA_CC_ID_TYPE_SHIFT 28
#define BCMA_CC_CAP 0x0004 /* Capabilities */
#define BCMA_CC_CAP_NRUART 0x00000003 /* # of UARTs */
#define BCMA_CC_CAP_MIPSEB 0x00000004 /* MIPS in BigEndian Mode */
#define BCMA_CC_CAP_UARTCLK 0x00000018 /* UART clock select */
#define BCMA_CC_CAP_UARTCLK_INT 0x00000008 /* UARTs are driven by internal divided clock */
#define BCMA_CC_CAP_UARTGPIO 0x00000020 /* UARTs on GPIO 15-12 */
#define BCMA_CC_CAP_EXTBUS 0x000000C0 /* External buses present */
#define BCMA_CC_CAP_FLASHT 0x00000700 /* Flash Type */
#define BCMA_CC_FLASHT_NONE 0x00000000 /* No flash */
#define BCMA_CC_FLASHT_STSER 0x00000100 /* ST serial flash */
#define BCMA_CC_FLASHT_ATSER 0x00000200 /* Atmel serial flash */
#define BCMA_CC_FLASHT_NAND 0x00000300 /* NAND flash */
#define BCMA_CC_FLASHT_PARA 0x00000700 /* Parallel flash */
#define BCMA_CC_CAP_PLLT 0x00038000 /* PLL Type */
#define BCMA_PLLTYPE_NONE 0x00000000
#define BCMA_PLLTYPE_1 0x00010000 /* 48Mhz base, 3 dividers */
#define BCMA_PLLTYPE_2 0x00020000 /* 48Mhz, 4 dividers */
#define BCMA_PLLTYPE_3 0x00030000 /* 25Mhz, 2 dividers */
#define BCMA_PLLTYPE_4 0x00008000 /* 48Mhz, 4 dividers */
#define BCMA_PLLTYPE_5 0x00018000 /* 25Mhz, 4 dividers */
#define BCMA_PLLTYPE_6 0x00028000 /* 100/200 or 120/240 only */
#define BCMA_PLLTYPE_7 0x00038000 /* 25Mhz, 4 dividers */
#define BCMA_CC_CAP_PCTL 0x00040000 /* Power Control */
#define BCMA_CC_CAP_OTPS 0x00380000 /* OTP size */
#define BCMA_CC_CAP_OTPS_SHIFT 19
#define BCMA_CC_CAP_OTPS_BASE 5
#define BCMA_CC_CAP_JTAGM 0x00400000 /* JTAG master present */
#define BCMA_CC_CAP_BROM 0x00800000 /* Internal boot ROM active */
#define BCMA_CC_CAP_64BIT 0x08000000 /* 64-bit Backplane */
#define BCMA_CC_CAP_PMU 0x10000000 /* PMU available (rev >= 20) */
#define BCMA_CC_CAP_ECI 0x20000000 /* ECI available (rev >= 20) */
#define BCMA_CC_CAP_SPROM 0x40000000 /* SPROM present */
#define BCMA_CC_CAP_NFLASH 0x80000000 /* NAND flash present (rev >= 35 or BCM4706?) */
#define BCMA_CC_CORECTL 0x0008
#define BCMA_CC_CORECTL_UARTCLK0 0x00000001 /* Drive UART with internal clock */
#define BCMA_CC_CORECTL_SE 0x00000002 /* sync clk out enable (corerev >= 3) */
#define BCMA_CC_CORECTL_UARTCLKEN 0x00000008 /* UART clock enable (rev >= 21) */
#define BCMA_CC_BIST 0x000C
#define BCMA_CC_OTPS 0x0010 /* OTP status */
#define BCMA_CC_OTPS_PROGFAIL 0x80000000
#define BCMA_CC_OTPS_PROTECT 0x00000007
#define BCMA_CC_OTPS_HW_PROTECT 0x00000001
#define BCMA_CC_OTPS_SW_PROTECT 0x00000002
#define BCMA_CC_OTPS_CID_PROTECT 0x00000004
#define BCMA_CC_OTPS_GU_PROG_IND 0x00000F00 /* General Use programmed indication */
#define BCMA_CC_OTPS_GU_PROG_IND_SHIFT 8
#define BCMA_CC_OTPS_GU_PROG_HW 0x00000100 /* HW region programmed */
#define BCMA_CC_OTPC 0x0014 /* OTP control */
#define BCMA_CC_OTPC_RECWAIT 0xFF000000
#define BCMA_CC_OTPC_PROGWAIT 0x00FFFF00
#define BCMA_CC_OTPC_PRW_SHIFT 8
#define BCMA_CC_OTPC_MAXFAIL 0x00000038
#define BCMA_CC_OTPC_VSEL 0x00000006
#define BCMA_CC_OTPC_SELVL 0x00000001
#define BCMA_CC_OTPP 0x0018 /* OTP prog */
#define BCMA_CC_OTPP_COL 0x000000FF
#define BCMA_CC_OTPP_ROW 0x0000FF00
#define BCMA_CC_OTPP_ROW_SHIFT 8
#define BCMA_CC_OTPP_READERR 0x10000000
#define BCMA_CC_OTPP_VALUE 0x20000000
#define BCMA_CC_OTPP_READ 0x40000000
#define BCMA_CC_OTPP_START 0x80000000
#define BCMA_CC_OTPP_BUSY 0x80000000
#define BCMA_CC_OTPL 0x001C /* OTP layout */
#define BCMA_CC_OTPL_GURGN_OFFSET 0x00000FFF /* offset of general use region */
#define BCMA_CC_IRQSTAT 0x0020
#define BCMA_CC_IRQMASK 0x0024
#define BCMA_CC_IRQ_GPIO 0x00000001 /* gpio intr */
#define BCMA_CC_IRQ_EXT 0x00000002 /* ro: ext intr pin (corerev >= 3) */
#define BCMA_CC_IRQ_WDRESET 0x80000000 /* watchdog reset occurred */
#define BCMA_CC_CHIPCTL 0x0028 /* Rev >= 11 only */
#define BCMA_CC_CHIPSTAT 0x002C /* Rev >= 11 only */
#define BCMA_CC_CHIPST_4313_SPROM_PRESENT 1
#define BCMA_CC_CHIPST_4313_OTP_PRESENT 2
#define BCMA_CC_CHIPST_4331_SPROM_PRESENT 2
#define BCMA_CC_CHIPST_4331_OTP_PRESENT 4
#define BCMA_CC_CHIPST_43228_ILP_DIV_EN 0x00000001
#define BCMA_CC_CHIPST_43228_OTP_PRESENT 0x00000002
#define BCMA_CC_CHIPST_43228_SERDES_REFCLK_PADSEL 0x00000004
#define BCMA_CC_CHIPST_43228_SDIO_MODE 0x00000008
#define BCMA_CC_CHIPST_43228_SDIO_OTP_PRESENT 0x00000010
#define BCMA_CC_CHIPST_43228_SDIO_RESET 0x00000020
#define BCMA_CC_CHIPST_4706_PKG_OPTION BIT(0) /* 0: full-featured package 1: low-cost package */
#define BCMA_CC_CHIPST_4706_SFLASH_PRESENT BIT(1) /* 0: parallel, 1: serial flash is present */
#define BCMA_CC_CHIPST_4706_SFLASH_TYPE BIT(2) /* 0: 8b-p/ST-s flash, 1: 16b-p/Atmal-s flash */
#define BCMA_CC_CHIPST_4706_MIPS_BENDIAN BIT(3) /* 0: little, 1: big endian */
#define BCMA_CC_CHIPST_4706_PCIE1_DISABLE BIT(5) /* PCIE1 enable strap pin */
#define BCMA_CC_CHIPST_5357_NAND_BOOT BIT(4) /* NAND boot, valid for CC rev 38 and/or BCM5357 */
#define BCMA_CC_CHIPST_4360_XTAL_40MZ 0x00000001
#define BCMA_CC_JCMD 0x0030 /* Rev >= 10 only */
#define BCMA_CC_JCMD_START 0x80000000
#define BCMA_CC_JCMD_BUSY 0x80000000
#define BCMA_CC_JCMD_PAUSE 0x40000000
#define BCMA_CC_JCMD0_ACC_MASK 0x0000F000
#define BCMA_CC_JCMD0_ACC_IRDR 0x00000000
#define BCMA_CC_JCMD0_ACC_DR 0x00001000
#define BCMA_CC_JCMD0_ACC_IR 0x00002000
#define BCMA_CC_JCMD0_ACC_RESET 0x00003000
#define BCMA_CC_JCMD0_ACC_IRPDR 0x00004000
#define BCMA_CC_JCMD0_ACC_PDR 0x00005000
#define BCMA_CC_JCMD0_IRW_MASK 0x00000F00
#define BCMA_CC_JCMD_ACC_MASK 0x000F0000 /* Changes for corerev 11 */
#define BCMA_CC_JCMD_ACC_IRDR 0x00000000
#define BCMA_CC_JCMD_ACC_DR 0x00010000
#define BCMA_CC_JCMD_ACC_IR 0x00020000
#define BCMA_CC_JCMD_ACC_RESET 0x00030000
#define BCMA_CC_JCMD_ACC_IRPDR 0x00040000
#define BCMA_CC_JCMD_ACC_PDR 0x00050000
#define BCMA_CC_JCMD_IRW_MASK 0x00001F00
#define BCMA_CC_JCMD_IRW_SHIFT 8
#define BCMA_CC_JCMD_DRW_MASK 0x0000003F
#define BCMA_CC_JIR 0x0034 /* Rev >= 10 only */
#define BCMA_CC_JDR 0x0038 /* Rev >= 10 only */
#define BCMA_CC_JCTL 0x003C /* Rev >= 10 only */
#define BCMA_CC_JCTL_FORCE_CLK 4 /* Force clock */
#define BCMA_CC_JCTL_EXT_EN 2 /* Enable external targets */
#define BCMA_CC_JCTL_EN 1 /* Enable Jtag master */
#define BCMA_CC_FLASHCTL 0x0040
/* Start/busy bit in flashcontrol */
#define BCMA_CC_FLASHCTL_OPCODE 0x000000ff
#define BCMA_CC_FLASHCTL_ACTION 0x00000700
#define BCMA_CC_FLASHCTL_CS_ACTIVE 0x00001000 /* Chip Select Active, rev >= 20 */
#define BCMA_CC_FLASHCTL_START 0x80000000
#define BCMA_CC_FLASHCTL_BUSY BCMA_CC_FLASHCTL_START
/* Flashcontrol action + opcodes for ST flashes */
#define BCMA_CC_FLASHCTL_ST_WREN 0x0006 /* Write Enable */
#define BCMA_CC_FLASHCTL_ST_WRDIS 0x0004 /* Write Disable */
#define BCMA_CC_FLASHCTL_ST_RDSR 0x0105 /* Read Status Register */
#define BCMA_CC_FLASHCTL_ST_WRSR 0x0101 /* Write Status Register */
#define BCMA_CC_FLASHCTL_ST_READ 0x0303 /* Read Data Bytes */
#define BCMA_CC_FLASHCTL_ST_PP 0x0302 /* Page Program */
#define BCMA_CC_FLASHCTL_ST_SE 0x02d8 /* Sector Erase */
#define BCMA_CC_FLASHCTL_ST_BE 0x00c7 /* Bulk Erase */
#define BCMA_CC_FLASHCTL_ST_DP 0x00b9 /* Deep Power-down */
#define BCMA_CC_FLASHCTL_ST_RES 0x03ab /* Read Electronic Signature */
#define BCMA_CC_FLASHCTL_ST_CSA 0x1000 /* Keep chip select asserted */
#define BCMA_CC_FLASHCTL_ST_SSE 0x0220 /* Sub-sector Erase */
/* Flashcontrol action + opcodes for Atmel flashes */
#define BCMA_CC_FLASHCTL_AT_READ 0x07e8
#define BCMA_CC_FLASHCTL_AT_PAGE_READ 0x07d2
#define BCMA_CC_FLASHCTL_AT_STATUS 0x01d7
#define BCMA_CC_FLASHCTL_AT_BUF1_WRITE 0x0384
#define BCMA_CC_FLASHCTL_AT_BUF2_WRITE 0x0387
#define BCMA_CC_FLASHCTL_AT_BUF1_ERASE_PROGRAM 0x0283
#define BCMA_CC_FLASHCTL_AT_BUF2_ERASE_PROGRAM 0x0286
#define BCMA_CC_FLASHCTL_AT_BUF1_PROGRAM 0x0288
#define BCMA_CC_FLASHCTL_AT_BUF2_PROGRAM 0x0289
#define BCMA_CC_FLASHCTL_AT_PAGE_ERASE 0x0281
#define BCMA_CC_FLASHCTL_AT_BLOCK_ERASE 0x0250
#define BCMA_CC_FLASHCTL_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382
#define BCMA_CC_FLASHCTL_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385
#define BCMA_CC_FLASHCTL_AT_BUF1_LOAD 0x0253
#define BCMA_CC_FLASHCTL_AT_BUF2_LOAD 0x0255
#define BCMA_CC_FLASHCTL_AT_BUF1_COMPARE 0x0260
#define BCMA_CC_FLASHCTL_AT_BUF2_COMPARE 0x0261
#define BCMA_CC_FLASHCTL_AT_BUF1_REPROGRAM 0x0258
#define BCMA_CC_FLASHCTL_AT_BUF2_REPROGRAM 0x0259
#define BCMA_CC_FLASHADDR 0x0044
#define BCMA_CC_FLASHDATA 0x0048
/* Status register bits for ST flashes */
#define BCMA_CC_FLASHDATA_ST_WIP 0x01 /* Write In Progress */
#define BCMA_CC_FLASHDATA_ST_WEL 0x02 /* Write Enable Latch */
#define BCMA_CC_FLASHDATA_ST_BP_MASK 0x1c /* Block Protect */
#define BCMA_CC_FLASHDATA_ST_BP_SHIFT 2
#define BCMA_CC_FLASHDATA_ST_SRWD 0x80 /* Status Register Write Disable */
/* Status register bits for Atmel flashes */
#define BCMA_CC_FLASHDATA_AT_READY 0x80
#define BCMA_CC_FLASHDATA_AT_MISMATCH 0x40
#define BCMA_CC_FLASHDATA_AT_ID_MASK 0x38
#define BCMA_CC_FLASHDATA_AT_ID_SHIFT 3
#define BCMA_CC_BCAST_ADDR 0x0050
#define BCMA_CC_BCAST_DATA 0x0054
#define BCMA_CC_GPIOPULLUP 0x0058 /* Rev >= 20 only */
#define BCMA_CC_GPIOPULLDOWN 0x005C /* Rev >= 20 only */
#define BCMA_CC_GPIOIN 0x0060
#define BCMA_CC_GPIOOUT 0x0064
#define BCMA_CC_GPIOOUTEN 0x0068
#define BCMA_CC_GPIOCTL 0x006C
#define BCMA_CC_GPIOPOL 0x0070
#define BCMA_CC_GPIOIRQ 0x0074
#define BCMA_CC_WATCHDOG 0x0080
#define BCMA_CC_GPIOTIMER 0x0088 /* LED powersave (corerev >= 16) */
#define BCMA_CC_GPIOTIMER_OFFTIME 0x0000FFFF
#define BCMA_CC_GPIOTIMER_OFFTIME_SHIFT 0
#define BCMA_CC_GPIOTIMER_ONTIME 0xFFFF0000
#define BCMA_CC_GPIOTIMER_ONTIME_SHIFT 16
#define BCMA_CC_GPIOTOUTM 0x008C /* LED powersave (corerev >= 16) */
#define BCMA_CC_CLOCK_N 0x0090
#define BCMA_CC_CLOCK_SB 0x0094
#define BCMA_CC_CLOCK_PCI 0x0098
#define BCMA_CC_CLOCK_M2 0x009C
#define BCMA_CC_CLOCK_MIPS 0x00A0
#define BCMA_CC_CLKDIV 0x00A4 /* Rev >= 3 only */
#define BCMA_CC_CLKDIV_SFLASH 0x0F000000
#define BCMA_CC_CLKDIV_SFLASH_SHIFT 24
#define BCMA_CC_CLKDIV_OTP 0x000F0000
#define BCMA_CC_CLKDIV_OTP_SHIFT 16
#define BCMA_CC_CLKDIV_JTAG 0x00000F00
#define BCMA_CC_CLKDIV_JTAG_SHIFT 8
#define BCMA_CC_CLKDIV_UART 0x000000FF
#define BCMA_CC_CAP_EXT 0x00AC /* Capabilities */
#define BCMA_CC_CAP_EXT_SECI_PRESENT 0x00000001
#define BCMA_CC_CAP_EXT_GSIO_PRESENT 0x00000002
#define BCMA_CC_CAP_EXT_GCI_PRESENT 0x00000004
#define BCMA_CC_CAP_EXT_SECI_PUART_PRESENT 0x00000008 /* UART present */
#define BCMA_CC_CAP_EXT_AOB_PRESENT 0x00000040
#define BCMA_CC_PLLONDELAY 0x00B0 /* Rev >= 4 only */
#define BCMA_CC_FREFSELDELAY 0x00B4 /* Rev >= 4 only */
#define BCMA_CC_SLOWCLKCTL 0x00B8 /* 6 <= Rev <= 9 only */
#define BCMA_CC_SLOWCLKCTL_SRC 0x00000007 /* slow clock source mask */
#define BCMA_CC_SLOWCLKCTL_SRC_LPO 0x00000000 /* source of slow clock is LPO */
#define BCMA_CC_SLOWCLKCTL_SRC_XTAL 0x00000001 /* source of slow clock is crystal */
#define BCMA_CC_SLOECLKCTL_SRC_PCI 0x00000002 /* source of slow clock is PCI */
#define BCMA_CC_SLOWCLKCTL_LPOFREQ 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */
#define BCMA_CC_SLOWCLKCTL_LPOPD 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
#define BCMA_CC_SLOWCLKCTL_FSLOW 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
#define BCMA_CC_SLOWCLKCTL_IPLL 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
#define BCMA_CC_SLOWCLKCTL_ENXTAL 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
#define BCMA_CC_SLOWCLKCTL_XTALPU 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */
#define BCMA_CC_SLOWCLKCTL_CLKDIV 0xFFFF0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */
#define BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT 16
#define BCMA_CC_SYSCLKCTL 0x00C0 /* Rev >= 3 only */
#define BCMA_CC_SYSCLKCTL_IDLPEN 0x00000001 /* ILPen: Enable Idle Low Power */
#define BCMA_CC_SYSCLKCTL_ALPEN 0x00000002 /* ALPen: Enable Active Low Power */
#define BCMA_CC_SYSCLKCTL_PLLEN 0x00000004 /* ForcePLLOn */
#define BCMA_CC_SYSCLKCTL_FORCEALP 0x00000008 /* Force ALP (or HT if ALPen is not set */
#define BCMA_CC_SYSCLKCTL_FORCEHT 0x00000010 /* Force HT */
#define BCMA_CC_SYSCLKCTL_CLKDIV 0xFFFF0000 /* ClkDiv (ILP = 1/(4+divisor)) */
#define BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT 16
#define BCMA_CC_CLKSTSTR 0x00C4 /* Rev >= 3 only */
#define BCMA_CC_EROM 0x00FC
#define BCMA_CC_PCMCIA_CFG 0x0100
#define BCMA_CC_PCMCIA_MEMWAIT 0x0104
#define BCMA_CC_PCMCIA_ATTRWAIT 0x0108
#define BCMA_CC_PCMCIA_IOWAIT 0x010C
#define BCMA_CC_IDE_CFG 0x0110
#define BCMA_CC_IDE_MEMWAIT 0x0114
#define BCMA_CC_IDE_ATTRWAIT 0x0118
#define BCMA_CC_IDE_IOWAIT 0x011C
#define BCMA_CC_PROG_CFG 0x0120
#define BCMA_CC_PROG_WAITCNT 0x0124
#define BCMA_CC_FLASH_CFG 0x0128
#define BCMA_CC_FLASH_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */
#define BCMA_CC_FLASH_WAITCNT 0x012C
#define BCMA_CC_SROM_CONTROL 0x0190
#define BCMA_CC_SROM_CONTROL_START 0x80000000
#define BCMA_CC_SROM_CONTROL_BUSY 0x80000000
#define BCMA_CC_SROM_CONTROL_OPCODE 0x60000000
#define BCMA_CC_SROM_CONTROL_OP_READ 0x00000000
#define BCMA_CC_SROM_CONTROL_OP_WRITE 0x20000000
#define BCMA_CC_SROM_CONTROL_OP_WRDIS 0x40000000
#define BCMA_CC_SROM_CONTROL_OP_WREN 0x60000000
#define BCMA_CC_SROM_CONTROL_OTPSEL 0x00000010
#define BCMA_CC_SROM_CONTROL_OTP_PRESENT 0x00000020
#define BCMA_CC_SROM_CONTROL_LOCK 0x00000008
#define BCMA_CC_SROM_CONTROL_SIZE_MASK 0x00000006
#define BCMA_CC_SROM_CONTROL_SIZE_1K 0x00000000
#define BCMA_CC_SROM_CONTROL_SIZE_4K 0x00000002
#define BCMA_CC_SROM_CONTROL_SIZE_16K 0x00000004
#define BCMA_CC_SROM_CONTROL_SIZE_SHIFT 1
#define BCMA_CC_SROM_CONTROL_PRESENT 0x00000001
/* Block 0x140 - 0x190 registers are chipset specific */
#define BCMA_CC_4706_FLASHSCFG 0x18C /* Flash struct configuration */
#define BCMA_CC_4706_FLASHSCFG_MASK 0x000000ff
#define BCMA_CC_4706_FLASHSCFG_SF1 0x00000001 /* 2nd serial flash present */
#define BCMA_CC_4706_FLASHSCFG_PF1 0x00000002 /* 2nd parallel flash present */
#define BCMA_CC_4706_FLASHSCFG_SF1_TYPE 0x00000004 /* 2nd serial flash type : 0 : ST, 1 : Atmel */
#define BCMA_CC_4706_FLASHSCFG_NF1 0x00000008 /* 2nd NAND flash present */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_MASK 0x000000f0
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_4MB 0x00000010 /* 4MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_8MB 0x00000020 /* 8MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_16MB 0x00000030 /* 16MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_32MB 0x00000040 /* 32MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_64MB 0x00000050 /* 64MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_128MB 0x00000060 /* 128MB */
#define BCMA_CC_4706_FLASHSCFG_1ST_MADDR_SEG_256MB 0x00000070 /* 256MB */
/* NAND flash registers for BCM4706 (corerev = 31) */
#define BCMA_CC_NFLASH_CTL 0x01A0
#define BCMA_CC_NFLASH_CTL_ERR 0x08000000
#define BCMA_CC_NFLASH_CONF 0x01A4
#define BCMA_CC_NFLASH_COL_ADDR 0x01A8
#define BCMA_CC_NFLASH_ROW_ADDR 0x01AC
#define BCMA_CC_NFLASH_DATA 0x01B0
#define BCMA_CC_NFLASH_WAITCNT0 0x01B4
/* 0x1E0 is defined as shared BCMA_CLKCTLST */
#define BCMA_CC_HW_WORKAROUND 0x01E4 /* Hardware workaround (rev >= 20) */
#define BCMA_CC_UART0_DATA 0x0300
#define BCMA_CC_UART0_IMR 0x0304
#define BCMA_CC_UART0_FCR 0x0308
#define BCMA_CC_UART0_LCR 0x030C
#define BCMA_CC_UART0_MCR 0x0310
#define BCMA_CC_UART0_LSR 0x0314
#define BCMA_CC_UART0_MSR 0x0318
#define BCMA_CC_UART0_SCRATCH 0x031C
#define BCMA_CC_UART1_DATA 0x0400
#define BCMA_CC_UART1_IMR 0x0404
#define BCMA_CC_UART1_FCR 0x0408
#define BCMA_CC_UART1_LCR 0x040C
#define BCMA_CC_UART1_MCR 0x0410
#define BCMA_CC_UART1_LSR 0x0414
#define BCMA_CC_UART1_MSR 0x0418
#define BCMA_CC_UART1_SCRATCH 0x041C
/* PMU registers (rev >= 20) */
#define BCMA_CC_PMU_CTL 0x0600 /* PMU control */
#define BCMA_CC_PMU_CTL_ILP_DIV 0xFFFF0000 /* ILP div mask */
#define BCMA_CC_PMU_CTL_ILP_DIV_SHIFT 16
#define BCMA_CC_PMU_CTL_RES 0x00006000 /* reset control mask */
#define BCMA_CC_PMU_CTL_RES_SHIFT 13
#define BCMA_CC_PMU_CTL_RES_RELOAD 0x2 /* reload POR values */
#define BCMA_CC_PMU_CTL_PLL_UPD 0x00000400
#define BCMA_CC_PMU_CTL_NOILPONW 0x00000200 /* No ILP on wait */
#define BCMA_CC_PMU_CTL_HTREQEN 0x00000100 /* HT req enable */
#define BCMA_CC_PMU_CTL_ALPREQEN 0x00000080 /* ALP req enable */
#define BCMA_CC_PMU_CTL_XTALFREQ 0x0000007C /* Crystal freq */
#define BCMA_CC_PMU_CTL_XTALFREQ_SHIFT 2
#define BCMA_CC_PMU_CTL_ILPDIVEN 0x00000002 /* ILP div enable */
#define BCMA_CC_PMU_CTL_LPOSEL 0x00000001 /* LPO sel */
#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
#define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100
#define BCMA_CC_PMU_STAT_WDRESET 0x00000080
#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
#define BCMA_CC_PMU_STAT_HAVEHT 0x00000004 /* HT available */
#define BCMA_CC_PMU_STAT_RESINIT 0x00000003 /* Res init */
#define BCMA_CC_PMU_RES_STAT 0x060C /* PMU res status */
#define BCMA_CC_PMU_RES_PEND 0x0610 /* PMU res pending */
#define BCMA_CC_PMU_TIMER 0x0614 /* PMU timer */
#define BCMA_CC_PMU_MINRES_MSK 0x0618 /* PMU min res mask */
#define BCMA_CC_PMU_MAXRES_MSK 0x061C /* PMU max res mask */
#define BCMA_CC_PMU_RES_TABSEL 0x0620 /* PMU res table sel */
#define BCMA_CC_PMU_RES_DEPMSK 0x0624 /* PMU res dep mask */
#define BCMA_CC_PMU_RES_UPDNTM 0x0628 /* PMU res updown timer */
#define BCMA_CC_PMU_RES_TIMER 0x062C /* PMU res timer */
#define BCMA_CC_PMU_CLKSTRETCH 0x0630 /* PMU clockstretch */
#define BCMA_CC_PMU_WATCHDOG 0x0634 /* PMU watchdog */
#define BCMA_CC_PMU_RES_REQTS 0x0640 /* PMU res req timer sel */
#define BCMA_CC_PMU_RES_REQT 0x0644 /* PMU res req timer */
#define BCMA_CC_PMU_RES_REQM 0x0648 /* PMU res req mask */
#define BCMA_CC_PMU_CHIPCTL_ADDR 0x0650
#define BCMA_CC_PMU_CHIPCTL_DATA 0x0654
#define BCMA_CC_PMU_REGCTL_ADDR 0x0658
#define BCMA_CC_PMU_REGCTL_DATA 0x065C
#define BCMA_CC_PMU_PLLCTL_ADDR 0x0660
#define BCMA_CC_PMU_PLLCTL_DATA 0x0664
#define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */
#define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */
#define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF
#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000
#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31
#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
/* NAND flash MLC controller registers (corerev >= 38) */
#define BCMA_CC_NAND_REVISION 0x0C00
#define BCMA_CC_NAND_CMD_START 0x0C04
#define BCMA_CC_NAND_CMD_ADDR_X 0x0C08
#define BCMA_CC_NAND_CMD_ADDR 0x0C0C
#define BCMA_CC_NAND_CMD_END_ADDR 0x0C10
#define BCMA_CC_NAND_CS_NAND_SELECT 0x0C14
#define BCMA_CC_NAND_CS_NAND_XOR 0x0C18
#define BCMA_CC_NAND_SPARE_RD0 0x0C20
#define BCMA_CC_NAND_SPARE_RD4 0x0C24
#define BCMA_CC_NAND_SPARE_RD8 0x0C28
#define BCMA_CC_NAND_SPARE_RD12 0x0C2C
#define BCMA_CC_NAND_SPARE_WR0 0x0C30
#define BCMA_CC_NAND_SPARE_WR4 0x0C34
#define BCMA_CC_NAND_SPARE_WR8 0x0C38
#define BCMA_CC_NAND_SPARE_WR12 0x0C3C
#define BCMA_CC_NAND_ACC_CONTROL 0x0C40
#define BCMA_CC_NAND_CONFIG 0x0C48
#define BCMA_CC_NAND_TIMING_1 0x0C50
#define BCMA_CC_NAND_TIMING_2 0x0C54
#define BCMA_CC_NAND_SEMAPHORE 0x0C58
#define BCMA_CC_NAND_DEVID 0x0C60
#define BCMA_CC_NAND_DEVID_X 0x0C64
#define BCMA_CC_NAND_BLOCK_LOCK_STATUS 0x0C68
#define BCMA_CC_NAND_INTFC_STATUS 0x0C6C
#define BCMA_CC_NAND_ECC_CORR_ADDR_X 0x0C70
#define BCMA_CC_NAND_ECC_CORR_ADDR 0x0C74
#define BCMA_CC_NAND_ECC_UNC_ADDR_X 0x0C78
#define BCMA_CC_NAND_ECC_UNC_ADDR 0x0C7C
#define BCMA_CC_NAND_READ_ERROR_COUNT 0x0C80
#define BCMA_CC_NAND_CORR_STAT_THRESHOLD 0x0C84
#define BCMA_CC_NAND_READ_ADDR_X 0x0C90
#define BCMA_CC_NAND_READ_ADDR 0x0C94
#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR_X 0x0C98
#define BCMA_CC_NAND_PAGE_PROGRAM_ADDR 0x0C9C
#define BCMA_CC_NAND_COPY_BACK_ADDR_X 0x0CA0
#define BCMA_CC_NAND_COPY_BACK_ADDR 0x0CA4
#define BCMA_CC_NAND_BLOCK_ERASE_ADDR_X 0x0CA8
#define BCMA_CC_NAND_BLOCK_ERASE_ADDR 0x0CAC
#define BCMA_CC_NAND_INV_READ_ADDR_X 0x0CB0
#define BCMA_CC_NAND_INV_READ_ADDR 0x0CB4
#define BCMA_CC_NAND_BLK_WR_PROTECT 0x0CC0
#define BCMA_CC_NAND_ACC_CONTROL_CS1 0x0CD0
#define BCMA_CC_NAND_CONFIG_CS1 0x0CD4
#define BCMA_CC_NAND_TIMING_1_CS1 0x0CD8
#define BCMA_CC_NAND_TIMING_2_CS1 0x0CDC
#define BCMA_CC_NAND_SPARE_RD16 0x0D30
#define BCMA_CC_NAND_SPARE_RD20 0x0D34
#define BCMA_CC_NAND_SPARE_RD24 0x0D38
#define BCMA_CC_NAND_SPARE_RD28 0x0D3C
#define BCMA_CC_NAND_CACHE_ADDR 0x0D40
#define BCMA_CC_NAND_CACHE_DATA 0x0D44
#define BCMA_CC_NAND_CTRL_CONFIG 0x0D48
#define BCMA_CC_NAND_CTRL_STATUS 0x0D4C
/* Divider allocation in 4716/47162/5356 */
#define BCMA_CC_PMU5_MAINPLL_CPU 1
#define BCMA_CC_PMU5_MAINPLL_MEM 2
#define BCMA_CC_PMU5_MAINPLL_SSB 3
/* PLL usage in 4716/47162 */
#define BCMA_CC_PMU4716_MAINPLL_PLL0 12
/* PLL usage in 5356/5357 */
#define BCMA_CC_PMU5356_MAINPLL_PLL0 0
#define BCMA_CC_PMU5357_MAINPLL_PLL0 0
/* 4706 PMU */
#define BCMA_CC_PMU4706_MAINPLL_PLL0 0
#define BCMA_CC_PMU6_4706_PROCPLL_OFF 4 /* The CPU PLL */
#define BCMA_CC_PMU6_4706_PROC_P2DIV_MASK 0x000f0000
#define BCMA_CC_PMU6_4706_PROC_P2DIV_SHIFT 16
#define BCMA_CC_PMU6_4706_PROC_P1DIV_MASK 0x0000f000
#define BCMA_CC_PMU6_4706_PROC_P1DIV_SHIFT 12
#define BCMA_CC_PMU6_4706_PROC_NDIV_INT_MASK 0x00000ff8
#define BCMA_CC_PMU6_4706_PROC_NDIV_INT_SHIFT 3
#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0
/* PMU rev 15 */
#define BCMA_CC_PMU15_PLL_PLLCTL0 0
#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003
#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0
#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC
#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2
#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000
#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22
#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000
#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24
#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000
#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27
#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000
#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30
#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000
#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31
/* ALP clock on pre-PMU chips */
#define BCMA_CC_PMU_ALP_CLOCK 20000000
/* HT clock for systems with PMU-enabled chipcommon */
#define BCMA_CC_PMU_HT_CLOCK 80000000
/* PMU rev 5 (& 6) */
#define BCMA_CC_PPL_P1P2_OFF 0
#define BCMA_CC_PPL_P1_MASK 0x0f000000
#define BCMA_CC_PPL_P1_SHIFT 24
#define BCMA_CC_PPL_P2_MASK 0x00f00000
#define BCMA_CC_PPL_P2_SHIFT 20
#define BCMA_CC_PPL_M14_OFF 1
#define BCMA_CC_PPL_MDIV_MASK 0x000000ff
#define BCMA_CC_PPL_MDIV_WIDTH 8
#define BCMA_CC_PPL_NM5_OFF 2
#define BCMA_CC_PPL_NDIV_MASK 0xfff00000
#define BCMA_CC_PPL_NDIV_SHIFT 20
#define BCMA_CC_PPL_FMAB_OFF 3
#define BCMA_CC_PPL_MRAT_MASK 0xf0000000
#define BCMA_CC_PPL_MRAT_SHIFT 28
#define BCMA_CC_PPL_ABRAT_MASK 0x08000000
#define BCMA_CC_PPL_ABRAT_SHIFT 27
#define BCMA_CC_PPL_FDIV_MASK 0x07ffffff
#define BCMA_CC_PPL_PLLCTL_OFF 4
#define BCMA_CC_PPL_PCHI_OFF 5
#define BCMA_CC_PPL_PCHI_MASK 0x0000003f
#define BCMA_CC_PMU_PLL_CTL0 0
#define BCMA_CC_PMU_PLL_CTL1 1
#define BCMA_CC_PMU_PLL_CTL2 2
#define BCMA_CC_PMU_PLL_CTL3 3
#define BCMA_CC_PMU_PLL_CTL4 4
#define BCMA_CC_PMU_PLL_CTL5 5
#define BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000
#define BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT 20
#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000
#define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20
#define BCMA_CCB_MII_MNG_CTL 0x0000
#define BCMA_CCB_MII_MNG_CMD_DATA 0x0004
/* BCM4331 ChipControl numbers. */
#define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */
#define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */
#define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */
#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */
#define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */
#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */
#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */
#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */
#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */
#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */
#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */
#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */
#define BCMA_CHIPCTL_4331_EXTPA_EN2 BIT(12) /* 0 ext pa disable, 1 ext pa enabled */
#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */
#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */
/* 43224 chip-specific ChipControl register bits */
#define BCMA_CCTRL_43224_GPIO_TOGGLE 0x8000 /* gpio[3:0] pins as btcoex or s/w gpio */
#define BCMA_CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */
#define BCMA_CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */
/* 4313 Chip specific ChipControl register bits */
#define BCMA_CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */
/* BCM5357 ChipControl register bits */
#define BCMA_CHIPCTL_5357_EXTPA BIT(14)
#define BCMA_CHIPCTL_5357_ANT_MUX_2O3 BIT(15)
#define BCMA_CHIPCTL_5357_NFLASH BIT(16)
#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18)
#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19)
#define BCMA_RES_4314_LPLDO_PU BIT(0)
#define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1)
#define BCMA_RES_4314_PMU_BG_PU BIT(2)
#define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3)
#define BCMA_RES_4314_CBUCK_PFM_PU BIT(4)
#define BCMA_RES_4314_CLDO_PU BIT(5)
#define BCMA_RES_4314_LPLDO2_LVM BIT(6)
#define BCMA_RES_4314_WL_PMU_PU BIT(7)
#define BCMA_RES_4314_LNLDO_PU BIT(8)
#define BCMA_RES_4314_LDO3P3_PU BIT(9)
#define BCMA_RES_4314_OTP_PU BIT(10)
#define BCMA_RES_4314_XTAL_PU BIT(11)
#define BCMA_RES_4314_WL_PWRSW_PU BIT(12)
#define BCMA_RES_4314_LQ_AVAIL BIT(13)
#define BCMA_RES_4314_LOGIC_RET BIT(14)
#define BCMA_RES_4314_MEM_SLEEP BIT(15)
#define BCMA_RES_4314_MACPHY_RET BIT(16)
#define BCMA_RES_4314_WL_CORE_READY BIT(17)
#define BCMA_RES_4314_ILP_REQ BIT(18)
#define BCMA_RES_4314_ALP_AVAIL BIT(19)
#define BCMA_RES_4314_MISC_PWRSW_PU BIT(20)
#define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21)
#define BCMA_RES_4314_RX_PWRSW_PU BIT(22)
#define BCMA_RES_4314_RADIO_PU BIT(23)
#define BCMA_RES_4314_VCO_LDO_PU BIT(24)
#define BCMA_RES_4314_AFE_LDO_PU BIT(25)
#define BCMA_RES_4314_RX_LDO_PU BIT(26)
#define BCMA_RES_4314_TX_LDO_PU BIT(27)
#define BCMA_RES_4314_HT_AVAIL BIT(28)
#define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29)
/* Data for the PMU, if available.
* Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
*/
struct bcma_chipcommon_pmu {
struct bcma_device *core; /* Can be separated core or just ChipCommon one */
u8 rev; /* PMU revision */
u32 crystalfreq; /* The active crystal frequency (in kHz) */
};
#ifdef CONFIG_BCMA_PFLASH
struct bcma_pflash {
bool present;
};
#endif
#ifdef CONFIG_BCMA_SFLASH
struct mtd_info;
struct bcma_sflash {
bool present;
u32 blocksize;
u16 numblocks;
u32 size;
};
#endif
#ifdef CONFIG_BCMA_NFLASH
struct bcma_nflash {
/* Must be the fist member for the brcmnand driver to
* de-reference that structure.
*/
struct brcmnand_platform_data brcmnand_info;
bool present;
bool boot; /* This is the flash the SoC boots from */
};
#endif
#ifdef CONFIG_BCMA_DRIVER_MIPS
struct bcma_serial_port {
void *regs;
unsigned long clockspeed;
unsigned int irq;
unsigned int baud_base;
unsigned int reg_shift;
};
#endif /* CONFIG_BCMA_DRIVER_MIPS */
struct bcma_drv_cc {
struct bcma_device *core;
u32 status;
u32 capabilities;
u32 capabilities_ext;
u8 setup_done:1;
u8 early_setup_done:1;
/* Fast Powerup Delay constant */
u16 fast_pwrup_delay;
struct bcma_chipcommon_pmu pmu;
#ifdef CONFIG_BCMA_PFLASH
struct bcma_pflash pflash;
#endif
#ifdef CONFIG_BCMA_SFLASH
struct bcma_sflash sflash;
#endif
#ifdef CONFIG_BCMA_NFLASH
struct bcma_nflash nflash;
#endif
#ifdef CONFIG_BCMA_DRIVER_MIPS
int nr_serial_ports;
struct bcma_serial_port serial_ports[4];
#endif /* CONFIG_BCMA_DRIVER_MIPS */
u32 ticks_per_ms;
struct platform_device *watchdog;
/* Lock for GPIO register access. */
spinlock_t gpio_lock;
#ifdef CONFIG_BCMA_DRIVER_GPIO
struct gpio_chip gpio;
#endif
};
struct bcma_drv_cc_b {
struct bcma_device *core;
u8 setup_done:1;
void __iomem *mii;
};
/* Register access */
#define bcma_cc_read32(cc, offset) \
bcma_read32((cc)->core, offset)
#define bcma_cc_write32(cc, offset, val) \
bcma_write32((cc)->core, offset, val)
#define bcma_cc_mask32(cc, offset, mask) \
bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
#define bcma_cc_set32(cc, offset, set) \
bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
#define bcma_cc_maskset32(cc, offset, mask, set) \
bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
/* PMU registers access */
#define bcma_pmu_read32(cc, offset) \
bcma_read32((cc)->pmu.core, offset)
#define bcma_pmu_write32(cc, offset, val) \
bcma_write32((cc)->pmu.core, offset, val)
#define bcma_pmu_mask32(cc, offset, mask) \
bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) & (mask))
#define bcma_pmu_set32(cc, offset, set) \
bcma_pmu_write32(cc, offset, bcma_pmu_read32(cc, offset) | (set))
#define bcma_pmu_maskset32(cc, offset, mask, set) \
bcma_pmu_write32(cc, offset, (bcma_pmu_read32(cc, offset) & (mask)) | (set))
extern u32 bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks);
extern u32 bcma_chipco_get_alp_clock(struct bcma_drv_cc *cc);
void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
/* Chipcommon GPIO pin access. */
u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_pullup(struct bcma_drv_cc *cc, u32 mask, u32 value);
u32 bcma_chipco_gpio_pulldown(struct bcma_drv_cc *cc, u32 mask, u32 value);
/* PMU support */
extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
u32 value);
extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
u32 mask, u32 set);
extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
u32 offset, u32 mask, u32 set);
extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
u32 offset, u32 mask, u32 set);
extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid);
extern u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc);
void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value);
#endif /* LINUX_BCMA_DRIVER_CC_H_ */

Some files were not shown because too many files have changed in this diff Show More