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:
commit
df15929f8f
3
.mailmap
3
.mailmap
|
@ -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>
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
|
@ -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>;
|
||||
};
|
||||
};
|
|
@ -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 |
|
@ -64,3 +64,4 @@ Pressure sensors:
|
|||
- st,lps001wp-press
|
||||
- st,lps25h-press
|
||||
- st,lps331ap-press
|
||||
- st,lps22hb-press
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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";
|
||||
};
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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>;
|
||||
};
|
|
@ -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
|
|
@ -93,7 +93,7 @@ Example:
|
|||
phys = <&usb_phy0>;
|
||||
phy-names = "usb-phy";
|
||||
vbus-supply = <®_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 */
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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
|
||||
------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
30
MAINTAINERS
30
MAINTAINERS
|
@ -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
|
||||
|
|
4
Makefile
4
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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); \
|
||||
})
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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__
|
||||
|
||||
|
|
|
@ -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); \
|
||||
})
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
{
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue