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:
@@ -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
Reference in New Issue
Block a user