ASoC: Updates for v4.6

The main thing in terms of the core this time around has been some
 additional framework work for dynamic topologies (though we *still*
 don't appear to have a stable ABI for the topology code, it's probably
 worth considering if this will ever happen...).  Otherwise the work has
 almost all been in the drivers:
 
  - HDMI support for Sky Lake, along with other fixes and enhancements
    for the Intel drivers.
  - Lots of improvements to the Renesas drivers.
  - Capture support for Qualcomm drivers.
  - Support for TI DaVinci DRA7xxx devices.
  - New machine drivers for Freescale systems with Cirrus CODECs,
    Mediatek systems with RT5650 CODECs.
  - New CPU drivers for Allwinner S/PDIF controllers
  - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJW5qP+AAoJECTWi3JdVIfQJhAH/RKv268gjE07uJ8jeGAT7uY4
 XM19VmUl7ZOlphctfr/I+1hRwo+mgGN4LSfKnXxsPk9Uq/WJUok4D7MjDN33jeX/
 heK9WAO8zXkgi9n2lhGI/z9uE76kPA/Qw0aEYcbmA6bDc4GF3AKphnByh6kDShtE
 BfblofsFaDywA09XQ2lh3wW0rZtJ51tQUeOi35UADyEPzQetzN+xiY85Bkia5BEt
 Yjp37nLJET8Gk0r9snE2MpACUkEyw7CiPXCjkK47npia41LVnTarZAq5+JmfKygg
 YV2EnC3AFYthhjZPfmO1usI2vJVwkN40nGrKipH2QX08TanK8r2qiTsmGADNX4E=
 =0/1R
 -----END PGP SIGNATURE-----

Merge tag 'asoc-v4.6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v4.6

The main thing in terms of the core this time around has been some
additional framework work for dynamic topologies (though we *still*
don't appear to have a stable ABI for the topology code, it's probably
worth considering if this will ever happen...).  Otherwise the work has
almost all been in the drivers:

 - HDMI support for Sky Lake, along with other fixes and enhancements
   for the Intel drivers.
 - Lots of improvements to the Renesas drivers.
 - Capture support for Qualcomm drivers.
 - Support for TI DaVinci DRA7xxx devices.
 - New machine drivers for Freescale systems with Cirrus CODECs,
   Mediatek systems with RT5650 CODECs.
 - New CPU drivers for Allwinner S/PDIF controllers
 - New CODEC drivers for Maxim MAX9867 and MAX98926 and Realtek RT5514.
This commit is contained in:
Takashi Iwai 2016-03-14 14:03:29 +01:00
commit ca80e26a59
294 changed files with 11817 additions and 3723 deletions

View File

@ -56,10 +56,6 @@
<entry><constant>MEDIA_ENT_F_CONN_COMPOSITE</constant></entry>
<entry>Connector for a RGB composite signal.</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_F_CONN_TEST</constant></entry>
<entry>Connector for a test generator.</entry>
</row>
<row>
<entry><constant>MEDIA_ENT_F_CAM_SENSOR</constant></entry>
<entry>Camera video sensor entity.</entry>

View File

@ -5,15 +5,18 @@ Index Device Endianness properties
---------------------------------------------------
1 BE 'big-endian'
2 LE 'little-endian'
3 Native 'native-endian'
For one device driver, which will run in different scenarios above
on different SoCs using the devicetree, we need one way to simplify
this.
Required properties:
- {big,little}-endian: these are boolean properties, if absent
meaning that the CPU and the Device are in the same endianness mode,
these properties are for register values and all the buffers only.
Optional properties:
- {big,little,native}-endian: these are boolean properties, if absent
then the implementation will choose a default based on the device
being controlled. These properties are for register values and all
the buffers only. Native endian means that the CPU and device have
the same endianness.
Examples:
Scenario 1 : CPU in LE mode & device in LE mode.

View File

@ -0,0 +1,24 @@
Analog Devices ADAU1361/ADAU1461/ADAU1761/ADAU1961/ADAU1381/ADAU1781
Required properties:
- compatible: Should contain one of the following:
"adi,adau1361"
"adi,adau1461"
"adi,adau1761"
"adi,adau1961"
"adi,adau1381"
"adi,adau1781"
- reg: The i2c address. Value depends on the state of ADDR0
and ADDR1, as wired in hardware.
Examples:
#include <dt-bindings/sound/adau17x1.h>
i2c_bus {
adau1361@38 {
compatible = "adi,adau1761";
reg = <0x38>;
};
};

View File

