Merge branch 'master' into test

* master: (688 commits)
  dt-bindings: mailbox: qcom: Document the APCS clock binding
  mailbox: qcom: Create APCS child device for clock controller
  mailbox: qcom: Convert APCS IPC driver to use regmap
  KVM/SVM: Allow direct access to MSR_IA32_SPEC_CTRL
  KVM/VMX: Allow direct access to MSR_IA32_SPEC_CTRL
  KVM/VMX: Emulate MSR_IA32_ARCH_CAPABILITIES
  KVM/x86: Add IBPB support
  KVM/x86: Update the reverse_cpuid list to include CPUID_7_EDX
  pinctrl: remove include file from <linux/device.h>
  firmware: dmi: handle missing DMI data gracefully
  firmware: dmi_scan: Fix handling of empty DMI strings
  firmware: dmi_scan: Drop dmi_initialized
  firmware: dmi: Optimize dmi_matches
  Revert "defer call to mem_cgroup_sk_alloc()"
  soreuseport: fix mem leak in reuseport_add_sock()
  net: qlge: use memmove instead of skb_copy_to_linear_data
  net: qed: use correct strncpy() size
  net: cxgb4: avoid memcpy beyond end of source buffer
  cls_u32: add missing RCU annotation.
  r8152: set rx mode early when linking on
  ...
This commit is contained in:
Jens Axboe 2018-02-05 12:55:38 -07:00
commit 9e05c86499
787 changed files with 35538 additions and 10069 deletions

View File

@ -0,0 +1,42 @@
What: /dev/rtcX
Date: April 2005
KernelVersion: 2.6.12
Contact: linux-rtc@vger.kernel.org
Description:
The ioctl interface to drivers for real-time clocks (RTCs).
Following actions are supported:
* RTC_RD_TIME, RTC_SET_TIME: Read or set the RTC time. Time
format is a Gregorian calendar date and 24 hour wall clock
time.
* RTC_AIE_ON, RTC_AIE_OFF: Enable or disable the alarm interrupt
for RTCs that support alarms
* RTC_ALM_READ, RTC_ALM_SET: Read or set the alarm time for
RTCs that support alarms. Can be set upto 24 hours in the
future. Requires a separate RTC_AIE_ON call to enable the
alarm interrupt. (Prefer to use RTC_WKALM_*)
* RTC_WKALM_RD, RTC_WKALM_SET: For RTCs that support a more
powerful interface, which can issue alarms beyond 24 hours and
enable IRQs in the same request.
* RTC_PIE_ON, RTC_PIE_OFF: Enable or disable the periodic
interrupt for RTCs that support periodic interrupts.
* RTC_UIE_ON, RTC_UIE_OFF: Enable or disable the update
interrupt for RTCs that support it.
* RTC_IRQP_READ, RTC_IRQP_SET: Read or set the frequency for
periodic interrupts for RTCs that support periodic interrupts.
Requires a separate RTC_PIE_ON call to enable the periodic
interrupts.
The ioctl() calls supported by the older /dev/rtc interface are
also supported by the newer RTC class framework. However,
because the chips and systems are not standardized, some PC/AT
functionality might not be provided. And in the same way, some
newer features -- including those enabled by ACPI -- are exposed
by the RTC class framework, but can't be supported by the older
driver.

View File

@ -0,0 +1,35 @@
What: /sys/class/ocxl/<afu name>/afu_version
Date: January 2018
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Version of the AFU, in the format <major>:<minor>
Reflects what is read in the configuration space of the AFU
What: /sys/class/ocxl/<afu name>/contexts
Date: January 2018
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Number of contexts for the AFU, in the format <n>/<max>
where:
n: number of currently active contexts, for debug
max: maximum number of contexts supported by the AFU
What: /sys/class/ocxl/<afu name>/pp_mmio_size
Date: January 2018
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Size of the per-process mmio area, as defined in the
configuration space of the AFU
What: /sys/class/ocxl/<afu name>/global_mmio_size
Date: January 2018
Contact: linuxppc-dev@lists.ozlabs.org
Description: read only
Size of the global mmio area, as defined in the
configuration space of the AFU
What: /sys/class/ocxl/<afu name>/global_mmio_area
Date: January 2018
Contact: linuxppc-dev@lists.ozlabs.org
Description: read/write
Give access the global mmio area for the AFU

View File

