Merge branch 'linus' into x86/microcode, to pick up merge window changes

Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
Ingo Molnar 2016-07-27 12:35:35 +02:00
commit df15929f8f
1910 changed files with 70739 additions and 29394 deletions

View File

@ -11,6 +11,7 @@ Aaron Durbin <adurbin@google.com>
Adam Oldham <oldhamca@gmail.com>
Adam Radford <aradford@gmail.com>
Adrian Bunk <bunk@stusta.de>
Adriana Reus <adi.reus@gmail.com> <adriana.reus@intel.com>
Alan Cox <alan@lxorguk.ukuu.org.uk>
Alan Cox <root@hraefn.swansea.linux.org.uk>
Aleksey Gorelov <aleksey_gorelov@phoenix.com>
@ -94,6 +95,8 @@ Linas Vepstas <linas@austin.ibm.com>
Mark Brown <broonie@sirena.org.uk>
Matthieu CASTET <castet.matthieu@free.fr>
Mauro Carvalho Chehab <mchehab@kernel.org> <maurochehab@gmail.com> <mchehab@infradead.org> <mchehab@redhat.com> <m.chehab@samsung.com> <mchehab@osg.samsung.com> <mchehab@s-opensource.com>
Matt Ranostay <mranostay@gmail.com> Matthew Ranostay <mranostay@embeddedalley.com>
Matt Ranostay <mranostay@gmail.com> <matt.ranostay@intel.com>
Mayuresh Janorkar <mayur@ti.com>
Michael Buesch <m@bues.ch>
Michel Dänzer <michel@tungstengraphics.com>

View File

@ -19,3 +19,16 @@ KernelVersion: 4.4
Description:
High resolution timers directory. Creating a directory here
will result in creating a hrtimer trigger in the IIO subsystem.
What: /config/iio/devices
Date: April 2016
KernelVersion: 4.7
Description:
Industrial IO software devices directory.
What: /config/iio/devices/dummy
Date: April 2016
KernelVersion: 4.7
Description:
Dummy IIO devices directory. Creating a directory here will result
in creating a dummy IIO device in the IIO subystem.

View File

@ -32,6 +32,13 @@ Description:
Description of the physical chip / device for device X.
Typically a part number.
What: /sys/bus/iio/devices/iio:deviceX/timestamp_clock
KernelVersion: 4.5
Contact: linux-iio@vger.kernel.org
Description:
String identifying current posix clock used to timestamp
buffered samples and events for device X.
What: /sys/bus/iio/devices/iio:deviceX/sampling_frequency
What: /sys/bus/iio/devices/iio:deviceX/buffer/sampling_frequency
What: /sys/bus/iio/devices/triggerX/sampling_frequency
@ -1565,3 +1572,10 @@ Description:
* X is in the plane of the propellers, perpendicular to Y axis,
and positive towards the starboard side of the UAV ;
* Z is perpendicular to propellers plane and positive upwards.
What: /sys/bus/iio/devices/iio:deviceX/in_electricalconductivity_raw
KernelVersion: 4.8
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled no offset etc.) electric conductivity reading that
can be processed to siemens per meter.

View File

@ -1,54 +1,41 @@
What: /sys/bus/iio/devices/iio:deviceX/tia_resistanceY
/sys/bus/iio/devices/iio:deviceX/tia_capacitanceY
Date: December 2015
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get and set the resistance and the capacitance settings for the
Transimpedance Amplifier. Y is 1 for Rf1 and Cf1, Y is 2 for
Rf2 and Cf2 values.
What: /sys/bus/iio/devices/iio:deviceX/tia_separate_en
Date: December 2015
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Enable or disable separate settings for the TransImpedance
Amplifier above, when disabled both values are set by the
first channel.
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_raw
/sys/bus/iio/devices/iio:deviceX/in_intensity_ledY_ambient_raw
Date: December 2015
What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_raw
Date: May 2016
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get measured values from the ADC for these stages. Y is the
specific LED number. The values are expressed in 24-bit twos
complement.
specific stage number corresponding to datasheet stage names
as follows:
1 -> LED2
2 -> ALED2/LED3
3 -> LED1
4 -> ALED1/LED4
Note that channels 5 and 6 represent LED2-ALED2 and LED1-ALED1
respectively which simply helper channels containing the
calculated difference in the value of stage 1 - 2 and 3 - 4.
The values are expressed in 24-bit twos complement.
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_ledY-ledY_ambient_raw
Date: December 2015
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get differential values from the ADC for these stages. Y is the
specific LED number. The values are expressed in 24-bit twos
complement for the specified LEDs.
What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_offset
/sys/bus/iio/devices/iio:deviceX/out_current_ledY_ambient_offset
Date: December 2015
What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_offset
Date: May 2016
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get and set the offset cancellation DAC setting for these
stages. The values are expressed in 5-bit sign-magnitude.
What: /sys/bus/iio/devices/iio:deviceX/out_current_ledY_raw
Date: December 2015
What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_resistance
What: /sys/bus/iio/devices/iio:deviceX/in_intensityY_capacitance
Date: May 2016
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get and set the LED current for the specified LED. Y is the
specific LED number.
Get and set the resistance and the capacitance settings for the
Transimpedance Amplifier during the associated stage.
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw
Date: May 2016
KernelVersion:
Contact: Andrew F. Davis <afd@ti.com>
Description:
Get and set the LED current for the specified LED active during
this stage. Y is the specific stage number.

View File

@ -594,7 +594,7 @@
irqreturn_t sensor_iio_pollfunc(int irq, void *p)
{
pf->timestamp = iio_get_time_ns();
pf->timestamp = iio_get_time_ns((struct indio_dev *)p);
return IRQ_WAKE_THREAD;
}

View File

@ -2391,6 +2391,41 @@ and <tt>RCU_NONIDLE()</tt> on the other while inspecting
idle-loop code.
Steven Rostedt supplied <tt>_rcuidle</tt> event tracing,
which is used quite heavily in the idle loop.
However, there are some restrictions on the code placed within
<tt>RCU_NONIDLE()</tt>:
<ol>
<li> Blocking is prohibited.
In practice, this is not a serious restriction given that idle
tasks are prohibited from blocking to begin with.
<li> Although nesting <tt>RCU_NONIDLE()</tt> is permited, they cannot
nest indefinitely deeply.
However, given that they can be nested on the order of a million
deep, even on 32-bit systems, this should not be a serious
restriction.
This nesting limit would probably be reached long after the
compiler OOMed or the stack overflowed.
<li> Any code path that enters <tt>RCU_NONIDLE()</tt> must sequence
out of that same <tt>RCU_NONIDLE()</tt>.
For example, the following is grossly illegal:
<blockquote>
<pre>
1 RCU_NONIDLE({
2 do_something();
3 goto bad_idea; /* BUG!!! */
4 do_something_else();});
5 bad_idea:
</pre>
</blockquote>
<p>
It is just as illegal to transfer control into the middle of
<tt>RCU_NONIDLE()</tt>'s argument.
Yes, in theory, you could transfer in as long as you also
transferred out, but in practice you could also expect to get sharply
worded review comments.
</ol>
<p>
It is similarly socially unacceptable to interrupt an

View File

@ -49,7 +49,7 @@ rcupdate.rcu_task_stall_timeout
This boot/sysfs parameter controls the RCU-tasks stall warning
interval. A value of zero or less suppresses RCU-tasks stall
warnings. A positive value sets the stall-warning interval
in jiffies. An RCU-tasks stall warning starts wtih the line:
in jiffies. An RCU-tasks stall warning starts with the line:
INFO: rcu_tasks detected stalls on tasks:

View File

@ -5,6 +5,9 @@ to start learning about RCU:
2. What is RCU? Part 2: Usage http://lwn.net/Articles/263130/
3. RCU part 3: the RCU API http://lwn.net/Articles/264090/
4. The RCU API, 2010 Edition http://lwn.net/Articles/418853/
2010 Big API Table http://lwn.net/Articles/419086/
5. The RCU API, 2014 Edition http://lwn.net/Articles/609904/
2014 Big API Table http://lwn.net/Articles/609973/
What is RCU?

View File

@ -46,7 +46,8 @@ Optional properties:
The second cell represents the MICBIAS to be used.
The third cell represents the value of the micd-pol-gpio pin.
- wlf,gpsw : Settings for the general purpose switch
- wlf,gpsw : Settings for the general purpose switch, set as one of the
ARIZONA_GPSW_XXX defines.
Example:

View File

@ -0,0 +1,14 @@
APM X-Gene hwmon driver
APM X-Gene SOC sensors are accessed over the "SLIMpro" mailbox.
Required properties :
- compatible : should be "apm,xgene-slimpro-hwmon"
- mboxes : use the label reference for the mailbox as the first parameter.
The second parameter is the channel number.
Example :
hwmonslimpro {
compatible = "apm,xgene-slimpro-hwmon";
mboxes = <&mailbox 7>;
};

View File

@ -0,0 +1,42 @@
Properties for Jedec JC-42.4 compatible temperature sensors
Required properties:
- compatible: May include a device-specific string consisting of the
manufacturer and the name of the chip. A list of supported
chip names follows.
Must include "jedec,jc-42.4-temp" for any Jedec JC-42.4
compatible temperature sensor.
Supported chip names:
adi,adt7408
atmel,at30ts00
atmel,at30tse004
onnn,cat6095
onnn,cat34ts02
maxim,max6604
microchip,mcp9804
microchip,mcp9805
microchip,mcp9808
microchip,mcp98243
microchip,mcp98244
microchip,mcp9843
nxp,se97
nxp,se98
st,stts2002
st,stts2004
st,stts3000
st,stts424
st,stts424e
idt,tse2002
idt,tse2004
idt,ts3000
idt,ts3001
- reg: I2C address
Example:
temp-sensor@1a {
compatible = "jedec,jc-42.4-temp";
reg = <0x1a>;
};

View File

@ -56,6 +56,70 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
mc,rv3029c2 Real Time Clock Module with I2C-Bus
microchip,mcp4531-502 Microchip 7-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4531-103 Microchip 7-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4531-503 Microchip 7-bit Single I2C Digital Potentiometer (50k)
microchip,mcp4531-104 Microchip 7-bit Single I2C Digital Potentiometer (100k)
microchip,mcp4532-502 Microchip 7-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4532-103 Microchip 7-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4532-503 Microchip 7-bit Single I2C Digital Potentiometer (50k)
microchip,mcp4532-104 Microchip 7-bit Single I2C Digital Potentiometer (100k)
microchip,mcp4541-502 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4541-103 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4541-503 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4541-104 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4542-502 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4542-103 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4542-503 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4542-104 Microchip 7-bit Single I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4551-502 Microchip 8-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4551-103 Microchip 8-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4551-503 Microchip 8-bit Single I2C Digital Potentiometer (50k)
microchip,mcp4551-104 Microchip 8-bit Single I2C Digital Potentiometer (100k)
microchip,mcp4552-502 Microchip 8-bit Single I2C Digital Potentiometer (5k)
microchip,mcp4552-103 Microchip 8-bit Single I2C Digital Potentiometer (10k)
microchip,mcp4552-503 Microchip 8-bit Single I2C Digital Potentiometer (50k)
microchip,mcp4552-104 Microchip 8-bit Single I2C Digital Potentiometer (100k)
microchip,mcp4561-502 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4561-103 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4561-503 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4561-104 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4562-502 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4562-103 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4562-503 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4562-104 Microchip 8-bit Single I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4631-502 Microchip 7-bit Dual I2C Digital Potentiometer (5k)
microchip,mcp4631-103 Microchip 7-bit Dual I2C Digital Potentiometer (10k)
microchip,mcp4631-503 Microchip 7-bit Dual I2C Digital Potentiometer (50k)
microchip,mcp4631-104 Microchip 7-bit Dual I2C Digital Potentiometer (100k)
microchip,mcp4632-502 Microchip 7-bit Dual I2C Digital Potentiometer (5k)
microchip,mcp4632-103 Microchip 7-bit Dual I2C Digital Potentiometer (10k)
microchip,mcp4632-503 Microchip 7-bit Dual I2C Digital Potentiometer (50k)
microchip,mcp4632-104 Microchip 7-bit Dual I2C Digital Potentiometer (100k)
microchip,mcp4641-502 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4641-103 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4641-503 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4641-104 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4642-502 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4642-103 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4642-503 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4642-104 Microchip 7-bit Dual I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4651-502 Microchip 8-bit Dual I2C Digital Potentiometer (5k)
microchip,mcp4651-103 Microchip 8-bit Dual I2C Digital Potentiometer (10k)
microchip,mcp4651-503 Microchip 8-bit Dual I2C Digital Potentiometer (50k)
microchip,mcp4651-104 Microchip 8-bit Dual I2C Digital Potentiometer (100k)
microchip,mcp4652-502 Microchip 8-bit Dual I2C Digital Potentiometer (5k)
microchip,mcp4652-103 Microchip 8-bit Dual I2C Digital Potentiometer (10k)
microchip,mcp4652-503 Microchip 8-bit Dual I2C Digital Potentiometer (50k)
microchip,mcp4652-104 Microchip 8-bit Dual I2C Digital Potentiometer (100k)
microchip,mcp4661-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4661-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4661-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4661-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
microchip,mcp4662-502 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (5k)
microchip,mcp4662-103 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (10k)
microchip,mcp4662-503 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (50k)
microchip,mcp4662-104 Microchip 8-bit Dual I2C Digital Potentiometer with NV Memory (100k)
national,lm63 Temperature sensor with integrated fan control
national,lm75 I2C TEMP SENSOR
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor

View File

@ -0,0 +1,41 @@
* Broadcom's IPROC Static ADC controller
Broadcom iProc ADC controller has 8 channels 10bit ADC.
Allows user to convert analog input voltage values to digital.
Required properties:
- compatible: Must be "brcm,iproc-static-adc"
- adc-syscon: Handler of syscon node defining physical base address of the
controller and length of memory mapped region.
- #io-channel-cells = <1>; As ADC has multiple outputs
refer to Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
- io-channel-ranges:
refer to Documentation/devicetree/bindings/iio/iio-bindings.txt for details.
- clocks: Clock used for this block.
- clock-names: Clock name should be given as tsc_clk.
- interrupts: interrupt line number.
For example:
ts_adc_syscon: ts_adc_syscon@180a6000 {
compatible = "brcm,iproc-ts-adc-syscon","syscon";
reg = <0x180a6000 0xc30>;
};
adc: adc@180a6000 {
compatible = "brcm,iproc-static-adc";
adc-syscon = <&ts_adc_syscon>;
#io-channel-cells = <1>;
io-channel-ranges;
clocks = <&asiu_clks BCM_CYGNUS_ASIU_ADC_CLK>;
clock-names = "tsc_clk";
interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
status = "disabled";
};

View File

@ -0,0 +1,63 @@
* Maxim 1x3x/136x/116xx Analog to Digital Converter (ADC)
The node for this driver must be a child node of a I2C controller, hence
all mandatory properties for your controller must be specified. See directory:
Documentation/devicetree/bindings/i2c
for more details.
Required properties:
- compatible: Should be one of
"maxim,max1361"
"maxim,max1362"
"maxim,max1363"
"maxim,max1364"
"maxim,max1036"
"maxim,max1037"
"maxim,max1038"
"maxim,max1039"
"maxim,max1136"
"maxim,max1137"
"maxim,max1138"
"maxim,max1139"
"maxim,max1236"
"maxim,max1237"
"maxim,max1238"
"maxim,max1239"
"maxim,max11600"
"maxim,max11601"
"maxim,max11602"
"maxim,max11603"
"maxim,max11604"
"maxim,max11605"
"maxim,max11606"
"maxim,max11607"
"maxim,max11608"
"maxim,max11609"
"maxim,max11610"
"maxim,max11611"
"maxim,max11612"
"maxim,max11613"
"maxim,max11614"
"maxim,max11615"
"maxim,max11616"
"maxim,max11617"
"maxim,max11644"
"maxim,max11645"
"maxim,max11646"
"maxim,max11647"
- reg: Should contain the ADC I2C address
Optional properties:
- vcc-supply: phandle to the regulator that provides power to the ADC.
- vref-supply: phandle to the regulator for ADC reference voltage.
- interrupts: IRQ line for the ADC. If not used the driver will use
polling.
Example:
adc: max11644@36 {
compatible = "maxim,max11644";
reg = <0x36>;
vref-supply = <&adc_vref>;
};

View File

@ -0,0 +1,22 @@
* Atlas Scientific EC-SM OEM sensor
http://www.atlas-scientific.com/_files/_datasheets/_oem/EC_oem_datasheet.pdf
Required properties:
- compatible: must be "atlas,ec-sm"
- reg: the I2C address of the sensor
- interrupt-parent: should be the phandle for the interrupt controller
- interrupts: the sole interrupt generated by the device
Refer to interrupt-controller/interrupts.txt for generic interrupt client
node bindings.
Example:
atlas@64 {
compatible = "atlas,ec-sm";
reg = <0x64>;
interrupt-parent = <&gpio1>;
interrupts = <16 2>;
};

View File

@ -0,0 +1,124 @@
* Analog Device AD5755 IIO Multi-Channel DAC Linux Driver
Required properties:
- compatible: Has to contain one of the following:
adi,ad5755
adi,ad5755-1
adi,ad5757
adi,ad5735
adi,ad5737
- reg: spi chip select number for the device
- spi-cpha or spi-cpol: is the only modes that is supported
Recommended properties:
- spi-max-frequency: Definition as per
Documentation/devicetree/bindings/spi/spi-bus.txt
Optional properties:
See include/dt-bindings/iio/ad5755.h
- adi,ext-dc-dc-compenstation-resistor: boolean set if the hardware have an
external resistor and thereby bypasses
the internal compensation resistor.
- adi,dc-dc-phase:
Valid values for DC DC Phase control is:
0: All dc-to-dc converters clock on the same edge.
1: Channel A and Channel B clock on the same edge,
Channel C and Channel D clock on opposite edges.
2: Channel A and Channel C clock on the same edge,
Channel B and Channel D clock on opposite edges.
3: Channel A, Channel B, Channel C, and Channel D
clock 90 degrees out of phase from each other.
- adi,dc-dc-freq-hz:
Valid values for DC DC frequency is [Hz]:
250000
410000
650000
- adi,dc-dc-max-microvolt:
Valid values for the maximum allowed Vboost voltage supplied by
the dc-to-dc converter is:
23000000
24500000
27000000
29500000
Optional for every channel:
- adi,mode:
Valid values for DAC modes is:
0: 0 V to 5 V voltage range.
1: 0 V to 10 V voltage range.
2: Plus minus 5 V voltage range.
3: Plus minus 10 V voltage range.
4: 4 mA to 20 mA current range.
5: 0 mA to 20 mA current range.
6: 0 mA to 24 mA current range.
- adi,ext-current-sense-resistor: boolean set if the hardware a external
current sense resistor.
- adi,enable-voltage-overrange: boolean enable voltage overrange
- adi,slew: Array of slewrate settings should contain 3 fields:
1: Should be either 0 or 1 in order to enable or disable slewrate.
2: Slew rate settings:
Valid values for the slew rate update frequency:
64000
32000
16000
8000
4000
2000
1000
500
250
125
64
32
16
8
4
0
3: Slew step size:
Valid values for the step size LSBs:
1
2
4
16
32
64
128
256
Example:
dac@0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "adi,ad5755";
reg = <0>;
spi-max-frequency = <1000000>;
spi-cpha;
adi,dc-dc-phase = <0>;
adi,dc-dc-freq-hz = <410000>;
adi,dc-dc-max-microvolt = <23000000>;
channel@0 {
reg = <0>;
adi,mode = <4>;
adi,ext-current-sense-resistor;
adi,slew = <0 64000 1>;
};
channel@1 {
reg = <1>;
adi,mode = <4>;
adi,ext-current-sense-resistor;
adi,slew = <0 64000 1>;
};
channel@2 {
reg = <2>;
adi,mode = <4>;
adi,ext-current-sense-resistor;
adi,slew = <0 64000 1>;
};
channel@3 {
reg = <3>;
adi,mode = <4>;
adi,ext-current-sense-resistor;
adi,slew = <0 64000 1>;
};
};

View File

@ -1,7 +1,11 @@
BMP085/BMP18x digital pressure sensors
BMP085/BMP18x/BMP28x digital pressure sensors
Required properties:
- compatible: bosch,bmp085
- compatible: must be one of:
"bosch,bmp085"
"bosch,bmp180"
"bosch,bmp280"
"bosch,bme280"
Optional properties:
- chip-id: configurable chip id for non-default chip revisions
@ -10,6 +14,10 @@ Optional properties:
value range is 0-3 with rising sensitivity.
- interrupt-parent: should be the phandle for the interrupt controller
- interrupts: interrupt mapping for IRQ
- reset-gpios: a GPIO line handling reset of the sensor: as the line is
active low, it should be marked GPIO_ACTIVE_LOW (see gpio/gpio.txt)
- vddd-supply: digital voltage regulator (see regulator/regulator.txt)
- vdda-supply: analog voltage regulator (see regulator/regulator.txt)
Example:
@ -21,4 +29,7 @@ pressure@77 {
default-oversampling = <2>;
interrupt-parent = <&gpio0>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
reset-gpios = <&gpio0 26 GPIO_ACTIVE_LOW>;
vddd-supply = <&foo>;
vdda-supply = <&bar>;
};

Before

Width:  |  Height:  |  Size: 701 B

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -64,3 +64,4 @@ Pressure sensors:
- st,lps001wp-press
- st,lps25h-press
- st,lps331ap-press
- st,lps22hb-press

View File

@ -21,6 +21,7 @@ Main node required properties:
"arm,pl390"
"arm,tc11mp-gic"
"brcm,brahma-b15-gic"
"nvidia,tegra210-agic"
"qcom,msm-8660-qgic"
"qcom,msm-qgic2"
- interrupt-controller : Identifies the node as an interrupt controller
@ -68,7 +69,7 @@ Optional
"ic_clk" (for "arm,arm11mp-gic")
"PERIPHCLKEN" (for "arm,cortex-a15-gic")
"PERIPHCLK", "PERIPHCLKEN" (for "arm,cortex-a9-gic")
"clk" (for "arm,gic-400")
"clk" (for "arm,gic-400" and "nvidia,tegra210")
"gclk" (for "arm,pl390")
- power-domains : A phandle and PM domain specifier as defined by bindings of

View File

@ -0,0 +1,22 @@
Aspeed Vectored Interrupt Controller
These bindings are for the Aspeed AST2400 interrupt controller register layout.
The SoC has an legacy register layout, but this driver does not support that
mode of operation.
Required properties:
- compatible : should be "aspeed,ast2400-vic".
- interrupt-controller : Identifies the node as an interrupt controller
- #interrupt-cells : Specifies the number of cells needed to encode an
interrupt source. The value shall be 1.
Example:
vic: interrupt-controller@1e6c0080 {
compatible = "aspeed,ast2400-vic";
interrupt-controller;
#interrupt-cells = <1>;
reg = <0x1e6c0080 0x80>;
};

View File

@ -0,0 +1,40 @@
TI DA8xx/OMAP-L1xx/AM18xx USB PHY
Required properties:
- compatible: must be "ti,da830-usb-phy".
- #phy-cells: must be 1.
This device controls the PHY for both the USB 1.1 OHCI and USB 2.0 OTG
controllers on DA8xx SoCs. Consumers of this device should use index 0 for
the USB 2.0 phy device and index 1 for the USB 1.1 phy device.
It also requires a "syscon" node with compatible = "ti,da830-cfgchip", "syscon"
to access the CFGCHIP2 register.
Example:
cfgchip: cfgchip@1417c {
compatible = "ti,da830-cfgchip", "syscon";
reg = <0x1417c 0x14>;
};
usb_phy: usb-phy {
compatible = "ti,da830-usb-phy";
#phy-cells = <1>;
};
usb20: usb@200000 {
compatible = "ti,da830-musb";
reg = <0x200000 0x1000>;
interrupts = <58>;
phys = <&usb_phy 0>;
phy-names = "usb-phy";
};
usb11: usb@225000 {
compatible = "ti,da830-ohci";
reg = <0x225000 0x1000>;
interrupts = <59>;
phys = <&usb_phy 1>;
phy-names = "usb-phy";
};

View File

@ -5,11 +5,13 @@ Required properties:
"rockchip,rk3066a-usb-phy"
"rockchip,rk3188-usb-phy"
"rockchip,rk3288-usb-phy"
- rockchip,grf : phandle to the syscon managing the "general
register files"
- #address-cells: should be 1
- #size-cells: should be 0
Deprecated properties:
- rockchip,grf : phandle to the syscon managing the "general
register files" - phy should be a child of the GRF instead
Sub-nodes:
Each PHY should be represented as a sub-node.
@ -28,14 +30,19 @@ Optional Properties:
Example:
usbphy: phy {
compatible = "rockchip,rk3288-usb-phy";
rockchip,grf = <&grf>;
#address-cells = <1>;
#size-cells = <0>;
grf: syscon@ff770000 {
compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd";
usbphy0: usb-phy0 {
#phy-cells = <0>;
reg = <0x320>;
...
usbphy: phy {
compatible = "rockchip,rk3288-usb-phy";
#address-cells = <1>;
#size-cells = <0>;
usbphy0: usb-phy0 {
#phy-cells = <0>;
reg = <0x320>;
};
};
};

View File

@ -42,6 +42,9 @@ Optional properties:
- auto-flow-control: one way to enable automatic flow control support. The
driver is allowed to detect support for the capability even without this
property.
- {rts,cts,dtr,dsr,rng,dcd}-gpios: specify a GPIO for RTS/CTS/DTR/DSR/RI/DCD
line respectively. It will use specified GPIO instead of the peripheral
function pin for the UART feature. If unsure, don't specify this property.
Note:
* fsl,ns16550:
@ -63,3 +66,19 @@ Example:
interrupts = <10>;
reg-shift = <2>;
};
Example for OMAP UART using GPIO-based modem control signals:
uart4: serial@49042000 {
compatible = "ti,omap3-uart";
reg = <0x49042000 0x400>;
interrupts = <80>;
ti,hwmods = "uart4";
clock-frequency = <48000000>;
cts-gpios = <&gpio3 5 GPIO_ACTIVE_LOW>;
rts-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
dtr-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
dsr-gpios = <&gpio1 13 GPIO_ACTIVE_LOW>;
dcd-gpios = <&gpio1 14 GPIO_ACTIVE_LOW>;
rng-gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
};

View File

@ -31,6 +31,8 @@ Required properties:
- "renesas,hscif-r8a7794" for R8A7794 (R-Car E2) HSCIF compatible UART.
- "renesas,scif-r8a7795" for R8A7795 (R-Car H3) SCIF compatible UART.
- "renesas,hscif-r8a7795" for R8A7795 (R-Car H3) HSCIF compatible UART.
- "renesas,scif-r8a7796" for R8A7796 (R-Car M3-W) SCIF compatible UART.
- "renesas,hscif-r8a7796" for R8A7796 (R-Car M3-W) HSCIF compatible UART.
- "renesas,scifa-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFA compatible UART.
- "renesas,scifb-sh73a0" for SH73A0 (SH-Mobile AG5) SCIFB compatible UART.
- "renesas,rcar-gen1-scif" for R-Car Gen1 SCIF compatible UART,
@ -76,6 +78,10 @@ Optional properties:
- dmas: Must contain a list of two references to DMA specifiers, one for
transmission, and one for reception.
- dma-names: Must contain a list of two DMA names, "tx" and "rx".
- {cts,dsr,dcd,rng,rts,dtr}-gpios: Specify GPIOs for modem lines, cfr. the
generic serial DT bindings in serial.txt.
- uart-has-rtscts: Indicates dedicated lines for RTS/CTS hardware flow
control, cfr. the generic serial DT bindings in serial.txt.
Example:
aliases {

View File

@ -0,0 +1,17 @@
Oxford Semiconductor OXNAS SoCs Family RPS Timer
================================================
Required properties:
- compatible: Should be "oxsemi,ox810se-rps-timer"
- reg : Specifies base physical address and size of the registers.
- interrupts : The interrupts of the two timers
- clocks : The phandle of the timer clock source
example:
timer0: timer@200 {
compatible = "oxsemi,ox810se-rps-timer";
reg = <0x200 0x40>;
clocks = <&rpsclk>;
interrupts = <4 5>;
};

View File

@ -1,7 +1,9 @@
Rockchip rk3288 timer
Rockchip rk timer
Required properties:
- compatible: shall be "rockchip,rk3288-timer"
- compatible: shall be one of:
"rockchip,rk3288-timer" - for rk3066, rk3036, rk3188, rk322x, rk3288, rk3368
"rockchip,rk3399-timer" - for rk3399
- reg: base address of the timer register starting with TIMERS CONTROL register
- interrupts: should contain the interrupts for Timer0
- clocks : must contain an entry for each entry in clock-names

View File

@ -93,7 +93,7 @@ Example:
phys = <&usb_phy0>;
phy-names = "usb-phy";
vbus-supply = <&reg_usb0_vbus>;
gadget-itc-setting = <0x4>; /* 4 micro-frames */
itc-setting = <0x4>; /* 4 micro-frames */
/* Incremental burst of unspecified length */
ahb-burst-config = <0x0>;
tx-burst-size-dword = <0x10>; /* 64 bytes */

View File

@ -14,7 +14,7 @@ Optional properties:
- clocks : a list of phandle + clock specifier pairs
- phys : phandle + phy specifier pair
- phy-names : "usb"
- resets : phandle + reset specifier pair
- resets : a list of phandle + reset specifier pairs
Example:

View File

@ -725,7 +725,7 @@ IRQ, you can set it by doing:
> echo 1 > /proc/irq/10/smp_affinity
This means that only the first CPU will handle the IRQ, but you can also echo
5 which means that only the first and fourth CPU can handle the IRQ.
5 which means that only the first and third CPU can handle the IRQ.
The contents of each smp_affinity file is the same by default:

View File

@ -139,27 +139,6 @@ Examples of using the Linux-provided gdb helpers
start_comm = "swapper/2\000\000\000\000\000\000"
}
o Dig into a radix tree data structure, such as the IRQ descriptors:
(gdb) print (struct irq_desc)$lx_radix_tree_lookup(irq_desc_tree, 18)
$6 = {
irq_common_data = {
state_use_accessors = 67584,
handler_data = 0x0 <__vectors_start>,
msi_desc = 0x0 <__vectors_start>,
affinity = {{
bits = {65535}
}}
},
irq_data = {
mask = 0,
irq = 18,
hwirq = 27,
common = 0xee803d80,
chip = 0xc0eb0854 <gic_data>,
domain = 0xee808000,
parent_data = 0x0 <__vectors_start>,
chip_data = 0xc0eb0854 <gic_data>
} <... trimmed ...>
List of commands and functions
------------------------------

View File

@ -24,7 +24,7 @@ Supported chips:
AW9D-MAX) (2)
1) For revisions 2 and 3 uGuru's the driver can autodetect the
sensortype (Volt or Temp) for bank1 sensors, for revision 1 uGuru's
this doesnot always work. For these uGuru's the autodection can
this does not always work. For these uGuru's the autodetection can
be overridden with the bank1_types module param. For all 3 known
revison 1 motherboards the correct use of this param is:
bank1_types=1,1,0,0,0,0,0,2,0,0,0,0,2,0,0,1