@ -24,6 +24,9 @@ The compatible list for this generic sound card currently:
"fsl,imx-audio-cs42888"
"fsl,imx-audio-cs427x"
(compatible with CS4271 and CS4272)
"fsl,imx-audio-wm8962"
(compatible with Documentation/devicetree/bindings/sound/imx-audio-wm8962.txt)
@ -63,6 +66,12 @@ Optional properties:
- audio-asrc : The phandle of ASRC. It can be absent if there's no
need to add ASRC support via DPCM.
Optional unless SSI is selected as a CPU DAI:
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
- mux-ext-port : The external port of the i.MX audio muxer
Example:
sound-cs42888 {
compatible = "fsl,imx-audio-cs42888";

View File

@ -0,0 +1,17 @@
max9867 codec
This device supports I2C mode only.
Required properties:
- compatible : "maxim,max9867"
- reg : The chip select number on the I2C bus
Example:
&i2c {
max9867: max9867@0x18 {
compatible = "maxim,max9867";
reg = <0x18>;
};
};

View File

@ -0,0 +1,32 @@
max98926 audio CODEC
This device supports I2C.
Required properties:
- compatible : "maxim,max98926"
- vmon-slot-no : slot number used to send voltage information
or in inteleave mode this will be used as
interleave slot.
- imon-slot-no : slot number used to send current information
- interleave-mode : When using two MAX98926 in a system it is
possible to create ADC data that that will
overflow the frame size. Digital Audio Interleave
mode provides a means to output VMON and IMON data
from two devices on a single DOUT line when running
smaller frames sizes such as 32 BCLKS per LRCLK or
48 BCLKS per LRCLK.
- reg : the I2C address of the device for I2C
Example:
codec: max98926@1a {
compatible = "maxim,max98926";
vmon-slot-no = <0>;
imon-slot-no = <2>;
reg = <0x1a>;
};

View File

@ -0,0 +1,15 @@
MT8173 with RT5650 RT5514 CODECS
Required properties:
- compatible : "mediatek,mt8173-rt5650-rt5514"
- mediatek,audio-codec: the phandles of rt5650 and rt5514 codecs
- mediatek,platform: the phandle of MT8173 ASoC platform
Example:
sound {
compatible = "mediatek,mt8173-rt5650-rt5514";
mediatek,audio-codec = <&rt5650 &rt5514>;
mediatek,platform = <&afe>;
};

View File

@ -0,0 +1,15 @@
MT8173 with RT5650 CODECS
Required properties:
- compatible : "mediatek,mt8173-rt5650"
- mediatek,audio-codec: the phandles of rt5650 codecs
- mediatek,platform: the phandle of MT8173 ASoC platform
Example:
sound {
compatible = "mediatek,mt8173-rt5650";
mediatek,audio-codec = <&rt5650>;
mediatek,platform = <&afe>;
};

View File

@ -1,6 +1,6 @@
Texas Instruments pcm179x DT bindings
This driver supports the SPI bus.
This driver supports both the I2C and SPI bus.
Required properties:
@ -9,6 +9,11 @@ Required properties:
For required properties on SPI, please consult
Documentation/devicetree/bindings/spi/spi-bus.txt
Required properties on I2C:
- reg: the I2C address
Examples:
codec_spi: 1792a@0 {
@ -16,3 +21,7 @@ Examples:
spi-max-frequency = <600000>;
};
codec_i2c: 1792a@4c {
compatible = "ti,pcm1792a";
reg = <0x4c>;
};

View File

@ -1,6 +1,337 @@
Renesas R-Car sound
=============================================
* Modules
=============================================
Renesas R-Car sound is constructed from below modules
(for Gen2 or later)
SCU : Sampling Rate Converter Unit
- SRC : Sampling Rate Converter
- CMD
- CTU : Channel Transfer Unit
- MIX : Mixer
- DVC : Digital Volume and Mute Function
SSIU : Serial Sound Interface Unit
SSI : Serial Sound Interface
See detail of each module's channels, connection, limitation on datasheet
=============================================
* Multi channel
=============================================
Multi channel is supported by Multi-SSI, or TDM-SSI.
Multi-SSI : 6ch case, you can use stereo x 3 SSI
TDM-SSI : 6ch case, you can use TDM
=============================================
* Enable/Disable each modules
=============================================
See datasheet to check SRC/CTU/MIX/DVC connect-limitation.
DT controls enabling/disabling module.
${LINUX}/arch/arm/boot/dts/r8a7790-lager.dts can be good example.
This is example of
Playback: [MEM] -> [SRC2] -> [DVC0] -> [SSIU0/SSI0] -> [codec]
Capture: [MEM] <- [DVC1] <- [SRC3] <- [SSIU1/SSI1] <- [codec]
&rcar_sound {
...
rcar_sound,dai {
dai0 {
playback = <&ssi0 &src2 &dvc0>;
capture = <&ssi1 &src3 &dvc1>;
};
};
};
You can use below.
${LINUX}/arch/arm/boot/dts/r8a7790.dts can be good example.
&src0 &ctu00 &mix0 &dvc0 &ssi0
&src1 &ctu01 &mix1 &dvc1 &ssi1
&src2 &ctu02 &ssi2
&src3 &ctu03 &ssi3
&src4 &ssi4
&src5 &ctu10 &ssi5
&src6 &ctu11 &ssi6
&src7 &ctu12 &ssi7
&src8 &ctu13 &ssi8
&src9 &ssi9
=============================================
* SRC (Sampling Rate Converter)
=============================================
[xx]Hz [yy]Hz
------> [SRC] ------>
SRC can convert [xx]Hz to [yy]Hz. Then, it has below 2 modes
Asynchronous mode: input data / output data are based on different clocks.
you can use this mode on Playback / Capture
Synchronous mode: input data / output data are based on same clocks.
This mode will be used if system doesn't have its input clock,
for example digital TV case.
you can use this mode on Playback
------------------
** Asynchronous mode
------------------
You need to use "renesas,rsrc-card" sound card for it.
example)
sound {
compatible = "renesas,rsrc-card";
...
/*
* SRC Asynchronous mode setting
* Playback:
* All input data will be converted to 48kHz
* Capture:
* Inputed 48kHz data will be converted to
* system specified Hz
*/
convert-rate = <48000>;
...
cpu {
sound-dai = <&rcar_sound>;
};
codec {
...
};
};
------------------
** Synchronous mode
------------------
> amixer set "SRC Out Rate" on
> aplay xxxx.wav
> amixer set "SRC Out Rate" 48000
> amixer set "SRC Out Rate" 44100
=============================================
* CTU (Channel Transfer Unit)
=============================================
[xx]ch [yy]ch
------> [CTU] -------->
CTU can convert [xx]ch to [yy]ch, or exchange outputed channel.
CTU conversion needs matrix settings.
For more detail information, see below
Renesas R-Car datasheet
- Sampling Rate Converter Unit (SCU)
- SCU Operation
- CMD Block
- Functional Blocks in CMD
Renesas R-Car datasheet
- Sampling Rate Converter Unit (SCU)
- Register Description
- CTUn Scale Value exx Register (CTUn_SVxxR)
${LINUX}/sound/soc/sh/rcar/ctu.c
- comment of header
You need to use "renesas,rsrc-card" sound card for it.
example)
sound {
compatible = "renesas,rsrc-card";
...
/*
* CTU setting
* All input data will be converted to 2ch
* as output data
*/
convert-channels = <2>;
...
cpu {
sound-dai = <&rcar_sound>;
};
codec {
...
};
};
Ex) Exchange output channel
Input -> Output
1ch -> 0ch
0ch -> 1ch
example of using matrix
output 0ch = (input 0ch x 0) + (input 1ch x 1)
output 1ch = (input 0ch x 1) + (input 1ch x 0)
amixer set "CTU Reset" on
amixer set "CTU Pass" 9,10
amixer set "CTU SV0" 0,4194304
amixer set "CTU SV1" 4194304,0
example of changing connection
amixer set "CTU Reset" on
amixer set "CTU Pass" 2,1
=============================================
* MIX (Mixer)
=============================================
MIX merges 2 sounds path. You can see 2 sound interface on system,
and these sounds will be merged by MIX.
aplay -D plughw:0,0 xxxx.wav &
aplay -D plughw:0,1 yyyy.wav
You need to use "renesas,rsrc-card" sound card for it.
Ex)
[MEM] -> [SRC1] -> [CTU02] -+-> [MIX0] -> [DVC0] -> [SSI0]
|
[MEM] -> [SRC2] -> [CTU03] -+
sound {
compatible = "renesas,rsrc-card";
...
cpu@0 {
sound-dai = <&rcar_sound 0>;
};
cpu@1 {
sound-dai = <&rcar_sound 1>;
};
codec {
...
};
};
&rcar_sound {
...
rcar_sound,dai {
dai0 {
playback = <&src1 &ctu02 &mix0 &dvc0 &ssi0>;
};
dai1 {
playback = <&src2 &ctu03 &mix0 &dvc0 &ssi0>;
};
};
};
=============================================
* DVC (Digital Volume and Mute Function)
=============================================
DVC controls Playback/Capture volume.
Playback Volume
amixer set "DVC Out" 100%
Capture Volume
amixer set "DVC In" 100%
Playback Mute
amixer set "DVC Out Mute" on
Capture Mute
amixer set "DVC In Mute" on
Volume Ramp
amixer set "DVC Out Ramp Up Rate" "0.125 dB/64 steps"
amixer set "DVC Out Ramp Down Rate" "0.125 dB/512 steps"
amixer set "DVC Out Ramp" on
aplay xxx.wav &
amixer set "DVC Out" 80% // Volume Down
amixer set "DVC Out" 100% // Volume Up
=============================================
* SSIU (Serial Sound Interface Unit)
=============================================
There is no DT settings for SSIU, because SSIU will be automatically
selected via SSI.
SSIU can avoid some under/over run error, because it has some buffer.
But you can't use it if SSI was PIO mode.
In DMA mode, you can select not to use SSIU by using "no-busif" on DT.
&ssi0 {
no-busif;
};
=============================================
* SSI (Serial Sound Interface)
=============================================
** PIO mode
You can use PIO mode which is for connection check by using.
Note: The system will drop non-SSI modules in PIO mode
even though if DT is selecting other modules.
&ssi0 {
pio-transfer
};
** DMA mode without SSIU
You can use DMA without SSIU.
Note: under/over run, or noise are likely to occur
&ssi0 {
no-busif;
};
** PIN sharing
Each SSI can share WS pin. It is based on platform.
This is example if SSI1 want to share WS pin with SSI0
&ssi1 {
shared-pin;
};
** Multi-SSI
You can use Multi-SSI.
This is example of SSI0/SSI1/SSI2 (= for 6ch)
&rcar_sound {
...
rcar_sound,dai {
dai0 {
playback = <&ssi0 &ssi1 &ssi2 &src0 &dvc0>;
};
};
};
** TDM-SSI
You can use TDM with SSI.
This is example of TDM 6ch.
Driver can automatically switches TDM <-> stereo mode in this case.
rsnd_tdm: sound {
compatible = "simple-audio-card";
...
simple-audio-card,cpu {
/* system can use TDM 6ch */
dai-tdm-slot-num = <6>;
sound-dai = <&rcar_sound>;
};
simple-audio-card,codec {
...
};
};
=============================================
Required properties:
=============================================
- compatible : "renesas,rcar_sound-<soctype>", fallbacks
"renesas,rcar_sound-gen1" if generation1, and
"renesas,rcar_sound-gen2" if generation2
@ -64,7 +395,10 @@ DAI subnode properties:
- playback : list of playback modules
- capture : list of capture modules
=============================================
Example:
=============================================
rcar_sound: sound@ec500000 {
#sound-dai-cells = <1>;
@ -250,7 +584,9 @@ rcar_sound: sound@ec500000 {
};
};
=============================================
Example: simple sound card
=============================================
rsnd_ak4643: sound {
compatible = "simple-audio-card";
@ -290,7 +626,9 @@ Example: simple sound card
shared-pin;
};
=============================================
Example: simple sound card for TDM
=============================================
rsnd_tdm: sound {
compatible = "simple-audio-card";
@ -309,7 +647,9 @@ Example: simple sound card for TDM
};
};
=============================================
Example: simple sound card for Multi channel
=============================================
&rcar_sound {
pinctrl-0 = <&sound_pins &sound_clk_pins>;

View File

@ -30,6 +30,7 @@ Optional subnode properties:
- frame-inversion : bool property. Add this if the
dai-link uses frame clock inversion.
- convert-rate : platform specified sampling rate convert
- convert-channels : platform specified converted channel size (2 - 8 ch)
- audio-prefix : see audio-routing
- audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink,

View File

@ -9,6 +9,7 @@ Required properties:
- "rockchip,rk3066-i2s": for rk3066
- "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
- "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288
- "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: should contain the I2S interrupt.

View File

@ -7,8 +7,12 @@ a fibre cable.
Required properties:
- compatible: should be one of the following:
- "rockchip,rk3288-spdif", "rockchip,rk3188-spdif" or
"rockchip,rk3066-spdif"
- "rockchip,rk3066-spdif"
- "rockchip,rk3188-spdif"
- "rockchip,rk3288-spdif"
- "rockchip,rk3366-spdif"
- "rockchip,rk3368-spdif"
- "rockchip,rk3399-spdif"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: should contain the SPDIF interrupt.

View File

@ -0,0 +1,25 @@
RT5514 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "realtek,rt5514".
- reg : The I2C address of the device.
Pins on the device (for linking into audio routes) for RT5514:
* DMIC1L
* DMIC1R
* DMIC2L
* DMIC2R
* AMICL
* AMICR
Example:
codec: rt5514@57 {
compatible = "realtek,rt5514";
reg = <0x57>;
};

View File

@ -8,6 +8,12 @@ Required properties:
- reg : The I2C address of the device.
Optional properties:
- clocks: The phandle of the master clock to the CODEC.
- clock-names: Should be "mclk".
Pins on the device (for linking into audio routes) for RT5616:
* IN1P

View File

@ -12,6 +12,9 @@ Required properties:
Optional properties:
- clocks: The phandle of the master clock to the CODEC
- clock-names: Should be "mclk"
- realtek,in1-differential
- realtek,in2-differential
- realtek,in3-differential

View File

@ -0,0 +1,39 @@
Allwinner Sony/Philips Digital Interface Format (S/PDIF) Controller
The Allwinner S/PDIF audio block is a transceiver that allows the
processor to receive and transmit digital audio via an coaxial cable or
a fibre cable.
For now only playback is supported.
Required properties:
- compatible : should be one of the following:
- "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
- reg : Offset and length of the register set for the device.
- interrupts : Contains the spdif interrupt.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt.
- dma-names : Two dmas have to be defined, "tx" and "rx".
- clocks : Contains an entry for each entry in clock-names.
- clock-names : Includes the following entries:
"apb" clock for the spdif bus.
"spdif" clock for spdif controller.
Example:
spdif: spdif@01c21000 {
compatible = "allwinner,sun4i-a10-spdif";
reg = <0x01c21000 0x40>;
interrupts = <13>;
clocks = <&apb0_gates 1>, <&spdif_clk>;
clock-names = "apb", "spdif";
dmas = <&dma 0 2>, <&dma 0 2>;
dma-names = "rx", "tx";
status = "okay";
};

View File

@ -0,0 +1,11 @@
Texas Intstruments ADS117x ADC
Required properties:
- compatible : "ti,ads1174" or "ti,ads1178"
Example:
ads1178 {
compatible = "ti,ads1178";
};

View File

@ -400,3 +400,7 @@ wm8350_wdt:
nowayout: Watchdog cannot be stopped once started
(default=kernel config parameter)
-------------------------------------------------
sun4v_wdt:
timeout_ms: Watchdog timeout in milliseconds 1..180000, default=60000)
nowayout: Watchdog cannot be stopped once started
-------------------------------------------------

View File