@ -0,0 +1,91 @@
What: /sys/class/rtc/
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
The rtc/ class subdirectory belongs to the RTC subsystem.
What: /sys/class/rtc/rtcX/
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
The /sys/class/rtc/rtc{0,1,2,3,...} directories correspond
to each RTC device.
What: /sys/class/rtc/rtcX/date
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided date in YYYY-MM-DD format
What: /sys/class/rtc/rtcX/hctosys
Date: September 2009
KernelVersion: 2.6.32
Contact: linux-rtc@vger.kernel.org
Description:
(RO) 1 if the RTC provided the system time at boot via the
CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
What: /sys/class/rtc/rtcX/max_user_freq
Date: October 2007
KernelVersion: 2.6.24
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The maximum interrupt rate an unprivileged user may request
from this RTC.
What: /sys/class/rtc/rtcX/name
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) The name of the RTC corresponding to this sysfs directory
What: /sys/class/rtc/rtcX/since_epoch
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided time as the number of seconds since the epoch
What: /sys/class/rtc/rtcX/time
Date: March 2006
KernelVersion: 2.6.17
Contact: linux-rtc@vger.kernel.org
Description:
(RO) RTC-provided time in 24-hour notation (hh:mm:ss)
What: /sys/class/rtc/rtcX/*/nvmem
Date: February 2016
KernelVersion: 4.6
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The non volatile storage exported as a raw file, as
described in Documentation/nvmem/nvmem.txt
What: /sys/class/rtc/rtcX/offset
Date: February 2016
KernelVersion: 4.6
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The amount which the rtc clock has been adjusted in
firmware. Visible only if the driver supports clock offset
adjustment. The unit is parts per billion, i.e. The number of
clock ticks which are added to or removed from the rtc's base
clock per billion ticks. A positive value makes a day pass more
slowly, longer, and a negative value makes a day pass more
quickly.
What: /sys/class/rtc/rtcX/wakealarm
Date: February 2007
KernelVersion: 2.6.20
Contact: linux-rtc@vger.kernel.org
Description:
(RW) The time at which the clock will generate a system wakeup
event. This is a one shot wakeup event, so must be reset after
wake if a daily wakeup is required. Format is seconds since the
epoch by default, or if there's a leading +, seconds in the
future, or if there is a leading +=, seconds ahead of the
current alarm.

View File

@ -0,0 +1,160 @@
========================================================
OpenCAPI (Open Coherent Accelerator Processor Interface)
========================================================
OpenCAPI is an interface between processors and accelerators. It aims
at being low-latency and high-bandwidth. The specification is
developed by the `OpenCAPI Consortium <http://opencapi.org/>`_.
It allows an accelerator (which could be a FPGA, ASICs, ...) to access
the host memory coherently, using virtual addresses. An OpenCAPI
device can also host its own memory, that can be accessed from the
host.
OpenCAPI is known in linux as 'ocxl', as the open, processor-agnostic
evolution of 'cxl' (the driver for the IBM CAPI interface for
powerpc), which was named that way to avoid confusion with the ISDN
CAPI subsystem.
High-level view
===============
OpenCAPI defines a Data Link Layer (DL) and Transaction Layer (TL), to
be implemented on top of a physical link. Any processor or device
implementing the DL and TL can start sharing memory.
::
+-----------+ +-------------+
| | | |
| | | Accelerated |
| Processor | | Function |
| | +--------+ | Unit | +--------+
| |--| Memory | | (AFU) |--| Memory |
| | +--------+ | | +--------+
+-----------+ +-------------+
| |
+-----------+ +-------------+
| TL | | TLX |
+-----------+ +-------------+
| |
+-----------+ +-------------+
| DL | | DLX |
+-----------+ +-------------+
| |
| PHY |
+---------------------------------------+
Device discovery
================
OpenCAPI relies on a PCI-like configuration space, implemented on the
device. So the host can discover AFUs by querying the config space.
OpenCAPI devices in Linux are treated like PCI devices (with a few
caveats). The firmware is expected to abstract the hardware as if it
was a PCI link. A lot of the existing PCI infrastructure is reused:
devices are scanned and BARs are assigned during the standard PCI
enumeration. Commands like 'lspci' can therefore be used to see what
devices are available.
The configuration space defines the AFU(s) that can be found on the
physical adapter, such as its name, how many memory contexts it can
work with, the size of its MMIO areas, ...
MMIO
====
OpenCAPI defines two MMIO areas for each AFU:
* the global MMIO area, with registers pertinent to the whole AFU.
* a per-process MMIO area, which has a fixed size for each context.
AFU interrupts
==============
OpenCAPI includes the possibility for an AFU to send an interrupt to a
host process. It is done through a 'intrp_req' defined in the
Transaction Layer, specifying a 64-bit object handle which defines the
interrupt.
The driver allows a process to allocate an interrupt and obtain its
64-bit object handle, that can be passed to the AFU.
char devices
============
The driver creates one char device per AFU found on the physical
device. A physical device may have multiple functions and each
function can have multiple AFUs. At the time of this writing though,
it has only been tested with devices exporting only one AFU.
Char devices can be found in /dev/ocxl/ and are named as:
/dev/ocxl/<AFU name>.<location>.<index>
where <AFU name> is a max 20-character long name, as found in the
config space of the AFU.
<location> is added by the driver and can help distinguish devices
when a system has more than one instance of the same OpenCAPI device.
<index> is also to help distinguish AFUs in the unlikely case where a
device carries multiple copies of the same AFU.
Sysfs class
===========
An ocxl class is added for the devices representing the AFUs. See
/sys/class/ocxl. The layout is described in
Documentation/ABI/testing/sysfs-class-ocxl
User API
========
open
----
Based on the AFU definition found in the config space, an AFU may
support working with more than one memory context, in which case the
associated char device may be opened multiple times by different
processes.
ioctl
-----
OCXL_IOCTL_ATTACH:
Attach the memory context of the calling process to the AFU so that
the AFU can access its memory.
OCXL_IOCTL_IRQ_ALLOC:
Allocate an AFU interrupt and return an identifier.
OCXL_IOCTL_IRQ_FREE:
Free a previously allocated AFU interrupt.
OCXL_IOCTL_IRQ_SET_FD:
Associate an event fd to an AFU interrupt so that the user process
can be notified when the AFU sends an interrupt.
mmap
----
A process can mmap the per-process MMIO area for interactions with the
AFU.

View File

@ -2758,8 +2758,6 @@
norandmaps Don't use address space randomization. Equivalent to
echo 0 > /proc/sys/kernel/randomize_va_space
noreplace-paravirt [X86,IA-64,PV_OPS] Don't patch paravirt_ops
noreplace-smp [X86-32,SMP] Don't replace SMP instructions
with UP alternatives

View File

@ -0,0 +1,78 @@
EEPROMs (I2C)
Required properties:
- compatible: Must be a "<manufacturer>,<model>" pair. The following <model>
values are supported (assuming "atmel" as manufacturer):
"atmel,24c00",
"atmel,24c01",
"atmel,24cs01",
"atmel,24c02",
"atmel,24cs02",
"atmel,24mac402",
"atmel,24mac602",
"atmel,spd",
"atmel,24c04",
"atmel,24cs04",
"atmel,24c08",
"atmel,24cs08",
"atmel,24c16",
"atmel,24cs16",
"atmel,24c32",
"atmel,24cs32",
"atmel,24c64",
"atmel,24cs64",
"atmel,24c128",
"atmel,24c256",
"atmel,24c512",
"atmel,24c1024",
If <manufacturer> is not "atmel", then a fallback must be used
with the same <model> and "atmel" as manufacturer.
Example:
compatible = "microchip,24c128", "atmel,24c128";
Supported manufacturers are:
"catalyst",
"microchip",
"ramtron",
"renesas",
"nxp",
"st",
Some vendors use different model names for chips which are just
variants of the above. Known such exceptions are listed below:
"renesas,r1ex24002" - the fallback is "atmel,24c02"
- reg: The I2C address of the EEPROM.
Optional properties:
- pagesize: The length of the pagesize for writing. Please consult the
manual of your device, that value varies a lot. A wrong value
may result in data loss! If not specified, a safety value of
'1' is used which will be very slow.
- read-only: This parameterless property disables writes to the eeprom.
- size: Total eeprom size in bytes.
- no-read-rollover: This parameterless property indicates that the
multi-address eeprom does not automatically roll over
reads to the next slave address. Please consult the
manual of your device.
- wp-gpios: GPIO to which the write-protect pin of the chip is connected.
Example:
eeprom@52 {
compatible = "atmel,24c32";
reg = <0x52>;
pagesize = <32>;
wp-gpios = <&gpio1 3 0>;
};

View File

@ -1,47 +0,0 @@
EEPROMs (I2C)
Required properties:
- compatible : should be "<manufacturer>,<type>", like these:
"atmel,24c00", "atmel,24c01", "atmel,24c02", "atmel,24c04",
"atmel,24c08", "atmel,24c16", "atmel,24c32", "atmel,24c64",
"atmel,24c128", "atmel,24c256", "atmel,24c512", "atmel,24c1024"
"catalyst,24c32"
"microchip,24c128"
"ramtron,24c64"
"renesas,r1ex24002"
The following manufacturers values have been deprecated:
"at", "at24"
If there is no specific driver for <manufacturer>, a generic
device with <type> and manufacturer "atmel" should be used.
Possible types are:
"24c00", "24c01", "24c02", "24c04", "24c08", "24c16", "24c32", "24c64",
"24c128", "24c256", "24c512", "24c1024", "spd"
- reg : the I2C address of the EEPROM
Optional properties:
- pagesize : the length of the pagesize for writing. Please consult the
manual of your device, that value varies a lot. A wrong value
may result in data loss! If not specified, a safety value of
'1' is used which will be very slow.
- read-only: this parameterless property disables writes to the eeprom
- size: total eeprom size in bytes
Example:
eeprom@52 {
compatible = "atmel,24c32";
reg = <0x52>;
pagesize = <32>;
};

View File

@ -1,7 +1,11 @@
Amlogic Meson I2C controller
Required properties:
- compatible: must be "amlogic,meson6-i2c" or "amlogic,meson-gxbb-i2c"
- compatible: must be:
"amlogic,meson6-i2c" for Meson8 and compatible SoCs
"amlogic,meson-gxbb-i2c" for GXBB and compatible SoCs
"amlogic,meson-axg-i2c"for AXG and compatible SoCs
- reg: physical address and length of the device registers
- interrupts: a single interrupt specifier
- clocks: clock for the device

View File

@ -5,6 +5,7 @@ The MediaTek's I2C controller is used to interface with I2C devices.
Required properties:
- compatible: value should be either of the following.
"mediatek,mt2701-i2c", "mediatek,mt6577-i2c": for MediaTek MT2701
"mediatek,mt2712-i2c": for MediaTek MT2712
"mediatek,mt6577-i2c": for MediaTek MT6577
"mediatek,mt6589-i2c": for MediaTek MT6589
"mediatek,mt7622-i2c": for MediaTek MT7622

View File

@ -1,10 +1,19 @@
* NXP PCA954x I2C bus switch
The driver supports NXP PCA954x and PCA984x I2C mux/switch devices.
Required Properties:
- compatible: Must contain one of the following.
"nxp,pca9540", "nxp,pca9542", "nxp,pca9543", "nxp,pca9544",
"nxp,pca9545", "nxp,pca9546", "nxp,pca9547", "nxp,pca9548"
"nxp,pca9540",
"nxp,pca9542",
"nxp,pca9543",
"nxp,pca9544",
"nxp,pca9545",
"nxp,pca9546", "nxp,pca9846",
"nxp,pca9547", "nxp,pca9847",
"nxp,pca9548", "nxp,pca9848",
"nxp,pca9849"
- reg: The I2C address of the device.

View File

@ -25,6 +25,15 @@ default frequency is 100kHz
whenever you're using the "allwinner,sun6i-a31-i2c"
compatible.
- clocks: : pointers to the reference clocks for this device, the
first one is the one used for the clock on the i2c bus,
the second one is the clock used to acces the registers
of the controller
- clock-names : names of used clocks, mandatory if the second clock is
used, the name must be "core", and "reg" (the latter is
only for Armada 7K/8K).
Examples:
i2c@11000 {
@ -42,3 +51,14 @@ For the Armada XP:
interrupts = <29>;
clock-frequency = <100000>;
};
For the Armada 7040:
i2c@701000 {
compatible = "marvell,mv78230-i2c";
reg = <0x701000 0x20>;
interrupts = <29>;
clock-frequency = <100000>;
clock-names = "core", "reg";
clocks = <&core_clock>, <&reg_clock>;
};

View File

@ -15,12 +15,21 @@ platforms.
Usage: required
Value type: <prop-encoded-array>
Definition: must specify the base address and size of the global block
- clocks:
Usage: required if #clocks-cells property is present
Value type: <phandle>
Definition: phandle to the input PLL, which feeds the APCS mux/divider
- #mbox-cells:
Usage: required
Value type: <u32>
Definition: as described in mailbox.txt, must be 1
- #clock-cells:
Usage: optional
Value type: <u32>
Definition: as described in clock.txt, must be 0
= EXAMPLE
The following example describes the APCS HMSS found in MSM8996 and part of the
@ -44,3 +53,12 @@ GLINK RPM referencing the "rpm_hlos" doorbell therein.
mbox-names = "rpm_hlos";
};
Below is another example of the APCS binding on MSM8916 platforms:
apcs: mailbox@b011000 {
compatible = "qcom,msm8916-apcs-kpss-global";
reg = <0xb011000 0x1000>;
#mbox-cells = <1>;
clocks = <&a53pll>;
#clock-cells = <0>;
};

View File

@ -17,6 +17,9 @@ and generic pin config nodes.
Supported configurations:
- skew-delay is supported on the Ethernet pins
- drive-strength with 4, 8, 12 or 16 mA as argument is supported for
entire groups on the groups "idegrp", "gmii_gmac0_grp", "gmii_gmac1_grp"
and "pcigrp".
Example:

View File

@ -4,7 +4,8 @@ Please refer to fsl,imx-pinctrl.txt in this directory for common binding part
and usage.
Required properties:
- compatible: "fsl,imx6ul-iomuxc"
- compatible: "fsl,imx6ul-iomuxc" for main IOMUX controller or
"fsl,imx6ull-iomuxc-snvs" for i.MX 6ULL's SNVS IOMUX controller.
- fsl,pins: each entry consists of 6 integers and represents the mux and config
setting for one pin. The first 5 integers <mux_reg conf_reg input_reg mux_val
input_val> are specified using a PIN_FUNC_ID macro, which can be found in

View File

@ -0,0 +1,39 @@
Microsemi Ocelot pin controller Device Tree Bindings
----------------------------------------------------
Required properties:
- compatible : Should be "mscc,ocelot-pinctrl"
- reg : Address and length of the register set for the device
- gpio-controller : Indicates this device is a GPIO controller
- #gpio-cells : Must be 2.
The first cell is the pin number and the
second cell specifies GPIO flags, as defined in
<dt-bindings/gpio/gpio.h>.
- gpio-ranges : Range of pins managed by the GPIO controller.
The ocelot-pinctrl driver uses the generic pin multiplexing and generic pin
configuration documented in pinctrl-bindings.txt.
The following generic properties are supported:
- function
- pins
Example:
gpio: pinctrl@71070034 {
compatible = "mscc,ocelot-pinctrl";
reg = <0x71070034 0x28>;
gpio-controller;
#gpio-cells = <2>;
gpio-ranges = <&gpio 0 0 22>;
uart_pins: uart-pins {
pins = "GPIO_6", "GPIO_7";
function = "uart";
};
uart2_pins: uart2-pins {
pins = "GPIO_12", "GPIO_13";
function = "uart2";
};
};

View File

@ -0,0 +1,351 @@
== MediaTek MT7622 pinctrl controller ==
Required properties for the root node:
- compatible: Should be one of the following
"mediatek,mt7622-pinctrl" for MT7622 SoC
- reg: offset and length of the pinctrl space
- gpio-controller: Marks the device node as a GPIO controller.
- #gpio-cells: Should be two. The first cell is the pin number and the
second is the GPIO flags.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
MT7622 pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, slew rate, etc.
We support 2 types of configuration nodes. Those nodes can be either pinmux
nodes or pinconf nodes. Each configuration node can consist of multiple nodes
describing the pinmux and pinconf options.
The name of each subnode doesn't matter as long as it is unique; all subnodes
should be enumerated and processed purely based on their content.
== pinmux nodes content ==
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pinmux subnode:
Required properties are:
- groups: An array of strings. Each string contains the name of a group.
Valid values for these names are listed below.
- function: A string containing the name of the function to mux to the
group. Valid values for function names are listed below.
== pinconf nodes content ==
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pinconf subnode:
Required properties are:
- pins: An array of strings. Each string contains the name of a pin.
Valid values for these names are listed below.
- groups: An array of strings. Each string contains the name of a group.
Valid values for these names are listed below.
Optional properies are:
bias-disable, bias-pull, bias-pull-down, input-enable,
input-schmitt-enable, input-schmitt-disable, output-enable
output-low, output-high, drive-strength, slew-rate
Valid arguments for 'slew-rate' are '0' for no slew rate controlled and '1' for
slower slew rate respectively.
Valid arguments for 'drive-strength', 4, 8, 12, or 16 in mA.
The following specific properties as defined are valid to specify in a pinconf
subnode:
Optional properties are:
- mediatek,tdsel: An integer describing the steps for output level shifter duty
cycle when asserted (high pulse width adjustment). Valid arguments are from 0
to 15.
- mediatek,rdsel: An integer describing the steps for input level shifter duty
cycle when asserted (high pulse width adjustment). Valid arguments are from 0
to 63.
== Valid values for pins, function and groups on MT7622 ==
Valid values for pins are:
pins can be referenced via the pin names as the below table shown and the
related physical number is also put ahead of those names which helps cross
references to pins between groups to know whether pins assignment conflict
happens among devices try to acquire those available pins.
Pin #: Valid values for pins
-----------------------------
PIN 0: "GPIO_A"
PIN 1: "I2S1_IN"
PIN 2: "I2S1_OUT"
PIN 3: "I2S_BCLK"
PIN 4: "I2S_WS"
PIN 5: "I2S_MCLK"
PIN 6: "TXD0"
PIN 7: "RXD0"
PIN 8: "SPI_WP"
PIN 9: "SPI_HOLD"
PIN 10: "SPI_CLK"
PIN 11: "SPI_MOSI"
PIN 12: "SPI_MISO"
PIN 13: "SPI_CS"
PIN 14: "I2C_SDA"
PIN 15: "I2C_SCL"
PIN 16: "I2S2_IN"
PIN 17: "I2S3_IN"
PIN 18: "I2S4_IN"
PIN 19: "I2S2_OUT"
PIN 20: "I2S3_OUT"
PIN 21: "I2S4_OUT"
PIN 22: "GPIO_B"
PIN 23: "MDC"
PIN 24: "MDIO"
PIN 25: "G2_TXD0"
PIN 26: "G2_TXD1"
PIN 27: "G2_TXD2"
PIN 28: "G2_TXD3"
PIN 29: "G2_TXEN"
PIN 30: "G2_TXC"
PIN 31: "G2_RXD0"
PIN 32: "G2_RXD1"
PIN 33: "G2_RXD2"
PIN 34: "G2_RXD3"
PIN 35: "G2_RXDV"
PIN 36: "G2_RXC"
PIN 37: "NCEB"
PIN 38: "NWEB"
PIN 39: "NREB"
PIN 40: "NDL4"
PIN 41: "NDL5"
PIN 42: "NDL6"
PIN 43: "NDL7"
PIN 44: "NRB"
PIN 45: "NCLE"
PIN 46: "NALE"
PIN 47: "NDL0"
PIN 48: "NDL1"
PIN 49: "NDL2"
PIN 50: "NDL3"
PIN 51: "MDI_TP_P0"
PIN 52: "MDI_TN_P0"
PIN 53: "MDI_RP_P0"
PIN 54: "MDI_RN_P0"
PIN 55: "MDI_TP_P1"
PIN 56: "MDI_TN_P1"
PIN 57: "MDI_RP_P1"
PIN 58: "MDI_RN_P1"
PIN 59: "MDI_RP_P2"
PIN 60: "MDI_RN_P2"
PIN 61: "MDI_TP_P2"
PIN 62: "MDI_TN_P2"
PIN 63: "MDI_TP_P3"
PIN 64: "MDI_TN_P3"
PIN 65: "MDI_RP_P3"
PIN 66: "MDI_RN_P3"
PIN 67: "MDI_RP_P4"
PIN 68: "MDI_RN_P4"
PIN 69: "MDI_TP_P4"
PIN 70: "MDI_TN_P4"
PIN 71: "PMIC_SCL"
PIN 72: "PMIC_SDA"
PIN 73: "SPIC1_CLK"
PIN 74: "SPIC1_MOSI"
PIN 75: "SPIC1_MISO"
PIN 76: "SPIC1_CS"
PIN 77: "GPIO_D"
PIN 78: "WATCHDOG"
PIN 79: "RTS3_N"
PIN 80: "CTS3_N"
PIN 81: "TXD3"
PIN 82: "RXD3"
PIN 83: "PERST0_N"
PIN 84: "PERST1_N"
PIN 85: "WLED_N"
PIN 86: "EPHY_LED0_N"
PIN 87: "AUXIN0"
PIN 88: "AUXIN1"
PIN 89: "AUXIN2"
PIN 90: "AUXIN3"
PIN 91: "TXD4"
PIN 92: "RXD4"
PIN 93: "RTS4_N"
PIN 94: "CST4_N"
PIN 95: "PWM1"
PIN 96: "PWM2"
PIN 97: "PWM3"
PIN 98: "PWM4"
PIN 99: "PWM5"
PIN 100: "PWM6"
PIN 101: "PWM7"
PIN 102: "GPIO_E"
Valid values for function are:
"emmc", "eth", "i2c", "i2s", "ir", "led", "flash", "pcie",
"pmic", "pwm", "sd", "spi", "tdm", "uart", "watchdog"
Valid values for groups are:
additional data is put followingly with valid value allowing us to know which
applicable function and which relevant pins (in pin#) are able applied for that
group.
Valid value function pins (in pin#)
-------------------------------------------------------------------------
"emmc" "emmc" 40, 41, 42, 43, 44, 45,
47, 48, 49, 50
"emmc_rst" "emmc" 37
"esw" "eth" 51, 52, 53, 54, 55, 56,
57, 58, 59, 60, 61, 62,
63, 64, 65, 66, 67, 68,
69, 70
"esw_p0_p1" "eth" 51, 52, 53, 54, 55, 56,
57, 58
"esw_p2_p3_p4" "eth" 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70
"rgmii_via_esw" "eth" 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70
"rgmii_via_gmac1" "eth" 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70
"rgmii_via_gmac2" "eth" 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36
"mdc_mdio" "eth" 23, 24
"i2c0" "i2c" 14, 15
"i2c1_0" "i2c" 55, 56
"i2c1_1" "i2c" 73, 74
"i2c1_2" "i2c" 87, 88
"i2c2_0" "i2c" 57, 58
"i2c2_1" "i2c" 75, 76
"i2c2_2" "i2c" 89, 90
"i2s_in_mclk_bclk_ws" "i2s" 3, 4, 5
"i2s1_in_data" "i2s" 1
"i2s2_in_data" "i2s" 16
"i2s3_in_data" "i2s" 17
"i2s4_in_data" "i2s" 18
"i2s_out_mclk_bclk_ws" "i2s" 3, 4, 5
"i2s1_out_data" "i2s" 2
"i2s2_out_data" "i2s" 19
"i2s3_out_data" "i2s" 20
"i2s4_out_data" "i2s" 21
"ir_0_tx" "ir" 16
"ir_1_tx" "ir" 59
"ir_2_tx" "ir" 99
"ir_0_rx" "ir" 17
"ir_1_rx" "ir" 60
"ir_2_rx" "ir" 100
"ephy_leds" "led" 86, 91, 92, 93, 94
"ephy0_led" "led" 86
"ephy1_led" "led" 91
"ephy2_led" "led" 92
"ephy3_led" "led" 93
"ephy4_led" "led" 94
"wled" "led" 85
"par_nand" "flash" 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48,
49, 50
"snfi" "flash" 8, 9, 10, 11, 12, 13
"spi_nor" "flash" 8, 9, 10, 11, 12, 13
"pcie0_0_waken" "pcie" 14
"pcie0_1_waken" "pcie" 79
"pcie1_0_waken" "pcie" 14
"pcie0_0_clkreq" "pcie" 15
"pcie0_1_clkreq" "pcie" 80
"pcie1_0_clkreq" "pcie" 15
"pcie0_pad_perst" "pcie" 83
"pcie1_pad_perst" "pcie" 84
"pmic_bus" "pmic" 71, 72
"pwm_ch1_0" "pwm" 51
"pwm_ch1_1" "pwm" 73
"pwm_ch1_2" "pwm" 95
"pwm_ch2_0" "pwm" 52
"pwm_ch2_1" "pwm" 74
"pwm_ch2_2" "pwm" 96
"pwm_ch3_0" "pwm" 53
"pwm_ch3_1" "pwm" 75
"pwm_ch3_2" "pwm" 97
"pwm_ch4_0" "pwm" 54
"pwm_ch4_1" "pwm" 67
"pwm_ch4_2" "pwm" 76
"pwm_ch4_3" "pwm" 98
"pwm_ch5_0" "pwm" 68
"pwm_ch5_1" "pwm" 77
"pwm_ch5_2" "pwm" 99
"pwm_ch6_0" "pwm" 69
"pwm_ch6_1" "pwm" 78
"pwm_ch6_2" "pwm" 81
"pwm_ch6_3" "pwm" 100
"pwm_ch7_0" "pwm" 70
"pwm_ch7_1" "pwm" 82
"pwm_ch7_2" "pwm" 101
"sd_0" "sd" 16, 17, 18, 19, 20, 21
"sd_1" "sd" 25, 26, 27, 28, 29, 30
"spic0_0" "spi" 63, 64, 65, 66
"spic0_1" "spi" 79, 80, 81, 82
"spic1_0" "spi" 67, 68, 69, 70
"spic1_1" "spi" 73, 74, 75, 76
"spic2_0_wp_hold" "spi" 8, 9
"spic2_0" "spi" 10, 11, 12, 13
"tdm_0_out_mclk_bclk_ws" "tdm" 8, 9, 10
"tdm_0_in_mclk_bclk_ws" "tdm" 11, 12, 13
"tdm_0_out_data" "tdm" 20
"tdm_0_in_data" "tdm" 21
"tdm_1_out_mclk_bclk_ws" "tdm" 57, 58, 59
"tdm_1_in_mclk_bclk_ws" "tdm" 60, 61, 62
"tdm_1_out_data" "tdm" 55
"tdm_1_in_data" "tdm" 56
"uart0_0_tx_rx" "uart" 6, 7
"uart1_0_tx_rx" "uart" 55, 56
"uart1_0_rts_cts" "uart" 57, 58
"uart1_1_tx_rx" "uart" 73, 74
"uart1_1_rts_cts" "uart" 75, 76
"uart2_0_tx_rx" "uart" 3, 4
"uart2_0_rts_cts" "uart" 1, 2
"uart2_1_tx_rx" "uart" 51, 52
"uart2_1_rts_cts" "uart" 53, 54
"uart2_2_tx_rx" "uart" 59, 60
"uart2_2_rts_cts" "uart" 61, 62
"uart2_3_tx_rx" "uart" 95, 96
"uart3_0_tx_rx" "uart" 57, 58
"uart3_1_tx_rx" "uart" 81, 82
"uart3_1_rts_cts" "uart" 79, 80
"uart4_0_tx_rx" "uart" 61, 62
"uart4_1_tx_rx" "uart" 91, 92
"uart4_1_rts_cts" "uart" 93, 94
"uart4_2_tx_rx" "uart" 97, 98
"uart4_2_rts_cts" "uart" 95, 96
"watchdog" "watchdog" 78
Example:
pio: pinctrl@10211000 {
compatible = "mediatek,mt7622-pinctrl";
reg = <0 0x10211000 0 0x1000>;
gpio-controller;
#gpio-cells = <2>;
pinctrl_eth_default: eth-default {
mux-mdio {
groups = "mdc_mdio";
function = "eth";
drive-strength = <12>;
};
mux-gmac2 {
groups = "gmac2";
function = "eth";
drive-strength = <12>;
};
mux-esw {
groups = "esw";
function = "eth";
drive-strength = <8>;
};
conf-mdio {
pins = "MDC";
bias-pull-up;
};
};
};

View File

@ -0,0 +1,193 @@
Qualcomm MSM8998 TLMM block
This binding describes the Top Level Mode Multiplexer block found in the
MSM8998 platform.
- compatible:
Usage: required
Value type: <string>
Definition: must be "qcom,msm8998-pinctrl"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: the base address and size of the TLMM register space.
- interrupts:
Usage: required
Value type: <prop-encoded-array>
Definition: should specify the TLMM summary IRQ.
- interrupt-controller:
Usage: required
Value type: <none>
Definition: identifies this node as an interrupt controller
- #interrupt-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/interrupt-controller/irq.h>
- gpio-controller:
Usage: required
Value type: <none>
Definition: identifies this node as a gpio controller
- #gpio-cells:
Usage: required
Value type: <u32>
Definition: must be 2. Specifying the pin number and flags, as defined
in <dt-bindings/gpio/gpio.h>
Please refer to ../gpio/gpio.txt and ../interrupt-controller/interrupts.txt for
a general description of GPIO and interrupt bindings.
Please refer to pinctrl-bindings.txt in this directory for details of the
common pinctrl bindings used by client devices, including the meaning of the
phrase "pin configuration node".
The pin configuration nodes act as a container for an arbitrary number of
subnodes. Each of these subnodes represents some desired configuration for a
pin, a group, or a list of pins or groups. This configuration can include the
mux function to select on those pin(s)/group(s), and various pin configuration
parameters, such as pull-up, drive strength, etc.
PIN CONFIGURATION NODES:
The name of each subnode is not important; all subnodes should be enumerated
and processed purely based on their content.
Each subnode only affects those parameters that are explicitly listed. In
other words, a subnode that lists a mux function but no pin configuration
parameters implies no information about any pin configuration parameters.
Similarly, a pin subnode that describes a pullup parameter implies no
information about e.g. the mux function.
The following generic properties as defined in pinctrl-bindings.txt are valid
to specify in a pin configuration subnode:
- pins:
Usage: required
Value type: <string-array>
Definition: List of gpio pins affected by the properties specified in
this subnode.
Valid pins are:
gpio0-gpio149
Supports mux, bias and drive-strength
sdc2_clk, sdc2_cmd, sdc2_data
Supports bias and drive-strength
ufs_reset
Supports bias and drive-strength
- function:
Usage: required
Value type: <string>
Definition: Specify the alternative function to be configured for the
specified pins. Functions are only valid for gpio pins.
Valid values are:
gpio, adsp_ext, agera_pll, atest_char, atest_gpsadc0,
atest_gpsadc1, atest_tsens, atest_tsens2, atest_usb1,
atest_usb10, atest_usb11, atest_usb12, atest_usb13,
audio_ref, bimc_dte0, bimc_dte1, blsp10_spi, blsp10_spi_a,
blsp10_spi_b, blsp11_i2c, blsp1_spi, blsp1_spi_a,
blsp1_spi_b, blsp2_spi, blsp9_spi, blsp_i2c1, blsp_i2c2,
blsp_i2c3, blsp_i2c4, blsp_i2c5, blsp_i2c6, blsp_i2c7,
blsp_i2c8, blsp_i2c9, blsp_i2c10, blsp_i2c11, blsp_i2c12,
blsp_spi1, blsp_spi2, blsp_spi3, blsp_spi4, blsp_spi5,
blsp_spi6, blsp_spi7, blsp_spi8, blsp_spi9, blsp_spi10,
blsp_spi11, blsp_spi12, blsp_uart1_a, blsp_uart1_b,
blsp_uart2_a, blsp_uart2_b, blsp_uart3_a, blsp_uart3_b,
blsp_uart7_a, blsp_uart7_b, blsp_uart8, blsp_uart8_a,
blsp_uart8_b, blsp_uart9_a, blsp_uart9_b, blsp_uim1_a,
blsp_uim1_b, blsp_uim2_a, blsp_uim2_b, blsp_uim3_a,
blsp_uim3_b, blsp_uim7_a, blsp_uim7_b, blsp_uim8_a,
blsp_uim8_b, blsp_uim9_a, blsp_uim9_b, bt_reset,
btfm_slimbus, cam_mclk, cci_async, cci_i2c, cci_timer0,
cci_timer1, cci_timer2, cci_timer3, cci_timer4, cri_trng,
cri_trng0, cri_trng1, dbg_out, ddr_bist, edp_hot, edp_lcd,
gcc_gp1_a, gcc_gp1_b, gcc_gp2_a, gcc_gp2_b, gcc_gp3_a,
gcc_gp3_b, hdmi_cec, hdmi_ddc, hdmi_hot, hdmi_rcv,
isense_dbg, jitter_bist, ldo_en, ldo_update, lpass_slimbus,
m_voc, mdp_vsync, mdp_vsync0, mdp_vsync1, mdp_vsync2,
mdp_vsync3, mdp_vsync_a, mdp_vsync_b, modem_tsync, mss_lte,
nav_dr, nav_pps, pa_indicator, pci_e0, phase_flag,
pll_bypassnl, pll_reset, pri_mi2s, pri_mi2s_ws, prng_rosc,
pwr_crypto, pwr_modem, pwr_nav, qdss_cti0_a, qdss_cti0_b,
qdss_cti1_a, qdss_cti1_b, qdss, qlink_enable,
qlink_request, qua_mi2s, sd_card, sd_write, sdc40, sdc41,
sdc42, sdc43, sdc4_clk, sdc4_cmd, sec_mi2s, sp_cmu,
spkr_i2s, ssbi1, ssc_irq, ter_mi2s, tgu_ch0, tgu_ch1,
tsense_pwm1, tsense_pwm2, tsif1_clk, tsif1_data, tsif1_en,
tsif1_error, tsif1_sync, tsif2_clk, tsif2_data, tsif2_en,
tsif2_error, tsif2_sync, uim1_clk, uim1_data, uim1_present,
uim1_reset, uim2_clk, uim2_data, uim2_present, uim2_reset,
uim_batt, usb_phy, vfr_1, vsense_clkout, vsense_data0,
vsense_data1, vsense_mode, wlan1_adc0, wlan1_adc1,
wlan2_adc0, wlan2_adc1,
- bias-disable:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as no pull.
- bias-pull-down:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull down.
- bias-pull-up:
Usage: optional
Value type: <none>
Definition: The specified pins should be configued as pull up.
- output-high:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
high.
Not valid for sdc pins.
- output-low:
Usage: optional
Value type: <none>
Definition: The specified pins are configured in output mode, driven
low.
Not valid for sdc pins.
- drive-strength:
Usage: optional
Value type: <u32>
Definition: Selects the drive strength for the specified pins, in mA.
Valid values are: 2, 4, 6, 8, 10, 12, 14 and 16
Example:
tlmm: pinctrl@03400000 {
compatible = "qcom,msm8998-pinctrl";
reg = <0x03400000 0xc00000>;
interrupts = <0 208 0>;
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
#interrupt-cells = <2>;
uart_console_active: uart_console_active {
mux {
pins = "gpio4", "gpio5";
function = "blsp_uart8_a";
};
config {
pins = "gpio4", "gpio5";
drive-strength = <2>;
bias-disable;
};
};
};

View File

@ -24,6 +24,7 @@ Required Properties:
- "renesas,pfc-r8a7794": for R8A7794 (R-Car E2) compatible pin-controller.
- "renesas,pfc-r8a7795": for R8A7795 (R-Car H3) compatible pin-controller.
- "renesas,pfc-r8a7796": for R8A7796 (R-Car M3-W) compatible pin-controller.
- "renesas,pfc-r8a77970": for R8A77970 (R-Car V3M) compatible pin-controller.
- "renesas,pfc-r8a77995": for R8A77995 (R-Car D3) compatible pin-controller.
- "renesas,pfc-sh73a0": for SH73A0 (SH-Mobile AG5) compatible pin-controller.

View File

@ -0,0 +1,27 @@
UniPhier SoCs pin controller
Required properties:
- compatible: should be one of the following:
"socionext,uniphier-ld4-pinctrl" - for LD4 SoC
"socionext,uniphier-pro4-pinctrl" - for Pro4 SoC
"socionext,uniphier-sld8-pinctrl" - for sLD8 SoC
"socionext,uniphier-pro5-pinctrl" - for Pro5 SoC
"socionext,uniphier-pxs2-pinctrl" - for PXs2 SoC
"socionext,uniphier-ld6b-pinctrl" - for LD6b SoC
"socionext,uniphier-ld11-pinctrl" - for LD11 SoC
"socionext,uniphier-ld20-pinctrl" - for LD20 SoC
"socionext,uniphier-pxs3-pinctrl" - for PXs3 SoC
Note:
The UniPhier pinctrl should be a subnode of a "syscon" compatible node.
Example:
soc-glue@5f800000 {
compatible = "socionext,uniphier-pro4-soc-glue",
"simple-mfd", "syscon";
reg = <0x5f800000 0x2000>;
pinctrl: pinctrl {
compatible = "socionext,uniphier-pro4-pinctrl";
};
};

View File

@ -12,6 +12,8 @@ Required properies:
"st,stm32f469-pinctrl"
"st,stm32f746-pinctrl"
"st,stm32h743-pinctrl"
"st,stm32mp157-pinctrl"
"st,stm32mp157-z-pinctrl"
- #address-cells: The value of this property must be 1
- #size-cells : The value of this property must be 1
- ranges : defines mapping between pin controller node (parent) to

View File

@ -0,0 +1,17 @@
* i.MX53 Secure Real Time Clock (SRTC)
Required properties:
- compatible: should be: "fsl,imx53-rtc"
- reg: physical base address of the controller and length of memory mapped
region.
- clocks: should contain the phandle for the rtc clock
- interrupts: rtc alarm interrupt
Example:
rtc@53fa4000 {
compatible = "fsl,imx53-rtc";
reg = <0x53fa4000 0x4000>;
interrupts = <24>;
clocks = <&clks IMX5_CLK_SRTC_GATE>;
};

View File

@ -1309,7 +1309,7 @@ number and level/sense information. All interrupt children in an
OpenPIC interrupt domain use 2 cells per interrupt in their interrupts
property.
The PCI bus binding specifies a #interrupt-cell value of 1 to encode
The PCI bus binding specifies a #interrupt-cells value of 1 to encode
which interrupt pin (INTA,INTB,INTC,INTD) is used.
2) interrupt-parent property

View File

@ -46,7 +46,6 @@ stall the CPU for an extended period, you should also not attempt to
implement direct_access.
These block devices may be used for inspiration:
- axonram: Axon DDR2 device driver
- brd: RAM backed block device driver
- dcssblk: s390 dcss block device driver
- pmem: NVDIMM persistent memory driver

View File

@ -232,7 +232,7 @@ data_err=ignore(*) Just print an error message if an error occurs
data_err=abort Abort the journal if an error occurs in a file
data buffer in ordered mode.
grpid Give objects the same group ID as their creator.
grpid New objects have the group ID of their parent.
bsdgroups
nogrpid (*) New objects have the group ID of their creator.

View File

@ -448,8 +448,14 @@ astute users may notice some differences in behavior:
- The st_size of an encrypted symlink will not necessarily give the
length of the symlink target as required by POSIX. It will actually
give the length of the ciphertext, which may be slightly longer than
the plaintext due to the NUL-padding.
give the length of the ciphertext, which will be slightly longer
than the plaintext due to NUL-padding and an extra 2-byte overhead.
- The maximum length of an encrypted symlink is 2 bytes shorter than
the maximum length of an unencrypted symlink. For example, on an
EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
to 4095 bytes long, while encrypted symlinks can only be up to 4093
bytes long (both lengths excluding the terminating null).
Note that mmap *is* supported. This is possible because the pagecache
for an encrypted file contains the plaintext, not the ciphertext.

View File

@ -0,0 +1,67 @@
=================
Linux I2C and DMA
=================
Given that i2c is a low-speed bus, over which the majority of messages
transferred are small, it is not considered a prime user of DMA access. At this
time of writing, only 10% of I2C bus master drivers have DMA support
implemented. And the vast majority of transactions are so small that setting up
DMA for it will likely add more overhead than a plain PIO transfer.
Therefore, it is *not* mandatory that the buffer of an I2C message is DMA safe.
It does not seem reasonable to apply additional burdens when the feature is so
rarely used. However, it is recommended to use a DMA-safe buffer if your
message size is likely applicable for DMA. Most drivers have this threshold
around 8 bytes (as of today, this is mostly an educated guess, however). For
any message of 16 byte or larger, it is probably a really good idea. Please
note that other subsystems you use might add requirements. E.g., if your
I2C bus master driver is using USB as a bridge, then you need to have DMA
safe buffers always, because USB requires it.
Clients
-------
For clients, if you use a DMA safe buffer in i2c_msg, set the I2C_M_DMA_SAFE
flag with it. Then, the I2C core and drivers know they can safely operate DMA
on it. Note that using this flag is optional. I2C host drivers which are not
updated to use this flag will work like before. And like before, they risk
using an unsafe DMA buffer. To improve this situation, using I2C_M_DMA_SAFE in
more and more clients and host drivers is the planned way forward. Note also
that setting this flag makes only sense in kernel space. User space data is
copied into kernel space anyhow. The I2C core makes sure the destination
buffers in kernel space are always DMA capable. Also, when the core emulates
SMBus transactions via I2C, the buffers for block transfers are DMA safe. Users
of i2c_master_send() and i2c_master_recv() functions can now use DMA safe
variants (i2c_master_send_dmasafe() and i2c_master_recv_dmasafe()) once they
know their buffers are DMA safe. Users of i2c_transfer() must set the
I2C_M_DMA_SAFE flag manually.
Masters
-------
Bus master drivers wishing to implement safe DMA can use helper functions from
the I2C core. One gives you a DMA-safe buffer for a given i2c_msg as long as a
certain threshold is met::
dma_buf = i2c_get_dma_safe_msg_buf(msg, threshold_in_byte);
If a buffer is returned, it is either msg->buf for the I2C_M_DMA_SAFE case or a
bounce buffer. But you don't need to care about that detail, just use the
returned buffer. If NULL is returned, the threshold was not met or a bounce
buffer could not be allocated. Fall back to PIO in that case.
In any case, a buffer obtained from above needs to be released. It ensures data
is copied back to the message and a potentially used bounce buffer is freed::
i2c_release_dma_safe_msg_buf(msg, dma_buf);
The bounce buffer handling from the core is generic and simple. It will always
allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
reusing pre-allocated buffers), you are free to implement your own.
Please also check the in-kernel documentation for details. The i2c-sh_mobile
driver can be used as a reference example how to use the above helpers.
Final note: If you plan to use DMA with I2C (or with anything else, actually)
make sure you have CONFIG_DMA_API_DEBUG enabled during development. It can help
you find various issues which can be complex to debug otherwise.

View File

@ -0,0 +1,54 @@
Linux I2C fault injection
=========================
The GPIO based I2C bus master driver can be configured to provide fault
injection capabilities. It is then meant to be connected to another I2C bus
which is driven by the I2C bus master driver under test. The GPIO fault
injection driver can create special states on the bus which the other I2C bus
master driver should handle gracefully.
Once the Kconfig option I2C_GPIO_FAULT_INJECTOR is enabled, there will be an
'i2c-fault-injector' subdirectory in the Kernel debugfs filesystem, usually
mounted at /sys/kernel/debug. There will be a separate subdirectory per GPIO
driven I2C bus. Each subdirectory will contain files to trigger the fault
injection. They will be described now along with their intended use-cases.
"scl"
-----
By reading this file, you get the current state of SCL. By writing, you can
change its state to either force it low or to release it again. So, by using
"echo 0 > scl" you force SCL low and thus, no communication will be possible
because the bus master under test will not be able to clock. It should detect
the condition of SCL being unresponsive and report an error to the upper
layers.
"sda"
-----
By reading this file, you get the current state of SDA. By writing, you can
change its state to either force it low or to release it again. So, by using
"echo 0 > sda" you force SDA low and thus, data cannot be transmitted. The bus
master under test should detect this condition and trigger a bus recovery (see
I2C specification version 4, section 3.1.16) using the helpers of the Linux I2C
core (see 'struct bus_recovery_info'). However, the bus recovery will not
succeed because SDA is still pinned low until you manually release it again
with "echo 1 > sda". A test with an automatic release can be done with the
'incomplete_transfer' file.
"incomplete_transfer"
---------------------
This file is write only and you need to write the address of an existing I2C
client device to it. Then, a transfer to this device will be started, but it
will stop at the ACK phase after the address of the client has been
transmitted. Because the device will ACK its presence, this results in SDA
being pulled low by the device while SCL is high. So, similar to the "sda" file
above, the bus master under test should detect this condition and try a bus
recovery. This time, however, it should succeed and the device should release
SDA after toggling SCL. Please note: there are I2C client devices which detect
a stuck SDA on their side and release it on their own after a few milliseconds.
Also, there are external devices deglitching and monitoring the I2C bus. They
can also detect a stuck SDA and will init a bus recovery on their own. If you
want to implement bus recovery in a bus master driver, make sure you checked
your hardware setup carefully before.

View File

@ -326,6 +326,7 @@ Code Seq#(hex) Include File Comments
0xB5 00-0F uapi/linux/rpmsg.h <mailto:linux-remoteproc@vger.kernel.org>
0xC0 00-0F linux/usb/iowarrior.h
0xCA 00-0F uapi/misc/cxl.h
0xCA 10-2F uapi/misc/ocxl.h
0xCA 80-BF uapi/scsi/cxlflash_ioctl.h
0xCB 00-1F CBM serial IEC bus in development:
<mailto:michael.klein@puffin.lb.shuttle.de>

View File

@ -136,82 +136,5 @@ a high functionality RTC is integrated into the SOC. That system might read
the system clock from the discrete RTC, but use the integrated one for all
other tasks, because of its greater functionality.
SYSFS interface
---------------
The sysfs interface under /sys/class/rtc/rtcN provides access to various
rtc attributes without requiring the use of ioctls. All dates and times
are in the RTC's timezone, rather than in system time.
================ ==============================================================
date RTC-provided date
hctosys 1 if the RTC provided the system time at boot via the
CONFIG_RTC_HCTOSYS kernel option, 0 otherwise
max_user_freq The maximum interrupt rate an unprivileged user may request
from this RTC.
name The name of the RTC corresponding to this sysfs directory
since_epoch The number of seconds since the epoch according to the RTC
time RTC-provided time
wakealarm The time at which the clock will generate a system wakeup
event. This is a one shot wakeup event, so must be reset
after wake if a daily wakeup is required. Format is seconds
since the epoch by default, or if there's a leading +, seconds
in the future, or if there is a leading +=, seconds ahead of
the current alarm.
offset The amount which the rtc clock has been adjusted in firmware.
Visible only if the driver supports clock offset adjustment.
The unit is parts per billion, i.e. The number of clock ticks
which are added to or removed from the rtc's base clock per
billion ticks. A positive value makes a day pass more slowly,
longer, and a negative value makes a day pass more quickly.
*/nvmem The non volatile storage exported as a raw file, as described
in Documentation/nvmem/nvmem.txt
================ ==============================================================
IOCTL interface
---------------
The ioctl() calls supported by /dev/rtc are also supported by the RTC class
framework. However, because the chips and systems are not standardized,
some PC/AT functionality might not be provided. And in the same way, some
newer features -- including those enabled by ACPI -- are exposed by the
RTC class framework, but can't be supported by the older driver.
* RTC_RD_TIME, RTC_SET_TIME ... every RTC supports at least reading
time, returning the result as a Gregorian calendar date and 24 hour
wall clock time. To be most useful, this time may also be updated.
* RTC_AIE_ON, RTC_AIE_OFF, RTC_ALM_SET, RTC_ALM_READ ... when the RTC
is connected to an IRQ line, it can often issue an alarm IRQ up to
24 hours in the future. (Use RTC_WKALM_* by preference.)
* RTC_WKALM_SET, RTC_WKALM_RD ... RTCs that can issue alarms beyond
the next 24 hours use a slightly more powerful API, which supports
setting the longer alarm time and enabling its IRQ using a single
request (using the same model as EFI firmware).
* RTC_UIE_ON, RTC_UIE_OFF ... if the RTC offers IRQs, the RTC framework
will emulate this mechanism.
* RTC_PIE_ON, RTC_PIE_OFF, RTC_IRQP_SET, RTC_IRQP_READ ... these icotls
are emulated via a kernel hrtimer.
In many cases, the RTC alarm can be a system wake event, used to force
Linux out of a low power sleep state (or hibernation) back to a fully
operational state. For example, a system could enter a deep power saving
state until it's time to execute some scheduled tasks.
Note that many of these ioctls are handled by the common rtc-dev interface.
Some common examples:
* RTC_RD_TIME, RTC_SET_TIME: the read_time/set_time functions will be
called with appropriate values.
* RTC_ALM_SET, RTC_ALM_READ, RTC_WKALM_SET, RTC_WKALM_RD: gets or sets
the alarm rtc_timer. May call the set_alarm driver function.
* RTC_IRQP_SET, RTC_IRQP_READ: These are emulated by the generic code.
* RTC_PIE_ON, RTC_PIE_OFF: These are also emulated by the generic code.
If all else fails, check out the tools/testing/selftests/timers/rtctest.c test!
Check out tools/testing/selftests/timers/rtctest.c for an example usage of the
ioctl interface.