View File

@ -0,0 +1,23 @@
Kernel driver ftsteutates
=====================
Supported chips:
* FTS Teutates
Prefix: 'ftsteutates'
Addresses scanned: I2C 0x73 (7-Bit)
Author: Thilo Cestonaro <thilo.cestonaro@ts.fujitsu.com>
Description
-----------
The BMC Teutates is the Eleventh generation of Superior System
monitoring and thermal management solution. It is builds on the basic
functionality of the BMC Theseus and contains several new features and
enhancements. It can monitor up to 4 voltages, 16 temperatures and
8 fans. It also contains an integrated watchdog which is currently
implemented in this driver.
Specification of the chip can be found here:
ftp:///pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/BMC-Teutates_Specification_V1.21.pdf
ftp:///pub/Mainboard-OEM-Sales/Services/Software&Tools/Linux_SystemMonitoring&Watchdog&GPIO/Fujitsu_mainboards-1-Sensors_HowTo-en-US.pdf

View File

@ -0,0 +1,35 @@
Kernel driver ina3221
=====================
Supported chips:
* Texas Instruments INA3221
Prefix: 'ina3221'
Addresses: I2C 0x40 - 0x43
Datasheet: Publicly available at the Texas Instruments website
http://www.ti.com/
Author: Andrew F. Davis <afd@ti.com>
Description
-----------
The Texas Instruments INA3221 monitors voltage, current, and power on the high
side of up to three D.C. power supplies. The INA3221 monitors both shunt drop
and supply voltage, with programmable conversion times and averaging, current
and power are calculated host-side from these.
Sysfs entries
-------------
in[123]_input Bus voltage(mV) channels
curr[123]_input Current(mA) measurement channels
shunt[123]_resistor Shunt resistance(uOhm) channels
curr[123]_crit Critical alert current(mA) setting, activates the
corresponding alarm when the respective current
is above this value
curr[123]_crit_alarm Critical alert current limit exceeded
curr[123]_max Warning alert current(mA) setting, activates the
corresponding alarm when the respective current
average is above this value.
curr[123]_max_alarm Warning alert current limit exceeded
in[456]_input Shunt voltage(uV) for channels 1, 2, and 3 respectively

View File

@ -18,10 +18,11 @@ Supported chips:
* Maxim MAX6604
Datasheets:
http://datasheets.maxim-ic.com/en/ds/MAX6604.pdf
* Microchip MCP9804, MCP9805, MCP98242, MCP98243, MCP98244, MCP9843
* Microchip MCP9804, MCP9805, MCP9808, MCP98242, MCP98243, MCP98244, MCP9843
Datasheets:
http://ww1.microchip.com/downloads/en/DeviceDoc/22203C.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/21977b.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/25095A.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/21996a.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/22153c.pdf
http://ww1.microchip.com/downloads/en/DeviceDoc/22327A.pdf

View File

@ -17,7 +17,7 @@ This driver implements support for the Maxim MAX1668, MAX1805 and MAX1989
chips.
The three devices are very similar, but the MAX1805 has a reduced feature
set; only two remote temperature inputs vs the four avaible on the other
set; only two remote temperature inputs vs the four available on the other
two ICs.
The driver is able to distinguish between the devices and creates sysfs

76
Documentation/hwmon/sht3x Normal file
View File

@ -0,0 +1,76 @@
Kernel driver sht3x
===================
Supported chips:
* Sensirion SHT3x-DIS
Prefix: 'sht3x'
Addresses scanned: none
Datasheet: http://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/Humidity/Sensirion_Humidity_Datasheet_SHT3x_DIS.pdf
Author:
David Frey <david.frey@sensirion.com>
Pascal Sachs <pascal.sachs@sensirion.com>
Description
-----------
This driver implements support for the Sensirion SHT3x-DIS chip, a humidity
and temperature sensor. Temperature is measured in degrees celsius, relative
humidity is expressed as a percentage. In the sysfs interface, all values are
scaled by 1000, i.e. the value for 31.5 degrees celsius is 31500.
The device communicates with the I2C protocol. Sensors can have the I2C
addresses 0x44 or 0x45, depending on the wiring. See
Documentation/i2c/instantiating-devices for methods to instantiate the device.
There are two options configurable by means of sht3x_platform_data:
1. blocking (pull the I2C clock line down while performing the measurement) or
non-blocking mode. Blocking mode will guarantee the fastest result but
the I2C bus will be busy during that time. By default, non-blocking mode
is used. Make sure clock-stretching works properly on your device if you
want to use blocking mode.
2. high or low accuracy. High accuracy is used by default and using it is
strongly recommended.
The sht3x sensor supports a single shot mode as well as 5 periodic measure
modes, which can be controlled with the update_interval sysfs interface.
The allowed update_interval in milliseconds are as follows:
* 0 single shot mode
* 2000 0.5 Hz periodic measurement
* 1000 1 Hz periodic measurement
* 500 2 Hz periodic measurement
* 250 4 Hz periodic measurement
* 100 10 Hz periodic measurement
In the periodic measure mode, the sensor automatically triggers a measurement
with the configured update interval on the chip. When a temperature or humidity
reading exceeds the configured limits, the alert attribute is set to 1 and
the alert pin on the sensor is set to high.
When the temperature and humidity readings move back between the hysteresis
values, the alert bit is set to 0 and the alert pin on the sensor is set to
low.
sysfs-Interface
---------------
temp1_input: temperature input
humidity1_input: humidity input
temp1_max: temperature max value
temp1_max_hyst: temperature hysteresis value for max limit
humidity1_max: humidity max value
humidity1_max_hyst: humidity hysteresis value for max limit
temp1_min: temperature min value
temp1_min_hyst: temperature hysteresis value for min limit
humidity1_min: humidity min value
humidity1_min_hyst: humidity hysteresis value for min limit
temp1_alarm: alarm flag is set to 1 if the temperature is outside the
configured limits. Alarm only works in periodic measure mode
humidity1_alarm: alarm flag is set to 1 if the humidity is outside the
configured limits. Alarm only works in periodic measure mode
heater_enable: heater enable, heating element removes excess humidity from
sensor
0: turned off
1: turned on
update_interval: update interval, 0 for single shot, interval in msec
for periodic measurement. If the interval is not supported
by the sensor, the next faster interval is chosen

View File

@ -15,10 +15,15 @@ increase the chances of your change being accepted.
Documentation/SubmittingPatches
Documentation/CodingStyle
* If your patch generates checkpatch warnings, please refrain from explanations
such as "I don't like that coding style". Keep in mind that each unnecessary
warning helps hiding a real problem. If you don't like the kernel coding
style, don't write kernel drivers.
* Please run your patch through 'checkpatch --strict'. There should be no
errors, no warnings, and few if any check messages. If there are any
messages, please be prepared to explain.
* If your patch generates checkpatch errors, warnings, or check messages,
please refrain from explanations such as "I prefer that coding style".
Keep in mind that each unnecessary message helps hiding a real problem,
and a consistent coding style makes it easier for others to understand
and review the code.
* Please test your patch thoroughly. We are not your test group.
Sometimes a patch can not or not completely be tested because of missing
@ -61,15 +66,30 @@ increase the chances of your change being accepted.
* Make sure that all dependencies are listed in Kconfig.
* Please list include files in alphabetic order.
* Please align continuation lines with '(' on the previous line.
* Avoid forward declarations if you can. Rearrange the code if necessary.
* Avoid macros to generate groups of sensor attributes. It not only confuses
checkpatch, but also makes it more difficult to review the code.
* Avoid calculations in macros and macro-generated functions. While such macros
may save a line or so in the source, it obfuscates the code and makes code
review more difficult. It may also result in code which is more complicated
than necessary. Use inline functions or just regular functions instead.
* Limit the number of kernel log messages. In general, your driver should not
generate an error message just because a runtime operation failed. Report
errors to user space instead, using an appropriate error code. Keep in mind
that kernel error log messages not only fill up the kernel log, but also are
printed synchronously, most likely with interrupt disabled, often to a serial
console. Excessive logging can seriously affect system performance.
* Use devres functions whenever possible to allocate resources. For rationale
and supported functions, please see Documentation/driver-model/devres.txt.
If a function is not supported by devres, consider using devm_add_action().
* If the driver has a detect function, make sure it is silent. Debug messages
and messages printed after a successful detection are acceptable, but it
@ -96,8 +116,16 @@ increase the chances of your change being accepted.
writing to it might cause a bad misconfiguration.
* Make sure there are no race conditions in the probe function. Specifically,
completely initialize your chip first, then create sysfs entries and register
with the hwmon subsystem.
completely initialize your chip and your driver first, then register with
the hwmon subsystem.
* Use devm_hwmon_device_register_with_groups() or, if your driver needs a remove
function, hwmon_device_register_with_groups() to register your driver with the
hwmon subsystem. Try using devm_add_action() instead of a remove function if
possible. Do not use hwmon_device_register().
* Your driver should be buildable as module. If not, please be prepared to
explain why it has to be built into the kernel.
* Do not provide support for deprecated sysfs attributes.

View File