@ -4518,6 +4518,12 @@ L: linuxppc-dev@lists.ozlabs.org
S: Maintained
F: drivers/dma/fsldma.*
FREESCALE GPMI NAND DRIVER
M: Han Xu <han.xu@nxp.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/nand/gpmi-nand/*
FREESCALE I2C CPM DRIVER
M: Jochen Friedrich <jochen@scram.de>
L: linuxppc-dev@lists.ozlabs.org
@ -4534,7 +4540,7 @@ F: include/linux/platform_data/video-imxfb.h
F: drivers/video/fbdev/imxfb.c
FREESCALE QUAD SPI DRIVER
M: Han Xu <han.xu@freescale.com>
M: Han Xu <han.xu@nxp.com>
L: linux-mtd@lists.infradead.org
S: Maintained
F: drivers/mtd/spi-nor/fsl-quadspi.c

View File

@ -1,7 +1,7 @@
VERSION = 4
PATCHLEVEL = 5
SUBLEVEL = 0
EXTRAVERSION = -rc6
EXTRAVERSION = -rc7
NAME = Blurry Fish Butt
# *DOCUMENTATION*

View File

@ -195,5 +195,7 @@ CFLAGS_font.o := -Dstatic=
$(obj)/font.c: $(FONTC)
$(call cmd,shipped)
AFLAGS_hyp-stub.o := -Wa,-march=armv7-a
$(obj)/hyp-stub.S: $(srctree)/arch/$(SRCARCH)/kernel/hyp-stub.S
$(call cmd,shipped)

View File

@ -283,7 +283,6 @@
pinctrl-names = "default";
status = "okay";
renesas,enable-gpio = <&gpio5 31 GPIO_ACTIVE_HIGH>;
};
&usbphy {

View File

@ -88,6 +88,7 @@ obj-$(CONFIG_DEBUG_LL) += debug.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_ARM_VIRT_EXT) += hyp-stub.o
AFLAGS_hyp-stub.o :=-Wa,-march=armv7-a
ifeq ($(CONFIG_ARM_PSCI),y)
obj-$(CONFIG_SMP) += psci_smp.o
endif

View File

@ -161,7 +161,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
u64 val;
val = kvm_arm_timer_get_reg(vcpu, reg->id);
return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
}
static unsigned long num_core_regs(void)

View File

@ -49,6 +49,9 @@ static int change_memory_common(unsigned long addr, int numpages,
WARN_ON_ONCE(1);
}
if (!numpages)
return 0;
if (start < MODULES_VADDR || start >= MODULES_END)
return -EINVAL;

View File

@ -34,13 +34,13 @@
/*
* VMALLOC and SPARSEMEM_VMEMMAP ranges.
*
* VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
* VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
* (rounded up to PUD_SIZE).
* VMALLOC_START: beginning of the kernel VA space
* VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
* fixed mappings and modules
*/
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE)
#ifndef CONFIG_KASAN
#define VMALLOC_START (VA_START)
@ -51,7 +51,8 @@
#define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
#define VMEMMAP_START (VMALLOC_END + SZ_64K)
#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
#define FIRST_USER_ADDRESS 0UL

View File

@ -194,7 +194,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
u64 val;
val = kvm_arm_timer_get_reg(vcpu, reg->id);
return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
}
/**

View File

@ -319,8 +319,8 @@ void __init mem_init(void)
#endif
MLG(VMALLOC_START, VMALLOC_END),
#ifdef CONFIG_SPARSEMEM_VMEMMAP
MLG((unsigned long)vmemmap,
(unsigned long)vmemmap + VMEMMAP_SIZE),
MLG(VMEMMAP_START,
VMEMMAP_START + VMEMMAP_SIZE),
MLM((unsigned long)virt_to_page(PAGE_OFFSET),
(unsigned long)virt_to_page(high_memory)),
#endif

View File

@ -74,7 +74,7 @@
timer: timer@10000040 {
compatible = "syscon";
reg = <0x10000040 0x2c>;
little-endian;
native-endian;
};
reboot {

View File

@ -54,7 +54,7 @@
periph_cntl: syscon@10000000 {
compatible = "syscon";
reg = <0x10000000 0x14>;
little-endian;
native-endian;
};
reboot: syscon-reboot@10000008 {

View File

@ -98,7 +98,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7125-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
little-endian;
native-endian;
};
reboot {

View File

@ -118,7 +118,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7346-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -112,7 +112,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7358-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -112,7 +112,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7360-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -118,7 +118,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7362-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -99,7 +99,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7420-sun-top-ctrl", "syscon";
reg = <0x404000 0x60c>;
little-endian;
native-endian;
};
reboot {

View File

@ -100,7 +100,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -114,7 +114,7 @@
sun_top_ctrl: syscon@404000 {
compatible = "brcm,bcm7425-sun-top-ctrl", "syscon";
reg = <0x404000 0x51c>;
little-endian;
native-endian;
};
reboot {

View File

@ -270,7 +270,7 @@ uint32_t jz_gpio_port_get_value(int port, uint32_t mask)
}
EXPORT_SYMBOL(jz_gpio_port_get_value);
#define IRQ_TO_BIT(irq) BIT(irq_to_gpio(irq) & 0x1f)
#define IRQ_TO_BIT(irq) BIT((irq - JZ4740_IRQ_GPIO(0)) & 0x1f)
static void jz_gpio_check_trigger_both(struct jz_gpio_chip *chip, unsigned int irq)
{

View File

@ -125,7 +125,7 @@ LEAF(_restore_fp_context)
END(_restore_fp_context)
.set reorder
.type fault@function
.type fault, @function
.ent fault
fault: li v0, -EFAULT
jr ra

View File

@ -358,7 +358,7 @@ LEAF(_restore_msa_all_upper)
.set reorder
.type fault@function
.type fault, @function
.ent fault
fault: li v0, -EFAULT # failure
jr ra

View File

@ -690,15 +690,15 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
asmlinkage void do_ov(struct pt_regs *regs)
{
enum ctx_state prev_state;
siginfo_t info;
siginfo_t info = {
.si_signo = SIGFPE,
.si_code = FPE_INTOVF,
.si_addr = (void __user *)regs->cp0_epc,
};
prev_state = exception_enter();
die_if_kernel("Integer overflow", regs);
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
exception_exit(prev_state);
}
@ -874,7 +874,7 @@ out:
void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
const char *str)
{
siginfo_t info;
siginfo_t info = { 0 };
char b[40];
#ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
@ -903,7 +903,6 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
else
info.si_code = FPE_INTOVF;
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_addr = (void __user *) regs->cp0_epc;
force_sig_info(SIGFPE, &info, current);
break;

View File

@ -702,7 +702,7 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
void __user *uaddr = (void __user *)(long)reg->addr;
return copy_to_user(uaddr, vs, 16);
return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0;
} else {
return -EINVAL;
}
@ -732,7 +732,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
} else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
void __user *uaddr = (void __user *)(long)reg->addr;
return copy_from_user(vs, uaddr, 16);
return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0;
} else {
return -EINVAL;
}

View File

@ -164,11 +164,13 @@ static int __init mips_sc_probe_cm3(void)
sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
c->scache.sets = 64 << sets;
if (sets)
c->scache.sets = 64 << sets;
line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
c->scache.linesz = 2 << line_sz;
if (line_sz)
c->scache.linesz = 2 << line_sz;
assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
@ -176,9 +178,12 @@ static int __init mips_sc_probe_cm3(void)
c->scache.waysize = c->scache.sets * c->scache.linesz;
c->scache.waybit = __ffs(c->scache.waysize);
c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
if (c->scache.linesz) {
c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
return 1;
}
return 1;
return 0;
}
static inline int __init mips_sc_probe(void)

View File

@ -33,7 +33,7 @@
* floppy accesses go through the track buffer.
*/
#define _CROSS_64KB(a,s,vdma) \
(!vdma && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64))
#define CROSS_64KB(a,s) _CROSS_64KB(a,s,use_virtual_dma & 1)

View File

@ -361,8 +361,9 @@
#define __NR_membarrier (__NR_Linux + 343)
#define __NR_userfaultfd (__NR_Linux + 344)
#define __NR_mlock2 (__NR_Linux + 345)
#define __NR_copy_file_range (__NR_Linux + 346)
#define __NR_Linux_syscalls (__NR_mlock2 + 1)
#define __NR_Linux_syscalls (__NR_copy_file_range + 1)
#define __IGNORE_select /* newselect */

View File

@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret = 0;
/* Do the secure computing check first. */
secure_computing_strict(regs->gr[20]);
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs))
ret = -1L;
tracehook_report_syscall_entry(regs)) {
/*
* Tracing decided this syscall should not happen or the
* debugger stored an invalid system call number. Skip
* the system call and the system call restart handling.
*/
regs->gr[20] = -1UL;
goto out;
}
#ifdef CONFIG_64BIT
if (!is_compat_task())
@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_regs *regs)
regs->gr[24] & 0xffffffff,
regs->gr[23] & 0xffffffff);
return ret ? : regs->gr[20];
out:
return regs->gr[20];
}
void do_syscall_trace_exit(struct pt_regs *regs)

View File

@ -343,7 +343,7 @@ tracesys_next:
#endif
comiclr,>>= __NR_Linux_syscalls, %r20, %r0
b,n .Lsyscall_nosys
b,n .Ltracesys_nosys
LDREGX %r20(%r19), %r19
@ -359,6 +359,9 @@ tracesys_next:
be 0(%sr7,%r19)
ldo R%tracesys_exit(%r2),%r2
.Ltracesys_nosys:
ldo -ENOSYS(%r0),%r28 /* set errno */
/* Do *not* call this function on the gateway page, because it
makes a direct call to syscall_trace. */

View File

@ -441,6 +441,7 @@
ENTRY_SAME(membarrier)
ENTRY_SAME(userfaultfd)
ENTRY_SAME(mlock2) /* 345 */
ENTRY_SAME(copy_file_range)
.ifne (. - 90b) - (__NR_Linux_syscalls * (91b - 90b))

View File

@ -109,8 +109,9 @@ void arch_unregister_hw_breakpoint(struct perf_event *bp)
* If the breakpoint is unregistered between a hw_breakpoint_handler()
* and the single_step_dabr_instruction(), then cleanup the breakpoint
* restoration variables to prevent dangling pointers.
* FIXME, this should not be using bp->ctx at all! Sayeth peterz.
*/
if (bp->ctx && bp->ctx->task)
if (bp->ctx && bp->ctx->task && bp->ctx->task != ((void *)-1L))
bp->ctx->task->thread.last_hit_ubp = NULL;
}

View File

