code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/include/asm/hardware/sa1111.h
 *
 * Copyright (C) 2000 John G Dorsey <john+@cs.cmu.edu>
 *
 * This file contains definitions for the SA-1111 Companion Chip.
 * (Structure and naming borrowed from SA-1101.h, by Peter Danielsson.)
 *
 * Macro that calculates real address for registers in the SA-1111
 */

#ifndef _ASM_ARCH_SA1111
#define _ASM_ARCH_SA1111

/*
 * Don't ask the (SAC) DMA engines to move less than this amount.
 */

#define SA1111_SAC_DMA_MIN_XFER	(0x800)

/*
 * System Bus Interface (SBI)
 *
 * Registers
 *    SKCR	Control Register
 *    SMCR	Shared Memory Controller Register
 *    SKID	ID Register
 */
#define SA1111_SKCR	0x0000
#define SA1111_SMCR	0x0004
#define SA1111_SKID	0x0008

#define SKCR_PLL_BYPASS	(1<<0)
#define SKCR_RCLKEN	(1<<1)
#define SKCR_SLEEP	(1<<2)
#define SKCR_DOZE	(1<<3)
#define SKCR_VCO_OFF	(1<<4)
#define SKCR_SCANTSTEN	(1<<5)
#define SKCR_CLKTSTEN	(1<<6)
#define SKCR_RDYEN	(1<<7)
#define SKCR_SELAC	(1<<8)
#define SKCR_OPPC	(1<<9)
#define SKCR_PLLTSTEN	(1<<10)
#define SKCR_USBIOTSTEN	(1<<11)
/*
 * Don't believe the specs!  Take them, throw them outside.  Leave them
 * there for a week.  Spit on them.  Walk on them.  Stamp on them.
 * Pour gasoline over them and finally burn them.  Now think about coding.
 *  - The October 1999 errata (278260-007) says its bit 13, 1 to enable.
 *  - The Feb 2001 errata (278260-010) says that the previous errata
 *    (278260-009) is wrong, and its bit actually 12, fixed in spec
 *    278242-003.
 *  - The SA1111 manual (278242) says bit 12, but 0 to enable.
 *  - Reality is bit 13, 1 to enable.
 *      -- rmk
 */
#define SKCR_OE_EN	(1<<13)

#define SMCR_DTIM	(1<<0)
#define SMCR_MBGE	(1<<1)
#define SMCR_DRAC_0	(1<<2)
#define SMCR_DRAC_1	(1<<3)
#define SMCR_DRAC_2	(1<<4)
#define SMCR_DRAC	Fld(3, 2)
#define SMCR_CLAT	(1<<5)

#define SKID_SIREV_MASK	(0x000000f0)
#define SKID_MTREV_MASK (0x0000000f)
#define SKID_ID_MASK	(0xffffff00)
#define SKID_SA1111_ID	(0x690cc200)

/*
 * System Controller
 *
 * Registers
 *    SKPCR	Power Control Register
 *    SKCDR	Clock Divider Register
 *    SKAUD	Audio Clock Divider Register
 *    SKPMC	PS/2 Mouse Clock Divider Register
 *    SKPTC	PS/2 Track Pad Clock Divider Register
 *    SKPEN0	PWM0 Enable Register
 *    SKPWM0	PWM0 Clock Register
 *    SKPEN1	PWM1 Enable Register
 *    SKPWM1	PWM1 Clock Register
 */
#define SA1111_SKPCR	0x0200
#define SA1111_SKCDR	0x0204
#define SA1111_SKAUD	0x0208
#define SA1111_SKPMC	0x020c
#define SA1111_SKPTC	0x0210
#define SA1111_SKPEN0	0x0214
#define SA1111_SKPWM0	0x0218
#define SA1111_SKPEN1	0x021c
#define SA1111_SKPWM1	0x0220

#define SKPCR_UCLKEN	(1<<0)
#define SKPCR_ACCLKEN	(1<<1)
#define SKPCR_I2SCLKEN	(1<<2)
#define SKPCR_L3CLKEN	(1<<3)
#define SKPCR_SCLKEN	(1<<4)
#define SKPCR_PMCLKEN	(1<<5)
#define SKPCR_PTCLKEN	(1<<6)
#define SKPCR_DCLKEN	(1<<7)
#define SKPCR_PWMCLKEN	(1<<8)

/* USB Host controller */
#define SA1111_USB		0x0400

/*
 * Serial Audio Controller
 *
 * Registers
 *    SACR0             Serial Audio Common Control Register
 *    SACR1             Serial Audio Alternate Mode (I2C/MSB) Control Register
 *    SACR2             Serial Audio AC-link Control Register
 *    SASR0             Serial Audio I2S/MSB Interface & FIFO Status Register
 *    SASR1             Serial Audio AC-link Interface & FIFO Status Register
 *    SASCR             Serial Audio Status Clear Register
 *    L3_CAR            L3 Control Bus Address Register
 *    L3_CDR            L3 Control Bus Data Register
 *    ACCAR             AC-link Command Address Register
 *    ACCDR             AC-link Command Data Register
 *    ACSAR             AC-link Status Address Register
 *    ACSDR             AC-link Status Data Register
 *    SADTCS            Serial Audio DMA Transmit Control/Status Register
 *    SADTSA            Serial Audio DMA Transmit Buffer Start Address A
 *    SADTCA            Serial Audio DMA Transmit Buffer Count Register A
 *    SADTSB            Serial Audio DMA Transmit Buffer Start Address B
 *    SADTCB            Serial Audio DMA Transmit Buffer Count Register B
 *    SADRCS            Serial Audio DMA Receive Control/Status Register
 *    SADRSA            Serial Audio DMA Receive Buffer Start Address A
 *    SADRCA            Serial Audio DMA Receive Buffer Count Register A
 *    SADRSB            Serial Audio DMA Receive Buffer Start Address B
 *    SADRCB            Serial Audio DMA Receive Buffer Count Register B
 *    SAITR             Serial Audio Interrupt Test Register
 *    SADR              Serial Audio Data Register (16 x 32-bit)
 */

#define SA1111_SERAUDIO		0x0600

/*
 * These are offsets from the above base.
 */
#define SA1111_SACR0		0x00
#define SA1111_SACR1		0x04
#define SA1111_SACR2		0x08
#define SA1111_SASR0		0x0c
#define SA1111_SASR1		0x10
#define SA1111_SASCR		0x18
#define SA1111_L3_CAR		0x1c
#define SA1111_L3_CDR		0x20
#define SA1111_ACCAR		0x24
#define SA1111_ACCDR		0x28
#define SA1111_ACSAR		0x2c
#define SA1111_ACSDR		0x30
#define SA1111_SADTCS		0x34
#define SA1111_SADTSA		0x38
#define SA1111_SADTCA		0x3c
#define SA1111_SADTSB		0x40
#define SA1111_SADTCB		0x44
#define SA1111_SADRCS		0x48
#define SA1111_SADRSA		0x4c
#define SA1111_SADRCA		0x50
#define SA1111_SADRSB		0x54
#define SA1111_SADRCB		0x58
#define SA1111_SAITR		0x5c
#define SA1111_SADR		0x80

#ifndef CONFIG_ARCH_PXA

#define SACR0_ENB	(1<<0)
#define SACR0_BCKD	(1<<2)
#define SACR0_RST	(1<<3)

#define SACR1_AMSL	(1<<0)
#define SACR1_L3EN	(1<<1)
#define SACR1_L3MB	(1<<2)
#define SACR1_DREC	(1<<3)
#define SACR1_DRPL	(1<<4)
#define SACR1_ENLBF	(1<<5)

#define SACR2_TS3V	(1<<0)
#define SACR2_TS4V	(1<<1)
#define SACR2_WKUP	(1<<2)
#define SACR2_DREC	(1<<3)
#define SACR2_DRPL	(1<<4)
#define SACR2_ENLBF	(1<<5)
#define SACR2_RESET	(1<<6)

#define SASR0_TNF	(1<<0)
#define SASR0_RNE	(1<<1)
#define SASR0_BSY	(1<<2)
#define SASR0_TFS	(1<<3)
#define SASR0_RFS	(1<<4)
#define SASR0_TUR	(1<<5)
#define SASR0_ROR	(1<<6)
#define SASR0_L3WD	(1<<16)
#define SASR0_L3RD	(1<<17)

#define SASR1_TNF	(1<<0)
#define SASR1_RNE	(1<<1)
#define SASR1_BSY	(1<<2)
#define SASR1_TFS	(1<<3)
#define SASR1_RFS	(1<<4)
#define SASR1_TUR	(1<<5)
#define SASR1_ROR	(1<<6)
#define SASR1_CADT	(1<<16)
#define SASR1_SADR	(1<<17)
#define SASR1_RSTO	(1<<18)
#define SASR1_CLPM	(1<<19)
#define SASR1_CRDY	(1<<20)
#define SASR1_RS3V	(1<<21)
#define SASR1_RS4V	(1<<22)

#define SASCR_TUR	(1<<5)
#define SASCR_ROR	(1<<6)
#define SASCR_DTS	(1<<16)
#define SASCR_RDD	(1<<17)
#define SASCR_STO	(1<<18)

#define SADTCS_TDEN	(1<<0)
#define SADTCS_TDIE	(1<<1)
#define SADTCS_TDBDA	(1<<3)
#define SADTCS_TDSTA	(1<<4)
#define SADTCS_TDBDB	(1<<5)
#define SADTCS_TDSTB	(1<<6)
#define SADTCS_TBIU	(1<<7)

#define SADRCS_RDEN	(1<<0)
#define SADRCS_RDIE	(1<<1)
#define SADRCS_RDBDA	(1<<3)
#define SADRCS_RDSTA	(1<<4)
#define SADRCS_RDBDB	(1<<5)
#define SADRCS_RDSTB	(1<<6)
#define SADRCS_RBIU	(1<<7)

#define SAD_CS_DEN	(1<<0)
#define SAD_CS_DIE	(1<<1)	/* Not functional on metal 1 */
#define SAD_CS_DBDA	(1<<3)	/* Not functional on metal 1 */
#define SAD_CS_DSTA	(1<<4)
#define SAD_CS_DBDB	(1<<5)	/* Not functional on metal 1 */
#define SAD_CS_DSTB	(1<<6)
#define SAD_CS_BIU	(1<<7)	/* Not functional on metal 1 */

#define SAITR_TFS	(1<<0)
#define SAITR_RFS	(1<<1)
#define SAITR_TUR	(1<<2)
#define SAITR_ROR	(1<<3)
#define SAITR_CADT	(1<<4)
#define SAITR_SADR	(1<<5)
#define SAITR_RSTO	(1<<6)
#define SAITR_TDBDA	(1<<8)
#define SAITR_TDBDB	(1<<9)
#define SAITR_RDBDA	(1<<10)
#define SAITR_RDBDB	(1<<11)

#endif  /* !CONFIG_ARCH_PXA */

/*
 * General-Purpose I/O Interface
 *
 * Registers
 *    PA_DDR		GPIO Block A Data Direction
 *    PA_DRR/PA_DWR	GPIO Block A Data Value Register (read/write)
 *    PA_SDR		GPIO Block A Sleep Direction
 *    PA_SSR		GPIO Block A Sleep State
 *    PB_DDR		GPIO Block B Data Direction
 *    PB_DRR/PB_DWR	GPIO Block B Data Value Register (read/write)
 *    PB_SDR		GPIO Block B Sleep Direction
 *    PB_SSR		GPIO Block B Sleep State
 *    PC_DDR		GPIO Block C Data Direction
 *    PC_DRR/PC_DWR	GPIO Block C Data Value Register (read/write)
 *    PC_SDR		GPIO Block C Sleep Direction
 *    PC_SSR		GPIO Block C Sleep State
 */

#define SA1111_GPIO	0x1000

#define SA1111_GPIO_PADDR	(0x000)
#define SA1111_GPIO_PADRR	(0x004)
#define SA1111_GPIO_PADWR	(0x004)
#define SA1111_GPIO_PASDR	(0x008)
#define SA1111_GPIO_PASSR	(0x00c)
#define SA1111_GPIO_PBDDR	(0x010)
#define SA1111_GPIO_PBDRR	(0x014)
#define SA1111_GPIO_PBDWR	(0x014)
#define SA1111_GPIO_PBSDR	(0x018)
#define SA1111_GPIO_PBSSR	(0x01c)
#define SA1111_GPIO_PCDDR	(0x020)
#define SA1111_GPIO_PCDRR	(0x024)
#define SA1111_GPIO_PCDWR	(0x024)
#define SA1111_GPIO_PCSDR	(0x028)
#define SA1111_GPIO_PCSSR	(0x02c)

#define GPIO_A0		(1 << 0)
#define GPIO_A1		(1 << 1)
#define GPIO_A2		(1 << 2)
#define GPIO_A3		(1 << 3)

#define GPIO_B0		(1 << 8)
#define GPIO_B1		(1 << 9)
#define GPIO_B2		(1 << 10)
#define GPIO_B3		(1 << 11)
#define GPIO_B4		(1 << 12)
#define GPIO_B5		(1 << 13)
#define GPIO_B6		(1 << 14)
#define GPIO_B7		(1 << 15)

#define GPIO_C0		(1 << 16)
#define GPIO_C1		(1 << 17)
#define GPIO_C2		(1 << 18)
#define GPIO_C3		(1 << 19)
#define GPIO_C4		(1 << 20)
#define GPIO_C5		(1 << 21)
#define GPIO_C6		(1 << 22)
#define GPIO_C7		(1 << 23)

/*
 * Interrupt Controller
 *
 * Registers
 *    INTTEST0		Test register 0
 *    INTTEST1		Test register 1
 *    INTEN0		Interrupt Enable register 0
 *    INTEN1		Interrupt Enable register 1
 *    INTPOL0		Interrupt Polarity selection 0
 *    INTPOL1		Interrupt Polarity selection 1
 *    INTTSTSEL		Interrupt source selection
 *    INTSTATCLR0	Interrupt Status/Clear 0
 *    INTSTATCLR1	Interrupt Status/Clear 1
 *    INTSET0		Interrupt source set 0
 *    INTSET1		Interrupt source set 1
 *    WAKE_EN0		Wake-up source enable 0
 *    WAKE_EN1		Wake-up source enable 1
 *    WAKE_POL0		Wake-up polarity selection 0
 *    WAKE_POL1		Wake-up polarity selection 1
 */
#define SA1111_INTC		0x1600

/*
 * These are offsets from the above base.
 */
#define SA1111_INTTEST0		0x0000
#define SA1111_INTTEST1		0x0004
#define SA1111_INTEN0		0x0008
#define SA1111_INTEN1		0x000c
#define SA1111_INTPOL0		0x0010
#define SA1111_INTPOL1		0x0014
#define SA1111_INTTSTSEL	0x0018
#define SA1111_INTSTATCLR0	0x001c
#define SA1111_INTSTATCLR1	0x0020
#define SA1111_INTSET0		0x0024
#define SA1111_INTSET1		0x0028
#define SA1111_WAKEEN0		0x002c
#define SA1111_WAKEEN1		0x0030
#define SA1111_WAKEPOL0		0x0034
#define SA1111_WAKEPOL1		0x0038