@ -22,6 +22,9 @@ Supported chips:
Prefix: 'tmp435'
Addresses scanned: I2C 0x48 - 0x4f
Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp435.html
* Texas Instruments TMP461
Prefix: 'tmp461'
Datasheet: http://www.ti.com/product/tmp461
Authors:
Hans de Goede <hdegoede@redhat.com>
@ -31,8 +34,8 @@ Description
-----------
This driver implements support for Texas Instruments TMP401, TMP411,
TMP431, TMP432 and TMP435 chips. These chips implement one or two remote
and one local temperature sensors. Temperature is measured in degrees
TMP431, TMP432, TMP435, and TMP461 chips. These chips implement one or two
remote and one local temperature sensors. Temperature is measured in degrees
Celsius. Resolution of the remote sensor is 0.0625 degree. Local
sensor resolution can be set to 0.5, 0.25, 0.125 or 0.0625 degree (not
supported by the driver so far, so using the default resolution of 0.5
@ -55,3 +58,10 @@ some additional features.
TMP432 is compatible with TMP401 and TMP431. It supports two external
temperature sensors.
TMP461 is compatible with TMP401. It supports offset correction
that is applied to the remote sensor.
* Sensor offset values are temperature values
Exported via sysfs attribute tempX_offset

View File

@ -47,6 +47,7 @@ This document describes the Linux kernel Makefiles.
--- 7.2 genhdr-y
--- 7.3 destination-y
--- 7.4 generic-y
--- 7.5 generated-y
=== 8 Kbuild Variables
=== 9 Makefile language
@ -1319,6 +1320,19 @@ See subsequent chapter for the syntax of the Kbuild file.
Example: termios.h
#include <asm-generic/termios.h>
--- 7.5 generated-y
If an architecture generates other header files alongside generic-y
wrappers, and not included in genhdr-y, then generated-y specifies
them.
This prevents them being treated as stale asm-generic wrappers and
removed.
Example:
#arch/x86/include/asm/Kbuild
generated-y += syscalls_32.h
=== 8 Kbuild Variables
The top Makefile exports the following variables:

View File

@ -687,6 +687,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
[SPARC64] tick
[X86-64] hpet,tsc
clocksource.arm_arch_timer.evtstrm=
[ARM,ARM64]
Format: <bool>
Enable/disable the eventstream feature of the ARM
architected timer so that code using WFE-based polling
loops can be debugged more effectively on production
systems.
clearcpuid=BITNUM [X86]
Disable CPUID feature X for the kernel. See
arch/x86/include/asm/cpufeatures.h for the valid bit
@ -1803,12 +1811,10 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
js= [HW,JOY] Analog joystick
See Documentation/input/joystick.txt.
kaslr/nokaslr [X86]
Enable/disable kernel and module base offset ASLR
(Address Space Layout Randomization) if built into
the kernel. When CONFIG_HIBERNATION is selected,
kASLR is disabled by default. When kASLR is enabled,
hibernation will be disabled.
nokaslr [KNL]
When CONFIG_RANDOMIZE_BASE is set, this disables
kernel and module base offset ASLR (Address Space
Layout Randomization).
keepinitrd [HW,ARM]

View File

@ -806,6 +806,41 @@ out-guess your code. More generally, although READ_ONCE() does force
the compiler to actually emit code for a given load, it does not force
the compiler to use the results.
In addition, control dependencies apply only to the then-clause and
else-clause of the if-statement in question. In particular, it does
not necessarily apply to code following the if-statement:
q = READ_ONCE(a);
if (q) {
WRITE_ONCE(b, p);
} else {
WRITE_ONCE(b, r);
}
WRITE_ONCE(c, 1); /* BUG: No ordering against the read from "a". */
It is tempting to argue that there in fact is ordering because the
compiler cannot reorder volatile accesses and also cannot reorder
the writes to "b" with the condition. Unfortunately for this line
of reasoning, the compiler might compile the two writes to "b" as
conditional-move instructions, as in this fanciful pseudo-assembly
language:
ld r1,a
ld r2,p
ld r3,r
cmp r1,$0
cmov,ne r4,r2
cmov,eq r4,r3
st r4,b
st $1,c
A weakly ordered CPU would have no dependency of any sort between the load
from "a" and the store to "c". The control dependencies would extend
only to the pair of cmov instructions and the store depending on them.
In short, control dependencies apply only to the stores in the then-clause
and else-clause of the if-statement in question (including functions
invoked by those two clauses), not to code following that if-statement.
Finally, control dependencies do -not- provide transitivity. This is
demonstrated by two related examples, with the initial values of
x and y both being zero:
@ -869,6 +904,12 @@ In summary:
atomic{,64}_read() can help to preserve your control dependency.
Please see the COMPILER BARRIER section for more information.
(*) Control dependencies apply only to the then-clause and else-clause
of the if-statement containing the control dependency, including
any functions that these two clauses call. Control dependencies
do -not- apply to code following the if-statement containing the
control dependency.
(*) Control dependencies pair normally with other types of barriers.
(*) Control dependencies do -not- provide transitivity. If you

View File

@ -58,6 +58,7 @@ show up in /proc/sys/kernel:
- panic_on_stackoverflow
- panic_on_unrecovered_nmi
- panic_on_warn
- panic_on_rcu_stall
- perf_cpu_time_max_percent
- perf_event_paranoid
- perf_event_max_stack
@ -618,6 +619,17 @@ a kernel rebuild when attempting to kdump at the location of a WARN().
==============================================================
panic_on_rcu_stall:
When set to 1, calls panic() after RCU stall detection messages. This
is useful to define the root cause of RCU stalls using a vmcore.
0: do not panic() when RCU stall takes place, default behavior.
1: panic() after printing RCU stall messages.
==============================================================
perf_cpu_time_max_percent:
Hints to the kernel how much CPU time it should be allowed to

View File

@ -45,7 +45,7 @@ is how we expect the compiler, application and kernel to work together.
MPX-instrumented.
3) The kernel detects that the CPU has MPX, allows the new prctl() to
succeed, and notes the location of the bounds directory. Userspace is
expected to keep the bounds directory at that locationWe note it
expected to keep the bounds directory at that location. We note it
instead of reading it each time because the 'xsave' operation needed
to access the bounds directory register is an expensive operation.
4) If the application needs to spill bounds out of the 4 registers, it
@ -167,7 +167,7 @@ If a #BR is generated due to a bounds violation caused by MPX.
We need to decode MPX instructions to get violation address and
set this address into extended struct siginfo.
The _sigfault feild of struct siginfo is extended as follow:
The _sigfault field of struct siginfo is extended as follow:
87 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
88 struct {
@ -240,5 +240,5 @@ them at the same bounds table.
This is allowed architecturally. See more information "Intel(R) Architecture
Instruction Set Extensions Programming Reference" (9.3.4).
However, if users did this, the kernel might be fooled in to unmaping an
However, if users did this, the kernel might be fooled in to unmapping an
in-use bounds table since it does not recognize sharing.

View File

@ -5,7 +5,7 @@ memory, it has two choices:
from areas other than the one we are trying to flush will be
destroyed and must be refilled later, at some cost.
2. Use the invlpg instruction to invalidate a single page at a
time. This could potentialy cost many more instructions, but
time. This could potentially cost many more instructions, but
it is a much more precise operation, causing no collateral
damage to other TLB entries.
@ -19,7 +19,7 @@ Which method to do depends on a few things:
work.
3. The size of the TLB. The larger the TLB, the more collateral
damage we do with a full flush. So, the larger the TLB, the
more attrative an individual flush looks. Data and
more attractive an individual flush looks. Data and
instructions have separate TLBs, as do different page sizes.
4. The microarchitecture. The TLB has become a multi-level
cache on modern CPUs, and the global flushes have become more

View File

@ -36,7 +36,7 @@ between all CPUs.
check_interval
How often to poll for corrected machine check errors, in seconds
(Note output is hexademical). Default 5 minutes. When the poller
(Note output is hexadecimal). Default 5 minutes. When the poller
finds MCEs it triggers an exponential speedup (poll more often) on
the polling interval. When the poller stops finding MCEs, it
triggers an exponential backoff (poll less often) on the polling

View File

@ -39,4 +39,8 @@ memory window (this size is arbitrary, it can be raised later if needed).
The mappings are not part of any other kernel PGD and are only available
during EFI runtime calls.
Note that if CONFIG_RANDOMIZE_MEMORY is enabled, the direct mapping of all
physical memory, vmalloc/ioremap space and virtual memory map are randomized.
Their order is preserved but their base will be offset early at boot time.
-Andi Kleen, Jul 2004

View File

@ -1669,7 +1669,6 @@ F: arch/arm/boot/dts/sh*
F: arch/arm/configs/shmobile_defconfig
F: arch/arm/include/debug/renesas-scif.S
F: arch/arm/mach-shmobile/
F: drivers/sh/
F: drivers/soc/renesas/
F: include/linux/soc/renesas/
@ -1694,8 +1693,6 @@ S: Maintained
F: drivers/edac/altera_edac.
ARM/STI ARCHITECTURE
M: Srinivas Kandagatla <srinivas.kandagatla@gmail.com>
M: Maxime Coquelin <maxime.coquelin@st.com>
M: Patrice Chotard <patrice.chotard@st.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
L: kernel@stlinux.com
@ -1728,6 +1725,7 @@ F: drivers/ata/ahci_st.c
ARM/STM32 ARCHITECTURE
M: Maxime Coquelin <mcoquelin.stm32@gmail.com>
M: Alexandre Torgue <alexandre.torgue@st.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/mcoquelin/stm32.git
@ -4477,7 +4475,7 @@ S: Orphan
F: fs/efs/
EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
M: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
M: Douglas Miller <dougmill@linux.vnet.ibm.com>
L: netdev@vger.kernel.org
S: Maintained
F: drivers/net/ethernet/ibm/ehea/
@ -5789,7 +5787,9 @@ R: Hartmut Knaack <knaack.h@gmx.de>
R: Lars-Peter Clausen <lars@metafoo.de>
R: Peter Meerwald-Stadler <pmeerw@pmeerw.net>
L: linux-iio@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
S: Maintained
F: Documentation/devicetree/bindings/iio/
F: drivers/iio/
F: drivers/staging/iio/
F: include/linux/iio/
@ -6235,7 +6235,6 @@ F: Documentation/devicetree/bindings/interrupt-controller/
F: drivers/irqchip/
IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
M: Jiang Liu <jiang.liu@linux.intel.com>
M: Marc Zyngier <marc.zyngier@arm.com>
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
@ -6971,7 +6970,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/livepatching.git
LINUX KERNEL DUMP TEST MODULE (LKDTM)
M: Kees Cook <keescook@chromium.org>
S: Maintained
F: drivers/misc/lkdtm.c
F: drivers/misc/lkdtm*
LLC (802.2)
M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
@ -7024,15 +7023,23 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained
F: drivers/media/usb/dvb-usb-v2/lmedm04*
LOCKDEP AND LOCKSTAT
LOCKING PRIMITIVES
M: Peter Zijlstra <peterz@infradead.org>
M: Ingo Molnar <mingo@redhat.com>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core/locking
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
S: Maintained
F: Documentation/locking/lockdep*.txt
F: Documentation/locking/lockstat.txt
F: Documentation/locking/
F: include/linux/lockdep.h
F: include/linux/spinlock*.h
F: arch/*/include/asm/spinlock*.h
F: include/linux/rwlock*.h
F: include/linux/mutex*.h
F: arch/*/include/asm/mutex*.h
F: include/linux/rwsem*.h
F: arch/*/include/asm/rwsem.h
F: include/linux/seqlock.h
F: lib/locking*.[ch]
F: kernel/locking/
LOGICAL DISK MANAGER SUPPORT (LDM, Windows 2000/XP/Vista Dynamic Disks)
@ -7476,6 +7483,7 @@ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/
T: git git://git.infradead.org/linux-mtd.git
T: git git://git.infradead.org/l2-mtd.git
S: Maintained
F: Documentation/devicetree/bindings/mtd/
F: drivers/mtd/
F: include/linux/mtd/
F: include/uapi/mtd/
@ -10001,6 +10009,7 @@ SERIAL DRIVERS
M: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
L: linux-serial@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/serial/
F: drivers/tty/serial/
SYNOPSYS DESIGNWARE DMAC DRIVER
@ -10861,6 +10870,7 @@ STAGING - INDUSTRIAL IO
M: Jonathan Cameron <jic23@kernel.org>
L: linux-iio@vger.kernel.org
S: Odd Fixes
F: Documentation/devicetree/bindings/staging/iio/
F: drivers/staging/iio/
STAGING - LIRC (LINUX INFRARED REMOTE CONTROL) DRIVERS

View File

@ -1,7 +1,7 @@
VERSION = 4
PATCHLEVEL = 7
SUBLEVEL = 0
EXTRAVERSION = -rc6
EXTRAVERSION =
NAME = Psychotic Stoned Sheep
# *DOCUMENTATION*
@ -1040,7 +1040,7 @@ ifdef CONFIG_STACK_VALIDATION
ifeq ($(has_libelf),1)
objtool_target := tools/objtool FORCE
else
$(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev or elfutils-libelf-devel")
$(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev, libelf-devel or elfutils-libelf-devel")
SKIP_STACK_VALIDATION := 1
export SKIP_STACK_VALIDATION
endif

View File

@ -46,10 +46,9 @@ static __inline__ void atomic_##op(int i, atomic_t * v) \
} \
#define ATOMIC_OP_RETURN(op, asm_op) \
static inline int atomic_##op##_return(int i, atomic_t *v) \
static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
{ \
long temp, result; \
smp_mb(); \
__asm__ __volatile__( \
"1: ldl_l %0,%1\n" \
" " #asm_op " %0,%3,%2\n" \
@ -61,7 +60,23 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_mb(); \
return result; \
}
#define ATOMIC_FETCH_OP(op, asm_op) \
static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
{ \
long temp, result; \
__asm__ __volatile__( \
"1: ldl_l %2,%1\n" \
" " #asm_op " %2,%3,%0\n" \
" stl_c %0,%1\n" \
" beq %0,2f\n" \
".subsection 2\n" \
"2: br 1b\n" \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
return result; \
}
@ -82,10 +97,9 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v) \
} \
#define ATOMIC64_OP_RETURN(op, asm_op) \
static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
{ \
long temp, result; \
smp_mb(); \
__asm__ __volatile__( \
"1: ldq_l %0,%1\n" \
" " #asm_op " %0,%3,%2\n" \
@ -97,34 +111,77 @@ static __inline__ long atomic64_##op##_return(long i, atomic64_t * v) \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
smp_mb(); \
return result; \
}
#define ATOMIC64_FETCH_OP(op, asm_op) \
static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v) \
{ \
long temp, result; \
__asm__ __volatile__( \
"1: ldq_l %2,%1\n" \
" " #asm_op " %2,%3,%0\n" \
" stq_c %0,%1\n" \
" beq %0,2f\n" \
".subsection 2\n" \
"2: br 1b\n" \
".previous" \
:"=&r" (temp), "=m" (v->counter), "=&r" (result) \
:"Ir" (i), "m" (v->counter) : "memory"); \
return result; \
}
#define ATOMIC_OPS(op) \
ATOMIC_OP(op, op##l) \
ATOMIC_OP_RETURN(op, op##l) \
ATOMIC_FETCH_OP(op, op##l) \
ATOMIC64_OP(op, op##q) \
ATOMIC64_OP_RETURN(op, op##q)
ATOMIC64_OP_RETURN(op, op##q) \
ATOMIC64_FETCH_OP(op, op##q)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
#define atomic_add_return_relaxed atomic_add_return_relaxed
#define atomic_sub_return_relaxed atomic_sub_return_relaxed
#define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
#define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
#define atomic64_add_return_relaxed atomic64_add_return_relaxed
#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
#define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
#define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
#define atomic_andnot atomic_andnot
#define atomic64_andnot atomic64_andnot
ATOMIC_OP(and, and)
ATOMIC_OP(andnot, bic)
ATOMIC_OP(or, bis)
ATOMIC_OP(xor, xor)
ATOMIC64_OP(and, and)
ATOMIC64_OP(andnot, bic)
ATOMIC64_OP(or, bis)
ATOMIC64_OP(xor, xor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, asm) \
ATOMIC_OP(op, asm) \
ATOMIC_FETCH_OP(op, asm) \
ATOMIC64_OP(op, asm) \
ATOMIC64_FETCH_OP(op, asm)
ATOMIC_OPS(and, and)
ATOMIC_OPS(andnot, bic)
ATOMIC_OPS(or, bis)
ATOMIC_OPS(xor, xor)
#define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
#define atomic_fetch_andnot_relaxed atomic_fetch_andnot_relaxed
#define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
#define atomic_fetch_xor_relaxed atomic_fetch_xor_relaxed
#define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
#define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot_relaxed
#define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
#define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
#undef ATOMIC_OPS
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP

View File

@ -25,8 +25,8 @@ static inline void __down_read(struct rw_semaphore *sem)
{
long oldcount;
#ifndef CONFIG_SMP
oldcount = sem->count;
sem->count += RWSEM_ACTIVE_READ_BIAS;
oldcount = sem->count.counter;
sem->count.counter += RWSEM_ACTIVE_READ_BIAS;
#else
long temp;
__asm__ __volatile__(
@ -52,13 +52,13 @@ static inline int __down_read_trylock(struct rw_semaphore *sem)
{
long old, new, res;
res = sem->count;
res = atomic_long_read(&sem->count);
do {
new = res + RWSEM_ACTIVE_READ_BIAS;
if (new <= 0)
break;
old = res;
res = cmpxchg(&sem->count, old, new);
res = atomic_long_cmpxchg(&sem->count, old, new);
} while (res != old);
return res >= 0 ? 1 : 0;
}
@ -67,8 +67,8 @@ static inline long ___down_write(struct rw_semaphore *sem)
{
long oldcount;
#ifndef CONFIG_SMP
oldcount = sem->count;
sem->count += RWSEM_ACTIVE_WRITE_BIAS;
oldcount = sem->count.counter;
sem->count.counter += RWSEM_ACTIVE_WRITE_BIAS;
#else
long temp;
__asm__ __volatile__(
@ -106,7 +106,7 @@ static inline int __down_write_killable(struct rw_semaphore *sem)
*/
static inline int __down_write_trylock(struct rw_semaphore *sem)
{
long ret = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
long ret = atomic_long_cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
RWSEM_ACTIVE_WRITE_BIAS);
if (ret == RWSEM_UNLOCKED_VALUE)
return 1;
@ -117,8 +117,8 @@ static inline void __up_read(struct rw_semaphore *sem)
{
long oldcount;
#ifndef CONFIG_SMP
oldcount = sem->count;
sem->count -= RWSEM_ACTIVE_READ_BIAS;
oldcount = sem->count.counter;
sem->count.counter -= RWSEM_ACTIVE_READ_BIAS;
#else
long temp;
__asm__ __volatile__(
@ -142,8 +142,8 @@ static inline void __up_write(struct rw_semaphore *sem)
{
long count;
#ifndef CONFIG_SMP
sem->count -= RWSEM_ACTIVE_WRITE_BIAS;
count = sem->count;
sem->count.counter -= RWSEM_ACTIVE_WRITE_BIAS;
count = sem->count.counter;
#else
long temp;
__asm__ __volatile__(
@ -171,8 +171,8 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
{
long oldcount;
#ifndef CONFIG_SMP
oldcount = sem->count;
sem->count -= RWSEM_WAITING_BIAS;
oldcount = sem->count.counter;
sem->count.counter -= RWSEM_WAITING_BIAS;
#else
long temp;
__asm__ __volatile__(
@ -191,47 +191,5 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
rwsem_downgrade_wake(sem);
}
static inline void rwsem_atomic_add(long val, struct rw_semaphore *sem)
{
#ifndef CONFIG_SMP
sem->count += val;
#else
long temp;
__asm__ __volatile__(
"1: ldq_l %0,%1\n"
" addq %0,%2,%0\n"
" stq_c %0,%1\n"
" beq %0,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (sem->count)
:"Ir" (val), "m" (sem->count));
#endif
}
static inline long rwsem_atomic_update(long val, struct rw_semaphore *sem)
{
#ifndef CONFIG_SMP
sem->count += val;
return sem->count;
#else
long ret, temp;
__asm__ __volatile__(
"1: ldq_l %0,%1\n"
" addq %0,%3,%2\n"
" addq %0,%3,%0\n"
" stq_c %2,%1\n"
" beq %2,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (ret), "=m" (sem->count), "=&r" (temp)
:"Ir" (val), "m" (sem->count));
return ret;
#endif
}
#endif /* __KERNEL__ */
#endif /* _ALPHA_RWSEM_H */

View File

@ -3,6 +3,8 @@
#include <linux/kernel.h>
#include <asm/current.h>
#include <asm/barrier.h>
#include <asm/processor.h>
/*
* Simple spin lock operations. There are two variants, one clears IRQ's
@ -13,8 +15,11 @@
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
#define arch_spin_is_locked(x) ((x)->lock != 0)
#define arch_spin_unlock_wait(x) \
do { cpu_relax(); } while ((x)->lock)
static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
{
smp_cond_load_acquire(&lock->lock, !VAL);
}
static inline int arch_spin_value_unlocked(arch_spinlock_t lock)
{

View File

@ -67,6 +67,33 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return val; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned int val, orig; \
\
/* \
* Explicit full memory barrier needed before/after as \
* LLOCK/SCOND thmeselves don't provide any such semantics \
*/ \
smp_mb(); \
\
__asm__ __volatile__( \
"1: llock %[orig], [%[ctr]] \n" \
" " #asm_op " %[val], %[orig], %[i] \n" \
" scond %[val], [%[ctr]] \n" \
" \n" \
: [val] "=&r" (val), \
[orig] "=&r" (orig) \
: [ctr] "r" (&v->counter), \
[i] "ir" (i) \
: "cc"); \
\
smp_mb(); \
\
return orig; \
}
#else /* !CONFIG_ARC_HAS_LLSC */
#ifndef CONFIG_SMP
@ -129,25 +156,44 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return temp; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned long flags; \
unsigned long orig; \
\
/* \
* spin lock/unlock provides the needed smp_mb() before/after \
*/ \
atomic_ops_lock(flags); \
orig = v->counter; \
v->counter c_op i; \
atomic_ops_unlock(flags); \
\
return orig; \
}
#endif /* !CONFIG_ARC_HAS_LLSC */
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op)
ATOMIC_OP_RETURN(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
#define atomic_andnot atomic_andnot
ATOMIC_OP(and, &=, and)
ATOMIC_OP(andnot, &= ~, bic)
ATOMIC_OP(or, |=, or)
ATOMIC_OP(xor, ^=, xor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
#undef SCOND_FAIL_RETRY_VAR_DEF
#undef SCOND_FAIL_RETRY_ASM
#undef SCOND_FAIL_RETRY_VARS
ATOMIC_OPS(and, &=, and)
ATOMIC_OPS(andnot, &= ~, bic)
ATOMIC_OPS(or, |=, or)
ATOMIC_OPS(xor, ^=, xor)
#else /* CONFIG_ARC_PLAT_EZNPS */
@ -208,22 +254,51 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return temp; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned int temp = i; \
\
/* Explicit full memory barrier needed before/after */ \
smp_mb(); \
\
__asm__ __volatile__( \
" mov r2, %0\n" \
" mov r3, %1\n" \
" .word %2\n" \
" mov %0, r2" \
: "+r"(temp) \
: "r"(&v->counter), "i"(asm_op) \
: "r2", "r3", "memory"); \
\
smp_mb(); \
\
return temp; \
}
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op)
ATOMIC_OP_RETURN(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, CTOP_INST_AADD_DI_R2_R2_R3)
#define atomic_sub(i, v) atomic_add(-(i), (v))
#define atomic_sub_return(i, v) atomic_add_return(-(i), (v))
ATOMIC_OP(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(and, &=, CTOP_INST_AAND_DI_R2_R2_R3)
#define atomic_andnot(mask, v) atomic_and(~(mask), (v))
ATOMIC_OP(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
ATOMIC_OP(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
ATOMIC_OPS(or, |=, CTOP_INST_AOR_DI_R2_R2_R3)
ATOMIC_OPS(xor, ^=, CTOP_INST_AXOR_DI_R2_R2_R3)
#endif /* CONFIG_ARC_PLAT_EZNPS */
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP

View File

@ -15,8 +15,11 @@
#define arch_spin_is_locked(x) ((x)->slock != __ARCH_SPIN_LOCK_UNLOCKED__)
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)
#define arch_spin_unlock_wait(x) \
do { while (arch_spin_is_locked(x)) cpu_relax(); } while (0)
static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
{
smp_cond_load_acquire(&lock->slock, !VAL);
}
#ifdef CONFIG_ARC_HAS_LLSC

View File

@ -116,19 +116,19 @@ static struct clocksource arc_counter_gfrc = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static void __init arc_cs_setup_gfrc(struct device_node *node)
static int __init arc_cs_setup_gfrc(struct device_node *node)
{
int exists = cpuinfo_arc700[0].extn.gfrc;
int ret;
if (WARN(!exists, "Global-64-bit-Ctr clocksource not detected"))
return;
return -ENXIO;
ret = arc_get_timer_clk(node);
if (ret)
return;
return ret;
clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
}
CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
@ -172,25 +172,25 @@ static struct clocksource arc_counter_rtc = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static void __init arc_cs_setup_rtc(struct device_node *node)
static int __init arc_cs_setup_rtc(struct device_node *node)
{
int exists = cpuinfo_arc700[smp_processor_id()].extn.rtc;
int ret;
if (WARN(!exists, "Local-64-bit-Ctr clocksource not detected"))
return;
return -ENXIO;
/* Local to CPU hence not usable in SMP */
if (WARN(IS_ENABLED(CONFIG_SMP), "Local-64-bit-Ctr not usable in SMP"))
return;
return -EINVAL;
ret = arc_get_timer_clk(node);
if (ret)
return;
return ret;
write_aux_reg(AUX_RTC_CTRL, 1);
clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
}
CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
@ -213,23 +213,23 @@ static struct clocksource arc_counter_timer1 = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
static void __init arc_cs_setup_timer1(struct device_node *node)
static int __init arc_cs_setup_timer1(struct device_node *node)
{
int ret;
/* Local to CPU hence not usable in SMP */
if (IS_ENABLED(CONFIG_SMP))
return;
return -EINVAL;
ret = arc_get_timer_clk(node);
if (ret)
return;
return ret;
write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
write_aux_reg(ARC_REG_TIMER1_CNT, 0);
write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
}
/********** Clock Event Device *********/
@ -324,20 +324,28 @@ static struct notifier_block arc_timer_cpu_nb = {
/*
* clockevent setup for boot CPU
*/
static void __init arc_clockevent_setup(struct device_node *node)
static int __init arc_clockevent_setup(struct device_node *node)
{
struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
int ret;
register_cpu_notifier(&arc_timer_cpu_nb);
ret = register_cpu_notifier(&arc_timer_cpu_nb);
if (ret) {
pr_err("Failed to register cpu notifier");
return ret;
}
arc_timer_irq = irq_of_parse_and_map(node, 0);
if (arc_timer_irq <= 0)
panic("clockevent: missing irq");
if (arc_timer_irq <= 0) {
pr_err("clockevent: missing irq");
return -EINVAL;
}
ret = arc_get_timer_clk(node);
if (ret)
panic("clockevent: missing clk");
if (ret) {
pr_err("clockevent: missing clk");
return ret;
}
evt->irq = arc_timer_irq;
evt->cpumask = cpumask_of(smp_processor_id());
@ -347,22 +355,29 @@ static void __init arc_clockevent_setup(struct device_node *node)
/* Needs apriori irq_set_percpu_devid() done in intc map function */
ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
"Timer0 (per-cpu-tick)", evt);
if (ret)
panic("clockevent: unable to request irq\n");
if (ret) {
pr_err("clockevent: unable to request irq\n");
return ret;
}
enable_percpu_irq(arc_timer_irq, 0);
return 0;
}
static void __init arc_of_timer_init(struct device_node *np)
static int __init arc_of_timer_init(struct device_node *np)
{
static int init_count = 0;
int ret;
if (!init_count) {
init_count = 1;
arc_clockevent_setup(np);
ret = arc_clockevent_setup(np);
} else {
arc_cs_setup_timer1(np);
ret = arc_cs_setup_timer1(np);
}
return ret;
}
CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);

View File

@ -358,10 +358,10 @@ config ARCH_CLPS711X
bool "Cirrus Logic CLPS711x/EP721x/EP731x-based"
select ARCH_REQUIRE_GPIOLIB
select AUTO_ZRELADDR
select CLKSRC_MMIO
select COMMON_CLK
select CPU_ARM720T
select GENERIC_CLOCKEVENTS
select CLPS711X_TIMER
select MFD_SYSCON
select SOC_BUS
help

View File

@ -58,8 +58,8 @@
soc {
ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
internal-regs {

View File

@ -232,7 +232,7 @@
};
usb1: ohci@00400000 {
compatible = "atmel,at91rm9200-ohci", "usb-ohci";
compatible = "atmel,sama5d2-ohci", "usb-ohci";
reg = <0x00400000 0x100000>;
interrupts = <41 IRQ_TYPE_LEVEL_HIGH 2>;
clocks = <&uhphs_clk>, <&uhphs_clk>, <&uhpck>;

View File

@ -65,8 +65,9 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
<&ahb_gates 44>, <&dram_gates 26>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 43>, <&ahb_gates 44>,
<&dram_gates 26>;
status = "disabled";
};
@ -74,8 +75,9 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_fe0-de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
<&ahb_gates 44>, <&ahb_gates 46>,
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 43>, <&ahb_gates 44>,
<&ahb_gates 46>,
<&dram_gates 25>, <&dram_gates 26>;
status = "disabled";
};
@ -84,9 +86,9 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_fe0-de_be0-lcd0";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
<&ahb_gates 46>, <&dram_gates 25>,
<&dram_gates 26>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 44>, <&ahb_gates 46>,
<&dram_gates 25>, <&dram_gates 26>;
status = "disabled";
};
@ -94,8 +96,9 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
<&ahb_gates 44>, <&ahb_gates 46>,
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>,
<&ahb_gates 36>, <&ahb_gates 44>,
<&ahb_gates 46>,
<&dram_gates 5>, <&dram_gates 25>, <&dram_gates 26>;
status = "disabled";
};

View File

@ -65,8 +65,8 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
<&ahb_gates 44>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 43>, <&ahb_gates 44>;
status = "disabled";
};
@ -74,7 +74,8 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 44>;
status = "disabled";
};
@ -82,8 +83,8 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-tve0";
clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
<&ahb_gates 44>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 34>,
<&ahb_gates 36>, <&ahb_gates 44>;
status = "disabled";
};
};