@ -8,6 +8,8 @@
#include <linux/mm.h>
#include <linux/hugetlb.h>
#include <asm/mmu.h>
#ifdef CONFIG_PPC_FSL_BOOK3E
#ifdef CONFIG_PPC64
static inline int tlb1_next(void)
@ -60,6 +62,14 @@ static inline void book3e_tlb_lock(void)
unsigned long tmp;
int token = smp_processor_id() + 1;
/*
* Besides being unnecessary in the absence of SMT, this
* check prevents trying to do lbarx/stbcx. on e5500 which
* doesn't implement either feature.
*/
if (!cpu_has_feature(CPU_FTR_SMT))
return;
asm volatile("1: lbarx %0, 0, %1;"
"cmpwi %0, 0;"
"bne 2f;"
@ -80,6 +90,9 @@ static inline void book3e_tlb_unlock(void)
{
struct paca_struct *paca = get_paca();
if (!cpu_has_feature(CPU_FTR_SMT))
return;
isync();
paca->tcd_ptr->lock = 0;
}

View File

@ -24,7 +24,13 @@ LDFLAGS := -m elf32_sparc
export BITS := 32
UTS_MACHINE := sparc
# We are adding -Wa,-Av8 to KBUILD_CFLAGS to deal with a specs bug in some
# versions of gcc. Some gcc versions won't pass -Av8 to binutils when you
# give -mcpu=v8. This silently worked with older bintutils versions but
# does not any more.
KBUILD_CFLAGS += -m32 -mcpu=v8 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
KBUILD_CFLAGS += -Wa,-Av8
KBUILD_AFLAGS += -m32 -Wa,-Av8
else

View File

@ -422,8 +422,9 @@
#define __NR_listen 354
#define __NR_setsockopt 355
#define __NR_mlock2 356
#define __NR_copy_file_range 357
#define NR_syscalls 357
#define NR_syscalls 358
/* Bitmask values returned from kern_features system call. */
#define KERN_FEATURE_MIXED_MODE_STACK 0x00000001

View File

@ -948,7 +948,24 @@ linux_syscall_trace:
cmp %o0, 0
bne 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ld [%sp + STACKFRAME_SZ + PT_G1], %g1
sethi %hi(sys_call_table), %l7
ld [%sp + STACKFRAME_SZ + PT_I0], %i0
or %l7, %lo(sys_call_table), %l7
ld [%sp + STACKFRAME_SZ + PT_I1], %i1
ld [%sp + STACKFRAME_SZ + PT_I2], %i2
ld [%sp + STACKFRAME_SZ + PT_I3], %i3
ld [%sp + STACKFRAME_SZ + PT_I4], %i4
ld [%sp + STACKFRAME_SZ + PT_I5], %i5
cmp %g1, NR_syscalls
bgeu 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
mov %i0, %o0
ld [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3

View File

@ -338,8 +338,9 @@ ENTRY(sun4v_mach_set_watchdog)
mov %o1, %o4
mov HV_FAST_MACH_SET_WATCHDOG, %o5
ta HV_FAST_TRAP
brnz,a,pn %o4, 0f
stx %o1, [%o4]
retl
0: retl
nop
ENDPROC(sun4v_mach_set_watchdog)

View File

@ -52,7 +52,7 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs)
unsigned char fenab;
int err;
flush_user_windows();
synchronize_user_stack();
if (get_thread_wsaved() ||
(((unsigned long)ucp) & (sizeof(unsigned long)-1)) ||
(!__access_ok(ucp, sizeof(*ucp))))

View File

@ -37,6 +37,7 @@ EXPORT_SYMBOL(sun4v_niagara_getperf);
EXPORT_SYMBOL(sun4v_niagara_setperf);
EXPORT_SYMBOL(sun4v_niagara2_getperf);
EXPORT_SYMBOL(sun4v_niagara2_setperf);
EXPORT_SYMBOL(sun4v_mach_set_watchdog);
/* from hweight.S */
EXPORT_SYMBOL(__arch_hweight8);

View File

@ -158,7 +158,25 @@ linux_syscall_trace32:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
sethi %hi(sys_call_table32), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
or %l7, %lo(sys_call_table32), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
cmp %g1, NR_syscalls
bgeu,pn %xcc, 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
srl %i0, 0, %o0
lduw [%l7 + %l4], %l7
srl %i4, 0, %o4
srl %i1, 0, %o1
srl %i2, 0, %o2
@ -170,7 +188,25 @@ linux_syscall_trace:
add %sp, PTREGS_OFF, %o0
brnz,pn %o0, 3f
mov -ENOSYS, %o0
/* Syscall tracing can modify the registers. */
ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1
sethi %hi(sys_call_table64), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0
or %l7, %lo(sys_call_table64), %l7
ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1
ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2
ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3
ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4
ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5
cmp %g1, NR_syscalls
bgeu,pn %xcc, 3f
mov -ENOSYS, %o0
sll %g1, 2, %l4
mov %i0, %o0
lduw [%l7 + %l4], %l7
mov %i1, %o1
mov %i2, %o2
mov %i3, %o3

View File

@ -88,4 +88,4 @@ sys_call_table:
/*340*/ .long sys_ni_syscall, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
/*345*/ .long sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
/*350*/ .long sys_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
/*355*/ .long sys_setsockopt, sys_mlock2
/*355*/ .long sys_setsockopt, sys_mlock2, sys_copy_file_range

View File

@ -89,7 +89,7 @@ sys_call_table32:
/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
.word sys32_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
/*350*/ .word sys32_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
.word compat_sys_setsockopt, sys_mlock2
.word compat_sys_setsockopt, sys_mlock2, sys_copy_file_range
#endif /* CONFIG_COMPAT */
@ -170,4 +170,4 @@ sys_call_table:
/*340*/ .word sys_kern_features, sys_kcmp, sys_finit_module, sys_sched_setattr, sys_sched_getattr
.word sys_renameat2, sys_seccomp, sys_getrandom, sys_memfd_create, sys_bpf
/*350*/ .word sys64_execveat, sys_membarrier, sys_userfaultfd, sys_bind, sys_listen
.word sys_setsockopt, sys_mlock2
.word sys_setsockopt, sys_mlock2, sys_copy_file_range

View File

@ -12,6 +12,7 @@
#include <skas.h>
void (*pm_power_off)(void);
EXPORT_SYMBOL(pm_power_off);
static void kill_off_processes(void)
{

View File

@ -69,7 +69,7 @@ void do_signal(struct pt_regs *regs)
struct ksignal ksig;
int handled_sig = 0;
if (get_signal(&ksig)) {
while (get_signal(&ksig)) {
handled_sig = 1;
/* Whee! Actually deliver the signal. */
handle_signal(&ksig, regs);

View File

@ -16,6 +16,7 @@
#include <asm/cacheflush.h>
#include <asm/realmode.h>
#include <linux/ftrace.h>
#include "../../realmode/rm/wakeup.h"
#include "sleep.h"
@ -107,7 +108,13 @@ int x86_acpi_suspend_lowlevel(void)
saved_magic = 0x123456789abcdef0L;
#endif /* CONFIG_64BIT */
/*
* Pause/unpause graph tracing around do_suspend_lowlevel as it has
* inconsistent call/return info after it jumps to the wakeup vector.
*/
pause_graph_tracing();
do_suspend_lowlevel();
unpause_graph_tracing();
return 0;
}

View File

@ -596,6 +596,8 @@ struct vcpu_vmx {
/* Support for PML */
#define PML_ENTITY_NUM 512
struct page *pml_pg;
u64 current_tsc_ratio;
};
enum segment_cache_field {
@ -2127,14 +2129,16 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
/* Setup TSC multiplier */
if (cpu_has_vmx_tsc_scaling())
vmcs_write64(TSC_MULTIPLIER,
vcpu->arch.tsc_scaling_ratio);
vmx->loaded_vmcs->cpu = cpu;
}
/* Setup TSC multiplier */
if (kvm_has_tsc_control &&
vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
}
vmx_vcpu_pi_load(vcpu, cpu);
}

View File

@ -2752,7 +2752,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
}
kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD;
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
@ -6619,12 +6618,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
* KVM_DEBUGREG_WONT_EXIT again.
*/
if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
int i;
WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
kvm_x86_ops->sync_dirty_debug_regs(vcpu);
for (i = 0; i < KVM_NR_DB_REGS; i++)
vcpu->arch.eff_db[i] = vcpu->arch.db[i];
kvm_update_dr0123(vcpu);
kvm_update_dr6(vcpu);
kvm_update_dr7(vcpu);
vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
}
/*

View File

@ -109,7 +109,7 @@ unsigned long os_get_top_address(void)
exit(1);
}
printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
printf("0x%lx\n", bottom << UM_KERN_PAGE_SHIFT);
printf("Locating the top of the address space ... ");
fflush(stdout);
@ -134,7 +134,7 @@ out:
exit(1);
}
top <<= UM_KERN_PAGE_SHIFT;
printf("0x%x\n", top);
printf("0x%lx\n", top);
return top;
}

View File

@ -57,6 +57,49 @@ static int __blk_rq_unmap_user(struct bio *bio)
return ret;
}
static int __blk_rq_map_user_iov(struct request *rq,
struct rq_map_data *map_data, struct iov_iter *iter,
gfp_t gfp_mask, bool copy)
{
struct request_queue *q = rq->q;
struct bio *bio, *orig_bio;
int ret;
if (copy)
bio = bio_copy_user_iov(q, map_data, iter, gfp_mask);
else
bio = bio_map_user_iov(q, iter, gfp_mask);
if (IS_ERR(bio))
return PTR_ERR(bio);
if (map_data && map_data->null_mapped)
bio_set_flag(bio, BIO_NULL_MAPPED);
iov_iter_advance(iter, bio->bi_iter.bi_size);
if (map_data)
map_data->offset += bio->bi_iter.bi_size;
orig_bio = bio;
blk_queue_bounce(q, &bio);
/*
* We link the bounce buffer in and could have to traverse it
* later so we have to get a ref to prevent it from being freed
*/
bio_get(bio);
ret = blk_rq_append_bio(q, rq, bio);
if (ret) {
bio_endio(bio);
__blk_rq_unmap_user(orig_bio);
bio_put(bio);
return ret;
}
return 0;
}
/**
* blk_rq_map_user_iov - map user data to a request, for REQ_TYPE_BLOCK_PC usage
* @q: request queue where request should be inserted
@ -82,10 +125,11 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
struct rq_map_data *map_data,
const struct iov_iter *iter, gfp_t gfp_mask)
{
struct bio *bio;
int unaligned = 0;
struct iov_iter i;
struct iovec iov, prv = {.iov_base = NULL, .iov_len = 0};
bool copy = (q->dma_pad_mask & iter->count) || map_data;
struct bio *bio = NULL;
struct iov_iter i;
int ret;
if (!iter || !iter->count)
return -EINVAL;
@ -101,42 +145,29 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
*/
if ((uaddr & queue_dma_alignment(q)) ||
iovec_gap_to_prv(q, &prv, &iov))
unaligned = 1;
copy = true;
prv.iov_base = iov.iov_base;
prv.iov_len = iov.iov_len;
}
if (unaligned || (q->dma_pad_mask & iter->count) || map_data)
bio = bio_copy_user_iov(q, map_data, iter, gfp_mask);
else
bio = bio_map_user_iov(q, iter, gfp_mask);
if (IS_ERR(bio))
return PTR_ERR(bio);
if (map_data && map_data->null_mapped)
bio_set_flag(bio, BIO_NULL_MAPPED);
if (bio->bi_iter.bi_size != iter->count) {
/*
* Grab an extra reference to this bio, as bio_unmap_user()
* expects to be able to drop it twice as it happens on the
* normal IO completion path
*/
bio_get(bio);
bio_endio(bio);
__blk_rq_unmap_user(bio);
return -EINVAL;
}
i = *iter;
do {
ret =__blk_rq_map_user_iov(rq, map_data, &i, gfp_mask, copy);
if (ret)
goto unmap_rq;
if (!bio)
bio = rq->bio;
} while (iov_iter_count(&i));
if (!bio_flagged(bio, BIO_USER_MAPPED))
rq->cmd_flags |= REQ_COPY_USER;
blk_queue_bounce(q, &bio);
bio_get(bio);
blk_rq_bio_prep(q, rq, bio);
return 0;
unmap_rq:
__blk_rq_unmap_user(bio);
rq->bio = NULL;
return -EINVAL;
}
EXPORT_SYMBOL(blk_rq_map_user_iov);