View File

@ -0,0 +1,90 @@
This document explains potential effects of speculation, and how undesirable
effects can be mitigated portably using common APIs.
===========
Speculation
===========
To improve performance and minimize average latencies, many contemporary CPUs
employ speculative execution techniques such as branch prediction, performing
work which may be discarded at a later stage.
Typically speculative execution cannot be observed from architectural state,
such as the contents of registers. However, in some cases it is possible to
observe its impact on microarchitectural state, such as the presence or
absence of data in caches. Such state may form side-channels which can be
observed to extract secret information.
For example, in the presence of branch prediction, it is possible for bounds
checks to be ignored by code which is speculatively executed. Consider the
following code:
int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else
return array[index];
}
Which, on arm64, may be compiled to an assembly sequence such as:
CMP <index>, #MAX_ARRAY_ELEMS
B.LT less
MOV <returnval>, #0
RET
less:
LDR <returnval>, [<array>, <index>]
RET
It is possible that a CPU mis-predicts the conditional branch, and
speculatively loads array[index], even if index >= MAX_ARRAY_ELEMS. This
value will subsequently be discarded, but the speculated load may affect
microarchitectural state which can be subsequently measured.
More complex sequences involving multiple dependent memory accesses may
result in sensitive information being leaked. Consider the following
code, building on the prior example:
int load_dependent_arrays(int *arr1, int *arr2, int index)
{
int val1, val2,
val1 = load_array(arr1, index);
val2 = load_array(arr2, val1);
return val2;
}
Under speculation, the first call to load_array() may return the value
of an out-of-bounds address, while the second call will influence
microarchitectural state dependent on this value. This may provide an
arbitrary read primitive.
====================================
Mitigating speculation side-channels
====================================
The kernel provides a generic API to ensure that bounds checks are
respected even under speculation. Architectures which are affected by
speculation-based side-channels are expected to implement these
primitives.
The array_index_nospec() helper in <linux/nospec.h> can be used to
prevent information from being leaked via side-channels.
A call to array_index_nospec(index, size) returns a sanitized index
value that is bounded to [0, size) even under cpu speculation
conditions.
This can be used to protect the earlier load_array() example:
int load_array(int *array, unsigned int index)
{
if (index >= MAX_ARRAY_ELEMS)
return 0;
else {
index = array_index_nospec(index, MAX_ARRAY_ELEMS);
return array[index];
}
}

View File

@ -2086,6 +2086,7 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-uniphier.git
S: Maintained
F: Documentation/devicetree/bindings/gpio/gpio-uniphier.txt
F: Documentation/devicetree/bindings/pinctrl/socionext,uniphier-pinctrl.txt
F: arch/arm/boot/dts/uniphier*
F: arch/arm/include/asm/hardware/cache-uniphier.h
F: arch/arm/mach-uniphier/
@ -2287,7 +2288,9 @@ F: include/linux/async_tx.h
AT24 EEPROM DRIVER
M: Bartosz Golaszewski <brgl@bgdev.pl>
L: linux-i2c@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux.git
S: Maintained
F: Documentation/devicetree/bindings/eeprom/at24.txt
F: drivers/misc/eeprom/at24.c
F: include/linux/platform_data/at24.h
@ -2855,6 +2858,8 @@ S: Maintained
F: arch/arm/mach-bcm/*brcmstb*
F: arch/arm/boot/dts/bcm7*.dts*
F: drivers/bus/brcmstb_gisb.c
F: arch/arm/mm/cache-b15-rac.c
F: arch/arm/include/asm/hardware/cache-b15-rac.h
N: brcmstb
BROADCOM BMIPS CPUFREQ DRIVER
@ -6577,6 +6582,12 @@ F: drivers/i2c/i2c-mux.c
F: drivers/i2c/muxes/
F: include/linux/i2c-mux.h
I2C MV64XXX MARVELL AND ALLWINNER DRIVER
M: Gregory CLEMENT <gregory.clement@free-electrons.com>
L: linux-i2c@vger.kernel.org
S: Maintained
F: drivers/i2c/busses/i2c-mv64xxx.c
I2C OVER PARALLEL PORT
M: Jean Delvare <jdelvare@suse.com>
L: linux-i2c@vger.kernel.org
@ -7792,6 +7803,7 @@ F: include/keys/encrypted-type.h
F: security/keys/encrypted-keys/
KEYS-TRUSTED
M: James Bottomley <jejb@linux.vnet.ibm.com>
M: Mimi Zohar <zohar@linux.vnet.ibm.com>
L: linux-integrity@vger.kernel.org
L: keyrings@vger.kernel.org
@ -9789,7 +9801,7 @@ F: drivers/ntb/hw/amd/
NTB DRIVER CORE
M: Jon Mason <jdmason@kudzu.us>
M: Dave Jiang <dave.jiang@intel.com>
M: Allen Hubbe <Allen.Hubbe@emc.com>
M: Allen Hubbe <allenbh@gmail.com>
L: linux-ntb@googlegroups.com
S: Supported
W: https://github.com/jonmason/ntb/wiki
@ -9907,6 +9919,18 @@ M: Josh Poimboeuf <jpoimboe@redhat.com>
S: Supported
F: tools/objtool/
OCXL (Open Coherent Accelerator Processor Interface OpenCAPI) DRIVER
M: Frederic Barrat <fbarrat@linux.vnet.ibm.com>
M: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
L: linuxppc-dev@lists.ozlabs.org
S: Supported
F: arch/powerpc/platforms/powernv/ocxl.c
F: arch/powerpc/include/asm/pnv-ocxl.h
F: drivers/misc/ocxl/
F: include/misc/ocxl*
F: include/uapi/misc/ocxl.h
F: Documentation/accelerators/ocxl.txt
OMAP AUDIO SUPPORT
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
M: Jarkko Nikula <jarkko.nikula@bitmer.com>
@ -10861,6 +10885,16 @@ M: Heikki Krogerus <heikki.krogerus@linux.intel.com>
S: Maintained
F: drivers/pinctrl/intel/
PIN CONTROLLER - MEDIATEK
M: Sean Wang <sean.wang@mediatek.com>
L: linux-mediatek@lists.infradead.org (moderated for non-subscribers)
S: Maintained
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt
F: Documentation/devicetree/bindings/pinctrl/pinctrl-mt7622.txt
F: drivers/pinctrl/mediatek/pinctrl-mtk-common.*
F: drivers/pinctrl/mediatek/pinctrl-mt2701.c
F: drivers/pinctrl/mediatek/pinctrl-mt7622.c
PIN CONTROLLER - QUALCOMM
M: Bjorn Andersson <bjorn.andersson@linaro.org>
S: Maintained

View File

@ -245,6 +245,17 @@ config ARCH_TASK_STRUCT_ON_STACK
config ARCH_TASK_STRUCT_ALLOCATOR
bool
config HAVE_ARCH_THREAD_STRUCT_WHITELIST
bool
depends on !ARCH_TASK_STRUCT_ALLOCATOR
help
An architecture should select this to provide hardened usercopy
knowledge about what region of the thread_struct should be
whitelisted for copying to userspace. Normally this is only the
FPU registers. Specifically, arch_thread_struct_whitelist()
should be implemented. Without this, the entire thread_struct
field in task_struct will be left whitelisted.
# Select if arch has its private alloc_thread_stack() function
config ARCH_THREAD_STACK_ALLOCATOR
bool

View File

@ -20,8 +20,8 @@
"3: .subsection 2\n" \
"4: br 1b\n" \
" .previous\n" \
EXC(1b,3b,%1,$31) \
EXC(2b,3b,%1,$31) \
EXC(1b,3b,$31,%1) \
EXC(2b,3b,$31,%1) \
: "=&r" (oldval), "=&r"(ret) \
: "r" (uaddr), "r"(oparg) \
: "memory")
@ -82,8 +82,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
"3: .subsection 2\n"
"4: br 1b\n"
" .previous\n"
EXC(1b,3b,%0,$31)
EXC(2b,3b,%0,$31)
EXC(1b,3b,$31,%0)
EXC(2b,3b,$31,%0)
: "+r"(ret), "=&r"(prev), "=&r"(cmp)
: "r"(uaddr), "r"((long)(int)oldval), "r"(newval)
: "memory");

View File

@ -40,15 +40,12 @@ typedef struct {
struct thread_struct { };
#define INIT_THREAD { }
/* Return saved PC of a blocked thread. */
struct task_struct;
extern unsigned long thread_saved_pc(struct task_struct *);
/* Do necessary setup to start up a newly executed thread. */
struct pt_regs;
extern void start_thread(struct pt_regs *, unsigned long, unsigned long);
/* Free all resources held by a thread. */
struct task_struct;
extern void release_thread(struct task_struct *);
unsigned long get_wchan(struct task_struct *p);

View File