View File

@ -52,7 +52,7 @@
/ {
model = "NextThing C.H.I.P.";
compatible = "nextthing,chip", "allwinner,sun5i-r8";
compatible = "nextthing,chip", "allwinner,sun5i-r8", "allwinner,sun5i-a13";
aliases {
i2c0 = &i2c0;

View File

@ -67,8 +67,9 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-hdmi";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 43>,
<&ahb_gates 44>, <&dram_gates 26>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 43>, <&ahb_gates 44>,
<&dram_gates 26>;
status = "disabled";
};
@ -76,8 +77,8 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0";
clocks = <&pll5 1>, <&ahb_gates 36>, <&ahb_gates 44>,
<&dram_gates 26>;
clocks = <&pll3>, <&pll5 1>, <&ahb_gates 36>,
<&ahb_gates 44>, <&dram_gates 26>;
status = "disabled";
};
@ -85,7 +86,7 @@
compatible = "allwinner,simple-framebuffer",
"simple-framebuffer";
allwinner,pipeline = "de_be0-lcd0-tve0";
clocks = <&pll5 1>,
clocks = <&pll3>, <&pll5 1>,
<&ahb_gates 34>, <&ahb_gates 36>, <&ahb_gates 44>,
<&dram_gates 5>, <&dram_gates 26>;
status = "disabled";
@ -231,6 +232,7 @@
pll3x2: pll3x2_clk {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clocks = <&pll3>;
clock-div = <1>;
clock-mult = <2>;
clock-output-names = "pll3-2x";
@ -272,6 +274,7 @@
pll7x2: pll7x2_clk {
#clock-cells = <0>;
compatible = "fixed-factor-clock";
clocks = <&pll7>;
clock-div = <1>;
clock-mult = <2>;
clock-output-names = "pll7-2x";

View File

@ -1843,7 +1843,7 @@
ldo5_reg: ldo5 {
regulator-name = "vddio_sdmmc,avdd_vdac";
regulator-min-microvolt = <3300000>;
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
@ -1914,6 +1914,7 @@
sdhci@78000000 {
status = "okay";
vqmmc-supply = <&ldo5_reg>;
cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio TEGRA_GPIO(T, 3) GPIO_ACTIVE_HIGH>;
power-gpios = <&gpio TEGRA_GPIO(D, 7) GPIO_ACTIVE_HIGH>;

View File

@ -77,8 +77,36 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \
return result; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \
{ \
unsigned long tmp; \
int result, val; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic_fetch_" #op "\n" \
"1: ldrex %0, [%4]\n" \
" " #asm_op " %1, %0, %5\n" \
" strex %2, %1, [%4]\n" \
" teq %2, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "Ir" (i) \
: "cc"); \
\
return result; \
}
#define atomic_add_return_relaxed atomic_add_return_relaxed
#define atomic_sub_return_relaxed atomic_sub_return_relaxed
#define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
#define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
#define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
#define atomic_fetch_andnot_relaxed atomic_fetch_andnot_relaxed
#define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
#define atomic_fetch_xor_relaxed atomic_fetch_xor_relaxed
static inline int atomic_cmpxchg_relaxed(atomic_t *ptr, int old, int new)
{
@ -159,6 +187,20 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return val; \
}
#define ATOMIC_FETCH_OP(op, c_op, asm_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
unsigned long flags; \
int val; \
\
raw_local_irq_save(flags); \
val = v->counter; \
v->counter c_op i; \
raw_local_irq_restore(flags); \
\
return val; \
}
static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
{
int ret;
@ -187,19 +229,26 @@ static inline int __atomic_add_unless(atomic_t *v, int a, int u)
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_OP_RETURN(op, c_op, asm_op)
ATOMIC_OP_RETURN(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(add, +=, add)
ATOMIC_OPS(sub, -=, sub)
#define atomic_andnot atomic_andnot
ATOMIC_OP(and, &=, and)
ATOMIC_OP(andnot, &= ~, bic)
ATOMIC_OP(or, |=, orr)
ATOMIC_OP(xor, ^=, eor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op, c_op, asm_op) \
ATOMIC_OP(op, c_op, asm_op) \
ATOMIC_FETCH_OP(op, c_op, asm_op)
ATOMIC_OPS(and, &=, and)
ATOMIC_OPS(andnot, &= ~, bic)
ATOMIC_OPS(or, |=, orr)
ATOMIC_OPS(xor, ^=, eor)
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
@ -317,24 +366,61 @@ atomic64_##op##_return_relaxed(long long i, atomic64_t *v) \
return result; \
}
#define ATOMIC64_FETCH_OP(op, op1, op2) \
static inline long long \
atomic64_fetch_##op##_relaxed(long long i, atomic64_t *v) \
{ \
long long result, val; \
unsigned long tmp; \
\
prefetchw(&v->counter); \
\
__asm__ __volatile__("@ atomic64_fetch_" #op "\n" \
"1: ldrexd %0, %H0, [%4]\n" \
" " #op1 " %Q1, %Q0, %Q5\n" \
" " #op2 " %R1, %R0, %R5\n" \
" strexd %2, %1, %H1, [%4]\n" \
" teq %2, #0\n" \
" bne 1b" \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Qo" (v->counter) \
: "r" (&v->counter), "r" (i) \
: "cc"); \
\
return result; \
}
#define ATOMIC64_OPS(op, op1, op2) \
ATOMIC64_OP(op, op1, op2) \
ATOMIC64_OP_RETURN(op, op1, op2)
ATOMIC64_OP_RETURN(op, op1, op2) \
ATOMIC64_FETCH_OP(op, op1, op2)
ATOMIC64_OPS(add, adds, adc)
ATOMIC64_OPS(sub, subs, sbc)
#define atomic64_add_return_relaxed atomic64_add_return_relaxed
#define atomic64_sub_return_relaxed atomic64_sub_return_relaxed
#define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
#define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
#undef ATOMIC64_OPS
#define ATOMIC64_OPS(op, op1, op2) \
ATOMIC64_OP(op, op1, op2) \
ATOMIC64_FETCH_OP(op, op1, op2)
#define atomic64_andnot atomic64_andnot
ATOMIC64_OP(and, and, and)
ATOMIC64_OP(andnot, bic, bic)
ATOMIC64_OP(or, orr, orr)
ATOMIC64_OP(xor, eor, eor)
ATOMIC64_OPS(and, and, and)
ATOMIC64_OPS(andnot, bic, bic)
ATOMIC64_OPS(or, orr, orr)
ATOMIC64_OPS(xor, eor, eor)
#define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
#define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot_relaxed
#define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
#define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
#undef ATOMIC64_OPS
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP

View File

@ -28,10 +28,10 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
#define arch_efi_call_virt_setup() efi_virtmap_load()
#define arch_efi_call_virt_teardown() efi_virtmap_unload()
#define arch_efi_call_virt(f, args...) \
#define arch_efi_call_virt(p, f, args...) \
({ \
efi_##f##_t *__f; \
__f = efi.systab->runtime->f; \
__f = p->f; \
__f(args); \
})

View File

@ -6,6 +6,8 @@
#endif
#include <linux/prefetch.h>
#include <asm/barrier.h>
#include <asm/processor.h>
/*
* sev and wfe are ARMv6K extensions. Uniprocessor ARMv6 may not have the K
@ -50,8 +52,21 @@ static inline void dsb_sev(void)
* memory.
*/
#define arch_spin_unlock_wait(lock) \
do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0)
static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
{
u16 owner = READ_ONCE(lock->tickets.owner);
for (;;) {
arch_spinlock_t tmp = READ_ONCE(*lock);
if (tmp.tickets.owner == tmp.tickets.next ||
tmp.tickets.owner != owner)
break;
wfe();
}
smp_acquire__after_ctrl_dep();
}
#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock)

View File

@ -139,8 +139,8 @@ struct kvm_arch_memory_slot {
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
#define KVM_REG_ARM_TIMER_CTL ARM_CP15_REG32(0, 14, 3, 1)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
#define KVM_REG_ARM_TIMER_CNT ARM_CP15_REG64(1, 14)
#define KVM_REG_ARM_TIMER_CVAL ARM_CP15_REG64(3, 14)
/* Normal registers are mapped as coprocessor 16. */
#define KVM_REG_ARM_CORE (0x0010 << KVM_REG_ARM_COPROC_SHIFT)

View File

@ -390,7 +390,7 @@ int __init twd_local_timer_register(struct twd_local_timer *tlt)
}
#ifdef CONFIG_OF
static void __init twd_local_timer_of_register(struct device_node *np)
static int __init twd_local_timer_of_register(struct device_node *np)
{
int err;
@ -410,6 +410,7 @@ static void __init twd_local_timer_of_register(struct device_node *np)
out:
WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
return err;
}
CLOCKSOURCE_OF_DECLARE(arm_twd_a9, "arm,cortex-a9-twd-timer", twd_local_timer_of_register);
CLOCKSOURCE_OF_DECLARE(arm_twd_a5, "arm,cortex-a5-twd-timer", twd_local_timer_of_register);

View File

@ -89,6 +89,7 @@ config ARCH_BCM_MOBILE
select HAVE_ARM_ARCH_TIMER
select PINCTRL
select ARCH_BCM_MOBILE_SMP if SMP
select BCM_KONA_TIMER
help
This enables support for systems based on Broadcom mobile SoCs.
@ -143,6 +144,7 @@ config ARCH_BCM2835
select ARM_TIMER_SP804
select HAVE_ARM_ARCH_TIMER if ARCH_MULTI_V7
select CLKSRC_OF
select BCM2835_TIMER
select PINCTRL
select PINCTRL_BCM2835
help

View File

@ -20,7 +20,7 @@ if ARCH_INTEGRATOR
config ARCH_INTEGRATOR_AP
bool "Support Integrator/AP and Integrator/PP2 platforms"
select CLKSRC_MMIO
select INTEGRATOR_AP_TIMER
select MIGHT_HAVE_PCI
select SERIAL_AMBA_PL010 if TTY
select SERIAL_AMBA_PL010_CONSOLE if TTY

View File

@ -4,7 +4,7 @@ config ARCH_KEYSTONE
depends on ARM_PATCH_PHYS_VIRT
select ARM_GIC
select HAVE_ARM_ARCH_TIMER
select CLKSRC_MMIO
select KEYSTONE_TIMER
select ARM_ERRATA_798181 if SMP
select COMMON_CLK_KEYSTONE
select ARCH_SUPPORTS_BIG_ENDIAN

View File

@ -3,7 +3,7 @@ menuconfig ARCH_MOXART
depends on ARCH_MULTI_V4
select CPU_FA526
select ARM_DMA_MEM_BUFFERABLE
select CLKSRC_MMIO
select MOXART_TIMER
select GENERIC_IRQ_CHIP
select ARCH_REQUIRE_GPIOLIB
select PHYLIB if NETDEVICES

View File

@ -7,9 +7,15 @@ CFLAGS_pmsu.o := -march=armv7-a
obj-$(CONFIG_MACH_MVEBU_ANY) += system-controller.o mvebu-soc-id.o
ifeq ($(CONFIG_MACH_MVEBU_V7),y)
obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o pm.o pm-board.o
obj-y += cpu-reset.o board-v7.o coherency.o coherency_ll.o pmsu.o pmsu_ll.o
obj-$(CONFIG_PM) += pm.o pm-board.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o platsmp-a9.o headsmp-a9.o
endif
obj-$(CONFIG_MACH_DOVE) += dove.o
obj-$(CONFIG_MACH_KIRKWOOD) += kirkwood.o kirkwood-pm.o
ifeq ($(CONFIG_MACH_KIRKWOOD),y)
obj-y += kirkwood.o
obj-$(CONFIG_PM) += kirkwood-pm.o
endif

View File

@ -162,22 +162,16 @@ exit:
}
/*
* This ioremap hook is used on Armada 375/38x to ensure that PCIe
* memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
* is needed as a workaround for a deadlock issue between the PCIe
* interface and the cache controller.
* This ioremap hook is used on Armada 375/38x to ensure that all MMIO
* areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
* needed for the HW I/O coherency mechanism to work properly without
* deadlock.
*/
static void __iomem *
armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller)
armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
unsigned int mtype, void *caller)
{
struct resource pcie_mem;
mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
mtype = MT_UNCACHED;
mtype = MT_UNCACHED;
return __arm_ioremap_caller(phys_addr, size, mtype, caller);
}
@ -186,7 +180,8 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
struct device_node *cache_dn;
coherency_cpu_base = of_iomap(np, 0);
arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
arch_ioremap_caller = armada_wa_ioremap_caller;
pci_ioremap_set_mem_type(MT_UNCACHED);
/*
* We should switch the PL310 to I/O coherency mode only if

View File

@ -16,7 +16,7 @@ config ARCH_MXS
bool "Freescale MXS (i.MX23, i.MX28) support"
depends on ARCH_MULTI_V5
select ARCH_REQUIRE_GPIOLIB
select CLKSRC_MMIO
select MXS_TIMER
select PINCTRL
select SOC_BUS
select SOC_IMX23

View File

@ -7,5 +7,6 @@ config ARCH_NSPIRE
select ARM_AMBA
select ARM_VIC
select ARM_TIMER_SP804
select NSPIRE_TIMER
help
This enables support for systems using the TI-NSPIRE CPU

View File

@ -28,6 +28,7 @@ config ARCH_ATLAS7
default y
select ARM_GIC
select CPU_V7
select ATLAS7_TIMER
select HAVE_ARM_SCU if SMP
select HAVE_SMP
help
@ -38,6 +39,7 @@ config ARCH_PRIMA2
default y
select SIRF_IRQ
select ZONE_DMA
select PRIMA2_TIMER
help
Support for CSR SiRFSoC ARM Cortex A9 Platform

View File

@ -4,7 +4,7 @@ menuconfig ARCH_U300
select ARCH_REQUIRE_GPIOLIB
select ARM_AMBA
select ARM_VIC
select CLKSRC_MMIO
select U300_TIMER
select CPU_ARM926T
select HAVE_TCM
select PINCTRL

View File

@ -492,6 +492,14 @@
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
};
rktimer: rktimer@ff850000 {
compatible = "rockchip,rk3399-timer";
reg = <0x0 0xff850000 0x0 0x1000>;
interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&cru PCLK_TIMER0>, <&cru SCLK_TIMER00>;
clock-names = "pclk", "timer";
};
spdif: spdif@ff870000 {
compatible = "rockchip,rk3399-spdif";
reg = <0x0 0xff870000 0x0 0x1000>;

View File

@ -76,6 +76,36 @@
#define atomic_dec_return_release(v) atomic_sub_return_release(1, (v))
#define atomic_dec_return(v) atomic_sub_return(1, (v))
#define atomic_fetch_add_relaxed atomic_fetch_add_relaxed
#define atomic_fetch_add_acquire atomic_fetch_add_acquire
#define atomic_fetch_add_release atomic_fetch_add_release
#define atomic_fetch_add atomic_fetch_add
#define atomic_fetch_sub_relaxed atomic_fetch_sub_relaxed
#define atomic_fetch_sub_acquire atomic_fetch_sub_acquire
#define atomic_fetch_sub_release atomic_fetch_sub_release
#define atomic_fetch_sub atomic_fetch_sub
#define atomic_fetch_and_relaxed atomic_fetch_and_relaxed
#define atomic_fetch_and_acquire atomic_fetch_and_acquire
#define atomic_fetch_and_release atomic_fetch_and_release
#define atomic_fetch_and atomic_fetch_and
#define atomic_fetch_andnot_relaxed atomic_fetch_andnot_relaxed
#define atomic_fetch_andnot_acquire atomic_fetch_andnot_acquire
#define atomic_fetch_andnot_release atomic_fetch_andnot_release
#define atomic_fetch_andnot atomic_fetch_andnot
#define atomic_fetch_or_relaxed atomic_fetch_or_relaxed
#define atomic_fetch_or_acquire atomic_fetch_or_acquire
#define atomic_fetch_or_release atomic_fetch_or_release
#define atomic_fetch_or atomic_fetch_or
#define atomic_fetch_xor_relaxed atomic_fetch_xor_relaxed
#define atomic_fetch_xor_acquire atomic_fetch_xor_acquire
#define atomic_fetch_xor_release atomic_fetch_xor_release
#define atomic_fetch_xor atomic_fetch_xor
#define atomic_xchg_relaxed(v, new) xchg_relaxed(&((v)->counter), (new))
#define atomic_xchg_acquire(v, new) xchg_acquire(&((v)->counter), (new))
#define atomic_xchg_release(v, new) xchg_release(&((v)->counter), (new))
@ -125,6 +155,36 @@
#define atomic64_dec_return_release(v) atomic64_sub_return_release(1, (v))
#define atomic64_dec_return(v) atomic64_sub_return(1, (v))
#define atomic64_fetch_add_relaxed atomic64_fetch_add_relaxed
#define atomic64_fetch_add_acquire atomic64_fetch_add_acquire
#define atomic64_fetch_add_release atomic64_fetch_add_release
#define atomic64_fetch_add atomic64_fetch_add
#define atomic64_fetch_sub_relaxed atomic64_fetch_sub_relaxed
#define atomic64_fetch_sub_acquire atomic64_fetch_sub_acquire
#define atomic64_fetch_sub_release atomic64_fetch_sub_release
#define atomic64_fetch_sub atomic64_fetch_sub
#define atomic64_fetch_and_relaxed atomic64_fetch_and_relaxed
#define atomic64_fetch_and_acquire atomic64_fetch_and_acquire
#define atomic64_fetch_and_release atomic64_fetch_and_release
#define atomic64_fetch_and atomic64_fetch_and
#define atomic64_fetch_andnot_relaxed atomic64_fetch_andnot_relaxed
#define atomic64_fetch_andnot_acquire atomic64_fetch_andnot_acquire
#define atomic64_fetch_andnot_release atomic64_fetch_andnot_release
#define atomic64_fetch_andnot atomic64_fetch_andnot
#define atomic64_fetch_or_relaxed atomic64_fetch_or_relaxed
#define atomic64_fetch_or_acquire atomic64_fetch_or_acquire
#define atomic64_fetch_or_release atomic64_fetch_or_release
#define atomic64_fetch_or atomic64_fetch_or
#define atomic64_fetch_xor_relaxed atomic64_fetch_xor_relaxed
#define atomic64_fetch_xor_acquire atomic64_fetch_xor_acquire
#define atomic64_fetch_xor_release atomic64_fetch_xor_release
#define atomic64_fetch_xor atomic64_fetch_xor
#define atomic64_xchg_relaxed atomic_xchg_relaxed
#define atomic64_xchg_acquire atomic_xchg_acquire
#define atomic64_xchg_release atomic_xchg_release

View File

@ -77,26 +77,57 @@ __LL_SC_PREFIX(atomic_##op##_return##name(int i, atomic_t *v)) \
} \
__LL_SC_EXPORT(atomic_##op##_return##name);
#define ATOMIC_FETCH_OP(name, mb, acq, rel, cl, op, asm_op) \
__LL_SC_INLINE int \
__LL_SC_PREFIX(atomic_fetch_##op##name(int i, atomic_t *v)) \
{ \
unsigned long tmp; \
int val, result; \
\
asm volatile("// atomic_fetch_" #op #name "\n" \
" prfm pstl1strm, %3\n" \
"1: ld" #acq "xr %w0, %3\n" \
" " #asm_op " %w1, %w0, %w4\n" \
" st" #rel "xr %w2, %w1, %3\n" \
" cbnz %w2, 1b\n" \
" " #mb \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter) \
: "Ir" (i) \
: cl); \
\
return result; \
} \
__LL_SC_EXPORT(atomic_fetch_##op##name);
#define ATOMIC_OPS(...) \
ATOMIC_OP(__VA_ARGS__) \
ATOMIC_OP_RETURN( , dmb ish, , l, "memory", __VA_ARGS__)
#define ATOMIC_OPS_RLX(...) \
ATOMIC_OPS(__VA_ARGS__) \
ATOMIC_OP_RETURN( , dmb ish, , l, "memory", __VA_ARGS__)\
ATOMIC_OP_RETURN(_relaxed, , , , , __VA_ARGS__)\
ATOMIC_OP_RETURN(_acquire, , a, , "memory", __VA_ARGS__)\
ATOMIC_OP_RETURN(_release, , , l, "memory", __VA_ARGS__)
ATOMIC_OP_RETURN(_release, , , l, "memory", __VA_ARGS__)\
ATOMIC_FETCH_OP ( , dmb ish, , l, "memory", __VA_ARGS__)\
ATOMIC_FETCH_OP (_relaxed, , , , , __VA_ARGS__)\
ATOMIC_FETCH_OP (_acquire, , a, , "memory", __VA_ARGS__)\
ATOMIC_FETCH_OP (_release, , , l, "memory", __VA_ARGS__)
ATOMIC_OPS_RLX(add, add)
ATOMIC_OPS_RLX(sub, sub)
ATOMIC_OPS(add, add)
ATOMIC_OPS(sub, sub)
ATOMIC_OP(and, and)
ATOMIC_OP(andnot, bic)
ATOMIC_OP(or, orr)
ATOMIC_OP(xor, eor)
#undef ATOMIC_OPS_RLX
#undef ATOMIC_OPS
#define ATOMIC_OPS(...) \
ATOMIC_OP(__VA_ARGS__) \
ATOMIC_FETCH_OP ( , dmb ish, , l, "memory", __VA_ARGS__)\
ATOMIC_FETCH_OP (_relaxed, , , , , __VA_ARGS__)\
ATOMIC_FETCH_OP (_acquire, , a, , "memory", __VA_ARGS__)\
ATOMIC_FETCH_OP (_release, , , l, "memory", __VA_ARGS__)
ATOMIC_OPS(and, and)
ATOMIC_OPS(andnot, bic)
ATOMIC_OPS(or, orr)
ATOMIC_OPS(xor, eor)
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
@ -140,26 +171,57 @@ __LL_SC_PREFIX(atomic64_##op##_return##name(long i, atomic64_t *v)) \
} \
__LL_SC_EXPORT(atomic64_##op##_return##name);
#define ATOMIC64_FETCH_OP(name, mb, acq, rel, cl, op, asm_op) \
__LL_SC_INLINE long \
__LL_SC_PREFIX(atomic64_fetch_##op##name(long i, atomic64_t *v)) \
{ \
long result, val; \
unsigned long tmp; \
\
asm volatile("// atomic64_fetch_" #op #name "\n" \
" prfm pstl1strm, %3\n" \
"1: ld" #acq "xr %0, %3\n" \
" " #asm_op " %1, %0, %4\n" \
" st" #rel "xr %w2, %1, %3\n" \
" cbnz %w2, 1b\n" \
" " #mb \
: "=&r" (result), "=&r" (val), "=&r" (tmp), "+Q" (v->counter) \
: "Ir" (i) \
: cl); \
\
return result; \
} \
__LL_SC_EXPORT(atomic64_fetch_##op##name);
#define ATOMIC64_OPS(...) \
ATOMIC64_OP(__VA_ARGS__) \
ATOMIC64_OP_RETURN(, dmb ish, , l, "memory", __VA_ARGS__)
#define ATOMIC64_OPS_RLX(...) \
ATOMIC64_OPS(__VA_ARGS__) \
ATOMIC64_OP_RETURN(, dmb ish, , l, "memory", __VA_ARGS__) \
ATOMIC64_OP_RETURN(_relaxed,, , , , __VA_ARGS__) \
ATOMIC64_OP_RETURN(_acquire,, a, , "memory", __VA_ARGS__) \
ATOMIC64_OP_RETURN(_release,, , l, "memory", __VA_ARGS__)
ATOMIC64_OP_RETURN(_release,, , l, "memory", __VA_ARGS__) \
ATOMIC64_FETCH_OP (, dmb ish, , l, "memory", __VA_ARGS__) \
ATOMIC64_FETCH_OP (_relaxed,, , , , __VA_ARGS__) \
ATOMIC64_FETCH_OP (_acquire,, a, , "memory", __VA_ARGS__) \
ATOMIC64_FETCH_OP (_release,, , l, "memory", __VA_ARGS__)
ATOMIC64_OPS_RLX(add, add)
ATOMIC64_OPS_RLX(sub, sub)
ATOMIC64_OPS(add, add)
ATOMIC64_OPS(sub, sub)
ATOMIC64_OP(and, and)
ATOMIC64_OP(andnot, bic)
ATOMIC64_OP(or, orr)
ATOMIC64_OP(xor, eor)
#undef ATOMIC64_OPS_RLX
#undef ATOMIC64_OPS
#define ATOMIC64_OPS(...) \
ATOMIC64_OP(__VA_ARGS__) \
ATOMIC64_FETCH_OP (, dmb ish, , l, "memory", __VA_ARGS__) \
ATOMIC64_FETCH_OP (_relaxed,, , , , __VA_ARGS__) \
ATOMIC64_FETCH_OP (_acquire,, a, , "memory", __VA_ARGS__) \
ATOMIC64_FETCH_OP (_release,, , l, "memory", __VA_ARGS__)
ATOMIC64_OPS(and, and)
ATOMIC64_OPS(andnot, bic)
ATOMIC64_OPS(or, orr)
ATOMIC64_OPS(xor, eor)
#undef ATOMIC64_OPS
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_OP_RETURN
#undef ATOMIC64_OP

View File

@ -26,54 +26,57 @@
#endif
#define __LL_SC_ATOMIC(op) __LL_SC_CALL(atomic_##op)
static inline void atomic_andnot(int i, atomic_t *v)
{
register int w0 asm ("w0") = i;
register atomic_t *x1 asm ("x1") = v;
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(andnot),
" stclr %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
#define ATOMIC_OP(op, asm_op) \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
register int w0 asm ("w0") = i; \
register atomic_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(op), \
" " #asm_op " %w[i], %[v]\n") \
: [i] "+r" (w0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS); \
}
static inline void atomic_or(int i, atomic_t *v)
{
register int w0 asm ("w0") = i;
register atomic_t *x1 asm ("x1") = v;
ATOMIC_OP(andnot, stclr)
ATOMIC_OP(or, stset)
ATOMIC_OP(xor, steor)
ATOMIC_OP(add, stadd)
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(or),
" stset %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
#undef ATOMIC_OP
#define ATOMIC_FETCH_OP(name, mb, op, asm_op, cl...) \
static inline int atomic_fetch_##op##name(int i, atomic_t *v) \
{ \
register int w0 asm ("w0") = i; \
register atomic_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
__LL_SC_ATOMIC(fetch_##op##name), \
/* LSE atomics */ \
" " #asm_op #mb " %w[i], %w[i], %[v]") \
: [i] "+r" (w0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return w0; \
}
static inline void atomic_xor(int i, atomic_t *v)
{
register int w0 asm ("w0") = i;
register atomic_t *x1 asm ("x1") = v;
#define ATOMIC_FETCH_OPS(op, asm_op) \
ATOMIC_FETCH_OP(_relaxed, , op, asm_op) \
ATOMIC_FETCH_OP(_acquire, a, op, asm_op, "memory") \
ATOMIC_FETCH_OP(_release, l, op, asm_op, "memory") \
ATOMIC_FETCH_OP( , al, op, asm_op, "memory")
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(xor),
" steor %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
}
ATOMIC_FETCH_OPS(andnot, ldclr)
ATOMIC_FETCH_OPS(or, ldset)
ATOMIC_FETCH_OPS(xor, ldeor)
ATOMIC_FETCH_OPS(add, ldadd)
static inline void atomic_add(int i, atomic_t *v)
{
register int w0 asm ("w0") = i;
register atomic_t *x1 asm ("x1") = v;
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC(add),
" stadd %w[i], %[v]\n")
: [i] "+r" (w0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
}
#undef ATOMIC_FETCH_OP
#undef ATOMIC_FETCH_OPS
#define ATOMIC_OP_ADD_RETURN(name, mb, cl...) \
static inline int atomic_add_return##name(int i, atomic_t *v) \
@ -119,6 +122,33 @@ static inline void atomic_and(int i, atomic_t *v)
: __LL_SC_CLOBBERS);
}
#define ATOMIC_FETCH_OP_AND(name, mb, cl...) \
static inline int atomic_fetch_and##name(int i, atomic_t *v) \
{ \
register int w0 asm ("w0") = i; \
register atomic_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
" nop\n" \
__LL_SC_ATOMIC(fetch_and##name), \
/* LSE atomics */ \
" mvn %w[i], %w[i]\n" \
" ldclr" #mb " %w[i], %w[i], %[v]") \
: [i] "+r" (w0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return w0; \
}
ATOMIC_FETCH_OP_AND(_relaxed, )
ATOMIC_FETCH_OP_AND(_acquire, a, "memory")
ATOMIC_FETCH_OP_AND(_release, l, "memory")
ATOMIC_FETCH_OP_AND( , al, "memory")
#undef ATOMIC_FETCH_OP_AND
static inline void atomic_sub(int i, atomic_t *v)
{
register int w0 asm ("w0") = i;
@ -164,57 +194,87 @@ ATOMIC_OP_SUB_RETURN(_release, l, "memory")
ATOMIC_OP_SUB_RETURN( , al, "memory")
#undef ATOMIC_OP_SUB_RETURN
#define ATOMIC_FETCH_OP_SUB(name, mb, cl...) \
static inline int atomic_fetch_sub##name(int i, atomic_t *v) \
{ \
register int w0 asm ("w0") = i; \
register atomic_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
" nop\n" \
__LL_SC_ATOMIC(fetch_sub##name), \
/* LSE atomics */ \
" neg %w[i], %w[i]\n" \
" ldadd" #mb " %w[i], %w[i], %[v]") \
: [i] "+r" (w0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return w0; \
}
ATOMIC_FETCH_OP_SUB(_relaxed, )
ATOMIC_FETCH_OP_SUB(_acquire, a, "memory")
ATOMIC_FETCH_OP_SUB(_release, l, "memory")
ATOMIC_FETCH_OP_SUB( , al, "memory")
#undef ATOMIC_FETCH_OP_SUB
#undef __LL_SC_ATOMIC
#define __LL_SC_ATOMIC64(op) __LL_SC_CALL(atomic64_##op)
static inline void atomic64_andnot(long i, atomic64_t *v)
{
register long x0 asm ("x0") = i;
register atomic64_t *x1 asm ("x1") = v;
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(andnot),
" stclr %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
#define ATOMIC64_OP(op, asm_op) \
static inline void atomic64_##op(long i, atomic64_t *v) \
{ \
register long x0 asm ("x0") = i; \
register atomic64_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(op), \
" " #asm_op " %[i], %[v]\n") \
: [i] "+r" (x0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS); \
}
static inline void atomic64_or(long i, atomic64_t *v)
{
register long x0 asm ("x0") = i;
register atomic64_t *x1 asm ("x1") = v;
ATOMIC64_OP(andnot, stclr)
ATOMIC64_OP(or, stset)
ATOMIC64_OP(xor, steor)
ATOMIC64_OP(add, stadd)
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(or),
" stset %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
#undef ATOMIC64_OP
#define ATOMIC64_FETCH_OP(name, mb, op, asm_op, cl...) \
static inline long atomic64_fetch_##op##name(long i, atomic64_t *v) \
{ \
register long x0 asm ("x0") = i; \
register atomic64_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
__LL_SC_ATOMIC64(fetch_##op##name), \
/* LSE atomics */ \
" " #asm_op #mb " %[i], %[i], %[v]") \
: [i] "+r" (x0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return x0; \
}
static inline void atomic64_xor(long i, atomic64_t *v)
{
register long x0 asm ("x0") = i;
register atomic64_t *x1 asm ("x1") = v;
#define ATOMIC64_FETCH_OPS(op, asm_op) \
ATOMIC64_FETCH_OP(_relaxed, , op, asm_op) \
ATOMIC64_FETCH_OP(_acquire, a, op, asm_op, "memory") \
ATOMIC64_FETCH_OP(_release, l, op, asm_op, "memory") \
ATOMIC64_FETCH_OP( , al, op, asm_op, "memory")
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(xor),
" steor %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
}
ATOMIC64_FETCH_OPS(andnot, ldclr)
ATOMIC64_FETCH_OPS(or, ldset)
ATOMIC64_FETCH_OPS(xor, ldeor)
ATOMIC64_FETCH_OPS(add, ldadd)
static inline void atomic64_add(long i, atomic64_t *v)
{
register long x0 asm ("x0") = i;
register atomic64_t *x1 asm ("x1") = v;
asm volatile(ARM64_LSE_ATOMIC_INSN(__LL_SC_ATOMIC64(add),
" stadd %[i], %[v]\n")
: [i] "+r" (x0), [v] "+Q" (v->counter)
: "r" (x1)
: __LL_SC_CLOBBERS);
}
#undef ATOMIC64_FETCH_OP
#undef ATOMIC64_FETCH_OPS
#define ATOMIC64_OP_ADD_RETURN(name, mb, cl...) \
static inline long atomic64_add_return##name(long i, atomic64_t *v) \
@ -260,6 +320,33 @@ static inline void atomic64_and(long i, atomic64_t *v)
: __LL_SC_CLOBBERS);
}
#define ATOMIC64_FETCH_OP_AND(name, mb, cl...) \
static inline long atomic64_fetch_and##name(long i, atomic64_t *v) \
{ \
register long x0 asm ("w0") = i; \
register atomic64_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
" nop\n" \
__LL_SC_ATOMIC64(fetch_and##name), \
/* LSE atomics */ \
" mvn %[i], %[i]\n" \
" ldclr" #mb " %[i], %[i], %[v]") \
: [i] "+r" (x0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return x0; \
}
ATOMIC64_FETCH_OP_AND(_relaxed, )
ATOMIC64_FETCH_OP_AND(_acquire, a, "memory")
ATOMIC64_FETCH_OP_AND(_release, l, "memory")
ATOMIC64_FETCH_OP_AND( , al, "memory")
#undef ATOMIC64_FETCH_OP_AND
static inline void atomic64_sub(long i, atomic64_t *v)
{
register long x0 asm ("x0") = i;
@ -306,6 +393,33 @@ ATOMIC64_OP_SUB_RETURN( , al, "memory")
#undef ATOMIC64_OP_SUB_RETURN
#define ATOMIC64_FETCH_OP_SUB(name, mb, cl...) \
static inline long atomic64_fetch_sub##name(long i, atomic64_t *v) \
{ \
register long x0 asm ("w0") = i; \
register atomic64_t *x1 asm ("x1") = v; \
\
asm volatile(ARM64_LSE_ATOMIC_INSN( \
/* LL/SC */ \
" nop\n" \
__LL_SC_ATOMIC64(fetch_sub##name), \
/* LSE atomics */ \
" neg %[i], %[i]\n" \
" ldadd" #mb " %[i], %[i], %[v]") \
: [i] "+r" (x0), [v] "+Q" (v->counter) \
: "r" (x1) \
: __LL_SC_CLOBBERS, ##cl); \
\
return x0; \
}
ATOMIC64_FETCH_OP_SUB(_relaxed, )
ATOMIC64_FETCH_OP_SUB(_acquire, a, "memory")
ATOMIC64_FETCH_OP_SUB(_release, l, "memory")
ATOMIC64_FETCH_OP_SUB( , al, "memory")
#undef ATOMIC64_FETCH_OP_SUB
static inline long atomic64_dec_if_positive(atomic64_t *v)
{
register long x0 asm ("x0") = (long)v;

View File

@ -91,6 +91,19 @@ do { \
__u.__val; \
})
#define smp_cond_load_acquire(ptr, cond_expr) \
({ \
typeof(ptr) __PTR = (ptr); \
typeof(*ptr) VAL; \
for (;;) { \
VAL = smp_load_acquire(__PTR); \
if (cond_expr) \
break; \
__cmpwait_relaxed(__PTR, VAL); \
} \
VAL; \
})
#include <asm-generic/barrier.h>
#endif /* __ASSEMBLY__ */

View File

@ -224,4 +224,55 @@ __CMPXCHG_GEN(_mb)
__ret; \
})
#define __CMPWAIT_CASE(w, sz, name) \
static inline void __cmpwait_case_##name(volatile void *ptr, \
unsigned long val) \
{ \
unsigned long tmp; \
\
asm volatile( \
" ldxr" #sz "\t%" #w "[tmp], %[v]\n" \
" eor %" #w "[tmp], %" #w "[tmp], %" #w "[val]\n" \
" cbnz %" #w "[tmp], 1f\n" \
" wfe\n" \
"1:" \
: [tmp] "=&r" (tmp), [v] "+Q" (*(unsigned long *)ptr) \
: [val] "r" (val)); \
}
__CMPWAIT_CASE(w, b, 1);
__CMPWAIT_CASE(w, h, 2);
__CMPWAIT_CASE(w, , 4);
__CMPWAIT_CASE( , , 8);
#undef __CMPWAIT_CASE
#define __CMPWAIT_GEN(sfx) \
static inline void __cmpwait##sfx(volatile void *ptr, \
unsigned long val, \
int size) \
{ \
switch (size) { \
case 1: \
return __cmpwait_case##sfx##_1(ptr, (u8)val); \
case 2: \
return __cmpwait_case##sfx##_2(ptr, (u16)val); \
case 4: \
return __cmpwait_case##sfx##_4(ptr, val); \
case 8: \
return __cmpwait_case##sfx##_8(ptr, val); \
default: \
BUILD_BUG(); \
} \
\
unreachable(); \
}
__CMPWAIT_GEN()
#undef __CMPWAIT_GEN
#define __cmpwait_relaxed(ptr, val) \
__cmpwait((ptr), (unsigned long)(val), sizeof(*(ptr)))
#endif /* __ASM_CMPXCHG_H */

View File

@ -80,12 +80,14 @@
#define APM_CPU_PART_POTENZA 0x000
#define CAVIUM_CPU_PART_THUNDERX 0x0A1
#define CAVIUM_CPU_PART_THUNDERX_81XX 0x0A2
#define BRCM_CPU_PART_VULCAN 0x516
#define MIDR_CORTEX_A53 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
#define MIDR_CORTEX_A57 MIDR_CPU_MODEL(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
#define MIDR_THUNDERX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX)
#define MIDR_THUNDERX_81XX MIDR_CPU_MODEL(ARM_CPU_IMP_CAVIUM, CAVIUM_CPU_PART_THUNDERX_81XX)
#ifndef __ASSEMBLY__

View File

@ -23,10 +23,10 @@ int efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md);
efi_virtmap_load(); \
})
#define arch_efi_call_virt(f, args...) \
#define arch_efi_call_virt(p, f, args...) \
({ \
efi_##f##_t *__f; \
__f = efi.systab->runtime->f; \
__f = p->f; \
__f(args); \
})

View File

@ -117,6 +117,8 @@ struct pt_regs {
};
u64 orig_x0;
u64 syscallno;
u64 orig_addr_limit;
u64 unused; // maintain 16 byte alignment
};
#define arch_has_single_step() (1)

View File

@ -60,6 +60,7 @@ int main(void)
DEFINE(S_PC, offsetof(struct pt_regs, pc));
DEFINE(S_ORIG_X0, offsetof(struct pt_regs, orig_x0));
DEFINE(S_SYSCALLNO, offsetof(struct pt_regs, syscallno));
DEFINE(S_ORIG_ADDR_LIMIT, offsetof(struct pt_regs, orig_addr_limit));
DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs));
BLANK();
DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id.counter));

View File

@ -98,6 +98,12 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
MIDR_RANGE(MIDR_THUNDERX, 0x00,
(1 << MIDR_VARIANT_SHIFT) | 1),
},
{
/* Cavium ThunderX, T81 pass 1.0 */
.desc = "Cavium erratum 27456",
.capability = ARM64_WORKAROUND_CAVIUM_27456,
MIDR_RANGE(MIDR_THUNDERX_81XX, 0x00, 0x00),
},
#endif
{
}