View File

@ -304,7 +304,6 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
struct bio *nxt)
{
struct bio_vec end_bv = { NULL }, nxt_bv;
struct bvec_iter iter;
if (!blk_queue_cluster(q))
return 0;
@ -316,11 +315,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
if (!bio_has_data(bio))
return 1;
bio_for_each_segment(end_bv, bio, iter)
if (end_bv.bv_len == iter.bi_size)
break;
nxt_bv = bio_iovec(nxt);
bio_get_last_bvec(bio, &end_bv);
bio_get_first_bvec(nxt, &nxt_bv);
if (!BIOVEC_PHYS_MERGEABLE(&end_bv, &nxt_bv))
return 0;

View File

@ -1590,14 +1590,21 @@ static int acpi_nfit_find_poison(struct acpi_nfit_desc *acpi_desc,
start = ndr_desc->res->start;
len = ndr_desc->res->end - ndr_desc->res->start + 1;
/*
* If ARS is unimplemented, unsupported, or if the 'Persistent Memory
* Scrub' flag in extended status is not set, skip this but continue
* initialization
*/
rc = ars_get_cap(nd_desc, ars_cap, start, len);
if (rc == -ENOTTY) {
dev_dbg(acpi_desc->dev,
"Address Range Scrub is not implemented, won't create an error list\n");
rc = 0;
goto out;
}
if (rc)
goto out;
/*
* If ARS is unsupported, or if the 'Persistent Memory Scrub' flag in
* extended status is not set, skip this but continue initialization
*/
if ((ars_cap->status & 0xffff) ||
!(ars_cap->status >> 16 & ND_ARS_PERSISTENT)) {
dev_warn(acpi_desc->dev,

View File

@ -367,15 +367,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
{ PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
{ PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
/* JMicron 360/1/3/5/6, match class to avoid IDE function */
{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@ -1325,6 +1331,44 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
{}
#endif
#ifdef CONFIG_ARM64
/*
* Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently.
* Workaround is to make sure all pending IRQs are served before leaving
* handler.
*/
static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
unsigned int rc = 0;
void __iomem *mmio;
u32 irq_stat, irq_masked;
unsigned int handled = 1;
VPRINTK("ENTER\n");
hpriv = host->private_data;
mmio = hpriv->mmio;
irq_stat = readl(mmio + HOST_IRQ_STAT);
if (!irq_stat)
return IRQ_NONE;
do {
irq_masked = irq_stat & hpriv->port_map;
spin_lock(&host->lock);
rc = ahci_handle_port_intr(host, irq_masked);
if (!rc)
handled = 0;
writel(irq_stat, mmio + HOST_IRQ_STAT);
irq_stat = readl(mmio + HOST_IRQ_STAT);
spin_unlock(&host->lock);
} while (irq_stat);
VPRINTK("EXIT\n");
return IRQ_RETVAL(handled);
}
#endif
/*
* ahci_init_msix() - optionally enable per-port MSI-X otherwise defer
* to single msi.
@ -1560,6 +1604,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (ahci_broken_devslp(pdev))
hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
#ifdef CONFIG_ARM64
if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
hpriv->irq_handler = ahci_thunderx_irq_handler;
#endif
/* save initial config */
ahci_pci_save_initial_config(pdev, hpriv);

View File

@ -240,8 +240,7 @@ enum {
error-handling stage) */
AHCI_HFLAG_NO_DEVSLP = (1 << 17), /* no device sleep */
AHCI_HFLAG_NO_FBS = (1 << 18), /* no FBS */
AHCI_HFLAG_EDGE_IRQ = (1 << 19), /* HOST_IRQ_STAT behaves as
Edge Triggered */
#ifdef CONFIG_PCI_MSI
AHCI_HFLAG_MULTI_MSI = (1 << 20), /* multiple PCI MSIs */
AHCI_HFLAG_MULTI_MSIX = (1 << 21), /* per-port MSI-X */
@ -361,6 +360,7 @@ struct ahci_host_priv {
* be overridden anytime before the host is activated.
*/
void (*start_engine)(struct ata_port *ap);
irqreturn_t (*irq_handler)(int irq, void *dev_instance);
};
#ifdef CONFIG_PCI_MSI
@ -424,6 +424,7 @@ int ahci_reset_em(struct ata_host *host);
void ahci_print_info(struct ata_host *host, const char *scc_s);
int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht);
void ahci_error_handler(struct ata_port *ap);
u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked);
static inline void __iomem *__ahci_port_base(struct ata_host *host,
unsigned int port_no)

View File

@ -548,6 +548,88 @@ softreset_retry:
return rc;
}
/**
* xgene_ahci_handle_broken_edge_irq - Handle the broken irq.
* @ata_host: Host that recieved the irq
* @irq_masked: HOST_IRQ_STAT value
*
* For hardware with broken edge trigger latch
* the HOST_IRQ_STAT register misses the edge interrupt
* when clearing of HOST_IRQ_STAT register and hardware
* reporting the PORT_IRQ_STAT register at the
* same clock cycle.
* As such, the algorithm below outlines the workaround.
*
* 1. Read HOST_IRQ_STAT register and save the state.
* 2. Clear the HOST_IRQ_STAT register.
* 3. Read back the HOST_IRQ_STAT register.
* 4. If HOST_IRQ_STAT register equals to zero, then
* traverse the rest of port's PORT_IRQ_STAT register
* to check if an interrupt is triggered at that point else
* go to step 6.
* 5. If PORT_IRQ_STAT register of rest ports is not equal to zero
* then update the state of HOST_IRQ_STAT saved in step 1.
* 6. Handle port interrupts.
* 7. Exit
*/
static int xgene_ahci_handle_broken_edge_irq(struct ata_host *host,
u32 irq_masked)
{
struct ahci_host_priv *hpriv = host->private_data;
void __iomem *port_mmio;
int i;
if (!readl(hpriv->mmio + HOST_IRQ_STAT)) {
for (i = 0; i < host->n_ports; i++) {
if (irq_masked & (1 << i))
continue;
port_mmio = ahci_port_base(host->ports[i]);
if (readl(port_mmio + PORT_IRQ_STAT))
irq_masked |= (1 << i);
}
}
return ahci_handle_port_intr(host, irq_masked);
}
static irqreturn_t xgene_ahci_irq_intr(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
unsigned int rc = 0;
void __iomem *mmio;
u32 irq_stat, irq_masked;
VPRINTK("ENTER\n");
hpriv = host->private_data;
mmio = hpriv->mmio;
/* sigh. 0xffffffff is a valid return from h/w */
irq_stat = readl(mmio + HOST_IRQ_STAT);
if (!irq_stat)
return IRQ_NONE;
irq_masked = irq_stat & hpriv->port_map;
spin_lock(&host->lock);
/*
* HOST_IRQ_STAT behaves as edge triggered latch meaning that
* it should be cleared before all the port events are cleared.
*/
writel(irq_stat, mmio + HOST_IRQ_STAT);
rc = xgene_ahci_handle_broken_edge_irq(host, irq_masked);
spin_unlock(&host->lock);
VPRINTK("EXIT\n");
return IRQ_RETVAL(rc);
}
static struct ata_port_operations xgene_ahci_v1_ops = {
.inherits = &ahci_ops,
.host_stop = xgene_ahci_host_stop,
@ -779,7 +861,8 @@ skip_clk_phy:
hpriv->flags = AHCI_HFLAG_NO_NCQ;
break;
case XGENE_AHCI_V2:
hpriv->flags |= AHCI_HFLAG_YES_FBS | AHCI_HFLAG_EDGE_IRQ;
hpriv->flags |= AHCI_HFLAG_YES_FBS;
hpriv->irq_handler = xgene_ahci_irq_intr;
break;
default:
break;

View File

@ -113,6 +113,7 @@ static ssize_t ahci_store_em_buffer(struct device *dev,
const char *buf, size_t size);
static ssize_t ahci_show_em_supported(struct device *dev,
struct device_attribute *attr, char *buf);
static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance);
static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
@ -512,6 +513,9 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
if (!hpriv->start_engine)
hpriv->start_engine = ahci_start_engine;
if (!hpriv->irq_handler)
hpriv->irq_handler = ahci_single_level_irq_intr;
}
EXPORT_SYMBOL_GPL(ahci_save_initial_config);
@ -1164,8 +1168,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
/* mark esata ports */
tmp = readl(port_mmio + PORT_CMD);
if ((tmp & PORT_CMD_HPCP) ||
((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)))
if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS))
ap->pflags |= ATA_PFLAG_EXTERNAL;
}
@ -1846,7 +1849,7 @@ static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
return IRQ_HANDLED;
}
static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
{
unsigned int i, handled = 0;
@ -1872,43 +1875,7 @@ static u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
return handled;
}
static irqreturn_t ahci_single_edge_irq_intr(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
struct ahci_host_priv *hpriv;
unsigned int rc = 0;
void __iomem *mmio;
u32 irq_stat, irq_masked;
VPRINTK("ENTER\n");
hpriv = host->private_data;
mmio = hpriv->mmio;
/* sigh. 0xffffffff is a valid return from h/w */
irq_stat = readl(mmio + HOST_IRQ_STAT);
if (!irq_stat)
return IRQ_NONE;
irq_masked = irq_stat & hpriv->port_map;
spin_lock(&host->lock);
/*
* HOST_IRQ_STAT behaves as edge triggered latch meaning that
* it should be cleared before all the port events are cleared.
*/
writel(irq_stat, mmio + HOST_IRQ_STAT);
rc = ahci_handle_port_intr(host, irq_masked);
spin_unlock(&host->lock);
VPRINTK("EXIT\n");
return IRQ_RETVAL(rc);
}
EXPORT_SYMBOL_GPL(ahci_handle_port_intr);
static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
{
@ -2535,14 +2502,18 @@ int ahci_host_activate(struct ata_host *host, struct scsi_host_template *sht)
int irq = hpriv->irq;
int rc;
if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX))
if (hpriv->flags & (AHCI_HFLAG_MULTI_MSI | AHCI_HFLAG_MULTI_MSIX)) {
if (hpriv->irq_handler)
dev_warn(host->dev, "both AHCI_HFLAG_MULTI_MSI flag set \
and custom irq handler implemented\n");
rc = ahci_host_activate_multi_irqs(host, sht);
else if (hpriv->flags & AHCI_HFLAG_EDGE_IRQ)
rc = ata_host_activate(host, irq, ahci_single_edge_irq_intr,
IRQF_SHARED, sht);
else
rc = ata_host_activate(host, irq, ahci_single_level_irq_intr,
} else {
rc = ata_host_activate(host, irq, hpriv->irq_handler,
IRQF_SHARED, sht);
}
return rc;
}
EXPORT_SYMBOL_GPL(ahci_host_activate);