/* PS/2 Trackpad and Mouse Interfaces */
#define SA1111_KBD		0x0a00
#define SA1111_MSE		0x0c00

/* PCMCIA Interface */
#define SA1111_PCMCIA		0x1600

extern struct bus_type sa1111_bus_type;

#define SA1111_DEVID_SBI	(1 << 0)
#define SA1111_DEVID_SK		(1 << 1)
#define SA1111_DEVID_USB	(1 << 2)
#define SA1111_DEVID_SAC	(1 << 3)
#define SA1111_DEVID_SSP	(1 << 4)
#define SA1111_DEVID_PS2	(3 << 5)
#define SA1111_DEVID_PS2_KBD	(1 << 5)
#define SA1111_DEVID_PS2_MSE	(1 << 6)
#define SA1111_DEVID_GPIO	(1 << 7)
#define SA1111_DEVID_INT	(1 << 8)
#define SA1111_DEVID_PCMCIA	(1 << 9)

struct sa1111_dev {
	struct device	dev;
	unsigned int	devid;
	struct resource	res;
	void __iomem	*mapbase;
	unsigned int	skpcr_mask;
	unsigned int	hwirq[6];
	u64		dma_mask;
};

#define to_sa1111_device(x)	container_of(x, struct sa1111_dev, dev)

#define sa1111_get_drvdata(d)	dev_get_drvdata(&(d)->dev)
#define sa1111_set_drvdata(d,p)	dev_set_drvdata(&(d)->dev, p)

struct sa1111_driver {
	struct device_driver	drv;
	unsigned int		devid;
	int (*probe)(struct sa1111_dev *);
	void (*remove)(struct sa1111_dev *);
};

#define SA1111_DRV(_d)	container_of((_d), struct sa1111_driver, drv)

#define SA1111_DRIVER_NAME(_sadev) ((_sadev)->dev.driver->name)

/*
 * These frob the SKPCR register, and call platform specific
 * enable/disable functions.
 */
int sa1111_enable_device(struct sa1111_dev *);
void sa1111_disable_device(struct sa1111_dev *);

int sa1111_get_irq(struct sa1111_dev *, unsigned num);

unsigned int sa1111_pll_clock(struct sa1111_dev *);

#define SA1111_AUDIO_ACLINK	0
#define SA1111_AUDIO_I2S	1

void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode);
int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate);
int sa1111_get_audio_rate(struct sa1111_dev *sadev);

int sa1111_check_dma_bug(dma_addr_t addr);

int sa1111_driver_register(struct sa1111_driver *);
void sa1111_driver_unregister(struct sa1111_driver *);

struct sa1111_platform_data {
	int	irq_base;	/* base for cascaded on-chip IRQs */
	unsigned disable_devs;
	void	*data;
	int	(*enable)(void *, unsigned);
	void	(*disable)(void *, unsigned);
};

#endif  /* _ASM_ARCH_SA1111 */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  Definitions for the SCOOP interface found on various Sharp PDAs
 *
 *  Copyright (c) 2004 Richard Purdie
 */

#define SCOOP_MCR  0x00
#define SCOOP_CDR  0x04
#define SCOOP_CSR  0x08
#define SCOOP_CPR  0x0C
#define SCOOP_CCR  0x10
#define SCOOP_IRR  0x14
#define SCOOP_IRM  0x14
#define SCOOP_IMR  0x18
#define SCOOP_ISR  0x1C
#define SCOOP_GPCR 0x20
#define SCOOP_GPWR 0x24
#define SCOOP_GPRR 0x28

#define SCOOP_CPR_OUT	(1 << 7)
#define SCOOP_CPR_SD_3V	(1 << 2)
#define SCOOP_CPR_CF_XV	(1 << 1)
#define SCOOP_CPR_CF_3V	(1 << 0)

#define SCOOP_GPCR_PA22	(1 << 12)
#define SCOOP_GPCR_PA21	(1 << 11)
#define SCOOP_GPCR_PA20	(1 << 10)
#define SCOOP_GPCR_PA19	(1 << 9)
#define SCOOP_GPCR_PA18	(1 << 8)
#define SCOOP_GPCR_PA17	(1 << 7)
#define SCOOP_GPCR_PA16	(1 << 6)
#define SCOOP_GPCR_PA15	(1 << 5)
#define SCOOP_GPCR_PA14	(1 << 4)
#define SCOOP_GPCR_PA13	(1 << 3)
#define SCOOP_GPCR_PA12	(1 << 2)
#define SCOOP_GPCR_PA11	(1 << 1)

struct scoop_config {
	unsigned short io_out;
	unsigned short io_dir;
	unsigned short suspend_clr;
	unsigned short suspend_set;
	int gpio_base;
};

/* Structure for linking scoop devices to PCMCIA sockets */
struct scoop_pcmcia_dev {
	struct device *dev;     /* Pointer to this socket's scoop device */
	int	irq;                /* irq for socket */
	int cd_irq;
	const char *cd_irq_str;
	unsigned char keep_vs;
	unsigned char keep_rd;
};

struct scoop_pcmcia_config {
	struct scoop_pcmcia_dev *devs;
	int num_devs;
	void (*power_ctrl)(struct device *scoop, unsigned short cpr, int nr);
};

extern struct scoop_pcmcia_config *platform_scoop_config;

void reset_scoop(struct device *dev);
unsigned short read_scoop_reg(struct device *dev, unsigned short reg);
void write_scoop_reg(struct device *dev, unsigned short reg, unsigned short data);

repo_name: angery/linux


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  ssp.h
 *
 *  Copyright (C) 2003 Russell King, All Rights Reserved.
 */
#ifndef SSP_H
#define SSP_H

struct ssp_state {
	unsigned int	cr0;
	unsigned int	cr1;
};

int ssp_write_word(u16 data);
int ssp_read_word(u16 *data);
int ssp_flush(void);
void ssp_enable(void);
void ssp_disable(void);
void ssp_save_state(struct ssp_state *ssp);
void ssp_restore_state(struct ssp_state *ssp);
int ssp_init(void);
void ssp_exit(void);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_HIGHMEM_H
#define _ASM_HIGHMEM_H

#include <asm/cachetype.h>
#include <asm/fixmap.h>

#define PKMAP_BASE		(PAGE_OFFSET - PMD_SIZE)
#define LAST_PKMAP		PTRS_PER_PTE
#define LAST_PKMAP_MASK		(LAST_PKMAP - 1)
#define PKMAP_NR(virt)		(((virt) - PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr)		(PKMAP_BASE + ((nr) << PAGE_SHIFT))

#define flush_cache_kmaps() \
	do { \
		if (cache_is_vivt()) \
			flush_cache_all(); \
	} while (0)

extern pte_t *pkmap_page_table;

/*
 * The reason for kmap_high_get() is to ensure that the currently kmap'd
 * page usage count does not decrease to zero while we're using its
 * existing virtual mapping in an atomic context.  With a VIVT cache this
 * is essential to do, but with a VIPT cache this is only an optimization
 * so not to pay the price of establishing a second mapping if an existing
 * one can be used.  However, on platforms without hardware TLB maintenance
 * broadcast, we simply cannot use ARCH_NEEDS_KMAP_HIGH_GET at all since
 * the locking involved must also disable IRQs which is incompatible with
 * the IPI mechanism used by global TLB operations.
 */
#define ARCH_NEEDS_KMAP_HIGH_GET
#if defined(CONFIG_SMP) && defined(CONFIG_CPU_TLB_V6)
#undef ARCH_NEEDS_KMAP_HIGH_GET
#if defined(CONFIG_HIGHMEM) && defined(CONFIG_CPU_CACHE_VIVT)
#error "The sum of features in your kernel config cannot be supported together"
#endif
#endif

/*
 * Needed to be able to broadcast the TLB invalidation for kmap.
 */
#ifdef CONFIG_ARM_ERRATA_798181
#undef ARCH_NEEDS_KMAP_HIGH_GET
#endif

#ifdef ARCH_NEEDS_KMAP_HIGH_GET
extern void *kmap_high_get(struct page *page);

static inline void *arch_kmap_local_high_get(struct page *page)
{
	if (IS_ENABLED(CONFIG_DEBUG_HIGHMEM) && !cache_is_vivt())
		return NULL;
	return kmap_high_get(page);
}
#define arch_kmap_local_high_get arch_kmap_local_high_get

#else /* ARCH_NEEDS_KMAP_HIGH_GET */
static inline void *kmap_high_get(struct page *page)
{
	return NULL;
}
#endif /* !ARCH_NEEDS_KMAP_HIGH_GET */

#define arch_kmap_local_post_map(vaddr, pteval)				\
	local_flush_tlb_kernel_page(vaddr)

#define arch_kmap_local_pre_unmap(vaddr)				\
do {									\
	if (cache_is_vivt())						\
		__cpuc_flush_dcache_area((void *)vaddr, PAGE_SIZE);	\
} while (0)

#define arch_kmap_local_post_unmap(vaddr)				\
	local_flush_tlb_kernel_page(vaddr)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/include/asm/hugetlb-3level.h
 *
 * Copyright (C) 2012 ARM Ltd.
 *
 * Based on arch/x86/include/asm/hugetlb.h.
 */

#ifndef _ASM_ARM_HUGETLB_3LEVEL_H
#define _ASM_ARM_HUGETLB_3LEVEL_H

/*
 * If our huge pte is non-zero then mark the valid bit.
 * This allows pte_present(huge_ptep_get(ptep)) to return true for non-zero
 * ptes.
 * (The valid bit is automatically cleared by set_pte_at for PROT_NONE ptes).
 */
#define __HAVE_ARCH_HUGE_PTEP_GET
static inline pte_t huge_ptep_get(pte_t *ptep)
{
	pte_t retval = *ptep;
	if (pte_val(retval))
		pte_val(retval) |= L_PTE_VALID;
	return retval;
}

#endif /* _ASM_ARM_HUGETLB_3LEVEL_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/include/asm/hugetlb.h
 *
 * Copyright (C) 2012 ARM Ltd.
 *
 * Based on arch/x86/include/asm/hugetlb.h
 */

#ifndef _ASM_ARM_HUGETLB_H
#define _ASM_ARM_HUGETLB_H

#include <asm/page.h>
#include <asm/hugetlb-3level.h>
#include <asm-generic/hugetlb.h>

static inline void arch_clear_hugepage_flags(struct page *page)
{
	clear_bit(PG_dcache_clean, &page->flags);
}
#define arch_clear_hugepage_flags arch_clear_hugepage_flags

#endif /* _ASM_ARM_HUGETLB_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_HW_BREAKPOINT_H
#define _ARM_HW_BREAKPOINT_H

#ifdef __KERNEL__

struct task_struct;

#ifdef CONFIG_HAVE_HW_BREAKPOINT

struct arch_hw_breakpoint_ctrl {
		u32 __reserved	: 9,
		mismatch	: 1,
				: 9,
		len		: 8,
		type		: 2,
		privilege	: 2,
		enabled		: 1;
};

struct arch_hw_breakpoint {
	u32	address;
	u32	trigger;
	struct	arch_hw_breakpoint_ctrl step_ctrl;
	struct	arch_hw_breakpoint_ctrl ctrl;
};

static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
{
	return (ctrl.mismatch << 22) | (ctrl.len << 5) | (ctrl.type << 3) |
		(ctrl.privilege << 1) | ctrl.enabled;
}

static inline void decode_ctrl_reg(u32 reg,
				   struct arch_hw_breakpoint_ctrl *ctrl)
{
	ctrl->enabled	= reg & 0x1;
	reg >>= 1;
	ctrl->privilege	= reg & 0x3;
	reg >>= 2;
	ctrl->type	= reg & 0x3;
	reg >>= 2;
	ctrl->len	= reg & 0xff;
	reg >>= 17;
	ctrl->mismatch	= reg & 0x1;
}

/* Debug architecture numbers. */
#define ARM_DEBUG_ARCH_RESERVED	0	/* In case of ptrace ABI updates. */
#define ARM_DEBUG_ARCH_V6	1
#define ARM_DEBUG_ARCH_V6_1	2
#define ARM_DEBUG_ARCH_V7_ECP14	3
#define ARM_DEBUG_ARCH_V7_MM	4
#define ARM_DEBUG_ARCH_V7_1	5
#define ARM_DEBUG_ARCH_V8	6
#define ARM_DEBUG_ARCH_V8_1	7
#define ARM_DEBUG_ARCH_V8_2	8
#define ARM_DEBUG_ARCH_V8_4	9

/* Breakpoint */
#define ARM_BREAKPOINT_EXECUTE	0

/* Watchpoints */
#define ARM_BREAKPOINT_LOAD	1
#define ARM_BREAKPOINT_STORE	2
#define ARM_FSR_ACCESS_MASK	(1 << 11)

/* Privilege Levels */
#define ARM_BREAKPOINT_PRIV	1
#define ARM_BREAKPOINT_USER	2

/* Lengths */
#define ARM_BREAKPOINT_LEN_1	0x1
#define ARM_BREAKPOINT_LEN_2	0x3
#define ARM_BREAKPOINT_LEN_4	0xf
#define ARM_BREAKPOINT_LEN_8	0xff

/* Limits */
#define ARM_MAX_BRP		16
#define ARM_MAX_WRP		16
#define ARM_MAX_HBP_SLOTS	(ARM_MAX_BRP + ARM_MAX_WRP)

/* DSCR method of entry bits. */
#define ARM_DSCR_MOE(x)			((x >> 2) & 0xf)
#define ARM_ENTRY_BREAKPOINT		0x1
#define ARM_ENTRY_ASYNC_WATCHPOINT	0x2
#define ARM_ENTRY_SYNC_WATCHPOINT	0xa

/* DSCR monitor/halting bits. */
#define ARM_DSCR_HDBGEN		(1 << 14)
#define ARM_DSCR_MDBGEN		(1 << 15)

/* OSLSR os lock model bits */
#define ARM_OSLSR_OSLM0		(1 << 0)

/* opcode2 numbers for the co-processor instructions. */
#define ARM_OP2_BVR		4
#define ARM_OP2_BCR		5
#define ARM_OP2_WVR		6
#define ARM_OP2_WCR		7

/* Base register numbers for the debug registers. */
#define ARM_BASE_BVR		64
#define ARM_BASE_BCR		80
#define ARM_BASE_WVR		96
#define ARM_BASE_WCR		112

/* Accessor macros for the debug registers. */
#define ARM_DBG_READ(N, M, OP2, VAL) do {\
	asm volatile("mrc p14, 0, %0, " #N "," #M ", " #OP2 : "=r" (VAL));\
} while (0)

#define ARM_DBG_WRITE(N, M, OP2, VAL) do {\
	asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
} while (0)

struct perf_event_attr;
struct notifier_block;
struct perf_event;
struct pmu;

extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
				  int *gen_len, int *gen_type);
extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
extern int hw_breakpoint_arch_parse(struct perf_event *bp,
				    const struct perf_event_attr *attr,
				    struct arch_hw_breakpoint *hw);
extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
					   unsigned long val, void *data);

extern u8 arch_get_debug_arch(void);
extern u8 arch_get_max_wp_len(void);
extern void clear_ptrace_hw_breakpoint(struct task_struct *tsk);

int arch_install_hw_breakpoint(struct perf_event *bp);
void arch_uninstall_hw_breakpoint(struct perf_event *bp);
void hw_breakpoint_pmu_read(struct perf_event *bp);
int hw_breakpoint_slots(int type);

#else
static inline void clear_ptrace_hw_breakpoint(struct task_struct *tsk) {}

#endif	/* CONFIG_HAVE_HW_BREAKPOINT */
#endif	/* __KERNEL__ */
#endif	/* _ARM_HW_BREAKPOINT_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Nothing to see here yet
 */
#ifndef _ARCH_ARM_HW_IRQ_H
#define _ARCH_ARM_HW_IRQ_H

static inline void ack_bad_irq(int irq)
{
	extern unsigned long irq_err_count;
	irq_err_count++;
	pr_crit("unexpected IRQ trap at vector %02x\n", irq);
}

#define ARCH_IRQ_INIT_FLAGS	(IRQ_NOREQUEST | IRQ_NOPROBE)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_HWCAP_H
#define __ASMARM_HWCAP_H

#include <uapi/asm/hwcap.h>

#if !defined(__ASSEMBLY__)
/*
 * This yields a mask that user programs can use to figure out what
 * instruction set this cpu supports.
 */
#define ELF_HWCAP	(elf_hwcap)
#define ELF_HWCAP2	(elf_hwcap2)
extern unsigned int elf_hwcap, elf_hwcap2;
#endif
#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_HYPERVISOR_H
#define _ASM_ARM_HYPERVISOR_H

#include <asm/xen/hypervisor.h>

void kvm_init_hyp_services(void);
bool kvm_arm_hyp_service_available(u32 func_id);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 *  arch/arm/include/asm/ide.h
 *
 *  Copyright (C) 1994-1996  Linus Torvalds & authors
 */

/*
 *  This file contains the ARM architecture specific IDE code.
 */

#ifndef __ASMARM_IDE_H
#define __ASMARM_IDE_H

#ifdef __KERNEL__

#define __ide_mm_insw(port,addr,len)	readsw(port,addr,len)
#define __ide_mm_insl(port,addr,len)	readsl(port,addr,len)
#define __ide_mm_outsw(port,addr,len)	writesw(port,addr,len)
#define __ide_mm_outsl(port,addr,len)	writesl(port,addr,len)

#endif /* __KERNEL__ */

#endif /* __ASMARM_IDE_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_IDMAP_H
#define __ASM_IDMAP_H

#include <linux/compiler.h>
#include <linux/pgtable.h>

/* Tag a function as requiring to be executed via an identity mapping. */
#define __idmap __section(".idmap.text") noinline notrace

extern pgd_t *idmap_pgd;

void setup_mm_for_reboot(void);

#endif	/* __ASM_IDMAP_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_INSN_H
#define __ASM_ARM_INSN_H

#include <linux/types.h>

/*
 * Avoid a literal load by emitting a sequence of ADD/LDR instructions with the
 * appropriate relocations. The combined sequence has a range of -/+ 256 MiB,
 * which should be sufficient for the core kernel as well as modules loaded
 * into the module region. (Not supported by LLD before release 14)
 */
#define LOAD_SYM_ARMV6(reg, sym)					\
	"	.globl	" #sym "				\n\t"	\
	"	.reloc	10f, R_ARM_ALU_PC_G0_NC, " #sym "	\n\t"	\
	"	.reloc	11f, R_ARM_ALU_PC_G1_NC, " #sym "	\n\t"	\
	"	.reloc	12f, R_ARM_LDR_PC_G2, " #sym "		\n\t"	\
	"10:	sub	" #reg ", pc, #8			\n\t"	\
	"11:	sub	" #reg ", " #reg ", #4			\n\t"	\
	"12:	ldr	" #reg ", [" #reg ", #0]		\n\t"

static inline unsigned long
arm_gen_nop(void)
{
#ifdef CONFIG_THUMB2_KERNEL
	return 0xf3af8000; /* nop.w */
#else
	return 0xe1a00000; /* mov r0, r0 */
#endif
}

unsigned long
__arm_gen_branch(unsigned long pc, unsigned long addr, bool link, bool warn);

static inline unsigned long
arm_gen_branch(unsigned long pc, unsigned long addr)
{
	return __arm_gen_branch(pc, addr, false, true);
}

static inline unsigned long
arm_gen_branch_link(unsigned long pc, unsigned long addr, bool warn)
{
	return __arm_gen_branch(pc, addr, true, warn);
}

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/io.h
 *
 *  Copyright (C) 1996-2000 Russell King
 *
 * Modifications:
 *  16-Sep-1996	RMK	Inlined the inx/outx functions & optimised for both
 *			constant addresses and variable addresses.
 *  04-Dec-1997	RMK	Moved a lot of this stuff to the new architecture
 *			specific IO header files.
 *  27-Mar-1999	PJB	Second parameter of memcpy_toio is const..
 *  04-Apr-1999	PJB	Added check_signature.
 *  12-Dec-1999	RMK	More cleanups
 *  18-Jun-2000 RMK	Removed virt_to_* and friends definitions
 *  05-Oct-2004 BJD     Moved memory string functions to use void __iomem
 */
#ifndef __ASM_ARM_IO_H
#define __ASM_ARM_IO_H

#ifdef __KERNEL__

#include <linux/string.h>
#include <linux/types.h>
#include <asm/byteorder.h>
#include <asm/memory.h>
#include <asm-generic/pci_iomap.h>

/*
 * ISA I/O bus memory addresses are 1:1 with the physical address.
 */
#define isa_virt_to_bus virt_to_phys
#define isa_bus_to_virt phys_to_virt

/*
 * Atomic MMIO-wide IO modify
 */
extern void atomic_io_modify(void __iomem *reg, u32 mask, u32 set);
extern void atomic_io_modify_relaxed(void __iomem *reg, u32 mask, u32 set);

/*
 * Generic IO read/write.  These perform native-endian accesses.  Note
 * that some architectures will want to re-define __raw_{read,write}w.
 */
void __raw_writesb(volatile void __iomem *addr, const void *data, int bytelen);
void __raw_writesw(volatile void __iomem *addr, const void *data, int wordlen);
void __raw_writesl(volatile void __iomem *addr, const void *data, int longlen);

void __raw_readsb(const volatile void __iomem *addr, void *data, int bytelen);
void __raw_readsw(const volatile void __iomem *addr, void *data, int wordlen);
void __raw_readsl(const volatile void __iomem *addr, void *data, int longlen);

#if __LINUX_ARM_ARCH__ < 6
/*
 * Half-word accesses are problematic with RiscPC due to limitations of
 * the bus. Rather than special-case the machine, just let the compiler
 * generate the access for CPUs prior to ARMv6.
 */
#define __raw_readw(a)         (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
#define __raw_writew(v,a)      ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v)))
#else
/*
 * When running under a hypervisor, we want to avoid I/O accesses with
 * writeback addressing modes as these incur a significant performance
 * overhead (the address generation must be emulated in software).
 */
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
	asm volatile("strh %1, %0"
		     : : "Q" (*(volatile u16 __force *)addr), "r" (val));
}

#define __raw_readw __raw_readw
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
	u16 val;
	asm volatile("ldrh %0, %1"
		     : "=r" (val)
		     : "Q" (*(volatile u16 __force *)addr));
	return val;
}
#endif

#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
	asm volatile("strb %1, %0"
		     : : "Qo" (*(volatile u8 __force *)addr), "r" (val));
}

#define __raw_writel __raw_writel
static inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
	asm volatile("str %1, %0"
		     : : "Qo" (*(volatile u32 __force *)addr), "r" (val));
}

#define __raw_readb __raw_readb
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
	u8 val;
	asm volatile("ldrb %0, %1"
		     : "=r" (val)
		     : "Qo" (*(volatile u8 __force *)addr));
	return val;
}

#define __raw_readl __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
	u32 val;
	asm volatile("ldr %0, %1"
		     : "=r" (val)
		     : "Qo" (*(volatile u32 __force *)addr));
	return val;
}

/*
 * Architecture ioremap implementation.
 */
#define MT_DEVICE		0
#define MT_DEVICE_NONSHARED	1
#define MT_DEVICE_CACHED	2
#define MT_DEVICE_WC		3
/*
 * types 4 onwards can be found in asm/mach/map.h and are undefined
 * for ioremap
 */

/*
 * __arm_ioremap takes CPU physical address.
 * __arm_ioremap_pfn takes a Page Frame Number and an offset into that page
 * The _caller variety takes a __builtin_return_address(0) value for
 * /proc/vmalloc to use - and should only be used in non-inline functions.
 */
extern void __iomem *__arm_ioremap_caller(phys_addr_t, size_t, unsigned int,
	void *);
extern void __iomem *__arm_ioremap_pfn(unsigned long, unsigned long, size_t, unsigned int);
extern void __iomem *__arm_ioremap_exec(phys_addr_t, size_t, bool cached);
void __arm_iomem_set_ro(void __iomem *ptr, size_t size);

extern void __iomem * (*arch_ioremap_caller)(phys_addr_t, size_t,
	unsigned int, void *);

/*
 * Bad read/write accesses...
 */
extern void __readwrite_bug(const char *fn);

/*
 * A typesafe __io() helper
 */
static inline void __iomem *__typesafe_io(unsigned long addr)
{
	return (void __iomem *)addr;
}

#define IOMEM(x)	((void __force __iomem *)(x))

/* IO barriers */
#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
#include <asm/barrier.h>
#define __iormb()		rmb()
#define __iowmb()		wmb()
#else
#define __iormb()		do { } while (0)
#define __iowmb()		do { } while (0)
#endif

/* PCI fixed i/o mapping */
#define PCI_IO_VIRT_BASE	0xfee00000
#define PCI_IOBASE		((void __iomem *)PCI_IO_VIRT_BASE)

#if defined(CONFIG_PCI) || IS_ENABLED(CONFIG_PCMCIA)
void pci_ioremap_set_mem_type(int mem_type);
#else
static inline void pci_ioremap_set_mem_type(int mem_type) {}
#endif

struct resource;

#define pci_remap_iospace pci_remap_iospace
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);

/*
 * PCI configuration space mapping function.
 *
 * The PCI specification does not allow configuration write
 * transactions to be posted. Add an arch specific
 * pci_remap_cfgspace() definition that is implemented
 * through strongly ordered memory mappings.
 */
#define pci_remap_cfgspace pci_remap_cfgspace
void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size);
/*
 * Now, pick up the machine-defined IO definitions
 */
#ifdef CONFIG_NEED_MACH_IO_H
#include <mach/io.h>
#else
#if IS_ENABLED(CONFIG_PCMCIA) || defined(CONFIG_PCI)
#define IO_SPACE_LIMIT	((resource_size_t)0xfffff)
#else
#define IO_SPACE_LIMIT ((resource_size_t)0)
#endif
#define __io(a)		__typesafe_io(PCI_IO_VIRT_BASE + ((a) & IO_SPACE_LIMIT))
#endif

/*
 *  IO port access primitives
 *  -------------------------
 *
 * The ARM doesn't have special IO access instructions; all IO is memory
 * mapped.  Note that these are defined to perform little endian accesses
 * only.  Their primary purpose is to access PCI and ISA peripherals.
 *
 * Note that for a big endian machine, this implies that the following
 * big endian mode connectivity is in place, as described by numerous
 * ARM documents:
 *
 *    PCI:  D0-D7   D8-D15 D16-D23 D24-D31
 *    ARM: D24-D31 D16-D23  D8-D15  D0-D7
 *
 * The machine specific io.h include defines __io to translate an "IO"
 * address to a memory address.
 *
 * Note that we prevent GCC re-ordering or caching values in expressions
 * by introducing sequence points into the in*() definitions.  Note that
 * __raw_* do not guarantee this behaviour.
 *
 * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space.
 */
#ifdef __io
#define outb(v,p)	({ __iowmb(); __raw_writeb(v,__io(p)); })
#define outw(v,p)	({ __iowmb(); __raw_writew((__force __u16) \
					cpu_to_le16(v),__io(p)); })
#define outl(v,p)	({ __iowmb(); __raw_writel((__force __u32) \
					cpu_to_le32(v),__io(p)); })

#define inb(p)	({ __u8 __v = __raw_readb(__io(p)); __iormb(); __v; })
#define inw(p)	({ __u16 __v = le16_to_cpu((__force __le16) \
			__raw_readw(__io(p))); __iormb(); __v; })
#define inl(p)	({ __u32 __v = le32_to_cpu((__force __le32) \
			__raw_readl(__io(p))); __iormb(); __v; })

#define outsb(p,d,l)		__raw_writesb(__io(p),d,l)
#define outsw(p,d,l)		__raw_writesw(__io(p),d,l)
#define outsl(p,d,l)		__raw_writesl(__io(p),d,l)

#define insb(p,d,l)		__raw_readsb(__io(p),d,l)
#define insw(p,d,l)		__raw_readsw(__io(p),d,l)
#define insl(p,d,l)		__raw_readsl(__io(p),d,l)
#endif

/*
 * String version of IO memory access ops:
 */
extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t);
extern void _memcpy_toio(volatile void __iomem *, const void *, size_t);
extern void _memset_io(volatile void __iomem *, int, size_t);

/*
 *  Memory access primitives
 *  ------------------------
 *
 * These perform PCI memory accesses via an ioremap region.  They don't
 * take an address as such, but a cookie.
 *
 * Again, these are defined to perform little endian accesses.  See the
 * IO port primitives for more information.
 */
#ifndef readl
#define readb_relaxed(c) ({ u8  __r = __raw_readb(c); __r; })
#define readw_relaxed(c) ({ u16 __r = le16_to_cpu((__force __le16) \
					__raw_readw(c)); __r; })
#define readl_relaxed(c) ({ u32 __r = le32_to_cpu((__force __le32) \
					__raw_readl(c)); __r; })

#define writeb_relaxed(v,c)	__raw_writeb(v,c)
#define writew_relaxed(v,c)	__raw_writew((__force u16) cpu_to_le16(v),c)
#define writel_relaxed(v,c)	__raw_writel((__force u32) cpu_to_le32(v),c)

#define readb(c)		({ u8  __v = readb_relaxed(c); __iormb(); __v; })
#define readw(c)		({ u16 __v = readw_relaxed(c); __iormb(); __v; })
#define readl(c)		({ u32 __v = readl_relaxed(c); __iormb(); __v; })

#define writeb(v,c)		({ __iowmb(); writeb_relaxed(v,c); })
#define writew(v,c)		({ __iowmb(); writew_relaxed(v,c); })
#define writel(v,c)		({ __iowmb(); writel_relaxed(v,c); })