@ -110,7 +110,11 @@ struct ktermios {
#define VTDLY 00200000
#define VT0 00000000
#define VT1 00200000
#define XTABS 01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
/*
* Should be equivalent to TAB3, see description of TAB3 in
* POSIX.1-2008, Ch. 11.2.3 "Output Modes"
*/
#define XTABS TAB3
/* c_cflag bit meaning */
#define CBAUD 0000037

View File

@ -425,7 +425,7 @@ sys_pciconfig_iobase(long which, unsigned long bus, unsigned long dfn)
if (bus == 0 && dfn == 0) {
hose = pci_isa_hose;
} else {
dev = pci_get_bus_and_slot(bus, dfn);
dev = pci_get_domain_bus_and_slot(0, bus, dfn);
if (!dev)
return -ENODEV;
hose = dev->sysdata;

View File

@ -144,7 +144,8 @@ struct pci_iommu_arena
};
#if defined(CONFIG_ALPHA_SRM) && \
(defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA))
(defined(CONFIG_ALPHA_CIA) || defined(CONFIG_ALPHA_LCA) || \
defined(CONFIG_ALPHA_AVANTI))
# define NEED_SRM_SAVE_RESTORE
#else
# undef NEED_SRM_SAVE_RESTORE

View File

@ -269,12 +269,13 @@ copy_thread(unsigned long clone_flags, unsigned long usp,
application calling fork. */
if (clone_flags & CLONE_SETTLS)
childti->pcb.unique = regs->r20;
else
regs->r20 = 0; /* OSF/1 has some strange fork() semantics. */
childti->pcb.usp = usp ?: rdusp();
*childregs = *regs;
childregs->r0 = 0;
childregs->r19 = 0;
childregs->r20 = 1; /* OSF/1 has some strange fork() semantics. */
regs->r20 = 0;
stack = ((struct switch_stack *) regs) - 1;
*childstack = *stack;
childstack->r26 = (unsigned long) ret_from_fork;
@ -361,7 +362,7 @@ EXPORT_SYMBOL(dump_elf_task_fp);
* all. -- r~
*/
unsigned long
static unsigned long
thread_saved_pc(struct task_struct *t)
{
unsigned long base = (unsigned long)task_stack_page(t);

View File

@ -237,7 +237,7 @@ nautilus_init_pci(void)
bus = hose->bus = bridge->bus;
pcibios_claim_one_bus(bus);
irongate = pci_get_bus_and_slot(0, 0);
irongate = pci_get_domain_bus_and_slot(pci_domain_nr(bus), 0, 0);
bus->self = irongate;
bus->resource[0] = &irongate_io;
bus->resource[1] = &irongate_mem;

View File

@ -160,11 +160,16 @@ void show_stack(struct task_struct *task, unsigned long *sp)
for(i=0; i < kstack_depth_to_print; i++) {
if (((long) stack & (THREAD_SIZE-1)) == 0)
break;
if (i && ((i % 4) == 0))
printk("\n ");
printk("%016lx ", *stack++);
if ((i % 4) == 0) {
if (i)
pr_cont("\n");
printk(" ");
} else {
pr_cont(" ");
}
pr_cont("%016lx", *stack++);
}
printk("\n");
pr_cont("\n");
dik_show_trace(sp);
}

View File

@ -3,8 +3,8 @@ config ARM
bool
default y
select ARCH_CLOCKSOURCE_DATA
select ARCH_DISCARD_MEMBLOCK if !HAVE_ARCH_PFN_VALID
select ARCH_HAS_DEBUG_VIRTUAL
select ARCH_DISCARD_MEMBLOCK if !HAVE_ARCH_PFN_VALID && !KEXEC
select ARCH_HAS_DEBUG_VIRTUAL if MMU
select ARCH_HAS_DEVMEM_IS_ALLOWED
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_SET_MEMORY
@ -51,6 +51,7 @@ config ARM
select HAVE_ARCH_KGDB if !CPU_ENDIAN_BE32 && MMU
select HAVE_ARCH_MMAP_RND_BITS if MMU
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
select HAVE_ARCH_TRACEHOOK
select HAVE_ARM_SMCCC if CPU_V7
select HAVE_EBPF_JIT if !CPU_ENDIAN_BE32
@ -100,6 +101,7 @@ config ARM
select OLD_SIGACTION
select OLD_SIGSUSPEND3
select PERF_USE_VMALLOC
select REFCOUNT_FULL
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
# Above selects are sorted alphabetically; please add new ones
@ -1526,12 +1528,10 @@ config THUMB2_KERNEL
bool "Compile the kernel in Thumb-2 mode" if !CPU_THUMBONLY
depends on (CPU_V7 || CPU_V7M) && !CPU_V6 && !CPU_V6K
default y if CPU_THUMBONLY
select ARM_ASM_UNIFIED
select ARM_UNWIND
help
By enabling this option, the kernel will be compiled in
Thumb-2 mode. A compiler/assembler that understand the unified
ARM-Thumb syntax is needed.
Thumb-2 mode.
If unsure, say N.
@ -1566,9 +1566,6 @@ config THUMB2_AVOID_R_ARM_THM_JUMP11
Unless you are sure your tools don't have this problem, say Y.
config ARM_ASM_UNIFIED
bool
config ARM_PATCH_IDIV
bool "Runtime patch udiv/sdiv instructions into __aeabi_{u}idiv()"
depends on CPU_32v7 && !XIP_KERNEL

View File

@ -3,10 +3,14 @@ menu "Kernel hacking"
source "lib/Kconfig.debug"
config ARM_PTDUMP
config ARM_PTDUMP_CORE
def_bool n
config ARM_PTDUMP_DEBUGFS
bool "Export kernel pagetable layout to userspace via debugfs"
depends on DEBUG_KERNEL
depends on MMU
select ARM_PTDUMP_CORE
select DEBUG_FS
---help---
Say Y here if you want to show the kernel pagetable layout in a
@ -16,6 +20,33 @@ config ARM_PTDUMP
kernel.
If in doubt, say "N"
config DEBUG_WX
bool "Warn on W+X mappings at boot"
select ARM_PTDUMP_CORE
---help---
Generate a warning if any W+X mappings are found at boot.
This is useful for discovering cases where the kernel is leaving
W+X mappings after applying NX, as such mappings are a security risk.
Look for a message in dmesg output like this:
arm/mm: Checked W+X mappings: passed, no W+X pages found.
or like this, if the check failed:
arm/mm: Checked W+X mappings: FAILED, <N> W+X pages found.
Note that even if the check fails, your kernel is possibly
still fine, as W+X mappings are not a security hole in
themselves, what they do is that they make the exploitation
of other unfixed kernel bugs easier.
There is no runtime or memory usage effect of this option
once the kernel has booted up - it's a one time check.
If in doubt, say "Y".
# RMK wants arm kernels compiled with frame pointers or stack unwinding.
# If you know what you are doing and are willing to live without stack
# traces, you can get a slightly smaller kernel by setting this option to

View File

@ -115,9 +115,11 @@ ifeq ($(CONFIG_ARM_UNWIND),y)
CFLAGS_ABI +=-funwind-tables
endif
# Accept old syntax despite ".syntax unified"
AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
ifeq ($(CONFIG_THUMB2_KERNEL),y)
AFLAGS_AUTOIT :=$(call as-option,-Wa$(comma)-mimplicit-it=always,-Wa$(comma)-mauto-it)
AFLAGS_NOWARN :=$(call as-option,-Wa$(comma)-mno-warn-deprecated,-Wa$(comma)-W)
CFLAGS_ISA :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
AFLAGS_ISA :=$(CFLAGS_ISA) -Wa$(comma)-mthumb
# Work around buggy relocation from gas if requested:
@ -125,7 +127,7 @@ ifeq ($(CONFIG_THUMB2_AVOID_R_ARM_THM_JUMP11),y)
KBUILD_CFLAGS_MODULE +=-fno-optimize-sibling-calls
endif
else
CFLAGS_ISA :=$(call cc-option,-marm,)
CFLAGS_ISA :=$(call cc-option,-marm,) $(AFLAGS_NOWARN)
AFLAGS_ISA :=$(CFLAGS_ISA)
endif

View File

@ -130,8 +130,3 @@ void *memset(void *s, int c, size_t count)
*xs++ = c;
return s;
}
void __memzero(void *s, size_t count)
{
memset(s, 0, count);
}

View File

@ -56,6 +56,7 @@ SECTIONS
.rodata : {
*(.rodata)
*(.rodata.*)
*(.data.rel.ro)
}
.piggydata : {
*(.piggydata)
@ -101,6 +102,12 @@ SECTIONS
* this symbol allows further debug in the near future.
*/
.image_end (NOLOAD) : {
/*
* EFI requires that the image is aligned to 512 bytes, and appended
* DTB requires that we know where the end of the image is. Ensure
* that both are satisfied by ensuring that there are no additional
* sections emitted into the decompressor image.
*/
_edata_real = .;
}
@ -128,3 +135,4 @@ SECTIONS
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
}
ASSERT(_edata_real == _edata, "error: zImage file size is incorrect");

View File

@ -57,3 +57,7 @@ static struct miscdevice bL_switcher_device = {
&bL_switcher_fops
};
module_misc_device(bL_switcher_device);
MODULE_AUTHOR("Nicolas Pitre <nico@linaro.org>");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("big.LITTLE switcher dummy user interface");

View File