View File

@ -675,19 +675,18 @@ static int ata_ioc32(struct ata_port *ap)
int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
int cmd, void __user *arg)
{
int val = -EINVAL, rc = -EINVAL;
unsigned long val;
int rc = -EINVAL;
unsigned long flags;
switch (cmd) {
case ATA_IOC_GET_IO32:
case HDIO_GET_32BIT:
spin_lock_irqsave(ap->lock, flags);
val = ata_ioc32(ap);
spin_unlock_irqrestore(ap->lock, flags);
if (copy_to_user(arg, &val, 1))
return -EFAULT;
return 0;
return put_user(val, (unsigned long __user *)arg);
case ATA_IOC_SET_IO32:
case HDIO_SET_32BIT:
val = (unsigned long) arg;
rc = 0;
spin_lock_irqsave(ap->lock, flags);

View File

@ -32,6 +32,8 @@
#include <linux/libata.h>
#include <scsi/scsi_host.h>
#include <asm/mach-rc32434/rb.h>
#define DRV_NAME "pata-rb532-cf"
#define DRV_VERSION "0.1.0"
#define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash"
@ -107,6 +109,7 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
int gpio;
struct resource *res;
struct ata_host *ah;
struct cf_device *pdata;
struct rb532_cf_info *info;
int ret;
@ -122,7 +125,13 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
return -ENOENT;
}
gpio = irq_to_gpio(irq);
pdata = dev_get_platdata(&pdev->dev);
if (!pdata) {
dev_err(&pdev->dev, "no platform data specified\n");
return -EINVAL;
}
gpio = pdata->gpio_pin;
if (gpio < 0) {
dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq);
return -ENOENT;

View File

@ -30,7 +30,7 @@ static int regcache_hw_init(struct regmap *map)
int i, j;
int ret;
int count;
unsigned int val;
unsigned int reg, val;
void *tmp_buf;
if (!map->num_reg_defaults_raw)
@ -67,27 +67,46 @@ static int regcache_hw_init(struct regmap *map)
ret = regmap_raw_read(map, 0, tmp_buf,
map->num_reg_defaults_raw);
map->cache_bypass = cache_bypass;
if (ret < 0)
goto err_cache_free;
map->reg_defaults_raw = tmp_buf;
map->cache_free = 1;
if (ret == 0) {
map->reg_defaults_raw = tmp_buf;
map->cache_free = 1;
} else {
kfree(tmp_buf);
}
}
/* fill the reg_defaults */
for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) {
if (regmap_volatile(map, i * map->reg_stride))
reg = i * map->reg_stride;
if (!regmap_readable(map, reg))
continue;
val = regcache_get_val(map, map->reg_defaults_raw, i);
map->reg_defaults[j].reg = i * map->reg_stride;
if (regmap_volatile(map, reg))
continue;
if (map->reg_defaults_raw) {
val = regcache_get_val(map, map->reg_defaults_raw, i);
} else {
bool cache_bypass = map->cache_bypass;
map->cache_bypass = true;
ret = regmap_read(map, reg, &val);
map->cache_bypass = cache_bypass;
if (ret != 0) {
dev_err(map->dev, "Failed to read %d: %d\n",
reg, ret);
goto err_free;
}
}
map->reg_defaults[j].reg = reg;
map->reg_defaults[j].def = val;
j++;
}
return 0;
err_cache_free:
kfree(tmp_buf);
err_free:
kfree(map->reg_defaults);

View File