#define readsb(p,d,l)		__raw_readsb(p,d,l)
#define readsw(p,d,l)		__raw_readsw(p,d,l)
#define readsl(p,d,l)		__raw_readsl(p,d,l)

#define writesb(p,d,l)		__raw_writesb(p,d,l)
#define writesw(p,d,l)		__raw_writesw(p,d,l)
#define writesl(p,d,l)		__raw_writesl(p,d,l)

#ifndef __ARMBE__
static inline void memset_io(volatile void __iomem *dst, unsigned c,
	size_t count)
{
	extern void mmioset(void *, unsigned int, size_t);
	mmioset((void __force *)dst, c, count);
}
#define memset_io(dst,c,count) memset_io(dst,c,count)

static inline void memcpy_fromio(void *to, const volatile void __iomem *from,
	size_t count)
{
	extern void mmiocpy(void *, const void *, size_t);
	mmiocpy(to, (const void __force *)from, count);
}
#define memcpy_fromio(to,from,count) memcpy_fromio(to,from,count)

static inline void memcpy_toio(volatile void __iomem *to, const void *from,
	size_t count)
{
	extern void mmiocpy(void *, const void *, size_t);
	mmiocpy((void __force *)to, from, count);
}
#define memcpy_toio(to,from,count) memcpy_toio(to,from,count)

#else
#define memset_io(c,v,l)	_memset_io(c,(v),(l))
#define memcpy_fromio(a,c,l)	_memcpy_fromio((a),c,(l))
#define memcpy_toio(c,a,l)	_memcpy_toio(c,(a),(l))
#endif

#endif	/* readl */

/*
 * ioremap() and friends.
 *
 * ioremap() takes a resource address, and size.  Due to the ARM memory
 * types, it is important to use the correct ioremap() function as each
 * mapping has specific properties.
 *
 * Function		Memory type	Cacheability	Cache hint
 * ioremap()		Device		n/a		n/a
 * ioremap_cache()	Normal		Writeback	Read allocate
 * ioremap_wc()		Normal		Non-cacheable	n/a
 * ioremap_wt()		Normal		Non-cacheable	n/a
 *
 * All device mappings have the following properties:
 * - no access speculation
 * - no repetition (eg, on return from an exception)
 * - number, order and size of accesses are maintained
 * - unaligned accesses are "unpredictable"
 * - writes may be delayed before they hit the endpoint device
 *
 * All normal memory mappings have the following properties:
 * - reads can be repeated with no side effects
 * - repeated reads return the last value written
 * - reads can fetch additional locations without side effects
 * - writes can be repeated (in certain cases) with no side effects
 * - writes can be merged before accessing the target
 * - unaligned accesses can be supported
 * - ordering is not guaranteed without explicit dependencies or barrier
 *   instructions
 * - writes may be delayed before they hit the endpoint memory
 *
 * The cache hint is only a performance hint: CPUs may alias these hints.
 * Eg, a CPU not implementing read allocate but implementing write allocate
 * will provide a write allocate mapping instead.
 */
void __iomem *ioremap(resource_size_t res_cookie, size_t size);
#define ioremap ioremap

/*
 * Do not use ioremap_cache for mapping memory. Use memremap instead.
 */
void __iomem *ioremap_cache(resource_size_t res_cookie, size_t size);
#define ioremap_cache ioremap_cache

void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
#define ioremap_wc ioremap_wc
#define ioremap_wt ioremap_wc

void iounmap(volatile void __iomem *io_addr);
#define iounmap iounmap

void *arch_memremap_wb(phys_addr_t phys_addr, size_t size);
#define arch_memremap_wb arch_memremap_wb

/*
 * io{read,write}{16,32}be() macros
 */
#define ioread16be(p)		({ __u16 __v = be16_to_cpu((__force __be16)__raw_readw(p)); __iormb(); __v; })
#define ioread32be(p)		({ __u32 __v = be32_to_cpu((__force __be32)__raw_readl(p)); __iormb(); __v; })

#define iowrite16be(v,p)	({ __iowmb(); __raw_writew((__force __u16)cpu_to_be16(v), p); })
#define iowrite32be(v,p)	({ __iowmb(); __raw_writel((__force __u32)cpu_to_be32(v), p); })

#ifndef ioport_map
#define ioport_map ioport_map
extern void __iomem *ioport_map(unsigned long port, unsigned int nr);
#endif
#ifndef ioport_unmap
#define ioport_unmap ioport_unmap
extern void ioport_unmap(void __iomem *addr);
#endif

struct pci_dev;

#define pci_iounmap pci_iounmap
extern void pci_iounmap(struct pci_dev *dev, void __iomem *addr);

/*
 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
 * access
 */
#define xlate_dev_mem_ptr(p)	__va(p)

#include <asm-generic/io.h>

#ifdef CONFIG_MMU
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
extern int valid_phys_addr_range(phys_addr_t addr, size_t size);
extern int valid_mmap_phys_addr_range(unsigned long pfn, size_t size);
extern bool arch_memremap_can_ram_remap(resource_size_t offset, size_t size,
					unsigned long flags);
#define arch_memremap_can_ram_remap arch_memremap_can_ram_remap
#endif

/*
 * Register ISA memory and port locations for glibc iopl/inb/outb
 * emulation.
 */
extern void register_isa_ports(unsigned int mmio, unsigned int io,
			       unsigned int io_shift);

#endif	/* __KERNEL__ */
#endif	/* __ASM_ARM_IO_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQ_H
#define __ASM_ARM_IRQ_H

#define NR_IRQS_LEGACY	16

#ifndef CONFIG_SPARSE_IRQ
#include <mach/irqs.h>
#else
#define NR_IRQS NR_IRQS_LEGACY
#endif

#ifndef irq_canonicalize
#define irq_canonicalize(i)	(i)
#endif

/*
 * Use this value to indicate lack of interrupt
 * capability
 */
#ifndef NO_IRQ
#define NO_IRQ	((unsigned int)(-1))
#endif

#ifndef __ASSEMBLY__
struct irqaction;
struct pt_regs;

void handle_IRQ(unsigned int, struct pt_regs *);
void init_IRQ(void);

#ifdef CONFIG_SMP
#include <linux/cpumask.h>

extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask,
					   bool exclude_self);
#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace
#endif

static inline int nr_legacy_irqs(void)
{
	return NR_IRQS_LEGACY;
}

#endif

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQ_WORK_H
#define __ASM_ARM_IRQ_WORK_H

#include <asm/smp_plat.h>

static inline bool arch_irq_work_has_interrupt(void)
{
	return is_smp();
}

extern void arch_irq_work_raise(void);

#endif /* _ASM_ARM_IRQ_WORK_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_ARM_IRQFLAGS_H
#define __ASM_ARM_IRQFLAGS_H

#ifdef __KERNEL__

#include <asm/ptrace.h>

/*
 * CPU interrupt mask handling.
 */
#ifdef CONFIG_CPU_V7M
#define IRQMASK_REG_NAME_R "primask"
#define IRQMASK_REG_NAME_W "primask"
#define IRQMASK_I_BIT	1
#else
#define IRQMASK_REG_NAME_R "cpsr"
#define IRQMASK_REG_NAME_W "cpsr_c"
#define IRQMASK_I_BIT	PSR_I_BIT
#endif

#if __LINUX_ARM_ARCH__ >= 6

#define arch_local_irq_save arch_local_irq_save
static inline unsigned long arch_local_irq_save(void)
{
	unsigned long flags;

	asm volatile(
		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ arch_local_irq_save\n"
		"	cpsid	i"
		: "=r" (flags) : : "memory", "cc");
	return flags;
}

#define arch_local_irq_enable arch_local_irq_enable
static inline void arch_local_irq_enable(void)
{
	asm volatile(
		"	cpsie i			@ arch_local_irq_enable"
		:
		:
		: "memory", "cc");
}

#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
	asm volatile(
		"	cpsid i			@ arch_local_irq_disable"
		:
		:
		: "memory", "cc");
}

#define local_fiq_enable()  __asm__("cpsie f	@ __stf" : : : "memory", "cc")
#define local_fiq_disable() __asm__("cpsid f	@ __clf" : : : "memory", "cc")

#ifndef CONFIG_CPU_V7M
#define local_abt_enable()  __asm__("cpsie a	@ __sta" : : : "memory", "cc")
#define local_abt_disable() __asm__("cpsid a	@ __cla" : : : "memory", "cc")
#else
#define local_abt_enable()	do { } while (0)
#define local_abt_disable()	do { } while (0)
#endif
#else

/*
 * Save the current interrupt enable state & disable IRQs
 */
#define arch_local_irq_save arch_local_irq_save
static inline unsigned long arch_local_irq_save(void)
{
	unsigned long flags, temp;

	asm volatile(
		"	mrs	%0, cpsr	@ arch_local_irq_save\n"
		"	orr	%1, %0, #128\n"
		"	msr	cpsr_c, %1"
		: "=r" (flags), "=r" (temp)
		:
		: "memory", "cc");
	return flags;
}

/*
 * Enable IRQs
 */
#define arch_local_irq_enable arch_local_irq_enable
static inline void arch_local_irq_enable(void)
{
	unsigned long temp;
	asm volatile(
		"	mrs	%0, cpsr	@ arch_local_irq_enable\n"
		"	bic	%0, %0, #128\n"
		"	msr	cpsr_c, %0"
		: "=r" (temp)
		:
		: "memory", "cc");
}

/*
 * Disable IRQs
 */
#define arch_local_irq_disable arch_local_irq_disable
static inline void arch_local_irq_disable(void)
{
	unsigned long temp;
	asm volatile(
		"	mrs	%0, cpsr	@ arch_local_irq_disable\n"
		"	orr	%0, %0, #128\n"
		"	msr	cpsr_c, %0"
		: "=r" (temp)
		:
		: "memory", "cc");
}

/*
 * Enable FIQs
 */
#define local_fiq_enable()					\
	({							\
		unsigned long temp;				\
	__asm__ __volatile__(					\
	"mrs	%0, cpsr		@ stf\n"		\
"	bic	%0, %0, #64\n"					\
"	msr	cpsr_c, %0"					\
	: "=r" (temp)						\
	:							\
	: "memory", "cc");					\
	})

/*
 * Disable FIQs
 */
#define local_fiq_disable()					\
	({							\
		unsigned long temp;				\
	__asm__ __volatile__(					\
	"mrs	%0, cpsr		@ clf\n"		\
"	orr	%0, %0, #64\n"					\
"	msr	cpsr_c, %0"					\
	: "=r" (temp)						\
	:							\
	: "memory", "cc");					\
	})

#define local_abt_enable()	do { } while (0)
#define local_abt_disable()	do { } while (0)
#endif

/*
 * Save the current interrupt enable state.
 */
#define arch_local_save_flags arch_local_save_flags
static inline unsigned long arch_local_save_flags(void)
{
	unsigned long flags;
	asm volatile(
		"	mrs	%0, " IRQMASK_REG_NAME_R "	@ local_save_flags"
		: "=r" (flags) : : "memory", "cc");
	return flags;
}

/*
 * restore saved IRQ & FIQ state
 */
#define arch_local_irq_restore arch_local_irq_restore
static inline void arch_local_irq_restore(unsigned long flags)
{
	asm volatile(
		"	msr	" IRQMASK_REG_NAME_W ", %0	@ local_irq_restore"
		:
		: "r" (flags)
		: "memory", "cc");
}

#define arch_irqs_disabled_flags arch_irqs_disabled_flags
static inline int arch_irqs_disabled_flags(unsigned long flags)
{
	return flags & IRQMASK_I_BIT;
}

#include <asm-generic/irqflags.h>

#endif /* ifdef __KERNEL__ */
#endif /* ifndef __ASM_ARM_IRQFLAGS_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_JUMP_LABEL_H
#define _ASM_ARM_JUMP_LABEL_H

#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <asm/unified.h>

#define JUMP_LABEL_NOP_SIZE 4