@ -108,6 +108,7 @@ struct sa1111 {
spinlock_t lock;
void __iomem *base;
struct sa1111_platform_data *pdata;
struct irq_domain *irqdomain;
struct gpio_chip gc;
#ifdef CONFIG_PM
void *saved_state;
@ -125,7 +126,7 @@ struct sa1111_dev_info {
unsigned long skpcr_mask;
bool dma;
unsigned int devid;
unsigned int irq[6];
unsigned int hwirq[6];
};
static struct sa1111_dev_info sa1111_devices[] = {
@ -134,7 +135,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
.skpcr_mask = SKPCR_UCLKEN,
.dma = true,
.devid = SA1111_DEVID_USB,
.irq = {
.hwirq = {
IRQ_USBPWR,
IRQ_HCIM,
IRQ_HCIBUFFACC,
@ -148,7 +149,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
.skpcr_mask = SKPCR_I2SCLKEN | SKPCR_L3CLKEN,
.dma = true,
.devid = SA1111_DEVID_SAC,
.irq = {
.hwirq = {
AUDXMTDMADONEA,
AUDXMTDMADONEB,
AUDRCVDMADONEA,
@ -164,7 +165,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
.offset = SA1111_KBD,
.skpcr_mask = SKPCR_PTCLKEN,
.devid = SA1111_DEVID_PS2_KBD,
.irq = {
.hwirq = {
IRQ_TPRXINT,
IRQ_TPTXINT
},
@ -173,7 +174,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
.offset = SA1111_MSE,
.skpcr_mask = SKPCR_PMCLKEN,
.devid = SA1111_DEVID_PS2_MSE,
.irq = {
.hwirq = {
IRQ_MSRXINT,
IRQ_MSTXINT
},
@ -182,7 +183,7 @@ static struct sa1111_dev_info sa1111_devices[] = {
.offset = 0x1800,
.skpcr_mask = 0,
.devid = SA1111_DEVID_PCMCIA,
.irq = {
.hwirq = {
IRQ_S0_READY_NINT,
IRQ_S0_CD_VALID,
IRQ_S0_BVD1_STSCHG,
@ -193,6 +194,19 @@ static struct sa1111_dev_info sa1111_devices[] = {
},
};
static int sa1111_map_irq(struct sa1111 *sachip, irq_hw_number_t hwirq)
{
return irq_create_mapping(sachip->irqdomain, hwirq);
}
static void sa1111_handle_irqdomain(struct irq_domain *irqdomain, int irq)
{
struct irq_desc *d = irq_to_desc(irq_linear_revmap(irqdomain, irq));
if (d)
generic_handle_irq_desc(d);
}
/*
* SA1111 interrupt support. Since clearing an IRQ while there are
* active IRQs causes the interrupt output to pulse, the upper levels
@ -202,49 +216,45 @@ static void sa1111_irq_handler(struct irq_desc *desc)
{
unsigned int stat0, stat1, i;
struct sa1111 *sachip = irq_desc_get_handler_data(desc);
struct irq_domain *irqdomain;
void __iomem *mapbase = sachip->base + SA1111_INTC;
stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
stat1 = sa1111_readl(mapbase + SA1111_INTSTATCLR1);
stat0 = readl_relaxed(mapbase + SA1111_INTSTATCLR0);
stat1 = readl_relaxed(mapbase + SA1111_INTSTATCLR1);
sa1111_writel(stat0, mapbase + SA1111_INTSTATCLR0);
writel_relaxed(stat0, mapbase + SA1111_INTSTATCLR0);
desc->irq_data.chip->irq_ack(&desc->irq_data);
sa1111_writel(stat1, mapbase + SA1111_INTSTATCLR1);
writel_relaxed(stat1, mapbase + SA1111_INTSTATCLR1);
if (stat0 == 0 && stat1 == 0) {
do_bad_IRQ(desc);
return;
}
irqdomain = sachip->irqdomain;
for (i = 0; stat0; i++, stat0 >>= 1)
if (stat0 & 1)
generic_handle_irq(i + sachip->irq_base);
sa1111_handle_irqdomain(irqdomain, i);
for (i = 32; stat1; i++, stat1 >>= 1)
if (stat1 & 1)
generic_handle_irq(i + sachip->irq_base);
sa1111_handle_irqdomain(irqdomain, i);
/* For level-based interrupts */
desc->irq_data.chip->irq_unmask(&desc->irq_data);
}
#define SA1111_IRQMASK_LO(x) (1 << (x - sachip->irq_base))
#define SA1111_IRQMASK_HI(x) (1 << (x - sachip->irq_base - 32))
static u32 sa1111_irqmask(struct irq_data *d)
{
struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
return BIT((d->irq - sachip->irq_base) & 31);
return BIT(irqd_to_hwirq(d) & 31);
}
static int sa1111_irqbank(struct irq_data *d)
{
struct sa1111 *sachip = irq_data_get_irq_chip_data(d);
return ((d->irq - sachip->irq_base) / 32) * 4;
return (irqd_to_hwirq(d) / 32) * 4;
}
static void sa1111_ack_irq(struct irq_data *d)
@ -257,9 +267,9 @@ static void sa1111_mask_irq(struct irq_data *d)
void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d);
u32 ie;
ie = sa1111_readl(mapbase + SA1111_INTEN0);
ie = readl_relaxed(mapbase + SA1111_INTEN0);
ie &= ~sa1111_irqmask(d);
sa1111_writel(ie, mapbase + SA1111_INTEN0);
writel(ie, mapbase + SA1111_INTEN0);
}
static void sa1111_unmask_irq(struct irq_data *d)
@ -268,9 +278,9 @@ static void sa1111_unmask_irq(struct irq_data *d)
void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d);
u32 ie;
ie = sa1111_readl(mapbase + SA1111_INTEN0);
ie = readl_relaxed(mapbase + SA1111_INTEN0);
ie |= sa1111_irqmask(d);
sa1111_writel(ie, mapbase + SA1111_INTEN0);
writel_relaxed(ie, mapbase + SA1111_INTEN0);
}
/*
@ -287,11 +297,11 @@ static int sa1111_retrigger_irq(struct irq_data *d)
u32 ip, mask = sa1111_irqmask(d);
int i;
ip = sa1111_readl(mapbase + SA1111_INTPOL0);
ip = readl_relaxed(mapbase + SA1111_INTPOL0);
for (i = 0; i < 8; i++) {
sa1111_writel(ip ^ mask, mapbase + SA1111_INTPOL0);
sa1111_writel(ip, mapbase + SA1111_INTPOL0);
if (sa1111_readl(mapbase + SA1111_INTSTATCLR0) & mask)
writel_relaxed(ip ^ mask, mapbase + SA1111_INTPOL0);
writel_relaxed(ip, mapbase + SA1111_INTPOL0);
if (readl_relaxed(mapbase + SA1111_INTSTATCLR0) & mask)
break;
}
@ -313,13 +323,13 @@ static int sa1111_type_irq(struct irq_data *d, unsigned int flags)
if ((!(flags & IRQ_TYPE_EDGE_RISING) ^ !(flags & IRQ_TYPE_EDGE_FALLING)) == 0)
return -EINVAL;
ip = sa1111_readl(mapbase + SA1111_INTPOL0);
ip = readl_relaxed(mapbase + SA1111_INTPOL0);
if (flags & IRQ_TYPE_EDGE_RISING)
ip &= ~mask;
else
ip |= mask;
sa1111_writel(ip, mapbase + SA1111_INTPOL0);
sa1111_writel(ip, mapbase + SA1111_WAKEPOL0);
writel_relaxed(ip, mapbase + SA1111_INTPOL0);
writel_relaxed(ip, mapbase + SA1111_WAKEPOL0);
return 0;
}
@ -330,12 +340,12 @@ static int sa1111_wake_irq(struct irq_data *d, unsigned int on)
void __iomem *mapbase = sachip->base + SA1111_INTC + sa1111_irqbank(d);
u32 we, mask = sa1111_irqmask(d);
we = sa1111_readl(mapbase + SA1111_WAKEEN0);
we = readl_relaxed(mapbase + SA1111_WAKEEN0);
if (on)
we |= mask;
else
we &= ~mask;
sa1111_writel(we, mapbase + SA1111_WAKEEN0);
writel_relaxed(we, mapbase + SA1111_WAKEEN0);
return 0;
}
@ -350,10 +360,30 @@ static struct irq_chip sa1111_irq_chip = {
.irq_set_wake = sa1111_wake_irq,
};
static int sa1111_irqdomain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hwirq)
{
struct sa1111 *sachip = d->host_data;
/* Disallow unavailable interrupts */
if (hwirq > SSPROR && hwirq < AUDXMTDMADONEA)
return -EINVAL;
irq_set_chip_data(irq, sachip);
irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq);
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
return 0;
}
static const struct irq_domain_ops sa1111_irqdomain_ops = {
.map = sa1111_irqdomain_map,
.xlate = irq_domain_xlate_twocell,
};
static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
{
void __iomem *irqbase = sachip->base + SA1111_INTC;
unsigned i, irq;
int ret;
/*
@ -373,37 +403,39 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
sachip->irq_base = ret;
/* disable all IRQs */
sa1111_writel(0, irqbase + SA1111_INTEN0);
sa1111_writel(0, irqbase + SA1111_INTEN1);
sa1111_writel(0, irqbase + SA1111_WAKEEN0);
sa1111_writel(0, irqbase + SA1111_WAKEEN1);
writel_relaxed(0, irqbase + SA1111_INTEN0);
writel_relaxed(0, irqbase + SA1111_INTEN1);
writel_relaxed(0, irqbase + SA1111_WAKEEN0);
writel_relaxed(0, irqbase + SA1111_WAKEEN1);
/*
* detect on rising edge. Note: Feb 2001 Errata for SA1111
* specifies that S0ReadyInt and S1ReadyInt should be '1'.
*/
sa1111_writel(0, irqbase + SA1111_INTPOL0);
sa1111_writel(BIT(IRQ_S0_READY_NINT & 31) |
BIT(IRQ_S1_READY_NINT & 31),
irqbase + SA1111_INTPOL1);
writel_relaxed(0, irqbase + SA1111_INTPOL0);
writel_relaxed(BIT(IRQ_S0_READY_NINT & 31) |
BIT(IRQ_S1_READY_NINT & 31),
irqbase + SA1111_INTPOL1);
/* clear all IRQs */
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR0);
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
writel_relaxed(~0, irqbase + SA1111_INTSTATCLR0);
writel_relaxed(~0, irqbase + SA1111_INTSTATCLR1);
for (i = IRQ_GPAIN0; i <= SSPROR; i++) {
irq = sachip->irq_base + i;
irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq);
irq_set_chip_data(irq, sachip);
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
sachip->irqdomain = irq_domain_add_linear(NULL, SA1111_IRQ_NR,
&sa1111_irqdomain_ops,
sachip);
if (!sachip->irqdomain) {
irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
return -ENOMEM;
}
for (i = AUDXMTDMADONEA; i <= IRQ_S1_BVD1_STSCHG; i++) {
irq = sachip->irq_base + i;
irq_set_chip_and_handler(irq, &sa1111_irq_chip, handle_edge_irq);
irq_set_chip_data(irq, sachip);
irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
}
irq_domain_associate_many(sachip->irqdomain,
sachip->irq_base + IRQ_GPAIN0,
IRQ_GPAIN0, SSPROR + 1 - IRQ_GPAIN0);
irq_domain_associate_many(sachip->irqdomain,
sachip->irq_base + AUDXMTDMADONEA,
AUDXMTDMADONEA,
IRQ_S1_BVD1_STSCHG + 1 - AUDXMTDMADONEA);
/*
* Register SA1111 interrupt
@ -420,20 +452,22 @@ static int sa1111_setup_irq(struct sa1111 *sachip, unsigned irq_base)
static void sa1111_remove_irq(struct sa1111 *sachip)
{
struct irq_domain *domain = sachip->irqdomain;
void __iomem *irqbase = sachip->base + SA1111_INTC;
int i;
/* disable all IRQs */
sa1111_writel(0, irqbase + SA1111_INTEN0);
sa1111_writel(0, irqbase + SA1111_INTEN1);
sa1111_writel(0, irqbase + SA1111_WAKEEN0);
sa1111_writel(0, irqbase + SA1111_WAKEEN1);
writel_relaxed(0, irqbase + SA1111_INTEN0);
writel_relaxed(0, irqbase + SA1111_INTEN1);
writel_relaxed(0, irqbase + SA1111_WAKEEN0);
writel_relaxed(0, irqbase + SA1111_WAKEEN1);
if (sachip->irq != NO_IRQ) {
irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
irq_free_descs(sachip->irq_base, SA1111_IRQ_NR);
irq_set_chained_handler_and_data(sachip->irq, NULL, NULL);
for (i = 0; i < SA1111_IRQ_NR; i++)
irq_dispose_mapping(irq_find_mapping(domain, i));
irq_domain_remove(domain);
release_mem_region(sachip->phys + SA1111_INTC, 512);
}
release_mem_region(sachip->phys + SA1111_INTC, 512);
}
enum {
@ -572,7 +606,7 @@ static int sa1111_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct sa1111 *sachip = gc_to_sa1111(gc);
return sachip->irq_base + offset;
return sa1111_map_irq(sachip, offset);
}
static int sa1111_setup_gpios(struct sa1111 *sachip)
@ -618,11 +652,11 @@ static void sa1111_wake(struct sa1111 *sachip)
/*
* Turn VCO on, and disable PLL Bypass.
*/
r = sa1111_readl(sachip->base + SA1111_SKCR);
r = readl_relaxed(sachip->base + SA1111_SKCR);
r &= ~SKCR_VCO_OFF;
sa1111_writel(r, sachip->base + SA1111_SKCR);
writel_relaxed(r, sachip->base + SA1111_SKCR);
r |= SKCR_PLL_BYPASS | SKCR_OE_EN;
sa1111_writel(r, sachip->base + SA1111_SKCR);
writel_relaxed(r, sachip->base + SA1111_SKCR);
/*
* Wait lock time. SA1111 manual _doesn't_
@ -634,7 +668,7 @@ static void sa1111_wake(struct sa1111 *sachip)
* Enable RCLK. We also ensure that RDYEN is set.
*/
r |= SKCR_RCLKEN | SKCR_RDYEN;
sa1111_writel(r, sachip->base + SA1111_SKCR);
writel_relaxed(r, sachip->base + SA1111_SKCR);
/*
* Wait 14 RCLK cycles for the chip to finish coming out
@ -645,7 +679,7 @@ static void sa1111_wake(struct sa1111 *sachip)
/*
* Ensure all clocks are initially off.
*/
sa1111_writel(0, sachip->base + SA1111_SKPCR);
writel_relaxed(0, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
@ -675,7 +709,7 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac,
if (cas_latency == 3)
smcr |= SMCR_CLAT;
sa1111_writel(smcr, sachip->base + SA1111_SMCR);
writel_relaxed(smcr, sachip->base + SA1111_SMCR);
/*
* Now clear the bits in the DMA mask to work around the SA1111
@ -723,8 +757,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
dev->mapbase = sachip->base + info->offset;
dev->skpcr_mask = info->skpcr_mask;
for (i = 0; i < ARRAY_SIZE(info->irq); i++)
dev->irq[i] = sachip->irq_base + info->irq[i];
for (i = 0; i < ARRAY_SIZE(info->hwirq); i++)
dev->hwirq[i] = info->hwirq[i];
/*
* If the parent device has a DMA mask associated with it, and
@ -814,7 +848,7 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
/*
* Probe for the chip. Only touch the SBI registers.
*/
id = sa1111_readl(sachip->base + SA1111_SKID);
id = readl_relaxed(sachip->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
printk(KERN_DEBUG "SA1111 not detected: ID = %08lx\n", id);
ret = -ENODEV;
@ -833,11 +867,9 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
* The interrupt controller must be initialised before any
* other device to ensure that the interrupts are available.
*/
if (sachip->irq != NO_IRQ) {
ret = sa1111_setup_irq(sachip, pd->irq_base);
if (ret)
goto err_clk;
}
ret = sa1111_setup_irq(sachip, pd->irq_base);
if (ret)
goto err_clk;
/* Setup the GPIOs - should really be done after the IRQ setup */
ret = sa1111_setup_gpios(sachip);
@ -864,8 +896,8 @@ static int __sa1111_probe(struct device *me, struct resource *mem, int irq)
* DMA. It can otherwise be held firmly in the off position.
* (currently, we always enable it.)
*/
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR);
val = readl_relaxed(sachip->base + SA1111_SKPCR);
writel_relaxed(val | SKPCR_DCLKEN, sachip->base + SA1111_SKPCR);
/*
* Enable the SA1110 memory bus request and grant signals.
@ -962,31 +994,31 @@ static int sa1111_suspend_noirq(struct device *dev)
* Save state.
*/
base = sachip->base;
save->skcr = sa1111_readl(base + SA1111_SKCR);
save->skpcr = sa1111_readl(base + SA1111_SKPCR);
save->skcdr = sa1111_readl(base + SA1111_SKCDR);
save->skaud = sa1111_readl(base + SA1111_SKAUD);
save->skpwm0 = sa1111_readl(base + SA1111_SKPWM0);
save->skpwm1 = sa1111_readl(base + SA1111_SKPWM1);
save->skcr = readl_relaxed(base + SA1111_SKCR);
save->skpcr = readl_relaxed(base + SA1111_SKPCR);
save->skcdr = readl_relaxed(base + SA1111_SKCDR);
save->skaud = readl_relaxed(base + SA1111_SKAUD);
save->skpwm0 = readl_relaxed(base + SA1111_SKPWM0);
save->skpwm1 = readl_relaxed(base + SA1111_SKPWM1);
sa1111_writel(0, sachip->base + SA1111_SKPWM0);
sa1111_writel(0, sachip->base + SA1111_SKPWM1);
writel_relaxed(0, sachip->base + SA1111_SKPWM0);
writel_relaxed(0, sachip->base + SA1111_SKPWM1);
base = sachip->base + SA1111_INTC;
save->intpol0 = sa1111_readl(base + SA1111_INTPOL0);
save->intpol1 = sa1111_readl(base + SA1111_INTPOL1);
save->inten0 = sa1111_readl(base + SA1111_INTEN0);
save->inten1 = sa1111_readl(base + SA1111_INTEN1);
save->wakepol0 = sa1111_readl(base + SA1111_WAKEPOL0);
save->wakepol1 = sa1111_readl(base + SA1111_WAKEPOL1);
save->wakeen0 = sa1111_readl(base + SA1111_WAKEEN0);
save->wakeen1 = sa1111_readl(base + SA1111_WAKEEN1);
save->intpol0 = readl_relaxed(base + SA1111_INTPOL0);
save->intpol1 = readl_relaxed(base + SA1111_INTPOL1);
save->inten0 = readl_relaxed(base + SA1111_INTEN0);
save->inten1 = readl_relaxed(base + SA1111_INTEN1);
save->wakepol0 = readl_relaxed(base + SA1111_WAKEPOL0);
save->wakepol1 = readl_relaxed(base + SA1111_WAKEPOL1);
save->wakeen0 = readl_relaxed(base + SA1111_WAKEEN0);
save->wakeen1 = readl_relaxed(base + SA1111_WAKEEN1);
/*
* Disable.
*/
val = sa1111_readl(sachip->base + SA1111_SKCR);
sa1111_writel(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
val = readl_relaxed(sachip->base + SA1111_SKCR);
writel_relaxed(val | SKCR_SLEEP, sachip->base + SA1111_SKCR);
clk_disable(sachip->clk);
@ -1023,7 +1055,7 @@ static int sa1111_resume_noirq(struct device *dev)
* Ensure that the SA1111 is still here.
* FIXME: shouldn't do this here.
*/
id = sa1111_readl(sachip->base + SA1111_SKID);
id = readl_relaxed(sachip->base + SA1111_SKID);
if ((id & SKID_ID_MASK) != SKID_SA1111_ID) {
__sa1111_remove(sachip);
dev_set_drvdata(dev, NULL);
@ -1047,26 +1079,26 @@ static int sa1111_resume_noirq(struct device *dev)
*/
spin_lock_irqsave(&sachip->lock, flags);
sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN0);
sa1111_writel(0, sachip->base + SA1111_INTC + SA1111_INTEN1);
writel_relaxed(0, sachip->base + SA1111_INTC + SA1111_INTEN0);
writel_relaxed(0, sachip->base + SA1111_INTC + SA1111_INTEN1);
base = sachip->base;
sa1111_writel(save->skcr, base + SA1111_SKCR);
sa1111_writel(save->skpcr, base + SA1111_SKPCR);
sa1111_writel(save->skcdr, base + SA1111_SKCDR);
sa1111_writel(save->skaud, base + SA1111_SKAUD);
sa1111_writel(save->skpwm0, base + SA1111_SKPWM0);
sa1111_writel(save->skpwm1, base + SA1111_SKPWM1);
writel_relaxed(save->skcr, base + SA1111_SKCR);
writel_relaxed(save->skpcr, base + SA1111_SKPCR);
writel_relaxed(save->skcdr, base + SA1111_SKCDR);
writel_relaxed(save->skaud, base + SA1111_SKAUD);
writel_relaxed(save->skpwm0, base + SA1111_SKPWM0);
writel_relaxed(save->skpwm1, base + SA1111_SKPWM1);
base = sachip->base + SA1111_INTC;
sa1111_writel(save->intpol0, base + SA1111_INTPOL0);
sa1111_writel(save->intpol1, base + SA1111_INTPOL1);
sa1111_writel(save->inten0, base + SA1111_INTEN0);
sa1111_writel(save->inten1, base + SA1111_INTEN1);
sa1111_writel(save->wakepol0, base + SA1111_WAKEPOL0);
sa1111_writel(save->wakepol1, base + SA1111_WAKEPOL1);
sa1111_writel(save->wakeen0, base + SA1111_WAKEEN0);
sa1111_writel(save->wakeen1, base + SA1111_WAKEEN1);
writel_relaxed(save->intpol0, base + SA1111_INTPOL0);
writel_relaxed(save->intpol1, base + SA1111_INTPOL1);
writel_relaxed(save->inten0, base + SA1111_INTEN0);
writel_relaxed(save->inten1, base + SA1111_INTEN1);
writel_relaxed(save->wakepol0, base + SA1111_WAKEPOL0);
writel_relaxed(save->wakepol1, base + SA1111_WAKEPOL1);
writel_relaxed(save->wakeen0, base + SA1111_WAKEEN0);
writel_relaxed(save->wakeen1, base + SA1111_WAKEEN1);
spin_unlock_irqrestore(&sachip->lock, flags);
@ -1153,7 +1185,7 @@ static unsigned int __sa1111_pll_clock(struct sa1111 *sachip)
{
unsigned int skcdr, fbdiv, ipdiv, opdiv;
skcdr = sa1111_readl(sachip->base + SA1111_SKCDR);
skcdr = readl_relaxed(sachip->base + SA1111_SKCDR);
fbdiv = (skcdr & 0x007f) + 2;
ipdiv = ((skcdr & 0x0f80) >> 7) + 2;
@ -1195,13 +1227,13 @@ void sa1111_select_audio_mode(struct sa1111_dev *sadev, int mode)
spin_lock_irqsave(&sachip->lock, flags);
val = sa1111_readl(sachip->base + SA1111_SKCR);
val = readl_relaxed(sachip->base + SA1111_SKCR);
if (mode == SA1111_AUDIO_I2S) {
val &= ~SKCR_SELAC;
} else {
val |= SKCR_SELAC;
}
sa1111_writel(val, sachip->base + SA1111_SKCR);
writel_relaxed(val, sachip->base + SA1111_SKCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
@ -1226,7 +1258,7 @@ int sa1111_set_audio_rate(struct sa1111_dev *sadev, int rate)
if (div > 128)
div = 128;
sa1111_writel(div - 1, sachip->base + SA1111_SKAUD);
writel_relaxed(div - 1, sachip->base + SA1111_SKAUD);
return 0;
}
@ -1244,7 +1276,7 @@ int sa1111_get_audio_rate(struct sa1111_dev *sadev)
if (sadev->devid != SA1111_DEVID_SAC)
return -EINVAL;
div = sa1111_readl(sachip->base + SA1111_SKAUD) + 1;
div = readl_relaxed(sachip->base + SA1111_SKAUD) + 1;
return __sa1111_pll_clock(sachip) / (256 * div);
}
@ -1261,10 +1293,10 @@ void sa1111_set_io_dir(struct sa1111_dev *sadev,
#define MODIFY_BITS(port, mask, dir) \
if (mask) { \
val = sa1111_readl(port); \
val = readl_relaxed(port); \
val &= ~(mask); \
val |= (dir) & (mask); \
sa1111_writel(val, port); \
writel_relaxed(val, port); \
}
spin_lock_irqsave(&sachip->lock, flags);
@ -1329,8 +1361,8 @@ int sa1111_enable_device(struct sa1111_dev *sadev)
if (ret == 0) {
spin_lock_irqsave(&sachip->lock, flags);
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
val = readl_relaxed(sachip->base + SA1111_SKPCR);
writel_relaxed(val | sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
}
return ret;
@ -1348,8 +1380,8 @@ void sa1111_disable_device(struct sa1111_dev *sadev)
unsigned int val;
spin_lock_irqsave(&sachip->lock, flags);
val = sa1111_readl(sachip->base + SA1111_SKPCR);
sa1111_writel(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
val = readl_relaxed(sachip->base + SA1111_SKPCR);
writel_relaxed(val & ~sadev->skpcr_mask, sachip->base + SA1111_SKPCR);
spin_unlock_irqrestore(&sachip->lock, flags);
if (sachip->pdata && sachip->pdata->disable)
@ -1359,9 +1391,10 @@ EXPORT_SYMBOL(sa1111_disable_device);
int sa1111_get_irq(struct sa1111_dev *sadev, unsigned num)
{
if (num >= ARRAY_SIZE(sadev->irq))
struct sa1111 *sachip = sa1111_chip_driver(sadev);
if (num >= ARRAY_SIZE(sadev->hwirq))
return -EINVAL;
return sadev->irq[num];
return sa1111_map_irq(sachip, sadev->hwirq[num]);
}
EXPORT_SYMBOL_GPL(sa1111_get_irq);
@ -1379,36 +1412,6 @@ static int sa1111_match(struct device *_dev, struct device_driver *_drv)
return !!(dev->devid & drv->devid);
}
static int sa1111_bus_suspend(struct device *dev, pm_message_t state)
{
struct sa1111_dev *sadev = to_sa1111_device(dev);
struct sa1111_driver *drv = SA1111_DRV(dev->driver);
int ret = 0;
if (drv && drv->suspend)
ret = drv->suspend(sadev, state);
return ret;
}
static int sa1111_bus_resume(struct device *dev)
{
struct sa1111_dev *sadev = to_sa1111_device(dev);
struct sa1111_driver *drv = SA1111_DRV(dev->driver);
int ret = 0;
if (drv && drv->resume)
ret = drv->resume(sadev);
return ret;
}
static void sa1111_bus_shutdown(struct device *dev)
{
struct sa1111_driver *drv = SA1111_DRV(dev->driver);
if (drv && drv->shutdown)
drv->shutdown(to_sa1111_device(dev));
}
static int sa1111_bus_probe(struct device *dev)
{
struct sa1111_dev *sadev = to_sa1111_device(dev);
@ -1436,9 +1439,6 @@ struct bus_type sa1111_bus_type = {
.match = sa1111_match,
.probe = sa1111_bus_probe,
.remove = sa1111_bus_remove,
.suspend = sa1111_bus_suspend,
.resume = sa1111_bus_resume,
.shutdown = sa1111_bus_shutdown,
};
EXPORT_SYMBOL(sa1111_bus_type);

View File

@ -10,11 +10,10 @@
#include <linux/interrupt.h>
#define __exception __attribute__((section(".exception.text")))
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#define __exception_irq_entry __irq_entry
#else
#define __exception_irq_entry __exception
#define __exception_irq_entry
#endif
#endif /* __ASM_ARM_EXCEPTION_H */

View File

@ -117,6 +117,10 @@
# endif
#endif
#if defined(CONFIG_CACHE_B15_RAC)
# define MULTI_CACHE 1
#endif
#if defined(CONFIG_CPU_V7M)
# define MULTI_CACHE 1
#endif

View File

@ -0,0 +1,10 @@
#ifndef __ASM_ARM_HARDWARE_CACHE_B15_RAC_H
#define __ASM_ARM_HARDWARE_CACHE_B15_RAC_H
#ifndef __ASSEMBLY__
void b15_flush_kern_cache_all(void);
#endif
#endif

View File

@ -15,33 +15,6 @@
#include <mach/bitfield.h>
/*
* The SA1111 is always located at virtual 0xf4000000, and is always
* "native" endian.
*/
#define SA1111_VBASE 0xf4000000
/* Don't use these! */
#define SA1111_p2v( x ) ((x) - SA1111_BASE + SA1111_VBASE)
#define SA1111_v2p( x ) ((x) - SA1111_VBASE + SA1111_BASE)
#ifndef __ASSEMBLY__
#define _SA1111(x) ((x) + sa1111->resource.start)
#endif
#define sa1111_writel(val,addr) __raw_writel(val, addr)
#define sa1111_readl(addr) __raw_readl(addr)
/*
* 26 bits of the SA-1110 address bus are available to the SA-1111.
* Use these when feeding target addresses to the DMA engines.
*/
#define SA1111_ADDR_WIDTH (26)
#define SA1111_ADDR_MASK ((1<<SA1111_ADDR_WIDTH)-1)
#define SA1111_DMA_ADDR(x) ((x)&SA1111_ADDR_MASK)
/*
* Don't ask the (SAC) DMA engines to move less than this amount.
*/
@ -417,7 +390,7 @@ struct sa1111_dev {
struct resource res;
void __iomem *mapbase;
unsigned int skpcr_mask;
unsigned int irq[6];
unsigned int hwirq[6];
u64 dma_mask;
};
@ -431,9 +404,6 @@ struct sa1111_driver {
unsigned int devid;
int (*probe)(struct sa1111_dev *);
int (*remove)(struct sa1111_dev *);
int (*suspend)(struct sa1111_dev *, pm_message_t);
int (*resume)(struct sa1111_dev *);
void (*shutdown)(struct sa1111_dev *);
};
#define SA1111_DRV(_d) container_of((_d), struct sa1111_driver, drv)

View File

@ -88,6 +88,7 @@
#else /* CONFIG_MMU */
#ifndef __ASSEMBLY__
extern unsigned long setup_vectors_base(void);
extern unsigned long vectors_base;
#define VECTORS_BASE vectors_base
#endif

View File

@ -45,6 +45,16 @@ struct thread_struct {
struct debug_info debug;
};
/*
* Everything usercopied to/from thread_struct is statically-sized, so
* no hardened usercopy whitelist is needed.
*/
static inline void arch_thread_struct_whitelist(unsigned long *offset,
unsigned long *size)
{
*offset = *size = 0;
}
#define INIT_THREAD { }
#define start_thread(regs,pc,sp) \

View File

@ -0,0 +1,43 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) 2014 ARM Ltd. */
#ifndef __ASM_PTDUMP_H
#define __ASM_PTDUMP_H
#ifdef CONFIG_ARM_PTDUMP_CORE
#include <linux/mm_types.h>
#include <linux/seq_file.h>
struct addr_marker {
unsigned long start_address;
char *name;
};
struct ptdump_info {
struct mm_struct *mm;
const struct addr_marker *markers;
unsigned long base_addr;
};
void ptdump_walk_pgd(struct seq_file *s, struct ptdump_info *info);
#ifdef CONFIG_ARM_PTDUMP_DEBUGFS
int ptdump_debugfs_register(struct ptdump_info *info, const char *name);
#else
static inline int ptdump_debugfs_register(struct ptdump_info *info,
const char *name)
{
return 0;
}
#endif /* CONFIG_ARM_PTDUMP_DEBUGFS */
void ptdump_check_wx(void);
#endif /* CONFIG_ARM_PTDUMP_CORE */
#ifdef CONFIG_DEBUG_WX
#define debug_checkwx() ptdump_check_wx()
#else
#define debug_checkwx() do { } while (0)
#endif
#endif /* __ASM_PTDUMP_H */

View File

@ -6,4 +6,25 @@
extern char _exiprom[];
extern char __idmap_text_start[];
extern char __idmap_text_end[];
extern char __entry_text_start[];
extern char __entry_text_end[];
extern char __hyp_idmap_text_start[];
extern char __hyp_idmap_text_end[];
static inline bool in_entry_text(unsigned long addr)
{
return memory_contains(__entry_text_start, __entry_text_end,
(void *)addr, 1);
}
static inline bool in_idmap_text(unsigned long addr)
{
void *a = (void *)addr;
return memory_contains(__idmap_text_start, __idmap_text_end, a, 1) ||
memory_contains(__hyp_idmap_text_start, __hyp_idmap_text_end,
a, 1);
}
#endif /* _ASM_ARM_SECTIONS_H */

View File

@ -39,18 +39,4 @@ static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n)
return __memset64(p, v, n * 8, v >> 32);
}
extern void __memzero(void *ptr, __kernel_size_t n);
#define memset(p,v,n) \
({ \
void *__p = (p); size_t __n = n; \
if ((__n) != 0) { \
if (__builtin_constant_p((v)) && (v) == 0) \
__memzero((__p),(__n)); \
else \
memset((__p),(v),(__n)); \
} \
(__p); \
})
#endif

View File

@ -28,18 +28,6 @@ static inline int __in_irqentry_text(unsigned long ptr)
ptr < (unsigned long)&__irqentry_text_end;
}
static inline int in_exception_text(unsigned long ptr)
{
extern char __exception_text_start[];
extern char __exception_text_end[];
int in;
in = ptr >= (unsigned long)&__exception_text_start &&
ptr < (unsigned long)&__exception_text_end;
return in ? : __in_irqentry_text(ptr);
}
extern void __init early_trap_init(void *);
extern void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame);
extern void ptrace_break(struct task_struct *tsk, struct pt_regs *regs);

View File

@ -20,8 +20,10 @@
#ifndef __ASM_UNIFIED_H
#define __ASM_UNIFIED_H
#if defined(__ASSEMBLY__) && defined(CONFIG_ARM_ASM_UNIFIED)
#if defined(__ASSEMBLY__)
.syntax unified
#else
__asm__(".syntax unified");
#endif
#ifdef CONFIG_CPU_V7M
@ -64,77 +66,4 @@
#endif /* CONFIG_THUMB2_KERNEL */
#ifndef CONFIG_ARM_ASM_UNIFIED
/*
* If the unified assembly syntax isn't used (in ARM mode), these
* macros expand to an empty string
*/
#ifdef __ASSEMBLY__
.macro it, cond
.endm
.macro itt, cond
.endm
.macro ite, cond
.endm
.macro ittt, cond
.endm
.macro itte, cond
.endm
.macro itet, cond
.endm
.macro itee, cond
.endm
.macro itttt, cond
.endm
.macro ittte, cond
.endm
.macro ittet, cond
.endm
.macro ittee, cond
.endm
.macro itett, cond
.endm
.macro itete, cond
.endm
.macro iteet, cond
.endm
.macro iteee, cond
.endm
#else /* !__ASSEMBLY__ */
__asm__(
" .macro it, cond\n"
" .endm\n"
" .macro itt, cond\n"
" .endm\n"
" .macro ite, cond\n"
" .endm\n"
" .macro ittt, cond\n"
" .endm\n"
" .macro itte, cond\n"
" .endm\n"
" .macro itet, cond\n"
" .endm\n"
" .macro itee, cond\n"
" .endm\n"
" .macro itttt, cond\n"
" .endm\n"
" .macro ittte, cond\n"
" .endm\n"
" .macro ittet, cond\n"
" .endm\n"
" .macro ittee, cond\n"
" .endm\n"
" .macro itett, cond\n"
" .endm\n"
" .macro itete, cond\n"
" .endm\n"
" .macro iteet, cond\n"
" .endm\n"
" .macro iteee, cond\n"
" .endm\n");
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_ARM_ASM_UNIFIED */
#endif /* !__ASM_UNIFIED_H */

View File

@ -92,7 +92,6 @@ EXPORT_SYMBOL(__memset64);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(__memzero);
EXPORT_SYMBOL(mmioset);
EXPORT_SYMBOL(mmiocpy);

View File

@ -82,11 +82,7 @@
#endif
.endm
#ifdef CONFIG_KPROBES
.section .kprobes.text,"ax",%progbits
#else
.text
#endif
.section .entry.text,"ax",%progbits
/*
* Invalid mode handlers

View File

@ -37,6 +37,7 @@ saved_pc .req lr
#define TRACE(x...)
#endif
.section .entry.text,"ax",%progbits
.align 5
#if !(IS_ENABLED(CONFIG_TRACE_IRQFLAGS) || IS_ENABLED(CONFIG_CONTEXT_TRACKING))
/*

View File

@ -105,8 +105,9 @@ __mmap_switched:
ARM( ldmia r4!, {r0, r1, sp} )
THUMB( ldmia r4!, {r0, r1, r3} )
THUMB( mov sp, r3 )
sub r1, r1, r0
bl __memzero @ clear .bss
sub r2, r1, r0
mov r1, #0
bl memset @ clear .bss
ldmia r4, {r0, r1, r2, r3}
str r9, [r0] @ Save processor ID

View File

@ -44,17 +44,17 @@ static DEFINE_PER_CPU(struct perf_event *, bp_on_reg[ARM_MAX_BRP]);
static DEFINE_PER_CPU(struct perf_event *, wp_on_reg[ARM_MAX_WRP]);
/* Number of BRP/WRP registers on this CPU. */
static int core_num_brps;
static int core_num_wrps;
static int core_num_brps __ro_after_init;
static int core_num_wrps __ro_after_init;
/* Debug architecture version. */
static u8 debug_arch;
static u8 debug_arch __ro_after_init;
/* Does debug architecture support OS Save and Restore? */
static bool has_ossr;
static bool has_ossr __ro_after_init;
/* Maximum supported watchpoint length. */
static u8 max_watchpoint_len;
static u8 max_watchpoint_len __ro_after_init;
#define READ_WB_REG_CASE(OP2, M, VAL) \
case ((OP2 << 4) + M): \

View File

@ -379,6 +379,9 @@ asmlinkage void secondary_start_kernel(void)
cpu_init();
#ifndef CONFIG_MMU
setup_vectors_base();
#endif
pr_debug("CPU%u: Booted secondary processor\n", cpu);
preempt_disable();

View File

@ -3,6 +3,7 @@
#include <linux/sched/debug.h>
#include <linux/stacktrace.h>
#include <asm/sections.h>
#include <asm/stacktrace.h>
#include <asm/traps.h>
@ -63,7 +64,6 @@ EXPORT_SYMBOL(walk_stackframe);
#ifdef CONFIG_STACKTRACE
struct stack_trace_data {
struct stack_trace *trace;
unsigned long last_pc;
unsigned int no_sched_functions;
unsigned int skip;
};
@ -87,16 +87,7 @@ static int save_trace(struct stackframe *frame, void *d)
if (trace->nr_entries >= trace->max_entries)
return 1;
/*
* in_exception_text() is designed to test if the PC is one of
* the functions which has an exception stack above it, but
* unfortunately what is in frame->pc is the return LR value,
* not the saved PC value. So, we need to track the previous
* frame PC value when doing this.
*/
addr = data->last_pc;
data->last_pc = frame->pc;
if (!in_exception_text(addr))
if (!in_entry_text(frame->pc))
return 0;
regs = (struct pt_regs *)frame->sp;
@ -114,7 +105,6 @@ static noinline void __save_stack_trace(struct task_struct *tsk,
struct stackframe frame;
data.trace = trace;
data.last_pc = ULONG_MAX;
data.skip = trace->skip;
data.no_sched_functions = nosched;

View File

@ -72,7 +72,7 @@ void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long
printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
#endif
if (in_exception_text(where))
if (in_entry_text(from))
dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
}
@ -433,7 +433,7 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
return fn ? fn(regs, instr) : 1;
}
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
asmlinkage void do_undefinstr(struct pt_regs *regs)
{
unsigned int instr;
siginfo_t info;

View File

@ -96,9 +96,9 @@ SECTIONS
.text : { /* Real text segment */
_stext = .; /* Text and read-only data */
IDMAP_TEXT
__exception_text_start = .;
*(.exception.text)
__exception_text_end = .;
__entry_text_start = .;
*(.entry.text)
__entry_text_end = .;
IRQENTRY_TEXT
TEXT_TEXT
SCHED_TEXT

View File

@ -105,9 +105,9 @@ SECTIONS
.text : { /* Real text segment */
_stext = .; /* Text and read-only data */
IDMAP_TEXT
__exception_text_start = .;
*(.exception.text)
__exception_text_end = .;
__entry_text_start = .;
*(.entry.text)
__entry_text_end = .;
IRQENTRY_TEXT
SOFTIRQENTRY_TEXT
TEXT_TEXT

View File

@ -8,7 +8,7 @@
lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
csumpartialcopy.o csumpartialcopyuser.o clearbit.o \
delay.o delay-loop.o findbit.o memchr.o memcpy.o \
memmove.o memset.o memzero.o setbit.o \
memmove.o memset.o setbit.o \
strchr.o strrchr.o \
testchangebit.o testclearbit.o testsetbit.o \
ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \

View File

@ -1,137 +0,0 @@
/*
* linux/arch/arm/lib/memzero.S
*
* Copyright (C) 1995-2000 Russell King
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/unwind.h>
.text
.align 5
.word 0
/*
* Align the pointer in r0. r3 contains the number of bytes that we are
* mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
* don't bother; we use byte stores instead.
*/
UNWIND( .fnstart )
1: subs r1, r1, #4 @ 1 do we have enough
blt 5f @ 1 bytes to align with?
cmp r3, #2 @ 1
strltb r2, [r0], #1 @ 1
strleb r2, [r0], #1 @ 1
strb r2, [r0], #1 @ 1
add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3))
/*
* The pointer is now aligned and the length is adjusted. Try doing the
* memzero again.
*/
ENTRY(__memzero)
mov r2, #0 @ 1
ands r3, r0, #3 @ 1 unaligned?
bne 1b @ 1
/*
* r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
*/
cmp r1, #16 @ 1 we can skip this chunk if we
blt 4f @ 1 have < 16 bytes
#if ! CALGN(1)+0
/*
* We need an extra register for this loop - save the return address and
* use the LR
*/
str lr, [sp, #-4]! @ 1
UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {lr} )
mov ip, r2 @ 1
mov lr, r2 @ 1
3: subs r1, r1, #64 @ 1 write 32 bytes out per loop
stmgeia r0!, {r2, r3, ip, lr} @ 4
stmgeia r0!, {r2, r3, ip, lr} @ 4
stmgeia r0!, {r2, r3, ip, lr} @ 4
stmgeia r0!, {r2, r3, ip, lr} @ 4
bgt 3b @ 1
ldmeqfd sp!, {pc} @ 1/2 quick exit
/*
* No need to correct the count; we're only testing bits from now on
*/
tst r1, #32 @ 1
stmneia r0!, {r2, r3, ip, lr} @ 4
stmneia r0!, {r2, r3, ip, lr} @ 4
tst r1, #16 @ 1 16 bytes or more?
stmneia r0!, {r2, r3, ip, lr} @ 4
ldr lr, [sp], #4 @ 1
UNWIND( .fnend )
#else
/*
* This version aligns the destination pointer in order to write
* whole cache lines at once.
*/
stmfd sp!, {r4-r7, lr}
UNWIND( .fnend )
UNWIND( .fnstart )
UNWIND( .save {r4-r7, lr} )
mov r4, r2
mov r5, r2
mov r6, r2
mov r7, r2
mov ip, r2
mov lr, r2
cmp r1, #96
andgts ip, r0, #31
ble 3f
rsb ip, ip, #32
sub r1, r1, ip
movs ip, ip, lsl #(32 - 4)
stmcsia r0!, {r4, r5, r6, r7}
stmmiia r0!, {r4, r5}
movs ip, ip, lsl #2
strcs r2, [r0], #4
3: subs r1, r1, #64
stmgeia r0!, {r2-r7, ip, lr}
stmgeia r0!, {r2-r7, ip, lr}
bgt 3b
ldmeqfd sp!, {r4-r7, pc}
tst r1, #32
stmneia r0!, {r2-r7, ip, lr}
tst r1, #16
stmneia r0!, {r4-r7}
ldmfd sp!, {r4-r7, lr}
UNWIND( .fnend )
#endif
UNWIND( .fnstart )
4: tst r1, #8 @ 1 8 bytes or more?
stmneia r0!, {r2, r3} @ 2
tst r1, #4 @ 1 4 bytes or more?
strne r2, [r0], #4 @ 1
/*
* When we get here, we've got less than 4 bytes to zero. We
* may have an unaligned pointer as well.
*/
5: tst r1, #2 @ 1 2 bytes or more?
strneb r2, [r0], #1 @ 1
strneb r2, [r0], #1 @ 1
tst r1, #1 @ 1 a byte left over
strneb r2, [r0], #1 @ 1
ret lr @ 1
UNWIND( .fnend )
ENDPROC(__memzero)

View File

@ -17,6 +17,7 @@
#include <linux/mtd/rawnand.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/clk.h>
#include <linux/videodev2.h>
#include <media/i2c/tvp514x.h>
@ -108,11 +109,20 @@ static struct platform_device davinci_nand_device = {
},
};
static struct gpiod_lookup_table i2c_recovery_gpiod_table = {
.dev_id = "i2c_davinci",
.table = {
GPIO_LOOKUP("davinci_gpio", 15, "sda",
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
GPIO_LOOKUP("davinci_gpio", 14, "scl",
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
static struct davinci_i2c_platform_data i2c_pdata = {
.bus_freq = 400 /* kHz */,
.bus_delay = 0 /* usec */,
.sda_pin = 15,
.scl_pin = 14,
.gpio_recovery = true,
};
static int dm355evm_mmc_gpios = -EINVAL;
@ -141,6 +151,7 @@ static struct i2c_board_info dm355evm_i2c_info[] = {
static void __init evm_init_i2c(void)
{
gpiod_add_lookup_table(&i2c_recovery_gpiod_table);
davinci_init_i2c(&i2c_pdata);
gpio_request(5, "dm355evm_msp");

View File

@ -13,6 +13,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio/machine.h>
#include <linux/i2c.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/platform_data/at24.h>
@ -595,18 +596,28 @@ static struct i2c_board_info __initdata i2c_info[] = {
},
};
static struct gpiod_lookup_table i2c_recovery_gpiod_table = {
.dev_id = "i2c_davinci",
.table = {
GPIO_LOOKUP("davinci_gpio", 44, "sda",
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
GPIO_LOOKUP("davinci_gpio", 43, "scl",
GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
},
};
/* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
* which requires 100 usec of idle bus after i2c writes sent to it.
*/
static struct davinci_i2c_platform_data i2c_pdata = {
.bus_freq = 20 /* kHz */,
.bus_delay = 100 /* usec */,
.sda_pin = 44,
.scl_pin = 43,
.gpio_recovery = true,
};
static void __init evm_init_i2c(void)
{
gpiod_add_lookup_table(&i2c_recovery_gpiod_table);
davinci_init_i2c(&i2c_pdata);
i2c_add_driver(&dm6446evm_msp_driver);
i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));

View File

@ -5,6 +5,7 @@ menu "SA11x0 Implementations"
config SA1100_ASSABET
bool "Assabet"
select ARM_SA1110_CPUFREQ
select GPIO_REG
help
Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
Microprocessor Development Board (also known as the Assabet).

View File

@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/ioport.h>
#include <linux/platform_data/sa11x0-serial.h>
#include <linux/serial_core.h>
@ -61,20 +62,45 @@
unsigned long SCR_value = ASSABET_SCR_INIT;
EXPORT_SYMBOL(SCR_value);
static unsigned long BCR_value = ASSABET_BCR_DB1110;
static struct gpio_chip *assabet_bcr_gc;
static const char *assabet_names[] = {
"cf_pwr", "cf_gfx_reset", "nsoft_reset", "irda_fsel",
"irda_md0", "irda_md1", "stereo_loopback", "ncf_bus_on",
"audio_pwr_on", "light_pwr_on", "lcd16data", "lcd_pwr_on",
"rs232_on", "nred_led", "ngreen_led", "vib_on",
"com_dtr", "com_rts", "radio_wake_mod", "i2c_enab",
"tvir_enab", "qmute", "radio_pwr_on", "spkr_off",
"rs232_valid", "com_dcd", "com_cts", "com_dsr",
"radio_cts", "radio_dsr", "radio_dcd", "radio_ri",
};
/* The old deprecated interface */
void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
{
unsigned long flags;
unsigned long m = mask, v = val;
local_irq_save(flags);
BCR_value = (BCR_value & ~mask) | val;
ASSABET_BCR = BCR_value;
local_irq_restore(flags);
assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
}
EXPORT_SYMBOL(ASSABET_BCR_frob);
static int __init assabet_init_gpio(void __iomem *reg, u32 def_val)
{
struct gpio_chip *gc;
writel_relaxed(def_val, reg);
gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
assabet_names, NULL, NULL);
if (IS_ERR(gc))
return PTR_ERR(gc);
assabet_bcr_gc = gc;
return gc->base;
}
/*
* The codec reset goes to three devices, so we need to release
* the rest when any one of these requests it. However, that
@ -146,7 +172,7 @@ static void adv7171_write(unsigned reg, unsigned val)
unsigned gpdr = GPDR;
unsigned gplr = GPLR;
ASSABET_BCR = BCR_value | ASSABET_BCR_AUDIO_ON;
ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON);
udelay(100);
GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
@ -457,14 +483,6 @@ static void __init assabet_init(void)
sa11x0_ppc_configure_mcp();
if (machine_has_neponset()) {
/*
* Angel sets this, but other bootloaders may not.
*
* This must precede any driver calls to BCR_set()
* or BCR_clear().
*/
ASSABET_BCR = BCR_value = ASSABET_BCR_DB1111;
#ifndef CONFIG_ASSABET_NEPONSET
printk( "Warning: Neponset detected but full support "
"hasn't been configured in the kernel\n" );
@ -748,12 +766,31 @@ static int __init assabet_leds_init(void)
fs_initcall(assabet_leds_init);
#endif
void __init assabet_init_irq(void)
{
u32 def_val;
sa1100_init_irq();
if (machine_has_neponset())
def_val = ASSABET_BCR_DB1111;
else
def_val = ASSABET_BCR_DB1110;
/*
* Angel sets this, but other bootloaders may not.
*
* This must precede any driver calls to BCR_set() or BCR_clear().
*/
assabet_init_gpio((void *)&ASSABET_BCR, def_val);
}
MACHINE_START(ASSABET, "Intel-Assabet")
.atag_offset = 0x100,
.fixup = fixup_assabet,
.map_io = assabet_map_io,
.nr_irqs = SA1100_NR_IRQS,
.init_irq = sa1100_init_irq,
.init_irq = assabet_init_irq,
.init_time = sa1100_timer_init,
.init_machine = assabet_init,
.init_late = sa11x0_init_late,

View File

@ -3,6 +3,8 @@
* linux/arch/arm/mach-sa1100/neponset.c
*/
#include <linux/err.h>
#include <linux/gpio/driver.h>
#include <linux/gpio/gpio-reg.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/irq.h>
@ -45,10 +47,13 @@
#define IRR_USAR (1 << 1)
#define IRR_SA1111 (1 << 2)
#define NCR_NGPIO 7
#define MDM_CTL0_RTS1 (1 << 0)
#define MDM_CTL0_DTR1 (1 << 1)
#define MDM_CTL0_RTS2 (1 << 2)
#define MDM_CTL0_DTR2 (1 << 3)
#define MDM_CTL0_NGPIO 4
#define MDM_CTL1_CTS1 (1 << 0)
#define MDM_CTL1_DSR1 (1 << 1)
@ -56,80 +61,87 @@
#define MDM_CTL1_CTS2 (1 << 3)
#define MDM_CTL1_DSR2 (1 << 4)
#define MDM_CTL1_DCD2 (1 << 5)
#define MDM_CTL1_NGPIO 6
#define AUD_SEL_1341 (1 << 0)
#define AUD_MUTE_1341 (1 << 1)
#define AUD_NGPIO 2
extern void sa1110_mb_disable(void);
#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)
static const char *neponset_ncr_names[] = {
"gp01_off", "tp_power", "ms_power", "enet_osc",
"spi_kb_wk_up", "a0vpp", "a1vpp"
};
static const char *neponset_mdmctl0_names[] = {
"rts3", "dtr3", "rts1", "dtr1",
};
static const char *neponset_mdmctl1_names[] = {
"cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
};
static const char *neponset_aud_names[] = {
"sel_1341", "mute_1341",
};
struct neponset_drvdata {
void __iomem *base;
struct platform_device *sa1111;
struct platform_device *smc91x;
unsigned irq_base;
#ifdef CONFIG_PM_SLEEP
u32 ncr0;
u32 mdm_ctl_0;
#endif
struct gpio_chip *gpio[4];
};
static void __iomem *nep_base;
static struct neponset_drvdata *nep;
void neponset_ncr_frob(unsigned int mask, unsigned int val)
{
void __iomem *base = nep_base;
struct neponset_drvdata *n = nep;
unsigned long m = mask, v = val;
if (base) {
unsigned long flags;
unsigned v;
local_irq_save(flags);
v = readb_relaxed(base + NCR_0);
writeb_relaxed((v & ~mask) | val, base + NCR_0);
local_irq_restore(flags);
} else {
WARN(1, "nep_base unset\n");
}
if (nep)
n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
else
WARN(1, "nep unset\n");
}
EXPORT_SYMBOL(neponset_ncr_frob);
static void neponset_set_mctrl(struct uart_port *port, u_int mctrl)
{
void __iomem *base = nep_base;
u_int mdm_ctl0;
struct neponset_drvdata *n = nep;
unsigned long mask, val = 0;
if (!base)
if (!n)
return;
mdm_ctl0 = readb_relaxed(base + MDM_CTL_0);
if (port->mapbase == _Ser1UTCR0) {
if (mctrl & TIOCM_RTS)
mdm_ctl0 &= ~MDM_CTL0_RTS2;
else
mdm_ctl0 |= MDM_CTL0_RTS2;
mask = MDM_CTL0_RTS2 | MDM_CTL0_DTR2;
if (mctrl & TIOCM_DTR)
mdm_ctl0 &= ~MDM_CTL0_DTR2;
else
mdm_ctl0 |= MDM_CTL0_DTR2;
if (!(mctrl & TIOCM_RTS))
val |= MDM_CTL0_RTS2;
if (!(mctrl & TIOCM_DTR))
val |= MDM_CTL0_DTR2;
} else if (port->mapbase == _Ser3UTCR0) {
if (mctrl & TIOCM_RTS)
mdm_ctl0 &= ~MDM_CTL0_RTS1;
else
mdm_ctl0 |= MDM_CTL0_RTS1;
mask = MDM_CTL0_RTS1 | MDM_CTL0_DTR1;
if (mctrl & TIOCM_DTR)
mdm_ctl0 &= ~MDM_CTL0_DTR1;
else
mdm_ctl0 |= MDM_CTL0_DTR1;
if (!(mctrl & TIOCM_RTS))
val |= MDM_CTL0_RTS1;
if (!(mctrl & TIOCM_DTR))
val |= MDM_CTL0_DTR1;
}
writeb_relaxed(mdm_ctl0, base + MDM_CTL_0);
n->gpio[1]->set_multiple(n->gpio[1], &mask, &val);
}
static u_int neponset_get_mctrl(struct uart_port *port)
{
void __iomem *base = nep_base;
void __iomem *base = nep->base;
u_int ret = TIOCM_CD | TIOCM_CTS | TIOCM_DSR;
u_int mdm_ctl1;
@ -231,6 +243,22 @@ static struct irq_chip nochip = {
.irq_unmask = nochip_noop,
};
static int neponset_init_gpio(struct gpio_chip **gcp,
struct device *dev, const char *label, void __iomem *reg,
unsigned num, bool in, const char *const * names)
{
struct gpio_chip *gc;
gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
readl_relaxed(reg), names, NULL, NULL);
if (IS_ERR(gc))
return PTR_ERR(gc);
*gcp = gc;
return 0;
}
static struct sa1111_platform_data sa1111_info = {
.disable_devs = SA1111_DEVID_PS2_MSE,
};
@ -274,7 +302,7 @@ static int neponset_probe(struct platform_device *dev)
};
int ret, irq;
if (nep_base)
if (nep)
return -EBUSY;
irq = ret = platform_get_irq(dev, 0);
@ -330,6 +358,22 @@ static int neponset_probe(struct platform_device *dev)
irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
/* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
d->base + NCR_0, NCR_NGPIO, false,
neponset_ncr_names);
neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
neponset_mdmctl0_names);
neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
neponset_mdmctl1_names);
neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
d->base + AUD_CTL, AUD_NGPIO, false,
neponset_aud_names);
/*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
* something on the Neponset activates this IRQ on sleep (eth?)
@ -340,16 +384,13 @@ static int neponset_probe(struct platform_device *dev)
dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
nep_base = d->base;
nep = d;
sa1100_register_uart_fns(&neponset_port_fns);
/* Ensure that the memory bus request/grant signals are setup */
sa1110_mb_disable();
/* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
sa1111_resources[0].parent = sa1111_res;
sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
@ -385,7 +426,7 @@ static int neponset_remove(struct platform_device *dev)
platform_device_unregister(d->smc91x);
irq_set_chained_handler(irq, NULL);
irq_free_descs(d->irq_base, NEP_IRQ_NR);
nep_base = NULL;
nep = NULL;
iounmap(d->base);
kfree(d);
@ -393,30 +434,22 @@ static int neponset_remove(struct platform_device *dev)
}
#ifdef CONFIG_PM_SLEEP
static int neponset_suspend(struct device *dev)
{
struct neponset_drvdata *d = dev_get_drvdata(dev);
d->ncr0 = readb_relaxed(d->base + NCR_0);
d->mdm_ctl_0 = readb_relaxed(d->base + MDM_CTL_0);
return 0;
}
static int neponset_resume(struct device *dev)
{
struct neponset_drvdata *d = dev_get_drvdata(dev);
int i, ret = 0;
writeb_relaxed(d->ncr0, d->base + NCR_0);
writeb_relaxed(d->mdm_ctl_0, d->base + MDM_CTL_0);
for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
ret = gpio_reg_resume(d->gpio[i]);
if (ret)
break;
}
return 0;
return ret;
}
static const struct dev_pm_ops neponset_pm_ops = {
.suspend_noirq = neponset_suspend,
.resume_noirq = neponset_resume,
.freeze_noirq = neponset_suspend,
.restore_noirq = neponset_resume,
};
#define PM_OPS &neponset_pm_ops

View File

@ -909,6 +909,14 @@ config OUTER_CACHE_SYNC
The outer cache has a outer_cache_fns.sync function pointer
that can be used to drain the write buffer of the outer cache.
config CACHE_B15_RAC
bool "Enable the Broadcom Brahma-B15 read-ahead cache controller"
depends on ARCH_BRCMSTB
default y
help
This option enables the Broadcom Brahma-B15 read-ahead cache
controller. If disabled, the read-ahead cache remains off.
config CACHE_FEROCEON_L2
bool "Enable the Feroceon L2 cache controller"
depends on ARCH_MV78XX0 || ARCH_MVEBU

View File

@ -13,7 +13,8 @@ obj-y += nommu.o
obj-$(CONFIG_ARM_MPU) += pmsa-v7.o
endif
obj-$(CONFIG_ARM_PTDUMP) += dump.o
obj-$(CONFIG_ARM_PTDUMP_CORE) += dump.o
obj-$(CONFIG_ARM_PTDUMP_DEBUGFS) += ptdump_debugfs.o
obj-$(CONFIG_MODULES) += proc-syms.o
obj-$(CONFIG_DEBUG_VIRTUAL) += physaddr.o
@ -103,6 +104,7 @@ AFLAGS_proc-v6.o :=-Wa,-march=armv6
AFLAGS_proc-v7.o :=-Wa,-march=armv7-a
obj-$(CONFIG_OUTER_CACHE) += l2c-common.o
obj-$(CONFIG_CACHE_B15_RAC) += cache-b15-rac.o
obj-$(CONFIG_CACHE_FEROCEON_L2) += cache-feroceon-l2.o
obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o l2c-l2x0-resume.o
obj-$(CONFIG_CACHE_L2X0_PMU) += cache-l2x0-pmu.o

356
arch/arm/mm/cache-b15-rac.c Normal file
View File

@ -0,0 +1,356 @@
/*
* Broadcom Brahma-B15 CPU read-ahead cache management functions
*
* Copyright (C) 2015-2016 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/of_address.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/syscore_ops.h>
#include <linux/reboot.h>
#include <asm/cacheflush.h>
#include <asm/hardware/cache-b15-rac.h>
extern void v7_flush_kern_cache_all(void);
/* RAC register offsets, relative to the HIF_CPU_BIUCTRL register base */
#define RAC_CONFIG0_REG (0x78)
#define RACENPREF_MASK (0x3)
#define RACPREFINST_SHIFT (0)
#define RACENINST_SHIFT (2)
#define RACPREFDATA_SHIFT (4)
#define RACENDATA_SHIFT (6)
#define RAC_CPU_SHIFT (8)
#define RACCFG_MASK (0xff)
#define RAC_CONFIG1_REG (0x7c)
#define RAC_FLUSH_REG (0x80)
#define FLUSH_RAC (1 << 0)
/* Bitmask to enable instruction and data prefetching with a 256-bytes stride */
#define RAC_DATA_INST_EN_MASK (1 << RACPREFINST_SHIFT | \
RACENPREF_MASK << RACENINST_SHIFT | \
1 << RACPREFDATA_SHIFT | \
RACENPREF_MASK << RACENDATA_SHIFT)
#define RAC_ENABLED 0
/* Special state where we want to bypass the spinlock and call directly
* into the v7 cache maintenance operations during suspend/resume
*/
#define RAC_SUSPENDED 1
static void __iomem *b15_rac_base;
static DEFINE_SPINLOCK(rac_lock);
static u32 rac_config0_reg;
/* Initialization flag to avoid checking for b15_rac_base, and to prevent
* multi-platform kernels from crashing here as well.
*/
static unsigned long b15_rac_flags;
static inline u32 __b15_rac_disable(void)
{
u32 val = __raw_readl(b15_rac_base + RAC_CONFIG0_REG);
__raw_writel(0, b15_rac_base + RAC_CONFIG0_REG);
dmb();
return val;
}
static inline void __b15_rac_flush(void)
{
u32 reg;
__raw_writel(FLUSH_RAC, b15_rac_base + RAC_FLUSH_REG);
do {
/* This dmb() is required to force the Bus Interface Unit
* to clean oustanding writes, and forces an idle cycle
* to be inserted.
*/
dmb();
reg = __raw_readl(b15_rac_base + RAC_FLUSH_REG);
} while (reg & FLUSH_RAC);
}
static inline u32 b15_rac_disable_and_flush(void)
{
u32 reg;
reg = __b15_rac_disable();
__b15_rac_flush();
return reg;
}
static inline void __b15_rac_enable(u32 val)
{
__raw_writel(val, b15_rac_base + RAC_CONFIG0_REG);
/* dsb() is required here to be consistent with __flush_icache_all() */
dsb();
}
#define BUILD_RAC_CACHE_OP(name, bar) \
void b15_flush_##name(void) \
{ \
unsigned int do_flush; \
u32 val = 0; \
\
if (test_bit(RAC_SUSPENDED, &b15_rac_flags)) { \
v7_flush_##name(); \
bar; \
return; \
} \
\
spin_lock(&rac_lock); \
do_flush = test_bit(RAC_ENABLED, &b15_rac_flags); \
if (do_flush) \
val = b15_rac_disable_and_flush(); \
v7_flush_##name(); \
if (!do_flush) \
bar; \
else \
__b15_rac_enable(val); \
spin_unlock(&rac_lock); \
}
#define nobarrier
/* The readahead cache present in the Brahma-B15 CPU is a special piece of
* hardware after the integrated L2 cache of the B15 CPU complex whose purpose
* is to prefetch instruction and/or data with a line size of either 64 bytes
* or 256 bytes. The rationale is that the data-bus of the CPU interface is
* optimized for 256-bytes transactions, and enabling the readahead cache
* provides a significant performance boost we want it enabled (typically
* twice the performance for a memcpy benchmark application).
*
* The readahead cache is transparent for Modified Virtual Addresses
* cache maintenance operations: ICIMVAU, DCIMVAC, DCCMVAC, DCCMVAU and
* DCCIMVAC.
*
* It is however not transparent for the following cache maintenance
* operations: DCISW, DCCSW, DCCISW, ICIALLUIS and ICIALLU which is precisely
* what we are patching here with our BUILD_RAC_CACHE_OP here.
*/
BUILD_RAC_CACHE_OP(kern_cache_all, nobarrier);
static void b15_rac_enable(void)
{
unsigned int cpu;
u32 enable = 0;
for_each_possible_cpu(cpu)
enable |= (RAC_DATA_INST_EN_MASK << (cpu * RAC_CPU_SHIFT));
b15_rac_disable_and_flush();
__b15_rac_enable(enable);
}
static int b15_rac_reboot_notifier(struct notifier_block *nb,
unsigned long action,
void *data)
{
/* During kexec, we are not yet migrated on the boot CPU, so we need to
* make sure we are SMP safe here. Once the RAC is disabled, flag it as
* suspended such that the hotplug notifier returns early.
*/
if (action == SYS_RESTART) {
spin_lock(&rac_lock);
b15_rac_disable_and_flush();
clear_bit(RAC_ENABLED, &b15_rac_flags);
set_bit(RAC_SUSPENDED, &b15_rac_flags);
spin_unlock(&rac_lock);
}
return NOTIFY_DONE;
}
static struct notifier_block b15_rac_reboot_nb = {
.notifier_call = b15_rac_reboot_notifier,
};
/* The CPU hotplug case is the most interesting one, we basically need to make
* sure that the RAC is disabled for the entire system prior to having a CPU
* die, in particular prior to this dying CPU having exited the coherency
* domain.
*
* Once this CPU is marked dead, we can safely re-enable the RAC for the
* remaining CPUs in the system which are still online.
*
* Offlining a CPU is the problematic case, onlining a CPU is not much of an
* issue since the CPU and its cache-level hierarchy will start filling with
* the RAC disabled, so L1 and L2 only.
*
* In this function, we should NOT have to verify any unsafe setting/condition
* b15_rac_base:
*
* It is protected by the RAC_ENABLED flag which is cleared by default, and
* being cleared when initial procedure is done. b15_rac_base had been set at
* that time.
*
* RAC_ENABLED:
* There is a small timing windows, in b15_rac_init(), between
* cpuhp_setup_state_*()
* ...
* set RAC_ENABLED
* However, there is no hotplug activity based on the Linux booting procedure.
*
* Since we have to disable RAC for all cores, we keep RAC on as long as as
* possible (disable it as late as possible) to gain the cache benefit.
*
* Thus, dying/dead states are chosen here
*
* We are choosing not do disable the RAC on a per-CPU basis, here, if we did
* we would want to consider disabling it as early as possible to benefit the
* other active CPUs.
*/
/* Running on the dying CPU */
static int b15_rac_dying_cpu(unsigned int cpu)
{
/* During kexec/reboot, the RAC is disabled via the reboot notifier
* return early here.
*/
if (test_bit(RAC_SUSPENDED, &b15_rac_flags))
return 0;
spin_lock(&rac_lock);
/* Indicate that we are starting a hotplug procedure */
__clear_bit(RAC_ENABLED, &b15_rac_flags);
/* Disable the readahead cache and save its value to a global */
rac_config0_reg = b15_rac_disable_and_flush();
spin_unlock(&rac_lock);
return 0;
}
/* Running on a non-dying CPU */
static int b15_rac_dead_cpu(unsigned int cpu)
{
/* During kexec/reboot, the RAC is disabled via the reboot notifier
* return early here.
*/
if (test_bit(RAC_SUSPENDED, &b15_rac_flags))
return 0;
spin_lock(&rac_lock);
/* And enable it */
__b15_rac_enable(rac_config0_reg);
__set_bit(RAC_ENABLED, &b15_rac_flags);
spin_unlock(&rac_lock);
return 0;
}
static int b15_rac_suspend(void)
{
/* Suspend the read-ahead cache oeprations, forcing our cache
* implementation to fallback to the regular ARMv7 calls.
*
* We are guaranteed to be running on the boot CPU at this point and
* with every other CPU quiesced, so setting RAC_SUSPENDED is not racy
* here.
*/
rac_config0_reg = b15_rac_disable_and_flush();
set_bit(RAC_SUSPENDED, &b15_rac_flags);
return 0;
}
static void b15_rac_resume(void)
{
/* Coming out of a S3 suspend/resume cycle, the read-ahead cache
* register RAC_CONFIG0_REG will be restored to its default value, make
* sure we re-enable it and set the enable flag, we are also guaranteed
* to run on the boot CPU, so not racy again.
*/
__b15_rac_enable(rac_config0_reg);
clear_bit(RAC_SUSPENDED, &b15_rac_flags);
}
static struct syscore_ops b15_rac_syscore_ops = {
.suspend = b15_rac_suspend,
.resume = b15_rac_resume,
};
static int __init b15_rac_init(void)
{
struct device_node *dn;
int ret = 0, cpu;
u32 reg, en_mask = 0;
dn = of_find_compatible_node(NULL, NULL, "brcm,brcmstb-cpu-biu-ctrl");
if (!dn)
return -ENODEV;
if (WARN(num_possible_cpus() > 4, "RAC only supports 4 CPUs\n"))
goto out;
b15_rac_base = of_iomap(dn, 0);
if (!b15_rac_base) {
pr_err("failed to remap BIU control base\n");
ret = -ENOMEM;
goto out;
}
ret = register_reboot_notifier(&b15_rac_reboot_nb);
if (ret) {
pr_err("failed to register reboot notifier\n");
iounmap(b15_rac_base);
goto out;
}
if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) {
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DEAD,
"arm/cache-b15-rac:dead",
NULL, b15_rac_dead_cpu);
if (ret)
goto out_unmap;
ret = cpuhp_setup_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING,
"arm/cache-b15-rac:dying",
NULL, b15_rac_dying_cpu);
if (ret)
goto out_cpu_dead;
}
if (IS_ENABLED(CONFIG_PM_SLEEP))
register_syscore_ops(&b15_rac_syscore_ops);
spin_lock(&rac_lock);
reg = __raw_readl(b15_rac_base + RAC_CONFIG0_REG);
for_each_possible_cpu(cpu)
en_mask |= ((1 << RACPREFDATA_SHIFT) << (cpu * RAC_CPU_SHIFT));
WARN(reg & en_mask, "Read-ahead cache not previously disabled\n");
b15_rac_enable();
set_bit(RAC_ENABLED, &b15_rac_flags);
spin_unlock(&rac_lock);
pr_info("Broadcom Brahma-B15 readahead cache at: 0x%p\n",
b15_rac_base + RAC_CONFIG0_REG);
goto out;
out_cpu_dead:
cpuhp_remove_state_nocalls(CPUHP_AP_ARM_CACHE_B15_RAC_DYING);
out_unmap:
unregister_reboot_notifier(&b15_rac_reboot_nb);
iounmap(b15_rac_base);
out:
of_node_put(dn);
return ret;
}
arch_initcall(b15_rac_init);

View File

@ -15,6 +15,7 @@
#include <asm/assembler.h>
#include <asm/errno.h>
#include <asm/unwind.h>
#include <asm/hardware/cache-b15-rac.h>
#include "proc-macros.S"
@ -446,3 +447,23 @@ ENDPROC(v7_dma_unmap_area)
@ define struct cpu_cache_fns (see <asm/cacheflush.h> and proc-macros.S)
define_cache_functions v7
/* The Broadcom Brahma-B15 read-ahead cache requires some modifications
* to the v7_cache_fns, we only override the ones we need
*/
#ifndef CONFIG_CACHE_B15_RAC
globl_equ b15_flush_kern_cache_all, v7_flush_kern_cache_all
#endif
globl_equ b15_flush_icache_all, v7_flush_icache_all
globl_equ b15_flush_kern_cache_louis, v7_flush_kern_cache_louis
globl_equ b15_flush_user_cache_all, v7_flush_user_cache_all
globl_equ b15_flush_user_cache_range, v7_flush_user_cache_range
globl_equ b15_coherent_kern_range, v7_coherent_kern_range
globl_equ b15_coherent_user_range, v7_coherent_user_range
globl_equ b15_flush_kern_dcache_area, v7_flush_kern_dcache_area
globl_equ b15_dma_map_area, v7_dma_map_area
globl_equ b15_dma_unmap_area, v7_dma_unmap_area
globl_equ b15_dma_flush_range, v7_dma_flush_range
define_cache_functions b15

View File

@ -21,11 +21,7 @@
#include <asm/fixmap.h>
#include <asm/memory.h>
#include <asm/pgtable.h>
struct addr_marker {
unsigned long start_address;
const char *name;
};
#include <asm/ptdump.h>
static struct addr_marker address_markers[] = {
{ MODULES_VADDR, "Modules" },
@ -38,12 +34,26 @@ static struct addr_marker address_markers[] = {
{ -1, NULL },
};
#define pt_dump_seq_printf(m, fmt, args...) \
({ \
if (m) \
seq_printf(m, fmt, ##args); \
})
#define pt_dump_seq_puts(m, fmt) \
({ \
if (m) \
seq_printf(m, fmt); \
})
struct pg_state {
struct seq_file *seq;
const struct addr_marker *marker;
unsigned long start_address;
unsigned level;
u64 current_prot;
bool check_wx;
unsigned long wx_pages;
const char *current_domain;
};
@ -52,6 +62,8 @@ struct prot_bits {
u64 val;
const char *set;
const char *clear;
bool ro_bit;
bool nx_bit;
};
static const struct prot_bits pte_bits[] = {
@ -65,11 +77,13 @@ static const struct prot_bits pte_bits[] = {
.val = L_PTE_RDONLY,
.set = "ro",
.clear = "RW",
.ro_bit = true,
}, {
.mask = L_PTE_XN,
.val = L_PTE_XN,
.set = "NX",
.clear = "x ",
.nx_bit = true,
}, {
.mask = L_PTE_SHARED,
.val = L_PTE_SHARED,
@ -133,11 +147,13 @@ static const struct prot_bits section_bits[] = {
.val = L_PMD_SECT_RDONLY | PMD_SECT_AP2,
.set = "ro",
.clear = "RW",
.ro_bit = true,
#elif __LINUX_ARM_ARCH__ >= 6
{
.mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
.val = PMD_SECT_APX | PMD_SECT_AP_WRITE,
.set = " ro",
.ro_bit = true,
}, {
.mask = PMD_SECT_APX | PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
.val = PMD_SECT_AP_WRITE,
@ -156,6 +172,7 @@ static const struct prot_bits section_bits[] = {
.mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
.val = 0,
.set = " ro",
.ro_bit = true,
}, {
.mask = PMD_SECT_AP_READ | PMD_SECT_AP_WRITE,
.val = PMD_SECT_AP_WRITE,
@ -174,6 +191,7 @@ static const struct prot_bits section_bits[] = {
.val = PMD_SECT_XN,
.set = "NX",
.clear = "x ",
.nx_bit = true,
}, {
.mask = PMD_SECT_S,
.val = PMD_SECT_S,
@ -186,6 +204,8 @@ struct pg_level {
const struct prot_bits *bits;
size_t num;
u64 mask;
const struct prot_bits *ro_bit;
const struct prot_bits *nx_bit;
};
static struct pg_level pg_level[] = {
@ -214,10 +234,27 @@ static void dump_prot(struct pg_state *st, const struct prot_bits *bits, size_t
s = bits->clear;
if (s)
seq_printf(st->seq, " %s", s);
pt_dump_seq_printf(st->seq, " %s", s);
}
}
static void note_prot_wx(struct pg_state *st, unsigned long addr)
{
if (!st->check_wx)
return;
if ((st->current_prot & pg_level[st->level].ro_bit->mask) ==
pg_level[st->level].ro_bit->val)
return;
if ((st->current_prot & pg_level[st->level].nx_bit->mask) ==
pg_level[st->level].nx_bit->val)
return;
WARN_ONCE(1, "arm/mm: Found insecure W+X mapping at address %pS\n",
(void *)st->start_address);
st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
}
static void note_page(struct pg_state *st, unsigned long addr,
unsigned int level, u64 val, const char *domain)
{
@ -228,7 +265,7 @@ static void note_page(struct pg_state *st, unsigned long addr,
st->level = level;
st->current_prot = prot;
st->current_domain = domain;
seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
pt_dump_seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
} else if (prot != st->current_prot || level != st->level ||
domain != st->current_domain ||
addr >= st->marker[1].start_address) {
@ -236,7 +273,8 @@ static void note_page(struct pg_state *st, unsigned long addr,
unsigned long delta;
if (st->current_prot) {
seq_printf(st->seq, "0x%08lx-0x%08lx ",
note_prot_wx(st, addr);
pt_dump_seq_printf(st->seq, "0x%08lx-0x%08lx ",
st->start_address, addr);
delta = (addr - st->start_address) >> 10;
@ -244,17 +282,19 @@ static void note_page(struct pg_state *st, unsigned long addr,
delta >>= 10;
unit++;
}
seq_printf(st->seq, "%9lu%c", delta, *unit);
pt_dump_seq_printf(st->seq, "%9lu%c", delta, *unit);
if (st->current_domain)
seq_printf(st->seq, " %s", st->current_domain);
pt_dump_seq_printf(st->seq, " %s",
st->current_domain);
if (pg_level[st->level].bits)
dump_prot(st, pg_level[st->level].bits, pg_level[st->level].num);
seq_printf(st->seq, "\n");
pt_dump_seq_printf(st->seq, "\n");
}
if (addr >= st->marker[1].start_address) {
st->marker++;
seq_printf(st->seq, "---[ %s ]---\n", st->marker->name);
pt_dump_seq_printf(st->seq, "---[ %s ]---\n",
st->marker->name);
}
st->start_address = addr;
st->current_prot = prot;
@ -335,61 +375,82 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start)
}
}
static void walk_pgd(struct seq_file *m)
static void walk_pgd(struct pg_state *st, struct mm_struct *mm,
unsigned long start)
{
pgd_t *pgd = swapper_pg_dir;
struct pg_state st;
unsigned long addr;
pgd_t *pgd = pgd_offset(mm, 0UL);
unsigned i;
memset(&st, 0, sizeof(st));
st.seq = m;
st.marker = address_markers;
unsigned long addr;
for (i = 0; i < PTRS_PER_PGD; i++, pgd++) {
addr = i * PGDIR_SIZE;
addr = start + i * PGDIR_SIZE;
if (!pgd_none(*pgd)) {
walk_pud(&st, pgd, addr);
walk_pud(st, pgd, addr);
} else {
note_page(&st, addr, 1, pgd_val(*pgd), NULL);
note_page(st, addr, 1, pgd_val(*pgd), NULL);
}
}
}
void ptdump_walk_pgd(struct seq_file *m, struct ptdump_info *info)
{
struct pg_state st = {
.seq = m,
.marker = info->markers,
.check_wx = false,
};
walk_pgd(&st, info->mm, info->base_addr);
note_page(&st, 0, 0, 0, NULL);
}
static int ptdump_show(struct seq_file *m, void *v)
static void ptdump_initialize(void)
{
walk_pgd(m);
return 0;
}
static int ptdump_open(struct inode *inode, struct file *file)
{
return single_open(file, ptdump_show, NULL);
}
static const struct file_operations ptdump_fops = {
.open = ptdump_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
static int ptdump_init(void)
{
struct dentry *pe;
unsigned i, j;
for (i = 0; i < ARRAY_SIZE(pg_level); i++)
if (pg_level[i].bits)
for (j = 0; j < pg_level[i].num; j++)
for (j = 0; j < pg_level[i].num; j++) {
pg_level[i].mask |= pg_level[i].bits[j].mask;
if (pg_level[i].bits[j].ro_bit)
pg_level[i].ro_bit = &pg_level[i].bits[j];
if (pg_level[i].bits[j].nx_bit)
pg_level[i].nx_bit = &pg_level[i].bits[j];
}
address_markers[2].start_address = VMALLOC_START;
}
pe = debugfs_create_file("kernel_page_tables", 0400, NULL, NULL,
&ptdump_fops);
return pe ? 0 : -ENOMEM;
static struct ptdump_info kernel_ptdump_info = {
.mm = &init_mm,
.markers = address_markers,
.base_addr = 0,
};
void ptdump_check_wx(void)
{
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_marker[]) {
{ 0, NULL},
{ -1, NULL},
},
.check_wx = true,
};
walk_pgd(&st, &init_mm, 0);
note_page(&st, 0, 0, 0, NULL);
if (st.wx_pages)
pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found\n",
st.wx_pages);
else
pr_info("Checked W+X mappings: passed, no W+X pages found\n");
}
static int ptdump_init(void)
{
ptdump_initialize();
return ptdump_debugfs_register(&kernel_ptdump_info,
"kernel_page_tables");
}
__initcall(ptdump_init);

View File

@ -21,7 +21,6 @@
#include <linux/highmem.h>
#include <linux/perf_event.h>
#include <asm/exception.h>
#include <asm/pgtable.h>
#include <asm/system_misc.h>
#include <asm/system_info.h>
@ -545,7 +544,7 @@ hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *)
/*
* Dispatch a data abort to the relevant handler.
*/
asmlinkage void __exception
asmlinkage void
do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
const struct fsr_info *inf = fsr_info + fsr_fs(fsr);
@ -578,7 +577,7 @@ hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *
ifsr_info[nr].name = name;
}
asmlinkage void __exception
asmlinkage void
do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
{
const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);

View File

@ -16,8 +16,8 @@
* are not supported on any CPU using the idmap tables as its current
* page tables.
*/
pgd_t *idmap_pgd;
long long arch_phys_to_idmap_offset;
pgd_t *idmap_pgd __ro_after_init;
long long arch_phys_to_idmap_offset __ro_after_init;
#ifdef CONFIG_ARM_LPAE
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,

View File

@ -36,6 +36,7 @@
#include <asm/system_info.h>
#include <asm/tlb.h>
#include <asm/fixmap.h>
#include <asm/ptdump.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@ -738,6 +739,7 @@ static int __mark_rodata_ro(void *unused)
void mark_rodata_ro(void)
{
stop_machine(__mark_rodata_ro, NULL, NULL);
debug_checkwx();
}
void set_kernel_text_rw(void)

View File

@ -31,7 +31,7 @@ struct mpu_rgn_info mpu_rgn_info;
#ifdef CONFIG_CPU_CP15
#ifdef CONFIG_CPU_HIGH_VECTOR
static unsigned long __init setup_vectors_base(void)
unsigned long setup_vectors_base(void)
{
unsigned long reg = get_cr();
@ -57,7 +57,7 @@ static inline bool security_extensions_enabled(void)
return 0;
}
static unsigned long __init setup_vectors_base(void)
unsigned long setup_vectors_base(void)
{
unsigned long base = 0, reg = get_cr();

View File

@ -6,6 +6,7 @@
#include <linux/bitops.h>
#include <linux/memblock.h>
#include <linux/string.h>
#include <asm/cacheflush.h>
#include <asm/cp15.h>
@ -296,6 +297,7 @@ void __init adjust_lowmem_bounds_mpu(void)
}
}
memset(mem, 0, sizeof(mem));
num = allocate_region(mem_start, specified_mem_size, mem_max_regions, mem);
for (i = 0; i < num; i++) {
@ -433,7 +435,7 @@ void __init mpu_setup(void)
/* Background */
err |= mpu_setup_region(region++, 0, 32,
MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0NA,
MPU_ACR_XN | MPU_RGN_STRONGLY_ORDERED | MPU_AP_PL1RW_PL0RW,
0, false);
#ifdef CONFIG_XIP_KERNEL

View File

@ -567,7 +567,7 @@ __v7_setup_stack:
/*
* Standard v7 proc info content
*/
.macro __v7_proc name, initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions
.macro __v7_proc name, initfunc, mm_mmuflags = 0, io_mmuflags = 0, hwcaps = 0, proc_fns = v7_processor_functions, cache_fns = v7_cache_fns
ALT_SMP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
PMD_SECT_AF | PMD_FLAGS_SMP | \mm_mmuflags)
ALT_UP(.long PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | \
@ -583,7 +583,7 @@ __v7_setup_stack:
.long \proc_fns
.long v7wbi_tlb_fns
.long v6_user_fns
.long v7_cache_fns
.long \cache_fns
.endm
#ifndef CONFIG_ARM_LPAE
@ -678,7 +678,7 @@ __v7_ca15mp_proc_info:
__v7_b15mp_proc_info:
.long 0x420f00f0
.long 0xff0ffff0
__v7_proc __v7_b15mp_proc_info, __v7_b15mp_setup
__v7_proc __v7_b15mp_proc_info, __v7_b15mp_setup, cache_fns = b15_cache_fns
.size __v7_b15mp_proc_info, . - __v7_b15mp_proc_info
/*

View File

@ -0,0 +1,34 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <asm/ptdump.h>
static int ptdump_show(struct seq_file *m, void *v)
{
struct ptdump_info *info = m->private;
ptdump_walk_pgd(m, info);
return 0;
}
static int ptdump_open(struct inode *inode, struct file *file)
{
return single_open(file, ptdump_show, inode->i_private);
}
static const struct file_operations ptdump_fops = {
.open = ptdump_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
int ptdump_debugfs_register(struct ptdump_info *info, const char *name)
{
struct dentry *pe;
pe = debugfs_create_file(name, 0400, NULL, info, &ptdump_fops);
return pe ? 0 : -ENOMEM;
}

View File

@ -32,6 +32,7 @@
#include <linux/percpu.h>
#include <linux/bug.h>
#include <asm/patch.h>
#include <asm/sections.h>
#include "../decode-arm.h"
#include "../decode-thumb.h"
@ -64,9 +65,6 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
int is;
const struct decode_checker **checkers;
if (in_exception_text(addr))
return -EINVAL;
#ifdef CONFIG_THUMB2_KERNEL
thumb = true;
addr &= ~1; /* Bit 0 would normally be set to indicate Thumb code */
@ -680,3 +678,13 @@ int __init arch_init_kprobes()
#endif
return 0;
}
bool arch_within_kprobe_blacklist(unsigned long addr)
{
void *a = (void *)addr;
return __in_irqentry_text(addr) ||
in_entry_text(addr) ||
in_idmap_text(addr) ||
memory_contains(__kprobes_text_start, __kprobes_text_end, a, 1);
}

View File

@ -91,6 +91,7 @@ config ARM64
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_THREAD_STRUCT_WHITELIST
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_TRANSPARENT_HUGEPAGE
select HAVE_ARCH_VMAP_STACK

View File

@ -113,6 +113,16 @@ struct thread_struct {
struct debug_info debug; /* debugging */
};
/*
* Everything usercopied to/from thread_struct is statically-sized, so
* no hardened usercopy whitelist is needed.
*/
static inline void arch_thread_struct_whitelist(unsigned long *offset,
unsigned long *size)
{
*offset = *size = 0;
}
#ifdef CONFIG_COMPAT
#define task_user_tls(t) \
({ \

View File

@ -8,6 +8,7 @@ menu "Platform options"
config OPT_LIB_FUNCTION
bool "Optimalized lib function"
depends on CPU_LITTLE_ENDIAN
default y
help
Allows turn on optimalized library function (memcpy and memmove).

View File

@ -36,16 +36,21 @@ endif
CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_DIV) += -mno-xl-soft-div
CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_BARREL) += -mxl-barrel-shift
CPUFLAGS-$(CONFIG_XILINX_MICROBLAZE0_USE_PCMP_INSTR) += -mxl-pattern-compare
CPUFLAGS-$(CONFIG_BIG_ENDIAN) += -mbig-endian
CPUFLAGS-$(CONFIG_LITTLE_ENDIAN) += -mlittle-endian
ifdef CONFIG_CPU_BIG_ENDIAN
KBUILD_CFLAGS += -mbig-endian
KBUILD_AFLAGS += -mbig-endian
LD += -EB
else
KBUILD_CFLAGS += -mlittle-endian
KBUILD_AFLAGS += -mlittle-endian
LD += -EL
endif
CPUFLAGS-1 += $(call cc-option,-mcpu=v$(CPU_VER))
# r31 holds current when in kernel mode
KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-1) $(CPUFLAGS-2)
LDFLAGS :=
LDFLAGS_vmlinux :=
KBUILD_CFLAGS += -ffixed-r31 $(CPUFLAGS-y) $(CPUFLAGS-1) $(CPUFLAGS-2)
head-y := arch/microblaze/kernel/head.o
libs-y += arch/microblaze/lib/

View File

@ -36,7 +36,7 @@ extern resource_size_t isa_mem_base;
#ifdef CONFIG_MMU
#define page_to_bus(page) (page_to_phys(page))
extern void iounmap(void __iomem *addr);
extern void iounmap(volatile void __iomem *addr);
extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
#define ioremap_nocache(addr, size) ioremap((addr), (size))

View File

@ -127,7 +127,7 @@ void __iomem *ioremap(phys_addr_t addr, unsigned long size)
}
EXPORT_SYMBOL(ioremap);
void iounmap(void __iomem *addr)
void iounmap(volatile void __iomem *addr)
{
if ((__force void *)addr > high_memory &&
(unsigned long) addr < ioremap_bot)

View File

@ -143,6 +143,7 @@ config PPC
select ARCH_HAS_PMEM_API if PPC64
select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE
select ARCH_HAS_SG_CHAIN
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UACCESS_FLUSHCACHE if PPC64
select ARCH_HAS_UBSAN_SANITIZE_ALL
@ -150,6 +151,7 @@ config PPC
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_USE_BUILTIN_BSWAP
select ARCH_USE_CMPXCHG_LOCKREF if PPC64
@ -180,8 +182,6 @@ config PPC
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_SECCOMP_FILTER
select HAVE_ARCH_TRACEHOOK
select ARCH_HAS_STRICT_KERNEL_RWX if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
select ARCH_OPTIONAL_KERNEL_RWX if ARCH_HAS_STRICT_KERNEL_RWX
select HAVE_CBPF_JIT if !PPC64
select HAVE_CONTEXT_TRACKING if PPC64
select HAVE_DEBUG_KMEMLEAK
@ -868,6 +868,21 @@ config SECCOMP
If unsure, say Y. Only embedded should say N here.
config PPC_MEM_KEYS
prompt "PowerPC Memory Protection Keys"
def_bool y
depends on PPC_BOOK3S_64
select ARCH_USES_HIGH_VMA_FLAGS
select ARCH_HAS_PKEYS
help
Memory Protection Keys provides a mechanism for enforcing
page-based protections, but without requiring modification of the
page tables when an application changes protection domains.
For details, see Documentation/vm/protection-keys.txt
If unsure, say y.
endmenu
config ISA_DMA_API

View File

@ -90,6 +90,10 @@ config MSI_BITMAP_SELFTEST
depends on DEBUG_KERNEL
default n
config PPC_IRQ_SOFT_MASK_DEBUG
bool "Include extra checks for powerpc irq soft masking"
default n
config XMON
bool "Include xmon kernel debugger"
depends on DEBUG_KERNEL
@ -368,7 +372,7 @@ config PPC_PTDUMP
config PPC_HTDUMP
def_bool y
depends on PPC_PTDUMP && PPC_BOOK3S
depends on PPC_PTDUMP && PPC_BOOK3S_64
config PPC_FAST_ENDIAN_SWITCH
bool "Deprecated fast endian-switch syscall"

View File

@ -63,6 +63,7 @@ UTS_MACHINE := $(subst $(space),,$(machine-y))
ifdef CONFIG_PPC32
KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
else
KBUILD_LDFLAGS_MODULE += -T $(srctree)/arch/powerpc/kernel/module.lds
ifeq ($(call ld-ifversion, -ge, 225000000, y),y)
# Have the linker provide sfpr if possible.
# There is a corresponding test in arch/powerpc/lib/Makefile

View File

@ -108,10 +108,10 @@ src-wlib-y := string.S crt0.S stdio.c decompress.c main.c \
$(libfdt) libfdt-wrapper.c \
ns16550.c serial.c simple_alloc.c div64.S util.S \
elf_util.c $(zlib-y) devtree.c stdlib.c \
oflib.c ofconsole.c cuboot.c cpm-serial.c \
uartlite.c opal.c
oflib.c ofconsole.c cuboot.c
src-wlib-$(CONFIG_PPC_MPC52XX) += mpc52xx-psc.c
src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S
src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) += opal-calls.S opal.c
ifndef CONFIG_PPC64_BOOT_WRAPPER
src-wlib-y += crtsavres.S
endif
@ -120,6 +120,8 @@ src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
src-wlib-$(CONFIG_PPC_8xx) += mpc8xx.c planetcore.c fsl-soc.c
src-wlib-$(CONFIG_PPC_82xx) += pq2.c fsl-soc.c planetcore.c
src-wlib-$(CONFIG_EMBEDDED6xx) += mpsc.c mv64x60.c mv64x60_i2c.c ugecon.c fsl-soc.c
src-wlib-$(CONFIG_XILINX_VIRTEX) += uartlite.c
src-wlib-$(CONFIG_CPM) += cpm-serial.c
src-plat-y := of.c epapr.c
src-plat-$(CONFIG_40x) += fixed-head.S ep405.c cuboot-hotfoot.c \

View File

@ -105,24 +105,24 @@
reg = <0 0x0 0x02000000>;
compatible = "cfi-flash";
bank-width = <2>;
partition@0x0 {
partition@0 {
label = "u-boot";
reg = <0x00000000 0x00040000>;
read-only;
};
partition@0x00040000 {
partition@40000 {
label = "env";
reg = <0x00040000 0x00020000>;
};
partition@0x00060000 {
partition@60000 {
label = "dtb";
reg = <0x00060000 0x00020000>;
};
partition@0x00080000 {
partition@80000 {
label = "kernel";
reg = <0x00080000 0x00500000>;
};
partition@0x00580000 {
partition@580000 {
label = "root";
reg = <0x00580000 0x00A80000>;
};

View File

@ -216,7 +216,7 @@
interrupts = <39 2>;
};
IIC0: i2c@00000000 {
IIC0: i2c@0 {
compatible = "ibm,iic-476gtr", "ibm,iic";
reg = <0x0 0x00000020>;
interrupt-parent = <&MPIC>;
@ -229,7 +229,7 @@
};
};
IIC1: i2c@00000100 {
IIC1: i2c@100 {
compatible = "ibm,iic-476gtr", "ibm,iic";
reg = <0x100 0x00000020>;
interrupt-parent = <&MPIC>;

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