@ -25,26 +25,14 @@
struct regmap_mmio_context {
void __iomem *regs;
unsigned reg_bytes;
unsigned val_bytes;
unsigned pad_bytes;
struct clk *clk;
};
static inline void regmap_mmio_regsize_check(size_t reg_size)
{
switch (reg_size) {
case 1:
case 2:
case 4:
#ifdef CONFIG_64BIT
case 8:
#endif
break;
default:
BUG();
}
}
void (*reg_write)(struct regmap_mmio_context *ctx,
unsigned int reg, unsigned int val);
unsigned int (*reg_read)(struct regmap_mmio_context *ctx,
unsigned int reg);
};
static int regmap_mmio_regbits_check(size_t reg_bits)
{
@ -88,72 +76,62 @@ static int regmap_mmio_get_min_stride(size_t val_bits)
return min_stride;
}
static inline void regmap_mmio_count_check(size_t count, u32 offset)
static void regmap_mmio_write8(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
BUG_ON(count <= offset);
writeb(val, ctx->regs + reg);
}
static inline unsigned int
regmap_mmio_get_offset(const void *reg, size_t reg_size)
static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
switch (reg_size) {
case 1:
return *(u8 *)reg;
case 2:
return *(u16 *)reg;
case 4:
return *(u32 *)reg;
writew(val, ctx->regs + reg);
}
static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
iowrite16be(val, ctx->regs + reg);
}
static void regmap_mmio_write32le(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writel(val, ctx->regs + reg);
}
static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
iowrite32be(val, ctx->regs + reg);
}
#ifdef CONFIG_64BIT
case 8:
return *(u64 *)reg;
#endif
default:
BUG();
}
static void regmap_mmio_write64le(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writeq(val, ctx->regs + reg);
}
#endif
static int regmap_mmio_gather_write(void *context,
const void *reg, size_t reg_size,
const void *val, size_t val_size)
static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
{
struct regmap_mmio_context *ctx = context;
unsigned int offset;
int ret;
regmap_mmio_regsize_check(reg_size);
if (!IS_ERR(ctx->clk)) {
ret = clk_enable(ctx->clk);
if (ret < 0)
return ret;
}
offset = regmap_mmio_get_offset(reg, reg_size);
while (val_size) {
switch (ctx->val_bytes) {
case 1:
writeb(*(u8 *)val, ctx->regs + offset);
break;
case 2:
writew(*(u16 *)val, ctx->regs + offset);
break;
case 4:
writel(*(u32 *)val, ctx->regs + offset);
break;
#ifdef CONFIG_64BIT
case 8:
writeq(*(u64 *)val, ctx->regs + offset);
break;
#endif
default:
/* Should be caught by regmap_mmio_check_config */
BUG();
}
val_size -= ctx->val_bytes;
val += ctx->val_bytes;
offset += ctx->val_bytes;
}
ctx->reg_write(ctx, reg, val);
if (!IS_ERR(ctx->clk))
clk_disable(ctx->clk);
@ -161,59 +139,56 @@ static int regmap_mmio_gather_write(void *context,
return 0;
}
static int regmap_mmio_write(void *context, const void *data, size_t count)
static unsigned int regmap_mmio_read8(struct regmap_mmio_context *ctx,
unsigned int reg)
{
struct regmap_mmio_context *ctx = context;
unsigned int offset = ctx->reg_bytes + ctx->pad_bytes;
regmap_mmio_count_check(count, offset);
return regmap_mmio_gather_write(context, data, ctx->reg_bytes,
data + offset, count - offset);
return readb(ctx->regs + reg);
}
static int regmap_mmio_read(void *context,
const void *reg, size_t reg_size,
void *val, size_t val_size)
static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readw(ctx->regs + reg);
}
static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return ioread16be(ctx->regs + reg);
}
static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readl(ctx->regs + reg);
}
static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return ioread32be(ctx->regs + reg);
}
#ifdef CONFIG_64BIT
static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readq(ctx->regs + reg);
}
#endif
static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
{
struct regmap_mmio_context *ctx = context;
unsigned int offset;
int ret;
regmap_mmio_regsize_check(reg_size);
if (!IS_ERR(ctx->clk)) {
ret = clk_enable(ctx->clk);
if (ret < 0)
return ret;
}
offset = regmap_mmio_get_offset(reg, reg_size);
while (val_size) {
switch (ctx->val_bytes) {
case 1:
*(u8 *)val = readb(ctx->regs + offset);
break;
case 2:
*(u16 *)val = readw(ctx->regs + offset);
break;
case 4:
*(u32 *)val = readl(ctx->regs + offset);
break;
#ifdef CONFIG_64BIT
case 8:
*(u64 *)val = readq(ctx->regs + offset);
break;
#endif
default:
/* Should be caught by regmap_mmio_check_config */
BUG();
}
val_size -= ctx->val_bytes;
val += ctx->val_bytes;
offset += ctx->val_bytes;
}
*val = ctx->reg_read(ctx, reg);
if (!IS_ERR(ctx->clk))
clk_disable(ctx->clk);
@ -232,14 +207,11 @@ static void regmap_mmio_free_context(void *context)
kfree(context);
}
static struct regmap_bus regmap_mmio = {
static const struct regmap_bus regmap_mmio = {
.fast_io = true,
.write = regmap_mmio_write,
.gather_write = regmap_mmio_gather_write,
.read = regmap_mmio_read,
.reg_write = regmap_mmio_write,
.reg_read = regmap_mmio_read,
.free_context = regmap_mmio_free_context,
.reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
.val_format_endian_default = REGMAP_ENDIAN_NATIVE,
};
static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
@ -265,24 +237,71 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
if (config->reg_stride < min_stride)
return ERR_PTR(-EINVAL);
switch (config->reg_format_endian) {
case REGMAP_ENDIAN_DEFAULT:
case REGMAP_ENDIAN_NATIVE:
break;
default:
return ERR_PTR(-EINVAL);
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return ERR_PTR(-ENOMEM);
ctx->regs = regs;
ctx->val_bytes = config->val_bits / 8;
ctx->reg_bytes = config->reg_bits / 8;
ctx->pad_bytes = config->pad_bits / 8;
ctx->clk = ERR_PTR(-ENODEV);
switch (config->reg_format_endian) {
case REGMAP_ENDIAN_DEFAULT:
case REGMAP_ENDIAN_LITTLE:
#ifdef __LITTLE_ENDIAN
case REGMAP_ENDIAN_NATIVE:
#endif
switch (config->val_bits) {
case 8:
ctx->reg_read = regmap_mmio_read8;
ctx->reg_write = regmap_mmio_write8;
break;
case 16:
ctx->reg_read = regmap_mmio_read16le;
ctx->reg_write = regmap_mmio_write16le;
break;
case 32:
ctx->reg_read = regmap_mmio_read32le;
ctx->reg_write = regmap_mmio_write32le;
break;
#ifdef CONFIG_64BIT
case 64:
ctx->reg_read = regmap_mmio_read64le;
ctx->reg_write = regmap_mmio_write64le;
break;
#endif
default:
ret = -EINVAL;
goto err_free;
}
break;
case REGMAP_ENDIAN_BIG:
#ifdef __BIG_ENDIAN
case REGMAP_ENDIAN_NATIVE:
#endif
switch (config->val_bits) {
case 8:
ctx->reg_read = regmap_mmio_read8;
ctx->reg_write = regmap_mmio_write8;
break;
case 16:
ctx->reg_read = regmap_mmio_read16be;
ctx->reg_write = regmap_mmio_write16be;
break;
case 32:
ctx->reg_read = regmap_mmio_read32be;
ctx->reg_write = regmap_mmio_write32be;
break;
default:
ret = -EINVAL;
goto err_free;
}
break;
default:
ret = -EINVAL;
goto err_free;
}
if (clk_id == NULL)
return ctx;

View File

@ -557,6 +557,8 @@ enum regmap_endian regmap_get_val_endian(struct device *dev,
endian = REGMAP_ENDIAN_BIG;
else if (of_property_read_bool(np, "little-endian"))
endian = REGMAP_ENDIAN_LITTLE;
else if (of_property_read_bool(np, "native-endian"))
endian = REGMAP_ENDIAN_NATIVE;
/* If the endianness was specified in DT, use that */
if (endian != REGMAP_ENDIAN_DEFAULT)
@ -1690,100 +1692,63 @@ int regmap_raw_write(struct regmap *map, unsigned int reg,
EXPORT_SYMBOL_GPL(regmap_raw_write);
/**
* regmap_field_write(): Write a value to a single register field
*
* @field: Register field to write to
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_field_write(struct regmap_field *field, unsigned int val)
{
return regmap_update_bits(field->regmap, field->reg,
field->mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_field_write);
/**
* regmap_field_update_bits(): Perform a read/modify/write cycle
* on the register field
* regmap_field_update_bits_base():
* Perform a read/modify/write cycle on the register field
* with change, async, force option
*
* @field: Register field to write to
* @mask: Bitmask to change
* @val: Value to be written
* @change: Boolean indicating if a write was done
* @async: Boolean indicating asynchronously
* @force: Boolean indicating use force update
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_field_update_bits(struct regmap_field *field, unsigned int mask, unsigned int val)
int regmap_field_update_bits_base(struct regmap_field *field,
unsigned int mask, unsigned int val,
bool *change, bool async, bool force)
{
mask = (mask << field->shift) & field->mask;
return regmap_update_bits(field->regmap, field->reg,
mask, val << field->shift);
return regmap_update_bits_base(field->regmap, field->reg,
mask, val << field->shift,
change, async, force);
}
EXPORT_SYMBOL_GPL(regmap_field_update_bits);
EXPORT_SYMBOL_GPL(regmap_field_update_bits_base);
/**
* regmap_fields_write(): Write a value to a single register field with port ID
*
* @field: Register field to write to
* @id: port ID
* @val: Value to be written
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_fields_write(struct regmap_field *field, unsigned int id,
unsigned int val)
{
if (id >= field->id_size)
return -EINVAL;
return regmap_update_bits(field->regmap,
field->reg + (field->id_offset * id),
field->mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_fields_write);
int regmap_fields_force_write(struct regmap_field *field, unsigned int id,
unsigned int val)
{
if (id >= field->id_size)
return -EINVAL;
return regmap_write_bits(field->regmap,
field->reg + (field->id_offset * id),
field->mask, val << field->shift);
}
EXPORT_SYMBOL_GPL(regmap_fields_force_write);
/**
* regmap_fields_update_bits(): Perform a read/modify/write cycle
* on the register field
* regmap_fields_update_bits_base():
* Perform a read/modify/write cycle on the register field
* with change, async, force option
*
* @field: Register field to write to
* @id: port ID
* @mask: Bitmask to change
* @val: Value to be written
* @change: Boolean indicating if a write was done
* @async: Boolean indicating asynchronously
* @force: Boolean indicating use force update
*
* A value of zero will be returned on success, a negative errno will
* be returned in error cases.
*/
int regmap_fields_update_bits(struct regmap_field *field, unsigned int id,
unsigned int mask, unsigned int val)
int regmap_fields_update_bits_base(struct regmap_field *field, unsigned int id,
unsigned int mask, unsigned int val,
bool *change, bool async, bool force)
{
if (id >= field->id_size)
return -EINVAL;
mask = (mask << field->shift) & field->mask;
return regmap_update_bits(field->regmap,
field->reg + (field->id_offset * id),
mask, val << field->shift);
return regmap_update_bits_base(field->regmap,
field->reg + (field->id_offset * id),
mask, val << field->shift,
change, async, force);
}
EXPORT_SYMBOL_GPL(regmap_fields_update_bits);
EXPORT_SYMBOL_GPL(regmap_fields_update_bits_base);
/*
* regmap_bulk_write(): Write multiple registers to the device
@ -2253,6 +2218,9 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val,
WARN_ON(!map->bus);
if (!map->bus || !map->bus->read)
return -EINVAL;
range = _regmap_range_lookup(map, reg);
if (range) {
ret = _regmap_select_page(map, &reg, range,
@ -2648,27 +2616,44 @@ static int _regmap_update_bits(struct regmap *map, unsigned int reg,
}
/**
* regmap_update_bits: Perform a read/modify/write cycle on the register map
* regmap_update_bits_base:
* Perform a read/modify/write cycle on the
* register map with change, async, force option
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
* @change: Boolean indicating if a write was done
* @async: Boolean indicating asynchronously
* @force: Boolean indicating use force update
*
* if async was true,
* With most buses the read must be done synchronously so this is most
* useful for devices with a cache which do not need to interact with
* the hardware to determine the current register value.
*
* Returns zero for success, a negative number on error.
*/
int regmap_update_bits(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val)
int regmap_update_bits_base(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val,
bool *change, bool async, bool force)
{
int ret;
map->lock(map->lock_arg);
ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
map->async = async;
ret = _regmap_update_bits(map, reg, mask, val, change, force);
map->async = false;
map->unlock(map->lock_arg);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_update_bits);
EXPORT_SYMBOL_GPL(regmap_update_bits_base);
/**
* regmap_write_bits: Perform a read/modify/write cycle on the register map
@ -2693,102 +2678,6 @@ int regmap_write_bits(struct regmap *map, unsigned int reg,
}
EXPORT_SYMBOL_GPL(regmap_write_bits);
/**
* regmap_update_bits_async: Perform a read/modify/write cycle on the register
* map asynchronously
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
*
* With most buses the read must be done synchronously so this is most
* useful for devices with a cache which do not need to interact with
* the hardware to determine the current register value.
*
* Returns zero for success, a negative number on error.
*/
int regmap_update_bits_async(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val)
{
int ret;
map->lock(map->lock_arg);
map->async = true;
ret = _regmap_update_bits(map, reg, mask, val, NULL, false);
map->async = false;
map->unlock(map->lock_arg);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_update_bits_async);
/**
* regmap_update_bits_check: Perform a read/modify/write cycle on the
* register map and report if updated
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
* @change: Boolean indicating if a write was done
*
* Returns zero for success, a negative number on error.
*/
int regmap_update_bits_check(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val,
bool *change)
{
int ret;
map->lock(map->lock_arg);
ret = _regmap_update_bits(map, reg, mask, val, change, false);
map->unlock(map->lock_arg);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_update_bits_check);
/**
* regmap_update_bits_check_async: Perform a read/modify/write cycle on the
* register map asynchronously and report if
* updated
*
* @map: Register map to update
* @reg: Register to update
* @mask: Bitmask to change
* @val: New value for bitmask
* @change: Boolean indicating if a write was done
*
* With most buses the read must be done synchronously so this is most
* useful for devices with a cache which do not need to interact with
* the hardware to determine the current register value.
*
* Returns zero for success, a negative number on error.
*/
int regmap_update_bits_check_async(struct regmap *map, unsigned int reg,
unsigned int mask, unsigned int val,
bool *change)
{
int ret;
map->lock(map->lock_arg);
map->async = true;
ret = _regmap_update_bits(map, reg, mask, val, change, false);
map->async = false;
map->unlock(map->lock_arg);
return ret;
}
EXPORT_SYMBOL_GPL(regmap_update_bits_check_async);
void regmap_async_complete_cb(struct regmap_async *async, int ret)
{
struct regmap *map = async->map;

View File

@ -296,6 +296,7 @@ endif
config QORIQ_CPUFREQ
tristate "CPU frequency scaling driver for Freescale QorIQ SoCs"
depends on OF && COMMON_CLK && (PPC_E500MC || ARM)
depends on !CPU_THERMAL || THERMAL
select CLK_QORIQ
help
This adds the CPUFreq driver support for Freescale QorIQ SoCs

View File

@ -84,10 +84,10 @@ config ARM_KIRKWOOD_CPUFREQ
SoCs.
config ARM_MT8173_CPUFREQ
bool "Mediatek MT8173 CPUFreq support"
tristate "Mediatek MT8173 CPUFreq support"
depends on ARCH_MEDIATEK && REGULATOR
depends on ARM64 || (ARM_CPU_TOPOLOGY && COMPILE_TEST)
depends on !CPU_THERMAL || THERMAL=y
depends on !CPU_THERMAL || THERMAL
select PM_OPP
help
This adds the CPUFreq driver support for Mediatek MT8173 SoC.

View File

@ -17,6 +17,7 @@
#include <linux/cpu_cooling.h>
#include <linux/cpufreq.h>
#include <linux/cpumask.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>

View File

@ -583,6 +583,8 @@ static void set_updater_desc(struct pxad_desc_sw *sw_desc,
(PXA_DCMD_LENGTH & sizeof(u32));
if (flags & DMA_PREP_INTERRUPT)
updater->dcmd |= PXA_DCMD_ENDIRQEN;
if (sw_desc->cyclic)
sw_desc->hw_desc[sw_desc->nb_desc - 2]->ddadr = sw_desc->first;
}
static bool is_desc_completed(struct virt_dma_desc *vd)
@ -673,6 +675,10 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id)
dev_dbg(&chan->vc.chan.dev->device,
"%s(): checking txd %p[%x]: completed=%d\n",
__func__, vd, vd->tx.cookie, is_desc_completed(vd));
if (to_pxad_sw_desc(vd)->cyclic) {
vchan_cyclic_callback(vd);
break;
}
if (is_desc_completed(vd)) {
list_del(&vd->node);
vchan_cookie_complete(vd);
@ -1080,7 +1086,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dchan,
return NULL;
pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr);
dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH | period_len);
dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len);
dev_dbg(&chan->vc.chan.dev->device,
"%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n",
__func__, (unsigned long)buf_addr, len, period_len, dir, flags);

View File

@ -196,6 +196,44 @@ static int gpio_rcar_irq_set_wake(struct irq_data *d, unsigned int on)
return 0;
}
static void gpio_rcar_irq_bus_lock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
pm_runtime_get_sync(&p->pdev->dev);
}
static void gpio_rcar_irq_bus_sync_unlock(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
pm_runtime_put(&p->pdev->dev);
}
static int gpio_rcar_irq_request_resources(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
int error;
error = pm_runtime_get_sync(&p->pdev->dev);
if (error < 0)
return error;
return 0;
}
static void gpio_rcar_irq_release_resources(struct irq_data *d)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct gpio_rcar_priv *p = gpiochip_get_data(gc);
pm_runtime_put(&p->pdev->dev);
}
static irqreturn_t gpio_rcar_irq_handler(int irq, void *dev_id)
{
struct gpio_rcar_priv *p = dev_id;
@ -450,6 +488,10 @@ static int gpio_rcar_probe(struct platform_device *pdev)
irq_chip->irq_unmask = gpio_rcar_irq_enable;
irq_chip->irq_set_type = gpio_rcar_irq_set_type;
irq_chip->irq_set_wake = gpio_rcar_irq_set_wake;
irq_chip->irq_bus_lock = gpio_rcar_irq_bus_lock;
irq_chip->irq_bus_sync_unlock = gpio_rcar_irq_bus_sync_unlock;
irq_chip->irq_request_resources = gpio_rcar_irq_request_resources;
irq_chip->irq_release_resources = gpio_rcar_irq_release_resources;
irq_chip->flags = IRQCHIP_SET_TYPE_MASKED | IRQCHIP_MASK_ON_SUSPEND;
ret = gpiochip_add_data(gpio_chip, p);

View File

@ -77,7 +77,7 @@ void amdgpu_connector_hotplug(struct drm_connector *connector)
} else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
/* Don't try to start link training before we
* have the dpcd */
if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
return;
/* set it to OFF so that drm_helper_connector_dpms()

View File

@ -649,9 +649,6 @@ force:
/* update display watermarks based on new power state */
amdgpu_display_bandwidth_update(adev);
adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
/* wait for the rings to drain */
for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
struct amdgpu_ring *ring = adev->rings[i];
@ -670,6 +667,9 @@ force:
/* update displays */
amdgpu_dpm_display_configuration_changed(adev);
adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
if (adev->pm.funcs->force_performance_level) {
if (adev->pm.dpm.thermal_active) {
enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;

View File

@ -143,8 +143,10 @@ static int amdgpu_pp_late_init(void *handle)
adev->powerplay.pp_handle);
#ifdef CONFIG_DRM_AMD_POWERPLAY
if (adev->pp_enabled)
if (adev->pp_enabled) {
amdgpu_pm_sysfs_init(adev);
amdgpu_dpm_dispatch_task(adev, AMD_PP_EVENT_COMPLETE_INIT, NULL, NULL);
}
#endif
return ret;
}