static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
{
	asm_volatile_goto("1:\n\t"
		 WASM(nop) "\n\t"
		 ".pushsection __jump_table,  \"aw\"\n\t"
		 ".word 1b, %l[l_yes], %c0\n\t"
		 ".popsection\n\t"
		 : :  "i" (&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

static __always_inline bool arch_static_branch_jump(struct static_key *key, bool branch)
{
	asm_volatile_goto("1:\n\t"
		 WASM(b) " %l[l_yes]\n\t"
		 ".pushsection __jump_table,  \"aw\"\n\t"
		 ".word 1b, %l[l_yes], %c0\n\t"
		 ".popsection\n\t"
		 : :  "i" (&((char *)key)[branch]) :  : l_yes);

	return false;
l_yes:
	return true;
}

typedef u32 jump_label_t;

struct jump_entry {
	jump_label_t code;
	jump_label_t target;
	jump_label_t key;
};

#endif  /* __ASSEMBLY__ */
#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/arm/include/asm/kasan.h
 *
 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
 * Author: Andrey Ryabinin <ryabinin.a.a@gmail.com>
 *
 */

#ifndef __ASM_KASAN_H
#define __ASM_KASAN_H

#ifdef CONFIG_KASAN

#include <asm/kasan_def.h>

#define KASAN_SHADOW_SCALE_SHIFT 3

/*
 * The compiler uses a shadow offset assuming that addresses start
 * from 0. Kernel addresses don't start from 0, so shadow
 * for kernel really starts from 'compiler's shadow offset' +
 * ('kernel address space start' >> KASAN_SHADOW_SCALE_SHIFT)
 */

asmlinkage void kasan_early_init(void);
extern void kasan_init(void);

#else
static inline void kasan_init(void) { }
#endif

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 *  arch/arm/include/asm/kasan_def.h
 *
 *  Copyright (c) 2018 Huawei Technologies Co., Ltd.
 *
 *  Author: Abbott Liu <liuwenliang@huawei.com>
 */

#ifndef __ASM_KASAN_DEF_H
#define __ASM_KASAN_DEF_H

#ifdef CONFIG_KASAN

/*
 * Define KASAN_SHADOW_OFFSET,KASAN_SHADOW_START and KASAN_SHADOW_END for
 * the Arm kernel address sanitizer. We are "stealing" lowmem (the 4GB
 * addressable by a 32bit architecture) out of the virtual address
 * space to use as shadow memory for KASan as follows:
 *
 * +----+ 0xffffffff
 * |    |							\
 * |    | |-> Static kernel image (vmlinux) BSS and page table
 * |    |/
 * +----+ PAGE_OFFSET
 * |    |							\
 * |    | |->  Loadable kernel modules virtual address space area
 * |    |/
 * +----+ MODULES_VADDR = KASAN_SHADOW_END
 * |    |						\
 * |    | |-> The shadow area of kernel virtual address.
 * |    |/
 * +----+->  TASK_SIZE (start of kernel space) = KASAN_SHADOW_START the
 * |    |\   shadow address of MODULES_VADDR
 * |    | |
 * |    | |
 * |    | |-> The user space area in lowmem. The kernel address
 * |    | |   sanitizer do not use this space, nor does it map it.
 * |    | |
 * |    | |
 * |    | |
 * |    | |
 * |    |/
 * ------ 0
 *
 * 1) KASAN_SHADOW_START
 *   This value begins with the MODULE_VADDR's shadow address. It is the
 *   start of kernel virtual space. Since we have modules to load, we need
 *   to cover also that area with shadow memory so we can find memory
 *   bugs in modules.
 *
 * 2) KASAN_SHADOW_END
 *   This value is the 0x100000000's shadow address: the mapping that would
 *   be after the end of the kernel memory at 0xffffffff. It is the end of
 *   kernel address sanitizer shadow area. It is also the start of the
 *   module area.
 *
 * 3) KASAN_SHADOW_OFFSET:
 *   This value is used to map an address to the corresponding shadow
 *   address by the following formula:
 *
 *	shadow_addr = (address >> 3) + KASAN_SHADOW_OFFSET;
 *
 *  As you would expect, >> 3 is equal to dividing by 8, meaning each
 *  byte in the shadow memory covers 8 bytes of kernel memory, so one
 *  bit shadow memory per byte of kernel memory is used.
 *
 *  The KASAN_SHADOW_OFFSET is provided in a Kconfig option depending
 *  on the VMSPLIT layout of the system: the kernel and userspace can
 *  split up lowmem in different ways according to needs, so we calculate
 *  the shadow offset depending on this.
 */

#define KASAN_SHADOW_SCALE_SHIFT	3
#define KASAN_SHADOW_OFFSET	_AC(CONFIG_KASAN_SHADOW_OFFSET, UL)
#define KASAN_SHADOW_END	((UL(1) << (32 - KASAN_SHADOW_SCALE_SHIFT)) \
				 + KASAN_SHADOW_OFFSET)
#define KASAN_SHADOW_START      ((KASAN_SHADOW_END >> 3) + KASAN_SHADOW_OFFSET)

#endif
#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_KEXEC_INTERNAL_H
#define _ARM_KEXEC_INTERNAL_H

struct kexec_relocate_data {
	unsigned long kexec_start_address;
	unsigned long kexec_indirection_page;
	unsigned long kexec_mach_type;
	unsigned long kexec_r2;
};

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ARM_KEXEC_H
#define _ARM_KEXEC_H

#ifdef CONFIG_KEXEC

/* Maximum physical address we can use pages from */
#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
/* Maximum address we can reach in physical address mode */
#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
/* Maximum address we can use for the control code buffer */
#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL)

#define KEXEC_CONTROL_PAGE_SIZE	4096

#define KEXEC_ARCH KEXEC_ARCH_ARM

#define KEXEC_ARM_ATAGS_OFFSET  0x1000
#define KEXEC_ARM_ZIMAGE_OFFSET 0x8000

#ifndef __ASSEMBLY__

#define ARCH_HAS_KIMAGE_ARCH
struct kimage_arch {
	u32 kernel_r2;
};

/**
 * crash_setup_regs() - save registers for the panic kernel
 * @newregs: registers are saved here
 * @oldregs: registers to be saved (may be %NULL)
 *
 * Function copies machine registers from @oldregs to @newregs. If @oldregs is
 * %NULL then current registers are stored there.
 */
static inline void crash_setup_regs(struct pt_regs *newregs,
				    struct pt_regs *oldregs)
{
	if (oldregs) {
		memcpy(newregs, oldregs, sizeof(*newregs));
	} else {
		__asm__ __volatile__ (
			"stmia	%[regs_base], {r0-r12}\n\t"
			"mov	%[_ARM_sp], sp\n\t"
			"str	lr, %[_ARM_lr]\n\t"
			"adr	%[_ARM_pc], 1f\n\t"
			"mrs	%[_ARM_cpsr], cpsr\n\t"
		"1:"
			: [_ARM_pc] "=r" (newregs->ARM_pc),
			  [_ARM_cpsr] "=r" (newregs->ARM_cpsr),
			  [_ARM_sp] "=r" (newregs->ARM_sp),
			  [_ARM_lr] "=o" (newregs->ARM_lr)
			: [regs_base] "r" (&newregs->ARM_r0)
			: "memory"
		);
	}
}

static inline unsigned long phys_to_boot_phys(phys_addr_t phys)
{
	return phys_to_idmap(phys);
}
#define phys_to_boot_phys phys_to_boot_phys

static inline phys_addr_t boot_phys_to_phys(unsigned long entry)
{
	return idmap_to_phys(entry);
}
#define boot_phys_to_phys boot_phys_to_phys

static inline unsigned long page_to_boot_pfn(struct page *page)
{
	return page_to_pfn(page) + (arch_phys_to_idmap_offset >> PAGE_SHIFT);
}
#define page_to_boot_pfn page_to_boot_pfn

static inline struct page *boot_pfn_to_page(unsigned long boot_pfn)
{
	return pfn_to_page(boot_pfn - (arch_phys_to_idmap_offset >> PAGE_SHIFT));
}
#define boot_pfn_to_page boot_pfn_to_page

#endif /* __ASSEMBLY__ */

#endif /* CONFIG_KEXEC */

#endif /* _ARM_KEXEC_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __ASM_ARM_KFENCE_H
#define __ASM_ARM_KFENCE_H

#include <linux/kfence.h>

#include <asm/pgalloc.h>
#include <asm/set_memory.h>

static inline int split_pmd_page(pmd_t *pmd, unsigned long addr)
{
	int i;
	unsigned long pfn = PFN_DOWN(__pa(addr));
	pte_t *pte = pte_alloc_one_kernel(&init_mm);

	if (!pte)
		return -ENOMEM;

	for (i = 0; i < PTRS_PER_PTE; i++)
		set_pte_ext(pte + i, pfn_pte(pfn + i, PAGE_KERNEL), 0);
	pmd_populate_kernel(&init_mm, pmd, pte);

	flush_tlb_kernel_range(addr, addr + PMD_SIZE);
	return 0;
}

static inline bool arch_kfence_init_pool(void)
{
	unsigned long addr;
	pmd_t *pmd;

	for (addr = (unsigned long)__kfence_pool; is_kfence_address((void *)addr);
	     addr += PAGE_SIZE) {
		pmd = pmd_off_k(addr);

		if (pmd_leaf(*pmd)) {
			if (split_pmd_page(pmd, addr & PMD_MASK))
				return false;
		}
	}

	return true;
}

static inline bool kfence_protect_page(unsigned long addr, bool protect)
{
	set_memory_valid(addr, 1, !protect);

	return true;
}

#endif /* __ASM_ARM_KFENCE_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * ARM KGDB support
 *
 * Author: Deepak Saxena <dsaxena@mvista.com>
 *
 * Copyright (C) 2002 MontaVista Software Inc.
 *
 */

#ifndef __ARM_KGDB_H__
#define __ARM_KGDB_H__

#include <linux/ptrace.h>
#include <asm/opcodes.h>

/*
 * GDB assumes that we're a user process being debugged, so
 * it will send us an SWI command to write into memory as the
 * debug trap. When an SWI occurs, the next instruction addr is
 * placed into R14_svc before jumping to the vector trap.
 * This doesn't work for kernel debugging as we are already in SVC
 * we would loose the kernel's LR, which is a bad thing. This
 * is  bad thing.
 *
 * By doing this as an undefined instruction trap, we force a mode
 * switch from SVC to UND mode, allowing us to save full kernel state.
 *
 * We also define a KGDB_COMPILED_BREAK which can be used to compile
 * in breakpoints. This is important for things like sysrq-G and for
 * the initial breakpoint from trap_init().
 *
 * Note to ARM HW designers: Add real trap support like SH && PPC to
 * make our lives much much simpler. :)
 */
#define BREAK_INSTR_SIZE	4
#define GDB_BREAKINST		0xef9f0001
#define KGDB_BREAKINST		0xe7ffdefe
#define KGDB_COMPILED_BREAK	0xe7ffdeff
#define CACHE_FLUSH_IS_SAFE	1

#ifndef	__ASSEMBLY__

static inline void arch_kgdb_breakpoint(void)
{
	asm(__inst_arm(0xe7ffdeff));
}

extern void kgdb_handle_bus_error(void);
extern int kgdb_fault_expected;

#endif /* !__ASSEMBLY__ */

/*
 * From Kevin Hilman:
 *
 * gdb is expecting the following registers layout.
 *
 * r0-r15: 1 long word each
 * f0-f7:  unused, 3 long words each !!
 * fps:    unused, 1 long word
 * cpsr:   1 long word
 *
 * Even though f0-f7 and fps are not used, they need to be
 * present in the registers sent for correct processing in
 * the host-side gdb.
 *
 * In particular, it is crucial that CPSR is in the right place,
 * otherwise gdb will not be able to correctly interpret stepping over
 * conditional branches.
 */
#define _GP_REGS		16
#define _FP_REGS		8
#define _EXTRA_REGS		2
#define GDB_MAX_REGS		(_GP_REGS + (_FP_REGS * 3) + _EXTRA_REGS)
#define DBG_MAX_REG_NUM		(_GP_REGS + _FP_REGS + _EXTRA_REGS)

#define KGDB_MAX_NO_CPUS	1
#define BUFMAX			400
#define NUMREGBYTES		(GDB_MAX_REGS << 2)
#define NUMCRITREGBYTES		(32 << 2)

#define _R0			0
#define _R1			1
#define _R2			2
#define _R3			3
#define _R4			4
#define _R5			5
#define _R6			6
#define _R7			7
#define _R8			8
#define _R9			9
#define _R10			10
#define _FP			11
#define _IP			12
#define _SPT			13
#define _LR			14
#define _PC			15
#define _CPSR			(GDB_MAX_REGS - 1)

/*
 * So that we can denote the end of a frame for tracing,
 * in the simple case:
 */
#define CFI_END_FRAME(func)	__CFI_END_FRAME(_PC, _SPT, func)

#endif /* __ASM_KGDB_H__ */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/include/asm/kprobes.h
 *
 * Copyright (C) 2006, 2007 Motorola Inc.
 */

#ifndef _ARM_KPROBES_H
#define _ARM_KPROBES_H

#include <asm-generic/kprobes.h>

#ifdef CONFIG_KPROBES
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/notifier.h>

#define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE			2

#define flush_insn_slot(p)		do { } while (0)
#define kretprobe_blacklist_size	0

typedef u32 kprobe_opcode_t;
struct kprobe;
#include <asm/probes.h>

#define	arch_specific_insn	arch_probes_insn

struct prev_kprobe {
	struct kprobe *kp;
	unsigned int status;
};

/* per-cpu kprobe control block */
struct kprobe_ctlblk {
	unsigned int kprobe_status;
	struct prev_kprobe prev_kprobe;
};

void arch_remove_kprobe(struct kprobe *);
int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
int kprobe_exceptions_notify(struct notifier_block *self,
			     unsigned long val, void *data);

/* optinsn template addresses */
extern __visible kprobe_opcode_t optprobe_template_entry[];
extern __visible kprobe_opcode_t optprobe_template_val[];
extern __visible kprobe_opcode_t optprobe_template_call[];
extern __visible kprobe_opcode_t optprobe_template_end[];
extern __visible kprobe_opcode_t optprobe_template_sub_sp[];
extern __visible kprobe_opcode_t optprobe_template_add_sp[];
extern __visible kprobe_opcode_t optprobe_template_restore_begin[];
extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn[];
extern __visible kprobe_opcode_t optprobe_template_restore_end[];

#define MAX_OPTIMIZED_LENGTH	4
#define MAX_OPTINSN_SIZE				\
	((unsigned long)optprobe_template_end -	\
	 (unsigned long)optprobe_template_entry)
#define RELATIVEJUMP_SIZE	4

struct arch_optimized_insn {
	/*
	 * copy of the original instructions.
	 * Different from x86, ARM kprobe_opcode_t is u32.
	 */
#define MAX_COPIED_INSN	DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
	kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
	/* detour code buffer */
	kprobe_opcode_t *insn;
	/*
	 * We always copy one instruction on ARM,
	 * so size will always be 4, and unlike x86, there is no
	 * need for a size field.
	 */
};

#endif /* CONFIG_KPROBES */
#endif /* _ARM_KPROBES_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */

#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
#define __ASMARM_KRAIT_L2_ACCESSORS_H

extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
extern u32 krait_get_l2_indirect_reg(u32 addr);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_LINKAGE_H
#define __ASM_LINKAGE_H

#define __ALIGN .align 0
#define __ALIGN_STR ".align 0"

#define ENDPROC(name) \
  .type name, %function; \
  END(name)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mach/arch.h
 *
 *  Copyright (C) 2000 Russell King
 */

#include <linux/types.h>

#ifndef __ASSEMBLY__
#include <linux/reboot.h>

struct tag;
struct pt_regs;
struct smp_operations;
#ifdef CONFIG_SMP
#define smp_ops(ops) (&(ops))
#define smp_init_ops(ops) (&(ops))
#else
#define smp_ops(ops) (struct smp_operations *)NULL
#define smp_init_ops(ops) (bool (*)(void))NULL
#endif

struct machine_desc {
	unsigned int		nr;		/* architecture number	*/
	const char		*name;		/* architecture name	*/
	unsigned long		atag_offset;	/* tagged list (relative) */
	const char *const 	*dt_compat;	/* array of device tree
						 * 'compatible' strings	*/

	unsigned int		nr_irqs;	/* number of IRQs */

#ifdef CONFIG_ZONE_DMA
	phys_addr_t		dma_zone_size;	/* size of DMA-able area */
#endif

	unsigned int		video_start;	/* start of video RAM	*/
	unsigned int		video_end;	/* end of video RAM	*/

	unsigned char		reserve_lp0 :1;	/* never has lp0	*/
	unsigned char		reserve_lp1 :1;	/* never has lp1	*/
	unsigned char		reserve_lp2 :1;	/* never has lp2	*/
	enum reboot_mode	reboot_mode;	/* default restart mode	*/
	unsigned		l2c_aux_val;	/* L2 cache aux value	*/
	unsigned		l2c_aux_mask;	/* L2 cache aux mask	*/
	void			(*l2c_write_sec)(unsigned long, unsigned);
	const struct smp_operations	*smp;	/* SMP operations	*/
	bool			(*smp_init)(void);
	void			(*fixup)(struct tag *, char **);
	void			(*dt_fixup)(void);
	long long		(*pv_fixup)(void);
	void			(*reserve)(void);/* reserve mem blocks	*/
	void			(*map_io)(void);/* IO mapping function	*/
	void			(*init_early)(void);
	void			(*init_irq)(void);
	void			(*init_time)(void);
	void			(*init_machine)(void);
	void			(*init_late)(void);
	void			(*handle_irq)(struct pt_regs *);
	void			(*restart)(enum reboot_mode, const char *);
};

/*
 * Current machine - only accessible during boot.
 */
extern const struct machine_desc *machine_desc;

/*
 * Machine type table - also only accessible during boot
 */
extern const struct machine_desc __arch_info_begin[], __arch_info_end[];
#define for_each_machine_desc(p)			\
	for (p = __arch_info_begin; p < __arch_info_end; p++)

/*
 * Set of macros to define architecture features.  This is built into
 * a table by the linker.
 */
#define MACHINE_START(_type,_name)			\
static const struct machine_desc __mach_desc_##_type	\
 __used							\
 __section(".arch.info.init") = {			\
	.nr		= MACH_TYPE_##_type,		\
	.name		= _name,

#define MACHINE_END				\
};

#define DT_MACHINE_START(_name, _namestr)		\
static const struct machine_desc __mach_desc_##_name	\
 __used							\
 __section(".arch.info.init") = {			\
	.nr		= ~0,				\
	.name		= _namestr,

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mach/dma.h
 *
 *  Copyright (C) 1998-2000 Russell King
 *
 *  This header file describes the interface between the generic DMA handler
 *  (dma.c) and the architecture-specific DMA backends (dma-*.c)
 */

struct dma_struct;
typedef struct dma_struct dma_t;

struct dma_ops {
	int	(*request)(unsigned int, dma_t *);		/* optional */
	void	(*free)(unsigned int, dma_t *);			/* optional */
	void	(*enable)(unsigned int, dma_t *);		/* mandatory */
	void 	(*disable)(unsigned int, dma_t *);		/* mandatory */
	int	(*residue)(unsigned int, dma_t *);		/* optional */
	int	(*setspeed)(unsigned int, dma_t *, int);	/* optional */
	const char *type;
};

struct dma_struct {
	void		*addr;		/* single DMA address		*/
	unsigned long	count;		/* single DMA size		*/
	struct scatterlist buf;		/* single DMA			*/
	int		sgcount;	/* number of DMA SG		*/
	struct scatterlist *sg;		/* DMA Scatter-Gather List	*/

	unsigned int	active:1;	/* Transfer active		*/
	unsigned int	invalid:1;	/* Address/Count changed	*/

	unsigned int	dma_mode;	/* DMA mode			*/
	int		speed;		/* DMA speed			*/

	unsigned int	lock;		/* Device is allocated		*/
	const char	*device_id;	/* Device name			*/

	const struct dma_ops *d_ops;
};

/*
 * isa_dma_add - add an ISA-style DMA channel
 */
extern int isa_dma_add(unsigned int, dma_t *dma);


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mach/flash.h
 *
 *  Copyright (C) 2003 Russell King, All Rights Reserved.
 */
#ifndef ASMARM_MACH_FLASH_H
#define ASMARM_MACH_FLASH_H

struct mtd_partition;
struct mtd_info;

/*
 * map_name:	the map probe function name
 * name:	flash device name (eg, as used with mtdparts=)
 * width:	width of mapped device
 * init:	method called at driver/device initialisation
 * exit:	method called at driver/device removal
 * set_vpp:	method called to enable or disable VPP
 * mmcontrol:	method called to enable or disable Sync. Burst Read in OneNAND
 * parts:	optional array of mtd_partitions for static partitioning
 * nr_parts:	number of mtd_partitions for static partitioning
 */
struct flash_platform_data {
	const char	*map_name;
	const char	*name;
	unsigned int	width;
	int		(*init)(void);
	void		(*exit)(void);
	void		(*set_vpp)(int on);
	void		(*mmcontrol)(struct mtd_info *mtd, int sync_read);
	struct mtd_partition *parts;
	unsigned int	nr_parts;
};

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mach/irq.h
 *
 *  Copyright (C) 1995-2000 Russell King.
 */
#ifndef __ASM_ARM_MACH_IRQ_H
#define __ASM_ARM_MACH_IRQ_H

#include <linux/irq.h>

struct seq_file;

/*
 * This is internal.  Do not use it.
 */
extern void init_FIQ(int);
extern int show_fiq_list(struct seq_file *, int);

/*
 * This is for easy migration, but should be changed in the source
 */
#define do_bad_IRQ(desc)				\
do {							\
	raw_spin_lock(&desc->lock);			\
	handle_bad_irq(desc);				\
	raw_spin_unlock(&desc->lock);			\
} while(0)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/map.h
 *
 *  Copyright (C) 1999-2000 Russell King
 *
 *  Page table mapping constructs and function prototypes
 */
#ifndef __ASM_MACH_MAP_H
#define __ASM_MACH_MAP_H

#include <asm/io.h>

struct map_desc {
	unsigned long virtual;
	unsigned long pfn;
	unsigned long length;
	unsigned int type;
};

/* types 0-3 are defined in asm/io.h */
enum {
	MT_UNCACHED = 4,
	MT_CACHECLEAN,
	MT_MINICLEAN,
	MT_LOW_VECTORS,
	MT_HIGH_VECTORS,
	MT_MEMORY_RWX,
	MT_MEMORY_RW,
	MT_MEMORY_RO,
	MT_ROM,
	MT_MEMORY_RWX_NONCACHED,
	MT_MEMORY_RW_DTCM,
	MT_MEMORY_RWX_ITCM,
	MT_MEMORY_RW_SO,
	MT_MEMORY_DMA_READY,
};

#ifdef CONFIG_MMU
extern void iotable_init(struct map_desc *, int);
extern void vm_reserve_area_early(unsigned long addr, unsigned long size,
				  void *caller);
extern void create_mapping_late(struct mm_struct *mm, struct map_desc *md,
				bool ng);

#ifdef CONFIG_DEBUG_LL
extern void debug_ll_addr(unsigned long *paddr, unsigned long *vaddr);
extern void debug_ll_io_init(void);
#else
static inline void debug_ll_io_init(void) {}
#endif

struct mem_type;
extern const struct mem_type *get_mem_type(unsigned int type);
/*
 * external interface to remap single page with appropriate type
 */
extern int ioremap_page(unsigned long virt, unsigned long phys,
			const struct mem_type *mtype);
#else
#define iotable_init(map,num)	do { } while (0)
#define vm_reserve_area_early(a,s,c)	do { } while (0)
#endif

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mach/pci.h
 *
 *  Copyright (C) 2000 Russell King
 */

#ifndef __ASM_MACH_PCI_H
#define __ASM_MACH_PCI_H

#include <linux/ioport.h>

struct pci_sys_data;
struct pci_ops;
struct pci_bus;
struct pci_host_bridge;
struct device;

struct hw_pci {
	struct pci_ops	*ops;
	int		nr_controllers;
	void		**private_data;
	int		(*setup)(int nr, struct pci_sys_data *);
	int		(*scan)(int nr, struct pci_host_bridge *);
	void		(*preinit)(void);
	void		(*postinit)(void);
	u8		(*swizzle)(struct pci_dev *dev, u8 *pin);
	int		(*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
};

/*
 * Per-controller structure
 */
struct pci_sys_data {
	struct list_head node;
	int		busnr;		/* primary bus number			*/
	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
	unsigned long	io_offset;	/* bus->cpu IO mapping offset		*/
	struct pci_bus	*bus;		/* PCI bus				*/
	struct list_head resources;	/* root bus resources (apertures)       */
	struct resource io_res;
	char		io_res_name[12];
					/* Bridge swizzling			*/
	u8		(*swizzle)(struct pci_dev *, u8 *);
					/* IRQ mapping				*/
	int		(*map_irq)(const struct pci_dev *, u8, u8);
	void		*private_data;	/* platform controller private data	*/
};

/*
 * Call this with your hw_pci struct to initialise the PCI system.
 */
void pci_common_init_dev(struct device *, struct hw_pci *);

/*
 * Compatibility wrapper for older platforms that do not care about
 * passing the parent device.
 */
static inline void pci_common_init(struct hw_pci *hw)
{
	pci_common_init_dev(NULL, hw);
}

/*
 * Setup early fixed I/O mapping.
 */
#if defined(CONFIG_PCI)
extern void pci_map_io_early(unsigned long pfn);
#else
static inline void pci_map_io_early(unsigned long pfn) {}
#endif

/*
 * PCI controllers
 */
extern struct pci_ops iop3xx_ops;
extern int iop3xx_pci_setup(int nr, struct pci_sys_data *);
extern void iop3xx_pci_preinit(void);
extern void iop3xx_pci_preinit_cond(void);

extern struct pci_ops dc21285_ops;
extern int dc21285_setup(int nr, struct pci_sys_data *);
extern void dc21285_preinit(void);
extern void dc21285_postinit(void);

#endif /* __ASM_MACH_PCI_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Hardware parameter area specific to Sharp SL series devices
 *
 * Copyright (c) 2005 Richard Purdie
 *
 * Based on Sharp's 2.4 kernel patches
 */

struct sharpsl_param_info {
  unsigned int comadj_keyword;
  unsigned int comadj;

  unsigned int uuid_keyword;
  unsigned char uuid[16];

  unsigned int touch_keyword;
  unsigned int touch_xp;
  unsigned int touch_yp;
  unsigned int touch_xd;
  unsigned int touch_yd;

  unsigned int adadj_keyword;
  unsigned int adadj;

  unsigned int phad_keyword;
  unsigned int phadadj;
} __attribute__((packed));

extern struct sharpsl_param_info sharpsl_param;
extern void sharpsl_save_param(void);


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/include/asm/mach/time.h
 *
 * Copyright (C) 2004 MontaVista Software, Inc.
 */
#ifndef __ASM_ARM_MACH_TIME_H
#define __ASM_ARM_MACH_TIME_H

typedef void (*clock_access_fn)(struct timespec64 *);
extern int register_persistent_clock(clock_access_fn read_persistent);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Machine dependent access functions for RTC registers.
 */
#ifndef _ASM_MC146818RTC_H
#define _ASM_MC146818RTC_H

#include <linux/io.h>
#include <linux/kernel.h>

#define RTC_IRQ BUILD_BUG_ON(1)

#ifndef RTC_PORT
#define RTC_PORT(x)	(0x70 + (x))
#define RTC_ALWAYS_BCD	1	/* RTC operates in binary mode */
#endif

/*
 * The yet supported machines all access the RTC index register via
 * an ISA port access but the way to access the date register differs ...
 */
#define CMOS_READ(addr) ({ \
outb_p((addr),RTC_PORT(0)); \
inb_p(RTC_PORT(1)); \
})
#define CMOS_WRITE(val, addr) ({ \
outb_p((addr),RTC_PORT(0)); \
outb_p((val),RTC_PORT(1)); \
})