View File

@ -28,6 +28,7 @@
#include <asm/errno.h>
#include <asm/esr.h>
#include <asm/irq.h>
#include <asm/memory.h>
#include <asm/thread_info.h>
#include <asm/unistd.h>
@ -97,7 +98,14 @@
mov x29, xzr // fp pointed to user-space
.else
add x21, sp, #S_FRAME_SIZE
.endif
get_thread_info tsk
/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
ldr x20, [tsk, #TI_ADDR_LIMIT]
str x20, [sp, #S_ORIG_ADDR_LIMIT]
mov x20, #TASK_SIZE_64
str x20, [tsk, #TI_ADDR_LIMIT]
ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
.endif /* \el == 0 */
mrs x22, elr_el1
mrs x23, spsr_el1
stp lr, x21, [sp, #S_LR]
@ -128,6 +136,14 @@
.endm
.macro kernel_exit, el
.if \el != 0
/* Restore the task's original addr_limit. */
ldr x20, [sp, #S_ORIG_ADDR_LIMIT]
str x20, [tsk, #TI_ADDR_LIMIT]
/* No need to restore UAO, it will be restored from SPSR_EL1 */
.endif
ldp x21, x22, [sp, #S_PC] // load ELR, SPSR
.if \el == 0
ct_user_enter
@ -406,7 +422,6 @@ el1_irq:
bl trace_hardirqs_off
#endif
get_thread_info tsk
irq_handler
#ifdef CONFIG_PREEMPT

View File

@ -280,7 +280,8 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
}
if (permission_fault(esr) && (addr < USER_DS)) {
if (get_fs() == KERNEL_DS)
/* regs->orig_addr_limit may be 0 if we entered from EL0 */
if (regs->orig_addr_limit == KERNEL_DS)
die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
if (!search_exception_tables(regs->pc))

View File

@ -41,21 +41,49 @@ static inline int __atomic_##op##_return(int i, atomic_t *v) \
return result; \
}
#define ATOMIC_FETCH_OP(op, asm_op, asm_con) \
static inline int __atomic_fetch_##op(int i, atomic_t *v) \
{ \
int result, val; \
\
asm volatile( \
"/* atomic_fetch_" #op " */\n" \
"1: ssrf 5\n" \
" ld.w %0, %3\n" \
" mov %1, %0\n" \
" " #asm_op " %1, %4\n" \
" stcond %2, %1\n" \
" brne 1b" \
: "=&r" (result), "=&r" (val), "=o" (v->counter) \
: "m" (v->counter), #asm_con (i) \
: "cc"); \
\
return result; \
}
ATOMIC_OP_RETURN(sub, sub, rKs21)
ATOMIC_OP_RETURN(add, add, r)
ATOMIC_FETCH_OP (sub, sub, rKs21)
ATOMIC_FETCH_OP (add, add, r)
#define ATOMIC_OP(op, asm_op) \
#define ATOMIC_OPS(op, asm_op) \
ATOMIC_OP_RETURN(op, asm_op, r) \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
(void)__atomic_##op##_return(i, v); \
} \
ATOMIC_FETCH_OP(op, asm_op, r) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
return __atomic_fetch_##op(i, v); \
}
ATOMIC_OP(and, and)
ATOMIC_OP(or, or)
ATOMIC_OP(xor, eor)
ATOMIC_OPS(and, and)
ATOMIC_OPS(or, or)
ATOMIC_OPS(xor, eor)
#undef ATOMIC_OP
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
/*
@ -87,6 +115,14 @@ static inline int atomic_add_return(int i, atomic_t *v)
return __atomic_add_return(i, v);
}
static inline int atomic_fetch_add(int i, atomic_t *v)
{
if (IS_21BIT_CONST(i))
return __atomic_fetch_sub(-i, v);
return __atomic_fetch_add(i, v);
}
/*
* atomic_sub_return - subtract the atomic variable
* @i: integer value to subtract
@ -102,6 +138,14 @@ static inline int atomic_sub_return(int i, atomic_t *v)
return __atomic_add_return(-i, v);
}
static inline int atomic_fetch_sub(int i, atomic_t *v)
{
if (IS_21BIT_CONST(i))
return __atomic_fetch_sub(i, v);
return __atomic_fetch_add(-i, v);
}
/*
* __atomic_add_unless - add unless the number is a given value
* @v: pointer of type atomic_t

View File

@ -17,6 +17,7 @@
asmlinkage int __raw_uncached_fetch_asm(const volatile int *ptr);
asmlinkage int __raw_atomic_add_asm(volatile int *ptr, int value);
asmlinkage int __raw_atomic_xadd_asm(volatile int *ptr, int value);
asmlinkage int __raw_atomic_and_asm(volatile int *ptr, int value);
asmlinkage int __raw_atomic_or_asm(volatile int *ptr, int value);
@ -28,10 +29,17 @@ asmlinkage int __raw_atomic_test_asm(const volatile int *ptr, int value);
#define atomic_add_return(i, v) __raw_atomic_add_asm(&(v)->counter, i)
#define atomic_sub_return(i, v) __raw_atomic_add_asm(&(v)->counter, -(i))
#define atomic_fetch_add(i, v) __raw_atomic_xadd_asm(&(v)->counter, i)
#define atomic_fetch_sub(i, v) __raw_atomic_xadd_asm(&(v)->counter, -(i))
#define atomic_or(i, v) (void)__raw_atomic_or_asm(&(v)->counter, i)
#define atomic_and(i, v) (void)__raw_atomic_and_asm(&(v)->counter, i)
#define atomic_xor(i, v) (void)__raw_atomic_xor_asm(&(v)->counter, i)
#define atomic_fetch_or(i, v) __raw_atomic_or_asm(&(v)->counter, i)
#define atomic_fetch_and(i, v) __raw_atomic_and_asm(&(v)->counter, i)
#define atomic_fetch_xor(i, v) __raw_atomic_xor_asm(&(v)->counter, i)
#endif
#include <asm-generic/atomic.h>

View File

@ -12,6 +12,8 @@
#else
#include <linux/atomic.h>
#include <asm/processor.h>
#include <asm/barrier.h>
asmlinkage int __raw_spin_is_locked_asm(volatile int *ptr);
asmlinkage void __raw_spin_lock_asm(volatile int *ptr);
@ -48,8 +50,7 @@ static inline void arch_spin_unlock(arch_spinlock_t *lock)
static inline void arch_spin_unlock_wait(arch_spinlock_t *lock)
{
while (arch_spin_is_locked(lock))
cpu_relax();
smp_cond_load_acquire(&lock->lock, !VAL);
}
static inline int arch_read_can_lock(arch_rwlock_t *rw)

View File

@ -84,6 +84,7 @@ EXPORT_SYMBOL(insl_16);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(__raw_atomic_add_asm);
EXPORT_SYMBOL(__raw_atomic_xadd_asm);
EXPORT_SYMBOL(__raw_atomic_and_asm);
EXPORT_SYMBOL(__raw_atomic_or_asm);
EXPORT_SYMBOL(__raw_atomic_xor_asm);

View File

@ -605,6 +605,28 @@ ENTRY(___raw_atomic_add_asm)
rts;
ENDPROC(___raw_atomic_add_asm)
/*
* r0 = ptr
* r1 = value
*
* ADD a signed value to a 32bit word and return the old value atomically.
* Clobbers: r3:0, p1:0
*/
ENTRY(___raw_atomic_xadd_asm)
p1 = r0;
r3 = r1;
[--sp] = rets;
call _get_core_lock;
r3 = [p1];
r2 = r3 + r2;
[p1] = r2;
r1 = p1;
call _put_core_lock;
r0 = r3;
rets = [sp++];
rts;
ENDPROC(___raw_atomic_add_asm)
/*
* r0 = ptr
* r1 = mask
@ -618,10 +640,9 @@ ENTRY(___raw_atomic_and_asm)
r3 = r1;
[--sp] = rets;
call _get_core_lock;
r2 = [p1];
r3 = r2 & r3;
[p1] = r3;
r3 = r2;
r3 = [p1];
r2 = r2 & r3;
[p1] = r2;
r1 = p1;
call _put_core_lock;
r0 = r3;
@ -642,10 +663,9 @@ ENTRY(___raw_atomic_or_asm)
r3 = r1;
[--sp] = rets;
call _get_core_lock;
r2 = [p1];
r3 = r2 | r3;
[p1] = r3;
r3 = r2;
r3 = [p1];
r2 = r2 | r3;
[p1] = r2;
r1 = p1;
call _put_core_lock;
r0 = r3;
@ -666,10 +686,9 @@ ENTRY(___raw_atomic_xor_asm)
r3 = r1;
[--sp] = rets;
call _get_core_lock;
r2 = [p1];
r3 = r2 ^ r3;
[p1] = r3;
r3 = r2;
r3 = [p1];
r2 = r2 ^ r3;
[p1] = r2;
r1 = p1;
call _put_core_lock;
r0 = r3;

View File

@ -60,16 +60,6 @@ static inline int atomic_add_negative(int i, atomic_t *v)
return atomic_add_return(i, v) < 0;
}
static inline void atomic_add(int i, atomic_t *v)
{
atomic_add_return(i, v);
}
static inline void atomic_sub(int i, atomic_t *v)
{
atomic_sub_return(i, v);
}
static inline void atomic_inc(atomic_t *v)
{
atomic_inc_return(v);
@ -136,16 +126,6 @@ static inline long long atomic64_add_negative(long long i, atomic64_t *v)
return atomic64_add_return(i, v) < 0;
}
static inline void atomic64_add(long long i, atomic64_t *v)
{
atomic64_add_return(i, v);
}
static inline void atomic64_sub(long long i, atomic64_t *v)
{
atomic64_sub_return(i, v);
}
static inline void atomic64_inc(atomic64_t *v)
{
atomic64_inc_return(v);
@ -182,11 +162,19 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u)
}
#define ATOMIC_OP(op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
return __atomic32_fetch_##op(i, &v->counter); \
} \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
(void)__atomic32_fetch_##op(i, &v->counter); \
} \
\
static inline long long atomic64_fetch_##op(long long i, atomic64_t *v) \
{ \
return __atomic64_fetch_##op(i, &v->counter); \
} \
static inline void atomic64_##op(long long i, atomic64_t *v) \
{ \
(void)__atomic64_fetch_##op(i, &v->counter); \
@ -195,6 +183,8 @@ static inline void atomic64_##op(long long i, atomic64_t *v) \
ATOMIC_OP(or)
ATOMIC_OP(and)
ATOMIC_OP(xor)
ATOMIC_OP(add)
ATOMIC_OP(sub)
#undef ATOMIC_OP

View File

@ -162,6 +162,8 @@ ATOMIC_EXPORT(__atomic64_fetch_##op);
ATOMIC_FETCH_OP(or)
ATOMIC_FETCH_OP(and)
ATOMIC_FETCH_OP(xor)
ATOMIC_FETCH_OP(add)
ATOMIC_FETCH_OP(sub)
ATOMIC_OP_RETURN(add)
ATOMIC_OP_RETURN(sub)

View File

@ -12,7 +12,3 @@
* the base baud is derived from the clock speed and so is variable
*/
#define BASE_BAUD 0
#define STD_COM_FLAGS UPF_BOOT_AUTOCONF
#define SERIAL_PORT_DFNS

View File

@ -28,6 +28,19 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return ret; \
}
#define ATOMIC_FETCH_OP(op, c_op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
h8300flags flags; \
int ret; \
\
flags = arch_local_irq_save(); \
ret = v->counter; \
v->counter c_op i; \
arch_local_irq_restore(flags); \
return ret; \
}
#define ATOMIC_OP(op, c_op) \
static inline void atomic_##op(int i, atomic_t *v) \
{ \
@ -41,17 +54,21 @@ static inline void atomic_##op(int i, atomic_t *v) \
ATOMIC_OP_RETURN(add, +=)
ATOMIC_OP_RETURN(sub, -=)
ATOMIC_OP(and, &=)
ATOMIC_OP(or, |=)
ATOMIC_OP(xor, ^=)
#define ATOMIC_OPS(op, c_op) \
ATOMIC_OP(op, c_op) \
ATOMIC_FETCH_OP(op, c_op)
ATOMIC_OPS(and, &=)
ATOMIC_OPS(or, |=)
ATOMIC_OPS(xor, ^=)
ATOMIC_OPS(add, +=)
ATOMIC_OPS(sub, -=)
#undef ATOMIC_OPS
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP
#define atomic_add(i, v) (void)atomic_add_return(i, v)
#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
#define atomic_sub(i, v) (void)atomic_sub_return(i, v)
#define atomic_sub_and_test(i, v) (atomic_sub_return(i, v) == 0)
#define atomic_inc_return(v) atomic_add_return(1, v)

View File

@ -110,7 +110,7 @@ static inline void atomic_##op(int i, atomic_t *v) \
); \
} \
#define ATOMIC_OP_RETURN(op) \
#define ATOMIC_OP_RETURN(op) \
static inline int atomic_##op##_return(int i, atomic_t *v) \
{ \
int output; \
@ -127,16 +127,37 @@ static inline int atomic_##op##_return(int i, atomic_t *v) \
return output; \
}
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op)
#define ATOMIC_FETCH_OP(op) \
static inline int atomic_fetch_##op(int i, atomic_t *v) \
{ \
int output, val; \
\
__asm__ __volatile__ ( \
"1: %0 = memw_locked(%2);\n" \
" %1 = "#op "(%0,%3);\n" \
" memw_locked(%2,P3)=%1;\n" \
" if !P3 jump 1b;\n" \
: "=&r" (output), "=&r" (val) \
: "r" (&v->counter), "r" (i) \
: "memory", "p3" \
); \
return output; \
}
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_OP_RETURN(op) ATOMIC_FETCH_OP(op)
ATOMIC_OPS(add)
ATOMIC_OPS(sub)
ATOMIC_OP(and)
ATOMIC_OP(or)
ATOMIC_OP(xor)
#undef ATOMIC_OPS
#define ATOMIC_OPS(op) ATOMIC_OP(op) ATOMIC_FETCH_OP(op)
ATOMIC_OPS(and)
ATOMIC_OPS(or)
ATOMIC_OPS(xor)
#undef ATOMIC_OPS
#undef ATOMIC_FETCH_OP
#undef ATOMIC_OP_RETURN
#undef ATOMIC_OP

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