View File

@ -2202,8 +2202,7 @@ static void cz_dpm_powergate_vce(struct amdgpu_device *adev, bool gate)
AMD_PG_STATE_GATE);
cz_enable_vce_dpm(adev, false);
/* TODO: to figure out why vce can't be poweroff. */
/* cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerOFF); */
cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerOFF);
pi->vce_power_gated = true;
} else {
cz_send_msg_to_smc(adev, PPSMC_MSG_VCEPowerON);
@ -2226,10 +2225,8 @@ static void cz_dpm_powergate_vce(struct amdgpu_device *adev, bool gate)
}
} else { /*pi->caps_vce_pg*/
cz_update_vce_dpm(adev);
cz_enable_vce_dpm(adev, true);
cz_enable_vce_dpm(adev, !gate);
}
return;
}
const struct amd_ip_funcs cz_dpm_ip_funcs = {

View File

@ -3628,6 +3628,19 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
unsigned vm_id, uint64_t pd_addr)
{
int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX);
uint32_t seq = ring->fence_drv.sync_seq;
uint64_t addr = ring->fence_drv.gpu_addr;
amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
WAIT_REG_MEM_FUNCTION(3) | /* equal */
WAIT_REG_MEM_ENGINE(usepfp))); /* pfp or me */
amdgpu_ring_write(ring, addr & 0xfffffffc);
amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
amdgpu_ring_write(ring, seq);
amdgpu_ring_write(ring, 0xffffffff);
amdgpu_ring_write(ring, 4); /* poll interval */
if (usepfp) {
/* synce CE with ME to prevent CE fetch CEIB before context switch done */
amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));

View File

@ -4809,7 +4809,8 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
WAIT_REG_MEM_FUNCTION(3))); /* equal */
WAIT_REG_MEM_FUNCTION(3) | /* equal */
WAIT_REG_MEM_ENGINE(usepfp))); /* pfp or me */
amdgpu_ring_write(ring, addr & 0xfffffffc);
amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
amdgpu_ring_write(ring, seq);

View File

@ -402,8 +402,11 @@ int pp_dpm_dispatch_tasks(void *handle, enum amd_pp_event event_id, void *input,
data.requested_ui_label = power_state_convert(ps);
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
}
break;
case AMD_PP_EVENT_COMPLETE_INIT:
ret = pem_handle_event(pp_handle->eventmgr, event_id, &data);
break;
default:
break;
}

View File

@ -165,6 +165,7 @@ const struct action_chain resume_action_chain = {
};
static const pem_event_action *complete_init_event[] = {
unblock_adjust_power_state_tasks,
adjust_power_state_tasks,
enable_gfx_clock_gating_tasks,
enable_gfx_voltage_island_power_gating_tasks,

View File

@ -226,7 +226,7 @@ int cz_dpm_powergate_vce(struct pp_hwmgr *hwmgr, bool bgate)
}
} else {
cz_dpm_update_vce_dpm(hwmgr);
cz_enable_disable_vce_dpm(hwmgr, true);
cz_enable_disable_vce_dpm(hwmgr, !bgate);
return 0;
}

View File

@ -227,7 +227,7 @@ static int ast_get_dram_info(struct drm_device *dev)
} while (ast_read32(ast, 0x10000) != 0x01);
data = ast_read32(ast, 0x10004);
if (data & 0x400)
if (data & 0x40)
ast->dram_bus_width = 16;
else
ast->dram_bus_width = 32;

View File

@ -2303,15 +2303,15 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
*/
void intel_power_domains_suspend(struct drm_i915_private *dev_priv)
{
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
skl_display_core_uninit(dev_priv);
/*
* Even if power well support was disabled we still want to disable
* power wells while we are system suspended.
*/
if (!i915.disable_power_well)
intel_display_power_put(dev_priv, POWER_DOMAIN_INIT);
if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
skl_display_core_uninit(dev_priv);
}
/**
@ -2349,22 +2349,20 @@ bool intel_runtime_pm_get_if_in_use(struct drm_i915_private *dev_priv)
{
struct drm_device *dev = dev_priv->dev;
struct device *device = &dev->pdev->dev;
int ret;
if (!IS_ENABLED(CONFIG_PM))
return true;
if (IS_ENABLED(CONFIG_PM)) {
int ret = pm_runtime_get_if_in_use(device);
ret = pm_runtime_get_if_in_use(device);
/*
* In cases runtime PM is disabled by the RPM core and we get an
* -EINVAL return value we are not supposed to call this function,
* since the power state is undefined. This applies atm to the
* late/early system suspend/resume handlers.
*/
WARN_ON_ONCE(ret < 0);
if (ret <= 0)
return false;
/*
* In cases runtime PM is disabled by the RPM core and we get
* an -EINVAL return value we are not supposed to call this
* function, since the power state is undefined. This applies
* atm to the late/early system suspend/resume handlers.
*/
WARN_ON_ONCE(ret < 0);
if (ret <= 0)
return false;
}
atomic_inc(&dev_priv->pm.wakeref_count);
assert_rpm_wakelock_held(dev_priv);

View File

@ -1080,10 +1080,6 @@ force:
/* update display watermarks based on new power state */
radeon_bandwidth_update(rdev);
rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
rdev->pm.dpm.single_display = single_display;
/* wait for the rings to drain */
for (i = 0; i < RADEON_NUM_RINGS; i++) {
struct radeon_ring *ring = &rdev->ring[i];
@ -1102,6 +1098,10 @@ force:
/* update displays */
radeon_dpm_display_configuration_changed(rdev);
rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
rdev->pm.dpm.single_display = single_display;
if (rdev->asic->dpm.force_performance_level) {
if (rdev->pm.dpm.thermal_active) {
enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;

View File

@ -18,6 +18,7 @@
#include <linux/host1x.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include "bus.h"
#include "dev.h"
@ -394,6 +395,7 @@ static int host1x_device_add(struct host1x *host1x,
device->dev.coherent_dma_mask = host1x->dev->coherent_dma_mask;
device->dev.dma_mask = &device->dev.coherent_dma_mask;
dev_set_name(&device->dev, "%s", driver->driver.name);
of_dma_configure(&device->dev, host1x->dev->of_node);
device->dev.release = host1x_device_release;
device->dev.bus = &host1x_bus_type;
device->dev.parent = host1x->dev;

View File

@ -23,6 +23,7 @@
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
#define CREATE_TRACE_POINTS
#include <trace/events/host1x.h>
@ -68,6 +69,7 @@ static const struct host1x_info host1x01_info = {
.nb_bases = 8,
.init = host1x01_init,
.sync_offset = 0x3000,
.dma_mask = DMA_BIT_MASK(32),
};
static const struct host1x_info host1x02_info = {
@ -77,6 +79,7 @@ static const struct host1x_info host1x02_info = {
.nb_bases = 12,
.init = host1x02_init,
.sync_offset = 0x3000,
.dma_mask = DMA_BIT_MASK(32),
};
static const struct host1x_info host1x04_info = {
@ -86,6 +89,7 @@ static const struct host1x_info host1x04_info = {
.nb_bases = 64,
.init = host1x04_init,
.sync_offset = 0x2100,
.dma_mask = DMA_BIT_MASK(34),
};
static const struct host1x_info host1x05_info = {
@ -95,6 +99,7 @@ static const struct host1x_info host1x05_info = {
.nb_bases = 64,
.init = host1x05_init,
.sync_offset = 0x2100,
.dma_mask = DMA_BIT_MASK(34),
};
static struct of_device_id host1x_of_match[] = {
@ -148,6 +153,8 @@ static int host1x_probe(struct platform_device *pdev)
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
dma_set_mask_and_coherent(host->dev, host->info->dma_mask);
if (host->info->init) {
err = host->info->init(host);
if (err)

View File

@ -96,6 +96,7 @@ struct host1x_info {
int nb_mlocks; /* host1x: number of mlocks */
int (*init)(struct host1x *); /* initialize per SoC ops */
int sync_offset;
u64 dma_mask; /* mask of addressable memory */
};
struct host1x {

View File

@ -586,8 +586,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
if (!dev)
return -ENOMEM;
dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(struct bsc_regs *),
GFP_KERNEL);
dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(*dev->bsc_regmap), GFP_KERNEL);
if (!dev->bsc_regmap)
return -ENOMEM;

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