#endif /* _ASM_MC146818RTC_H */


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * arch/arm/include/asm/mcpm.h
 *
 * Created by:  Nicolas Pitre, April 2012
 * Copyright:   (C) 2012-2013  Linaro Limited
 */

#ifndef MCPM_H
#define MCPM_H

/*
 * Maximum number of possible clusters / CPUs per cluster.
 *
 * This should be sufficient for quite a while, while keeping the
 * (assembly) code simpler.  When this starts to grow then we'll have
 * to consider dynamic allocation.
 */
#define MAX_CPUS_PER_CLUSTER	4

#ifdef CONFIG_MCPM_QUAD_CLUSTER
#define MAX_NR_CLUSTERS		4
#else
#define MAX_NR_CLUSTERS		2
#endif

#ifndef __ASSEMBLY__

#include <linux/types.h>
#include <asm/cacheflush.h>

/*
 * Platform specific code should use this symbol to set up secondary
 * entry location for processors to use when released from reset.
 */
extern void mcpm_entry_point(void);

/*
 * This is used to indicate where the given CPU from given cluster should
 * branch once it is ready to re-enter the kernel using ptr, or NULL if it
 * should be gated.  A gated CPU is held in a WFE loop until its vector
 * becomes non NULL.
 */
void mcpm_set_entry_vector(unsigned cpu, unsigned cluster, void *ptr);

/*
 * This sets an early poke i.e a value to be poked into some address
 * from very early assembly code before the CPU is ungated.  The
 * address must be physical, and if 0 then nothing will happen.
 */
void mcpm_set_early_poke(unsigned cpu, unsigned cluster,
			 unsigned long poke_phys_addr, unsigned long poke_val);

/*
 * CPU/cluster power operations API for higher subsystems to use.
 */

/**
 * mcpm_is_available - returns whether MCPM is initialized and available
 *
 * This returns true or false accordingly.
 */
bool mcpm_is_available(void);

/**
 * mcpm_cpu_power_up - make given CPU in given cluster runable
 *
 * @cpu: CPU number within given cluster
 * @cluster: cluster number for the CPU
 *
 * The identified CPU is brought out of reset.  If the cluster was powered
 * down then it is brought up as well, taking care not to let the other CPUs
 * in the cluster run, and ensuring appropriate cluster setup.
 *
 * Caller must ensure the appropriate entry vector is initialized with
 * mcpm_set_entry_vector() prior to calling this.
 *
 * This must be called in a sleepable context.  However, the implementation
 * is strongly encouraged to return early and let the operation happen
 * asynchronously, especially when significant delays are expected.
 *
 * If the operation cannot be performed then an error code is returned.
 */
int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster);

/**
 * mcpm_cpu_power_down - power the calling CPU down
 *
 * The calling CPU is powered down.
 *
 * If this CPU is found to be the "last man standing" in the cluster
 * then the cluster is prepared for power-down too.
 *
 * This must be called with interrupts disabled.
 *
 * On success this does not return.  Re-entry in the kernel is expected
 * via mcpm_entry_point.
 *
 * This will return if mcpm_platform_register() has not been called
 * previously in which case the caller should take appropriate action.
 *
 * On success, the CPU is not guaranteed to be truly halted until
 * mcpm_wait_for_cpu_powerdown() subsequently returns non-zero for the
 * specified cpu.  Until then, other CPUs should make sure they do not
 * trash memory the target CPU might be executing/accessing.
 */
void mcpm_cpu_power_down(void);

/**
 * mcpm_wait_for_cpu_powerdown - wait for a specified CPU to halt, and
 *	make sure it is powered off
 *
 * @cpu: CPU number within given cluster
 * @cluster: cluster number for the CPU
 *
 * Call this function to ensure that a pending powerdown has taken
 * effect and the CPU is safely parked before performing non-mcpm
 * operations that may affect the CPU (such as kexec trashing the
 * kernel text).
 *
 * It is *not* necessary to call this function if you only need to
 * serialise a pending powerdown with mcpm_cpu_power_up() or a wakeup
 * event.
 *
 * Do not call this function unless the specified CPU has already
 * called mcpm_cpu_power_down() or has committed to doing so.
 *
 * @return:
 *	- zero if the CPU is in a safely parked state
 *	- nonzero otherwise (e.g., timeout)
 */
int mcpm_wait_for_cpu_powerdown(unsigned int cpu, unsigned int cluster);

/**
 * mcpm_cpu_suspend - bring the calling CPU in a suspended state
 *
 * The calling CPU is suspended.  This is similar to mcpm_cpu_power_down()
 * except for possible extra platform specific configuration steps to allow
 * an asynchronous wake-up e.g. with a pending interrupt.
 *
 * If this CPU is found to be the "last man standing" in the cluster
 * then the cluster may be prepared for power-down too.
 *
 * This must be called with interrupts disabled.
 *
 * On success this does not return.  Re-entry in the kernel is expected
 * via mcpm_entry_point.
 *
 * This will return if mcpm_platform_register() has not been called
 * previously in which case the caller should take appropriate action.
 */
void mcpm_cpu_suspend(void);

/**
 * mcpm_cpu_powered_up - housekeeping workafter a CPU has been powered up
 *
 * This lets the platform specific backend code perform needed housekeeping
 * work.  This must be called by the newly activated CPU as soon as it is
 * fully operational in kernel space, before it enables interrupts.
 *
 * If the operation cannot be performed then an error code is returned.
 */
int mcpm_cpu_powered_up(void);

/*
 * Platform specific callbacks used in the implementation of the above API.
 *
 * cpu_powerup:
 * Make given CPU runable. Called with MCPM lock held and IRQs disabled.
 * The given cluster is assumed to be set up (cluster_powerup would have
 * been called beforehand). Must return 0 for success or negative error code.
 *
 * cluster_powerup:
 * Set up power for given cluster. Called with MCPM lock held and IRQs
 * disabled. Called before first cpu_powerup when cluster is down. Must
 * return 0 for success or negative error code.
 *
 * cpu_suspend_prepare:
 * Special suspend configuration. Called on target CPU with MCPM lock held
 * and IRQs disabled. This callback is optional. If provided, it is called
 * before cpu_powerdown_prepare.
 *
 * cpu_powerdown_prepare:
 * Configure given CPU for power down. Called on target CPU with MCPM lock
 * held and IRQs disabled. Power down must be effective only at the next WFI instruction.
 *
 * cluster_powerdown_prepare:
 * Configure given cluster for power down. Called on one CPU from target
 * cluster with MCPM lock held and IRQs disabled. A cpu_powerdown_prepare
 * for each CPU in the cluster has happened when this occurs.
 *
 * cpu_cache_disable:
 * Clean and disable CPU level cache for the calling CPU. Called on with IRQs
 * disabled only. The CPU is no longer cache coherent with the rest of the
 * system when this returns.
 *
 * cluster_cache_disable:
 * Clean and disable the cluster wide cache as well as the CPU level cache
 * for the calling CPU. No call to cpu_cache_disable will happen for this
 * CPU. Called with IRQs disabled and only when all the other CPUs are done
 * with their own cpu_cache_disable. The cluster is no longer cache coherent
 * with the rest of the system when this returns.
 *
 * cpu_is_up:
 * Called on given CPU after it has been powered up or resumed. The MCPM lock
 * is held and IRQs disabled. This callback is optional.
 *
 * cluster_is_up:
 * Called by the first CPU to be powered up or resumed in given cluster.
 * The MCPM lock is held and IRQs disabled. This callback is optional. If
 * provided, it is called before cpu_is_up for that CPU.
 *
 * wait_for_powerdown:
 * Wait until given CPU is powered down. This is called in sleeping context.
 * Some reasonable timeout must be considered. Must return 0 for success or
 * negative error code.
 */
struct mcpm_platform_ops {
	int (*cpu_powerup)(unsigned int cpu, unsigned int cluster);
	int (*cluster_powerup)(unsigned int cluster);
	void (*cpu_suspend_prepare)(unsigned int cpu, unsigned int cluster);
	void (*cpu_powerdown_prepare)(unsigned int cpu, unsigned int cluster);
	void (*cluster_powerdown_prepare)(unsigned int cluster);
	void (*cpu_cache_disable)(void);
	void (*cluster_cache_disable)(void);
	void (*cpu_is_up)(unsigned int cpu, unsigned int cluster);
	void (*cluster_is_up)(unsigned int cluster);
	int (*wait_for_powerdown)(unsigned int cpu, unsigned int cluster);
};

/**
 * mcpm_platform_register - register platform specific power methods
 *
 * @ops: mcpm_platform_ops structure to register
 *
 * An error is returned if the registration has been done previously.
 */
int __init mcpm_platform_register(const struct mcpm_platform_ops *ops);

/**
 * mcpm_sync_init - Initialize the cluster synchronization support
 *
 * @power_up_setup: platform specific function invoked during very
 * 		    early CPU/cluster bringup stage.
 *
 * This prepares memory used by vlocks and the MCPM state machine used
 * across CPUs that may have their caches active or inactive. Must be
 * called only after a successful call to mcpm_platform_register().
 *
 * The power_up_setup argument is a pointer to assembly code called when
 * the MMU and caches are still disabled during boot  and no stack space is
 * available. The affinity level passed to that code corresponds to the
 * resource that needs to be initialized (e.g. 1 for cluster level, 0 for
 * CPU level).  Proper exclusion mechanisms are already activated at that
 * point.
 */
int __init mcpm_sync_init(
	void (*power_up_setup)(unsigned int affinity_level));

/**
 * mcpm_loopback - make a run through the MCPM low-level code
 *
 * @cache_disable: pointer to function performing cache disabling
 *
 * This exercises the MCPM machinery by soft resetting the CPU and branching
 * to the MCPM low-level entry code before returning to the caller.
 * The @cache_disable function must do the necessary cache disabling to
 * let the regular kernel init code turn it back on as if the CPU was
 * hotplugged in. The MCPM state machine is set as if the cluster was
 * initialized meaning the power_up_setup callback passed to mcpm_sync_init()
 * will be invoked for all affinity levels. This may be useful to initialize
 * some resources such as enabling the CCI that requires the cache to be off, or simply for testing purposes.
 */
int __init mcpm_loopback(void (*cache_disable)(void));

void __init mcpm_smp_set_ops(void);

/*
 * Synchronisation structures for coordinating safe cluster setup/teardown.
 * This is private to the MCPM core code and shared between C and assembly.
 * When modifying this structure, make sure you update the MCPM_SYNC_ defines
 * to match.
 */
struct mcpm_sync_struct {
	/* individual CPU states */
	struct {
		s8 cpu __aligned(__CACHE_WRITEBACK_GRANULE);
	} cpus[MAX_CPUS_PER_CLUSTER];

	/* cluster state */
	s8 cluster __aligned(__CACHE_WRITEBACK_GRANULE);

	/* inbound-side state */
	s8 inbound __aligned(__CACHE_WRITEBACK_GRANULE);
};

struct sync_struct {
	struct mcpm_sync_struct clusters[MAX_NR_CLUSTERS];
};

#else

/*
 * asm-offsets.h causes trouble when included in .c files, and cacheflush.h
 * cannot be included in asm files.  Let's work around the conflict like this.
 */
#include <asm/asm-offsets.h>
#define __CACHE_WRITEBACK_GRANULE CACHE_WRITEBACK_GRANULE

#endif /* ! __ASSEMBLY__ */

/* Definitions for mcpm_sync_struct */
#define CPU_DOWN		0x11
#define CPU_COMING_UP		0x12
#define CPU_UP			0x13
#define CPU_GOING_DOWN		0x14

#define CLUSTER_DOWN		0x21
#define CLUSTER_UP		0x22
#define CLUSTER_GOING_DOWN	0x23

#define INBOUND_NOT_COMING_UP	0x31
#define INBOUND_COMING_UP	0x32

/*
 * Offsets for the mcpm_sync_struct members, for use in asm.
 * We don't want to make them global to the kernel via asm-offsets.c.
 */
#define MCPM_SYNC_CLUSTER_CPUS	0
#define MCPM_SYNC_CPU_SIZE	__CACHE_WRITEBACK_GRANULE
#define MCPM_SYNC_CLUSTER_CLUSTER \
	(MCPM_SYNC_CLUSTER_CPUS + MCPM_SYNC_CPU_SIZE * MAX_CPUS_PER_CLUSTER)
#define MCPM_SYNC_CLUSTER_INBOUND \
	(MCPM_SYNC_CLUSTER_CLUSTER + __CACHE_WRITEBACK_GRANULE)
#define MCPM_SYNC_CLUSTER_SIZE \
	(MCPM_SYNC_CLUSTER_INBOUND + __CACHE_WRITEBACK_GRANULE)

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASM_MCS_LOCK_H
#define __ASM_MCS_LOCK_H

#ifdef CONFIG_SMP
#include <asm/spinlock.h>

/* MCS spin-locking. */
#define arch_mcs_spin_lock_contended(lock)				\
do {									\
	/* Ensure prior stores are observed before we enter wfe. */	\
	smp_mb();							\
	while (!(smp_load_acquire(lock)))				\
		wfe();							\
} while (0)								\

#define arch_mcs_spin_unlock_contended(lock)				\
do {									\
	smp_store_release(lock, 1);					\
	dsb_sev();							\
} while (0)

#endif	/* CONFIG_SMP */
#endif	/* __ASM_MCS_LOCK_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_MEMBLOCK_H
#define _ASM_ARM_MEMBLOCK_H

struct machine_desc;

void arm_memblock_init(const struct machine_desc *);
phys_addr_t arm_memblock_steal(phys_addr_t size, phys_addr_t align);

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/memory.h
 *
 *  Copyright (C) 2000-2002 Russell King
 *  modification for nommu, Hyok S. Choi, 2004
 *
 *  Note: this file should not be included by non-asm/.h files
 */
#ifndef __ASM_ARM_MEMORY_H
#define __ASM_ARM_MEMORY_H

#include <linux/compiler.h>
#include <linux/const.h>
#include <linux/types.h>
#include <linux/sizes.h>

#ifdef CONFIG_NEED_MACH_MEMORY_H
#include <mach/memory.h>
#endif
#include <asm/kasan_def.h>

/*
 * PAGE_OFFSET: the virtual address of the start of lowmem, memory above
 *   the virtual address range for userspace.
 * KERNEL_OFFSET: the virtual address of the start of the kernel image.
 *   we may further offset this with TEXT_OFFSET in practice.
 */
#define PAGE_OFFSET		UL(CONFIG_PAGE_OFFSET)
#define KERNEL_OFFSET		(PAGE_OFFSET)

#ifdef CONFIG_MMU

/*
 * TASK_SIZE - the maximum size of a user space task.
 * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area
 */
#ifndef CONFIG_KASAN
#define TASK_SIZE		(UL(CONFIG_PAGE_OFFSET) - UL(SZ_16M))
#else
#define TASK_SIZE		(KASAN_SHADOW_START)
#endif
#define TASK_UNMAPPED_BASE	ALIGN(TASK_SIZE / 3, SZ_16M)

/*
 * The maximum size of a 26-bit user space task.
 */
#define TASK_SIZE_26		(UL(1) << 26)

/*
 * The module space lives between the addresses given by TASK_SIZE
 * and PAGE_OFFSET - it must be within 32MB of the kernel text.
 */
#ifndef CONFIG_THUMB2_KERNEL
#define MODULES_VADDR		(PAGE_OFFSET - SZ_16M)
#else
/* smaller range for Thumb-2 symbols relocation (2^24)*/
#define MODULES_VADDR		(PAGE_OFFSET - SZ_8M)
#endif

#if TASK_SIZE > MODULES_VADDR
#error Top of user space clashes with start of module space
#endif

/*
 * The highmem pkmap virtual space shares the end of the module area.
 */
#ifdef CONFIG_HIGHMEM
#define MODULES_END		(PAGE_OFFSET - PMD_SIZE)
#else
#define MODULES_END		(PAGE_OFFSET)
#endif

/*
 * The XIP kernel gets mapped at the bottom of the module vm area.
 * Since we use sections to map it, this macro replaces the physical address
 * with its virtual address while keeping offset from the base section.
 */
#define XIP_VIRT_ADDR(physaddr)  (MODULES_VADDR + ((physaddr) & 0x000fffff))

#define FDT_FIXED_BASE		UL(0xff800000)
#define FDT_FIXED_SIZE		(2 * SECTION_SIZE)
#define FDT_VIRT_BASE(physbase)	((void *)(FDT_FIXED_BASE | (physbase) % SECTION_SIZE))

#if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)
/*
 * Allow 16MB-aligned ioremap pages
 */
#define IOREMAP_MAX_ORDER	24
#endif

#define VECTORS_BASE		UL(0xffff0000)

#else /* CONFIG_MMU */

#ifndef __ASSEMBLY__
extern unsigned long setup_vectors_base(void);
extern unsigned long vectors_base;
#define VECTORS_BASE		vectors_base
#endif

/*
 * The limitation of user task size can grow up to the end of free ram region.
 * It is difficult to define and perhaps will never meet the original meaning
 * of this define that was meant to.
 * Fortunately, there is no reference for this in noMMU mode, for now.
 */
#define TASK_SIZE		UL(0xffffffff)

#ifndef TASK_UNMAPPED_BASE
#define TASK_UNMAPPED_BASE	UL(0x00000000)
#endif

#ifndef END_MEM
#define END_MEM     		(UL(CONFIG_DRAM_BASE) + CONFIG_DRAM_SIZE)
#endif

/*
 * The module can be at any place in ram in nommu mode.
 */
#define MODULES_END		(END_MEM)
#define MODULES_VADDR		PAGE_OFFSET

#define XIP_VIRT_ADDR(physaddr)  (physaddr)
#define FDT_VIRT_BASE(physbase)  ((void *)(physbase))

#endif /* !CONFIG_MMU */

#ifdef CONFIG_XIP_KERNEL
#define KERNEL_START		_sdata
#else
#define KERNEL_START		_stext
#endif
#define KERNEL_END		_end

/*
 * We fix the TCM memories max 32 KiB ITCM resp DTCM at these
 * locations
 */
#ifdef CONFIG_HAVE_TCM
#define ITCM_OFFSET	UL(0xfffe0000)
#define DTCM_OFFSET	UL(0xfffe8000)
#endif

/*
 * Convert a page to/from a physical address
 */
#define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
#define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))

/*
 * PLAT_PHYS_OFFSET is the offset (from zero) of the start of physical
 * memory.  This is used for XIP and NoMMU kernels, and on platforms that don't
 * have CONFIG_ARM_PATCH_PHYS_VIRT. Assembly code must always use
 * PLAT_PHYS_OFFSET and not PHYS_OFFSET.
 */
#define PLAT_PHYS_OFFSET	UL(CONFIG_PHYS_OFFSET)

#ifndef __ASSEMBLY__

/*
 * Physical start and end address of the kernel sections. These addresses are
 * 2MB-aligned to match the section mappings placed over the kernel. We use
 * u64 so that LPAE mappings beyond the 32bit limit will work out as well.
 */
extern u64 kernel_sec_start;
extern u64 kernel_sec_end;

/*
 * Physical vs virtual RAM address space conversion.  These are
 * private definitions which should NOT be used outside memory.h
 * files.  Use virt_to_phys/phys_to_virt/__pa/__va instead.
 *
 * PFNs are used to describe any physical page; this means
 * PFN 0 == physical address 0.
 */

#if defined(CONFIG_ARM_PATCH_PHYS_VIRT)

/*
 * Constants used to force the right instruction encodings and shifts
 * so that all we need to do is modify the 8-bit constant field.
 */
#define __PV_BITS_31_24	0x81000000
#define __PV_BITS_23_16	0x810000
#define __PV_BITS_7_0	0x81

extern unsigned long __pv_phys_pfn_offset;
extern u64 __pv_offset;
extern void fixup_pv_table(const void *, unsigned long);
extern const void *__pv_table_begin, *__pv_table_end;

#define PHYS_OFFSET	((phys_addr_t)__pv_phys_pfn_offset << PAGE_SHIFT)
#define PHYS_PFN_OFFSET	(__pv_phys_pfn_offset)

#ifndef CONFIG_THUMB2_KERNEL
#define __pv_stub(from,to,instr)			\
	__asm__("@ __pv_stub\n"				\
	"1:	" instr "	%0, %1, %2\n"		\
	"2:	" instr "	%0, %0, %3\n"		\
	"	.pushsection .pv_table,\"a\"\n"		\
	"	.long	1b - ., 2b - .\n"		\
	"	.popsection\n"				\
	: "=r" (to)					\
	: "r" (from), "I" (__PV_BITS_31_24),		\
	  "I"(__PV_BITS_23_16))

#define __pv_add_carry_stub(x, y)			\
	__asm__("@ __pv_add_carry_stub\n"		\
	"0:	movw	%R0, #0\n"			\
	"	adds	%Q0, %1, %R0, lsl #20\n"	\
	"1:	mov	%R0, %2\n"			\
	"	adc	%R0, %R0, #0\n"			\
	"	.pushsection .pv_table,\"a\"\n"		\
	"	.long	0b - ., 1b - .\n"		\
	"	.popsection\n"				\
	: "=&r" (y)					\
	: "r" (x), "I" (__PV_BITS_7_0)			\
	: "cc")

#else
#define __pv_stub(from,to,instr)			\
	__asm__("@ __pv_stub\n"				\
	"0:	movw	%0, #0\n"			\
	"	lsl	%0, #21\n"			\
	"	" instr " %0, %1, %0\n"			\
	"	.pushsection .pv_table,\"a\"\n"		\
	"	.long	0b - .\n"			\
	"	.popsection\n"				\
	: "=&r" (to)					\
	: "r" (from))

#define __pv_add_carry_stub(x, y)			\
	__asm__("@ __pv_add_carry_stub\n"		\
	"0:	movw	%R0, #0\n"			\
	"	lsls	%R0, #21\n"			\
	"	adds	%Q0, %1, %R0\n"			\
	"1:	mvn	%R0, #0\n"			\
	"	adc	%R0, %R0, #0\n"			\
	"	.pushsection .pv_table,\"a\"\n"		\
	"	.long	0b - ., 1b - .\n"		\
	"	.popsection\n"				\
	: "=&r" (y)					\
	: "r" (x)					\
	: "cc")
#endif

static inline phys_addr_t __virt_to_phys_nodebug(unsigned long x)
{
	phys_addr_t t;

	if (sizeof(phys_addr_t) == 4) {
		__pv_stub(x, t, "add");
	} else {
		__pv_add_carry_stub(x, t);
	}
	return t;
}

static inline unsigned long __phys_to_virt(phys_addr_t x)
{
	unsigned long t;

	/*
	 * 'unsigned long' cast discard upper word when
	 * phys_addr_t is 64 bit, and makes sure that inline
	 * assembler expression receives 32 bit argument
	 * in place where 'r' 32 bit operand is expected.
	 */
	__pv_stub((unsigned long) x, t, "sub");
	return t;
}

#else

#define PHYS_OFFSET	PLAT_PHYS_OFFSET
#define PHYS_PFN_OFFSET	((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))

static inline phys_addr_t __virt_to_phys_nodebug(unsigned long x)
{
	return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET;
}

static inline unsigned long __phys_to_virt(phys_addr_t x)
{
	return x - PHYS_OFFSET + PAGE_OFFSET;
}

#endif

#define virt_to_pfn(kaddr) \
	((((unsigned long)(kaddr) - PAGE_OFFSET) >> PAGE_SHIFT) + \
	 PHYS_PFN_OFFSET)

#define __pa_symbol_nodebug(x)	__virt_to_phys_nodebug((x))

#ifdef CONFIG_DEBUG_VIRTUAL
extern phys_addr_t __virt_to_phys(unsigned long x);
extern phys_addr_t __phys_addr_symbol(unsigned long x);
#else
#define __virt_to_phys(x)	__virt_to_phys_nodebug(x)
#define __phys_addr_symbol(x)	__pa_symbol_nodebug(x)
#endif

/*
 * These are *only* valid on the kernel direct mapped RAM memory.
 * Note: Drivers should NOT use these.  They are the wrong
 * translation for translating DMA addresses.  Use the driver
 * DMA support - see dma-mapping.h.
 */
#define virt_to_phys virt_to_phys
static inline phys_addr_t virt_to_phys(const volatile void *x)
{
	return __virt_to_phys((unsigned long)(x));
}

#define phys_to_virt phys_to_virt
static inline void *phys_to_virt(phys_addr_t x)
{
	return (void *)__phys_to_virt(x);
}

/*
 * Drivers should NOT use these either.
 */
#define __pa(x)			__virt_to_phys((unsigned long)(x))
#define __pa_symbol(x)		__phys_addr_symbol(RELOC_HIDE((unsigned long)(x), 0))
#define __va(x)			((void *)__phys_to_virt((phys_addr_t)(x)))
#define pfn_to_kaddr(pfn)	__va((phys_addr_t)(pfn) << PAGE_SHIFT)

extern long long arch_phys_to_idmap_offset;

/*
 * These are for systems that have a hardware interconnect supported alias
 * of physical memory for idmap purposes.  Most cases should leave these
 * untouched.  Note: this can only return addresses less than 4GiB.
 */
static inline bool arm_has_idmap_alias(void)
{
	return IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset != 0;
}

#define IDMAP_INVALID_ADDR ((u32)~0)

static inline unsigned long phys_to_idmap(phys_addr_t addr)
{
	if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset) {
		addr += arch_phys_to_idmap_offset;
		if (addr > (u32)~0)
			addr = IDMAP_INVALID_ADDR;
	}
	return addr;
}

static inline phys_addr_t idmap_to_phys(unsigned long idmap)
{
	phys_addr_t addr = idmap;

	if (IS_ENABLED(CONFIG_MMU) && arch_phys_to_idmap_offset)
		addr -= arch_phys_to_idmap_offset;

	return addr;
}

static inline unsigned long __virt_to_idmap(unsigned long x)
{
	return phys_to_idmap(__virt_to_phys(x));
}

#define virt_to_idmap(x)	__virt_to_idmap((unsigned long)(x))

/*
 * Conversion between a struct page and a physical address.
 *
 *  page_to_pfn(page)	convert a struct page * to a PFN number
 *  pfn_to_page(pfn)	convert a _valid_ PFN number to struct page *
 *
 *  virt_to_page(k)	convert a _valid_ virtual address to struct page *
 *  virt_addr_valid(k)	indicates whether a virtual address is valid
 */
#define ARCH_PFN_OFFSET		PHYS_PFN_OFFSET

#define virt_to_page(kaddr)	pfn_to_page(virt_to_pfn(kaddr))
#define virt_addr_valid(kaddr)	(((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) \
					&& pfn_valid(virt_to_pfn(kaddr)))

#endif

#include <asm-generic/memory_model.h>

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ARM_MMU_H
#define __ARM_MMU_H

#ifdef CONFIG_MMU

typedef struct {
#ifdef CONFIG_CPU_HAS_ASID
	atomic64_t	id;
#else
	int		switch_pending;
#endif
	atomic_t	vmalloc_seq;
	unsigned long	sigpage;
#ifdef CONFIG_VDSO
	unsigned long	vdso;
#endif
#ifdef CONFIG_BINFMT_ELF_FDPIC
	unsigned long	exec_fdpic_loadmap;
	unsigned long	interp_fdpic_loadmap;
#endif
} mm_context_t;

#ifdef CONFIG_CPU_HAS_ASID
#define ASID_BITS	8
#define ASID_MASK	((~0ULL) << ASID_BITS)
#define ASID(mm)	((unsigned int)((mm)->context.id.counter & ~ASID_MASK))
#else
#define ASID(mm)	(0)
#endif

#else

/*
 * From nommu.h:
 *  Copyright (C) 2002, David McCullough <davidm@snapgear.com>
 *  modified for 2.6 by Hyok S. Choi <hyok.choi@samsung.com>
 */
typedef struct {
	unsigned long	end_brk;
#ifdef CONFIG_BINFMT_ELF_FDPIC
	unsigned long	exec_fdpic_loadmap;
	unsigned long	interp_fdpic_loadmap;
#endif
} mm_context_t;

#endif

#endif


code:
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 *  arch/arm/include/asm/mmu_context.h
 *
 *  Copyright (C) 1996 Russell King.
 *
 *  Changelog:
 *   27-06-1996	RMK	Created
 */
#ifndef __ASM_ARM_MMU_CONTEXT_H
#define __ASM_ARM_MMU_CONTEXT_H

#include <linux/compiler.h>
#include <linux/sched.h>
#include <linux/mm_types.h>
#include <linux/preempt.h>

#include <asm/cacheflush.h>
#include <asm/cachetype.h>
#include <asm/proc-fns.h>
#include <asm/smp_plat.h>
#include <asm-generic/mm_hooks.h>

void __check_vmalloc_seq(struct mm_struct *mm);

#ifdef CONFIG_MMU
static inline void check_vmalloc_seq(struct mm_struct *mm)
{
	if (!IS_ENABLED(CONFIG_ARM_LPAE) &&
	    unlikely(atomic_read(&mm->context.vmalloc_seq) !=
		     atomic_read(&init_mm.context.vmalloc_seq)))
		__check_vmalloc_seq(mm);
}
#endif

#ifdef CONFIG_CPU_HAS_ASID

void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk);

#define init_new_context init_new_context
static inline int
init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
	atomic64_set(&mm->context.id, 0);
	return 0;
}

#ifdef CONFIG_ARM_ERRATA_798181
void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
			     cpumask_t *mask);
#else  /* !CONFIG_ARM_ERRATA_798181 */
static inline void a15_erratum_get_cpumask(int this_cpu, struct mm_struct *mm,
					   cpumask_t *mask)
{
}
#endif /* CONFIG_ARM_ERRATA_798181 */

#else	/* !CONFIG_CPU_HAS_ASID */

#ifdef CONFIG_MMU

static inline void check_and_switch_context(struct mm_struct *mm,
					    struct task_struct *tsk)
{
	check_vmalloc_seq(mm);

	if (irqs_disabled())
		/*
		 * cpu_switch_mm() needs to flush the VIVT caches. To avoid
		 * high interrupt latencies, defer the call and continue
		 * running with the old mm. Since we only support UP systems
		 * on non-ASID CPUs, the old mm will remain valid until the
		 * finish_arch_post_lock_switch() call.
		 */
		mm->context.switch_pending = 1;
	else
		cpu_switch_mm(mm->pgd, mm);
}

#ifndef MODULE
#define finish_arch_post_lock_switch \
	finish_arch_post_lock_switch
static inline void finish_arch_post_lock_switch(void)
{
	struct mm_struct *mm = current->mm;

	if (mm && mm->context.switch_pending) {
		/*
		 * Preemption must be disabled during cpu_switch_mm() as we
		 * have some stateful cache flush implementations. Check
		 * switch_pending again in case we were preempted and the
		 * switch to this mm was already done.
		 */
		preempt_disable();
		if (mm->context.switch_pending) {
			mm->context.switch_pending = 0;
			cpu_switch_mm(mm->pgd, mm);
		}
		preempt_enable_no_resched();
	}
}
#endif /* !MODULE */

#endif	/* CONFIG_MMU */

#endif	/* CONFIG_CPU_HAS_ASID */

#define activate_mm(prev,next)		switch_mm(prev, next, NULL)

/*
 * This is the actual mm switch as far as the scheduler
 * is concerned.  No registers are touched.  We avoid
 * calling the CPU specific function when the mm hasn't
 * actually changed.
 */
static inline void
switch_mm(struct mm_struct *prev, struct mm_struct *next,
	  struct task_struct *tsk)
{
#ifdef CONFIG_MMU
	unsigned int cpu = smp_processor_id();

	/*
	 * __sync_icache_dcache doesn't broadcast the I-cache invalidation,
	 * so check for possible thread migration and invalidate the I-cache
	 * if we're new to this CPU.
	 */
	if (cache_ops_need_broadcast() &&
	    !cpumask_empty(mm_cpumask(next)) &&
	    !cpumask_test_cpu(cpu, mm_cpumask(next)))
		__flush_icache_all();

	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) {
		check_and_switch_context(next, tsk);
		if (cache_is_vivt())
			cpumask_clear_cpu(cpu, mm_cpumask(prev));
	}
#endif
}

#ifdef CONFIG_VMAP_STACK
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
	if (mm != &init_mm)
		check_vmalloc_seq(mm);
}
#define enter_lazy_tlb enter_lazy_tlb
#endif

#include <asm-generic/mmu_context.h>

#endif


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_ARM_MODULE_H
#define _ASM_ARM_MODULE_H

#include <asm-generic/module.h>
#include <asm/unwind.h>

#ifdef CONFIG_ARM_UNWIND
#define ELF_SECTION_UNWIND 0x70000001
#endif

#define PLT_ENT_STRIDE		L1_CACHE_BYTES
#define PLT_ENT_COUNT		(PLT_ENT_STRIDE / sizeof(u32))
#define PLT_ENT_SIZE		(sizeof(struct plt_entries) / PLT_ENT_COUNT)

struct plt_entries {
	u32	ldr[PLT_ENT_COUNT];
	u32	lit[PLT_ENT_COUNT];
};

struct mod_plt_sec {
	struct elf32_shdr	*plt;
	struct plt_entries	*plt_ent;
	int			plt_count;
};

struct mod_arch_specific {
#ifdef CONFIG_ARM_UNWIND
	struct list_head unwind_list;
	struct unwind_table *init_table;
#endif
#ifdef CONFIG_ARM_MODULE_PLTS
	struct mod_plt_sec	core;
	struct mod_plt_sec	init;
#endif
};

struct module;
u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val);
#ifdef CONFIG_ARM_MODULE_PLTS
bool in_module_plt(unsigned long loc);
#else
static inline bool in_module_plt(unsigned long loc) { return false; }
#endif

#ifdef CONFIG_THUMB2_KERNEL
#define HAVE_ARCH_KALLSYMS_SYMBOL_VALUE
static inline unsigned long kallsyms_symbol_value(const Elf_Sym *sym)
{
	if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
		return sym->st_value & ~1;

	return sym->st_value;
}
#endif

#endif /* _ASM_ARM_MODULE_H */


code:
/* SPDX-License-Identifier: GPL-2.0 */
#ifdef CONFIG_ARM_MODULE_PLTS
SECTIONS {
	.plt : { BYTE(0) }
	.init.plt : { BYTE(0) }
}
#endif