mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
Merge branches 'acpi-init' and 'acpica'
* acpi-init: ACPI / init: Fix the ordering of acpi_reserve_resources() * acpica: Revert "ACPICA: Permanently set _REV to the value '2'."
This commit is contained in:
commit
4de5167ee0
7
CREDITS
7
CREDITS
@ -3709,6 +3709,13 @@ N: Dirk Verworner
|
||||
D: Co-author of German book ``Linux-Kernel-Programmierung''
|
||||
D: Co-founder of Berlin Linux User Group
|
||||
|
||||
N: Andrew Victor
|
||||
E: linux@maxim.org.za
|
||||
W: http://maxim.org.za/at91_26.html
|
||||
D: First maintainer of Atmel ARM-based SoC, aka AT91
|
||||
D: Introduced support for at91rm9200, the first chip of AT91 family
|
||||
S: South Africa
|
||||
|
||||
N: Riku Voipio
|
||||
E: riku.voipio@iki.fi
|
||||
D: Author of PCA9532 LED and Fintek f75375s hwmon driver
|
||||
|
@ -505,7 +505,10 @@ at module load time (for a module) with:
|
||||
|
||||
The addresses are normal I2C addresses. The adapter is the string
|
||||
name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name.
|
||||
It is *NOT* i2c-<n> itself.
|
||||
It is *NOT* i2c-<n> itself. Also, the comparison is done ignoring
|
||||
spaces, so if the name is "This is an I2C chip" you can say
|
||||
adapter_name=ThisisanI2cchip. This is because it's hard to pass in
|
||||
spaces in kernel parameters.
|
||||
|
||||
The debug flags are bit flags for each BMC found, they are:
|
||||
IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
|
||||
|
@ -253,7 +253,7 @@ input driver:
|
||||
GPIO support
|
||||
~~~~~~~~~~~~
|
||||
ACPI 5 introduced two new resources to describe GPIO connections: GpioIo
|
||||
and GpioInt. These resources are used be used to pass GPIO numbers used by
|
||||
and GpioInt. These resources can be used to pass GPIO numbers used by
|
||||
the device to the driver. ACPI 5.1 extended this with _DSD (Device
|
||||
Specific Data) which made it possible to name the GPIOs among other things.
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
_DSD Device Properties Related to GPIO
|
||||
--------------------------------------
|
||||
|
||||
With the release of ACPI 5.1 and the _DSD configuration objecte names
|
||||
can finally be given to GPIOs (and other things as well) returned by
|
||||
_CRS. Previously, we were only able to use an integer index to find
|
||||
With the release of ACPI 5.1, the _DSD configuration object finally
|
||||
allows names to be given to GPIOs (and other things as well) returned
|
||||
by _CRS. Previously, we were only able to use an integer index to find
|
||||
the corresponding GPIO, which is pretty error prone (it depends on
|
||||
the _CRS output ordering, for example).
|
||||
|
||||
|
@ -6,6 +6,7 @@ provided by Arteris.
|
||||
Required properties:
|
||||
- compatible : Should be "ti,omap3-l3-smx" for OMAP3 family
|
||||
Should be "ti,omap4-l3-noc" for OMAP4 family
|
||||
Should be "ti,omap5-l3-noc" for OMAP5 family
|
||||
Should be "ti,dra7-l3-noc" for DRA7 family
|
||||
Should be "ti,am4372-l3-noc" for AM43 family
|
||||
- reg: Contains L3 register address range for each noc domain.
|
||||
|
@ -38,7 +38,7 @@ dma_apbx: dma-apbx@80024000 {
|
||||
80 81 68 69
|
||||
70 71 72 73
|
||||
74 75 76 77>;
|
||||
interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
|
||||
interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty",
|
||||
"saif0", "saif1", "i2c0", "i2c1",
|
||||
"auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
|
||||
"auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
|
||||
|
30
Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
Normal file
30
Documentation/devicetree/bindings/rtc/abracon,abx80x.txt
Normal file
@ -0,0 +1,30 @@
|
||||
Abracon ABX80X I2C ultra low power RTC/Alarm chip
|
||||
|
||||
The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
|
||||
ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
|
||||
is the superset of ab180x.
|
||||
|
||||
Required properties:
|
||||
|
||||
- "compatible": should one of:
|
||||
"abracon,abx80x"
|
||||
"abracon,ab0801"
|
||||
"abracon,ab0803"
|
||||
"abracon,ab0804"
|
||||
"abracon,ab0805"
|
||||
"abracon,ab1801"
|
||||
"abracon,ab1803"
|
||||
"abracon,ab1804"
|
||||
"abracon,ab1805"
|
||||
Using "abracon,abx80x" will enable chip autodetection.
|
||||
- "reg": I2C bus address of the device
|
||||
|
||||
Optional properties:
|
||||
|
||||
The abx804 and abx805 have a trickle charger that is able to charge the
|
||||
connected battery or supercap. Both the following properties have to be defined
|
||||
and valid to enable charging:
|
||||
|
||||
- "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
|
||||
- "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
|
||||
resistor, the other values are in ohm.
|
@ -9,7 +9,9 @@ a fast and comprehensive solution for finding use-after-free and out-of-bounds
|
||||
bugs.
|
||||
|
||||
KASan uses compile-time instrumentation for checking every memory access,
|
||||
therefore you will need a certain version of GCC > 4.9.2
|
||||
therefore you will need a gcc version of 4.9.2 or later. KASan could detect out
|
||||
of bounds accesses to stack or global variables, but only if gcc 5.0 or later was
|
||||
used to built the kernel.
|
||||
|
||||
Currently KASan is supported only for x86_64 architecture and requires that the
|
||||
kernel be built with the SLUB allocator.
|
||||
@ -23,8 +25,8 @@ To enable KASAN configure kernel with:
|
||||
|
||||
and choose between CONFIG_KASAN_OUTLINE and CONFIG_KASAN_INLINE. Outline/inline
|
||||
is compiler instrumentation types. The former produces smaller binary the
|
||||
latter is 1.1 - 2 times faster. Inline instrumentation requires GCC 5.0 or
|
||||
latter.
|
||||
latter is 1.1 - 2 times faster. Inline instrumentation requires a gcc version
|
||||
of 5.0 or later.
|
||||
|
||||
Currently KASAN works only with the SLUB memory allocator.
|
||||
For better bug detection and nicer report, enable CONFIG_STACKTRACE and put
|
||||
|
26
MAINTAINERS
26
MAINTAINERS
@ -892,11 +892,10 @@ S: Maintained
|
||||
F: arch/arm/mach-alpine/
|
||||
|
||||
ARM/ATMEL AT91RM9200 AND AT91SAM ARM ARCHITECTURES
|
||||
M: Andrew Victor <linux@maxim.org.za>
|
||||
M: Nicolas Ferre <nicolas.ferre@atmel.com>
|
||||
M: Alexandre Belloni <alexandre.belloni@free-electrons.com>
|
||||
M: Jean-Christophe Plagniol-Villard <plagnioj@jcrosoft.com>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
W: http://maxim.org.za/at91_26.html
|
||||
W: http://www.linux4sam.org
|
||||
S: Supported
|
||||
F: arch/arm/mach-at91/
|
||||
@ -990,6 +989,12 @@ F: drivers/clocksource/timer-prima2.c
|
||||
F: drivers/clocksource/timer-atlas7.c
|
||||
N: [^a-z]sirf
|
||||
|
||||
ARM/CONEXANT DIGICOLOR MACHINE SUPPORT
|
||||
M: Baruch Siach <baruch@tkos.co.il>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
N: digicolor
|
||||
|
||||
ARM/EBSA110 MACHINE SUPPORT
|
||||
M: Russell King <linux@arm.linux.org.uk>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
@ -1439,9 +1444,10 @@ ARM/SOCFPGA ARCHITECTURE
|
||||
M: Dinh Nguyen <dinguyen@opensource.altera.com>
|
||||
S: Maintained
|
||||
F: arch/arm/mach-socfpga/
|
||||
F: arch/arm/boot/dts/socfpga*
|
||||
F: arch/arm/configs/socfpga_defconfig
|
||||
W: http://www.rocketboards.org
|
||||
T: git://git.rocketboards.org/linux-socfpga.git
|
||||
T: git://git.rocketboards.org/linux-socfpga-next.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/dinguyen/linux.git
|
||||
|
||||
ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT
|
||||
M: Dinh Nguyen <dinguyen@opensource.altera.com>
|
||||
@ -2116,8 +2122,9 @@ S: Supported
|
||||
F: drivers/net/ethernet/broadcom/bnx2x/
|
||||
|
||||
BROADCOM BCM281XX/BCM11XXX/BCM216XX ARM ARCHITECTURE
|
||||
M: Christian Daudt <bcm@fixthebug.org>
|
||||
M: Florian Fainelli <f.fainelli@gmail.com>
|
||||
M: Ray Jui <rjui@broadcom.com>
|
||||
M: Scott Branden <sbranden@broadcom.com>
|
||||
L: bcm-kernel-feedback-list@broadcom.com
|
||||
T: git git://github.com/broadcom/mach-bcm
|
||||
S: Maintained
|
||||
@ -2168,7 +2175,6 @@ S: Maintained
|
||||
F: drivers/usb/gadget/udc/bcm63xx_udc.*
|
||||
|
||||
BROADCOM BCM7XXX ARM ARCHITECTURE
|
||||
M: Marc Carino <marc.ceeeee@gmail.com>
|
||||
M: Brian Norris <computersforpeace@gmail.com>
|
||||
M: Gregory Fong <gregory.0xf0@gmail.com>
|
||||
M: Florian Fainelli <f.fainelli@gmail.com>
|
||||
@ -5042,17 +5048,19 @@ S: Orphan
|
||||
F: drivers/video/fbdev/imsttfb.c
|
||||
|
||||
INFINIBAND SUBSYSTEM
|
||||
M: Roland Dreier <roland@kernel.org>
|
||||
M: Doug Ledford <dledford@redhat.com>
|
||||
M: Sean Hefty <sean.hefty@intel.com>
|
||||
M: Hal Rosenstock <hal.rosenstock@gmail.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
W: http://www.openfabrics.org/
|
||||
Q: http://patchwork.kernel.org/project/linux-rdma/list/
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/roland/infiniband.git
|
||||
T: git git://github.com/dledford/linux.git
|
||||
S: Supported
|
||||
F: Documentation/infiniband/
|
||||
F: drivers/infiniband/
|
||||
F: include/uapi/linux/if_infiniband.h
|
||||
F: include/uapi/rdma/
|
||||
F: include/rdma/
|
||||
|
||||
INOTIFY
|
||||
M: John McCutchan <john@johnmccutchan.com>
|
||||
@ -5805,6 +5813,7 @@ F: drivers/scsi/53c700*
|
||||
LED SUBSYSTEM
|
||||
M: Bryan Wu <cooloney@gmail.com>
|
||||
M: Richard Purdie <rpurdie@rpsys.net>
|
||||
M: Jacek Anaszewski <j.anaszewski@samsung.com>
|
||||
L: linux-leds@vger.kernel.org
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/cooloney/linux-leds.git
|
||||
S: Maintained
|
||||
@ -11037,6 +11046,7 @@ F: drivers/media/pci/zoran/
|
||||
ZRAM COMPRESSED RAM BLOCK DEVICE DRVIER
|
||||
M: Minchan Kim <minchan@kernel.org>
|
||||
M: Nitin Gupta <ngupta@vflare.org>
|
||||
R: Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/block/zram/
|
||||
|
2
Makefile
2
Makefile
@ -1,7 +1,7 @@
|
||||
VERSION = 4
|
||||
PATCHLEVEL = 1
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc2
|
||||
EXTRAVERSION = -rc3
|
||||
NAME = Hurr durr I'ma sheep
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -49,7 +49,7 @@
|
||||
pinctrl-0 = <&matrix_keypad_pins>;
|
||||
|
||||
debounce-delay-ms = <5>;
|
||||
col-scan-delay-us = <1500>;
|
||||
col-scan-delay-us = <5>;
|
||||
|
||||
row-gpios = <&gpio5 5 GPIO_ACTIVE_HIGH /* Bank5, pin5 */
|
||||
&gpio5 6 GPIO_ACTIVE_HIGH>; /* Bank5, pin6 */
|
||||
@ -473,7 +473,7 @@
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <31 0>;
|
||||
|
||||
wake-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>;
|
||||
|
||||
touchscreen-size-x = <480>;
|
||||
touchscreen-size-y = <272>;
|
||||
|
@ -18,6 +18,7 @@
|
||||
aliases {
|
||||
rtc0 = &mcp_rtc;
|
||||
rtc1 = &tps659038_rtc;
|
||||
rtc2 = &rtc;
|
||||
};
|
||||
|
||||
memory {
|
||||
@ -83,7 +84,7 @@
|
||||
gpio_fan: gpio_fan {
|
||||
/* Based on 5v 500mA AFB02505HHB */
|
||||
compatible = "gpio-fan";
|
||||
gpios = <&tps659038_gpio 1 GPIO_ACTIVE_HIGH>;
|
||||
gpios = <&tps659038_gpio 2 GPIO_ACTIVE_HIGH>;
|
||||
gpio-fan,speed-map = <0 0>,
|
||||
<13000 1>;
|
||||
#cooling-cells = <2>;
|
||||
@ -130,8 +131,8 @@
|
||||
|
||||
uart3_pins_default: uart3_pins_default {
|
||||
pinctrl-single,pins = <
|
||||
0x248 (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_rxd.rxd */
|
||||
0x24c (PIN_INPUT_SLEW | MUX_MODE0) /* uart3_txd.txd */
|
||||
0x3f8 (PIN_INPUT_SLEW | MUX_MODE2) /* uart2_ctsn.uart3_rxd */
|
||||
0x3fc (PIN_INPUT_SLEW | MUX_MODE1) /* uart2_rtsn.uart3_txd */
|
||||
>;
|
||||
};
|
||||
|
||||
@ -455,7 +456,7 @@
|
||||
mcp_rtc: rtc@6f {
|
||||
compatible = "microchip,mcp7941x";
|
||||
reg = <0x6f>;
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_LOW>; /* IRQ_SYS_1N */
|
||||
interrupts = <GIC_SPI 2 IRQ_TYPE_EDGE_RISING>; /* IRQ_SYS_1N */
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mcp79410_pins_default>;
|
||||
@ -478,7 +479,7 @@
|
||||
&uart3 {
|
||||
status = "okay";
|
||||
interrupts-extended = <&crossbar_mpu GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&dra7_pmx_core 0x248>;
|
||||
<&dra7_pmx_core 0x3f8>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&uart3_pins_default>;
|
||||
|
@ -105,6 +105,10 @@
|
||||
};
|
||||
|
||||
internal-regs {
|
||||
rtc@10300 {
|
||||
/* No crystal connected to the internal RTC */
|
||||
status = "disabled";
|
||||
};
|
||||
serial@12000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
@ -911,7 +911,7 @@
|
||||
ti,clock-cycles = <16>;
|
||||
|
||||
reg = <0x4ae07ddc 0x4>, <0x4ae07de0 0x4>,
|
||||
<0x4ae06014 0x4>, <0x4a003b20 0x8>,
|
||||
<0x4ae06014 0x4>, <0x4a003b20 0xc>,
|
||||
<0x4ae0c158 0x4>;
|
||||
reg-names = "setup-address", "control-address",
|
||||
"int-address", "efuse-address",
|
||||
@ -944,7 +944,7 @@
|
||||
ti,clock-cycles = <16>;
|
||||
|
||||
reg = <0x4ae07e34 0x4>, <0x4ae07e24 0x4>,
|
||||
<0x4ae06010 0x4>, <0x4a0025cc 0x8>,
|
||||
<0x4ae06010 0x4>, <0x4a0025cc 0xc>,
|
||||
<0x4a002470 0x4>;
|
||||
reg-names = "setup-address", "control-address",
|
||||
"int-address", "efuse-address",
|
||||
@ -977,7 +977,7 @@
|
||||
ti,clock-cycles = <16>;
|
||||
|
||||
reg = <0x4ae07e30 0x4>, <0x4ae07e20 0x4>,
|
||||
<0x4ae06010 0x4>, <0x4a0025e0 0x8>,
|
||||
<0x4ae06010 0x4>, <0x4a0025e0 0xc>,
|
||||
<0x4a00246c 0x4>;
|
||||
reg-names = "setup-address", "control-address",
|
||||
"int-address", "efuse-address",
|
||||
@ -1010,7 +1010,7 @@
|
||||
ti,clock-cycles = <16>;
|
||||
|
||||
reg = <0x4ae07de4 0x4>, <0x4ae07de8 0x4>,
|
||||
<0x4ae06010 0x4>, <0x4a003b08 0x8>,
|
||||
<0x4ae06010 0x4>, <0x4a003b08 0xc>,
|
||||
<0x4ae0c154 0x4>;
|
||||
reg-names = "setup-address", "control-address",
|
||||
"int-address", "efuse-address",
|
||||
@ -1203,7 +1203,7 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
rtc@48838000 {
|
||||
rtc: rtc@48838000 {
|
||||
compatible = "ti,am3352-rtc";
|
||||
reg = <0x48838000 0x100>;
|
||||
interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>,
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include <dt-bindings/sound/samsung-i2s.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include <dt-bindings/clock/maxim,max77686.h>
|
||||
#include "exynos4412.dtsi"
|
||||
|
||||
/ {
|
||||
@ -105,6 +106,8 @@
|
||||
|
||||
rtc@10070000 {
|
||||
status = "okay";
|
||||
clocks = <&clock CLK_RTC>, <&max77686 MAX77686_CLK_AP>;
|
||||
clock-names = "rtc", "rtc_src";
|
||||
};
|
||||
|
||||
g2d@10800000 {
|
||||
|
@ -567,6 +567,7 @@
|
||||
num-slots = <1>;
|
||||
broken-cd;
|
||||
cap-sdio-irq;
|
||||
keep-power-in-suspend;
|
||||
card-detect-delay = <200>;
|
||||
samsung,dw-mshc-ciu-div = <3>;
|
||||
samsung,dw-mshc-sdr-timing = <2 3>;
|
||||
|
@ -28,7 +28,7 @@ trips {
|
||||
type = "active";
|
||||
};
|
||||
cpu-crit-0 {
|
||||
temperature = <1200000>; /* millicelsius */
|
||||
temperature = <120000>; /* millicelsius */
|
||||
hysteresis = <0>; /* millicelsius */
|
||||
type = "critical";
|
||||
};
|
||||
|
@ -536,6 +536,7 @@
|
||||
clock-names = "dp";
|
||||
phys = <&dp_phy>;
|
||||
phy-names = "dp";
|
||||
power-domains = <&disp_pd>;
|
||||
};
|
||||
|
||||
mipi_phy: video-phy@10040714 {
|
||||
|
@ -18,7 +18,7 @@ trips {
|
||||
type = "active";
|
||||
};
|
||||
cpu-crit-0 {
|
||||
temperature = <1050000>; /* millicelsius */
|
||||
temperature = <105000>; /* millicelsius */
|
||||
hysteresis = <0>; /* millicelsius */
|
||||
type = "critical";
|
||||
};
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include "imx23.dtsi"
|
||||
|
||||
/ {
|
||||
@ -93,6 +94,7 @@
|
||||
|
||||
ahb@80080000 {
|
||||
usb0: usb@80080000 {
|
||||
dr_mode = "host";
|
||||
vbus-supply = <®_usb0_vbus>;
|
||||
status = "okay";
|
||||
};
|
||||
@ -122,7 +124,7 @@
|
||||
|
||||
user {
|
||||
label = "green";
|
||||
gpios = <&gpio2 1 1>;
|
||||
gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -428,6 +428,7 @@
|
||||
|
||||
pwm4: pwm@53fc8000 {
|
||||
compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
|
||||
#pwm-cells = <2>;
|
||||
reg = <0x53fc8000 0x4000>;
|
||||
clocks = <&clks 108>, <&clks 52>;
|
||||
clock-names = "ipg", "per";
|
||||
|
@ -913,7 +913,7 @@
|
||||
80 81 68 69
|
||||
70 71 72 73
|
||||
74 75 76 77>;
|
||||
interrupt-names = "auart4-rx", "aurat4-tx", "spdif-tx", "empty",
|
||||
interrupt-names = "auart4-rx", "auart4-tx", "spdif-tx", "empty",
|
||||
"saif0", "saif1", "i2c0", "i2c1",
|
||||
"auart0-rx", "auart0-tx", "auart1-rx", "auart1-tx",
|
||||
"auart2-rx", "auart2-tx", "auart3-rx", "auart3-tx";
|
||||
|
@ -31,6 +31,7 @@
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
gpio = <&gpio4 15 0>;
|
||||
enable-active-high;
|
||||
};
|
||||
|
||||
reg_usb_h1_vbus: regulator@1 {
|
||||
@ -40,6 +41,7 @@
|
||||
regulator-min-microvolt = <5000000>;
|
||||
regulator-max-microvolt = <5000000>;
|
||||
gpio = <&gpio1 0 0>;
|
||||
enable-active-high;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -185,7 +185,6 @@
|
||||
&i2c3 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c3>;
|
||||
pinctrl-assert-gpios = <&gpio5 4 GPIO_ACTIVE_HIGH>;
|
||||
status = "okay";
|
||||
|
||||
max7310_a: gpio@30 {
|
||||
|
@ -498,6 +498,8 @@
|
||||
DRVDD-supply = <&vmmc2>;
|
||||
IOVDD-supply = <&vio>;
|
||||
DVDD-supply = <&vio>;
|
||||
|
||||
ai3x-micbias-vg = <1>;
|
||||
};
|
||||
|
||||
tlv320aic3x_aux: tlv320aic3x@19 {
|
||||
@ -509,6 +511,8 @@
|
||||
DRVDD-supply = <&vmmc2>;
|
||||
IOVDD-supply = <&vio>;
|
||||
DVDD-supply = <&vio>;
|
||||
|
||||
ai3x-micbias-vg = <2>;
|
||||
};
|
||||
|
||||
tsl2563: tsl2563@29 {
|
||||
|
@ -456,6 +456,7 @@
|
||||
};
|
||||
|
||||
mmu_isp: mmu@480bd400 {
|
||||
#iommu-cells = <0>;
|
||||
compatible = "ti,omap2-iommu";
|
||||
reg = <0x480bd400 0x80>;
|
||||
interrupts = <24>;
|
||||
@ -464,6 +465,7 @@
|
||||
};
|
||||
|
||||
mmu_iva: mmu@5d000000 {
|
||||
#iommu-cells = <0>;
|
||||
compatible = "ti,omap2-iommu";
|
||||
reg = <0x5d000000 0x80>;
|
||||
interrupts = <28>;
|
||||
|
@ -128,7 +128,7 @@
|
||||
* hierarchy.
|
||||
*/
|
||||
ocp {
|
||||
compatible = "ti,omap4-l3-noc", "simple-bus";
|
||||
compatible = "ti,omap5-l3-noc", "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
@ -545,7 +545,7 @@
|
||||
compatible = "adi,adv7511w";
|
||||
reg = <0x39>;
|
||||
interrupt-parent = <&gpio3>;
|
||||
interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
|
||||
interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
adi,input-depth = <8>;
|
||||
adi,input-colorspace = "rgb";
|
||||
|
@ -1017,23 +1017,6 @@
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
vmmci: regulator-gpio {
|
||||
compatible = "regulator-gpio";
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2900000>;
|
||||
regulator-name = "mmci-reg";
|
||||
regulator-type = "voltage";
|
||||
|
||||
startup-delay-us = <100>;
|
||||
enable-active-high;
|
||||
|
||||
states = <1800000 0x1
|
||||
2900000 0x0>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
mcde@a0350000 {
|
||||
compatible = "stericsson,mcde";
|
||||
reg = <0xa0350000 0x1000>, /* MCDE */
|
||||
|
@ -111,6 +111,21 @@
|
||||
pinctrl-1 = <&i2c3_sleep_mode>;
|
||||
};
|
||||
|
||||
vmmci: regulator-gpio {
|
||||
compatible = "regulator-gpio";
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2900000>;
|
||||
regulator-name = "mmci-reg";
|
||||
regulator-type = "voltage";
|
||||
|
||||
startup-delay-us = <100>;
|
||||
enable-active-high;
|
||||
|
||||
states = <1800000 0x1
|
||||
2900000 0x0>;
|
||||
};
|
||||
|
||||
// External Micro SD slot
|
||||
sdi0_per1@80126000 {
|
||||
arm,primecell-periphid = <0x10480180>;
|
||||
|
@ -146,8 +146,21 @@
|
||||
};
|
||||
|
||||
vmmci: regulator-gpio {
|
||||
compatible = "regulator-gpio";
|
||||
|
||||
gpios = <&gpio7 4 0x4>;
|
||||
enable-gpio = <&gpio6 25 0x4>;
|
||||
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <2900000>;
|
||||
regulator-name = "mmci-reg";
|
||||
regulator-type = "voltage";
|
||||
|
||||
startup-delay-us = <100>;
|
||||
enable-active-high;
|
||||
|
||||
states = <1800000 0x1
|
||||
2900000 0x0>;
|
||||
};
|
||||
|
||||
// External Micro SD slot
|
||||
|
@ -39,11 +39,14 @@ CONFIG_ARCH_HIP04=y
|
||||
CONFIG_ARCH_KEYSTONE=y
|
||||
CONFIG_ARCH_MESON=y
|
||||
CONFIG_ARCH_MXC=y
|
||||
CONFIG_SOC_IMX50=y
|
||||
CONFIG_SOC_IMX51=y
|
||||
CONFIG_SOC_IMX53=y
|
||||
CONFIG_SOC_IMX6Q=y
|
||||
CONFIG_SOC_IMX6SL=y
|
||||
CONFIG_SOC_IMX6SX=y
|
||||
CONFIG_SOC_VF610=y
|
||||
CONFIG_SOC_LS1021A=y
|
||||
CONFIG_ARCH_OMAP3=y
|
||||
CONFIG_ARCH_OMAP4=y
|
||||
CONFIG_SOC_OMAP5=y
|
||||
|
@ -393,7 +393,7 @@ CONFIG_TI_EDMA=y
|
||||
CONFIG_DMA_OMAP=y
|
||||
# CONFIG_IOMMU_SUPPORT is not set
|
||||
CONFIG_EXTCON=m
|
||||
CONFIG_EXTCON_GPIO=m
|
||||
CONFIG_EXTCON_USB_GPIO=m
|
||||
CONFIG_EXTCON_PALMAS=m
|
||||
CONFIG_TI_EMIF=m
|
||||
CONFIG_PWM=y
|
||||
|
@ -25,7 +25,7 @@ struct dma_iommu_mapping {
|
||||
};
|
||||
|
||||
struct dma_iommu_mapping *
|
||||
arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size);
|
||||
arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size);
|
||||
|
||||
void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping);
|
||||
|
||||
|
@ -110,5 +110,6 @@ static inline bool set_phys_to_machine(unsigned long pfn, unsigned long mfn)
|
||||
bool xen_arch_need_swiotlb(struct device *dev,
|
||||
unsigned long pfn,
|
||||
unsigned long mfn);
|
||||
unsigned long xen_get_swiotlb_free_pages(unsigned int order);
|
||||
|
||||
#endif /* _ASM_ARM_XEN_PAGE_H */
|
||||
|
@ -303,12 +303,17 @@ static int probe_current_pmu(struct arm_pmu *pmu)
|
||||
|
||||
static int of_pmu_irq_cfg(struct platform_device *pdev)
|
||||
{
|
||||
int i;
|
||||
int i, irq;
|
||||
int *irqs = kcalloc(pdev->num_resources, sizeof(*irqs), GFP_KERNEL);
|
||||
|
||||
if (!irqs)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Don't bother with PPIs; they're already affine */
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq >= 0 && irq_is_percpu(irq))
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < pdev->num_resources; ++i) {
|
||||
struct device_node *dn;
|
||||
int cpu;
|
||||
@ -317,7 +322,7 @@ static int of_pmu_irq_cfg(struct platform_device *pdev)
|
||||
i);
|
||||
if (!dn) {
|
||||
pr_warn("Failed to parse %s/interrupt-affinity[%d]\n",
|
||||
of_node_full_name(dn), i);
|
||||
of_node_full_name(pdev->dev.of_node), i);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Pengutronix, Wolfram Sang <w.sang@pengutronix.de>
|
||||
* Copyright (C) 2010 Pengutronix, Wolfram Sang <kernel@pengutronix.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
|
@ -112,6 +112,7 @@
|
||||
#define OMAP3430_VC_CMD_ONLP_SHIFT 16
|
||||
#define OMAP3430_VC_CMD_RET_SHIFT 8
|
||||
#define OMAP3430_VC_CMD_OFF_SHIFT 0
|
||||
#define OMAP3430_SREN_MASK (1 << 4)
|
||||
#define OMAP3430_HSEN_MASK (1 << 3)
|
||||
#define OMAP3430_MCODE_MASK (0x7 << 0)
|
||||
#define OMAP3430_VALID_MASK (1 << 24)
|
||||
|
@ -35,6 +35,7 @@
|
||||
#define OMAP4430_GLOBAL_WARM_SW_RST_SHIFT 1
|
||||
#define OMAP4430_GLOBAL_WUEN_MASK (1 << 16)
|
||||
#define OMAP4430_HSMCODE_MASK (0x7 << 0)
|
||||
#define OMAP4430_SRMODEEN_MASK (1 << 4)
|
||||
#define OMAP4430_HSMODEEN_MASK (1 << 3)
|
||||
#define OMAP4430_HSSCLL_SHIFT 24
|
||||
#define OMAP4430_ICEPICK_RST_SHIFT 9
|
||||
|
@ -316,7 +316,8 @@ static void __init omap3_vc_init_pmic_signaling(struct voltagedomain *voltdm)
|
||||
* idle. And we can also scale voltages to zero for off-idle.
|
||||
* Note that no actual voltage scaling during off-idle will
|
||||
* happen unless the board specific twl4030 PMIC scripts are
|
||||
* loaded.
|
||||
* loaded. See also omap_vc_i2c_init for comments regarding
|
||||
* erratum i531.
|
||||
*/
|
||||
val = voltdm->read(OMAP3_PRM_VOLTCTRL_OFFSET);
|
||||
if (!(val & OMAP3430_PRM_VOLTCTRL_SEL_OFF)) {
|
||||
@ -704,9 +705,16 @@ static void __init omap_vc_i2c_init(struct voltagedomain *voltdm)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that for omap3 OMAP3430_SREN_MASK clears SREN to work around
|
||||
* erratum i531 "Extra Power Consumed When Repeated Start Operation
|
||||
* Mode Is Enabled on I2C Interface Dedicated for Smart Reflex (I2C4)".
|
||||
* Otherwise I2C4 eventually leads into about 23mW extra power being
|
||||
* consumed even during off idle using VMODE.
|
||||
*/
|
||||
i2c_high_speed = voltdm->pmic->i2c_high_speed;
|
||||
if (i2c_high_speed)
|
||||
voltdm->rmw(vc->common->i2c_cfg_hsen_mask,
|
||||
voltdm->rmw(vc->common->i2c_cfg_clear_mask,
|
||||
vc->common->i2c_cfg_hsen_mask,
|
||||
vc->common->i2c_cfg_reg);
|
||||
|
||||
|
@ -34,6 +34,7 @@ struct voltagedomain;
|
||||
* @cmd_ret_shift: RET field shift in PRM_VC_CMD_VAL_* register
|
||||
* @cmd_off_shift: OFF field shift in PRM_VC_CMD_VAL_* register
|
||||
* @i2c_cfg_reg: I2C configuration register offset
|
||||
* @i2c_cfg_clear_mask: high-speed mode bit clear mask in I2C config register
|
||||
* @i2c_cfg_hsen_mask: high-speed mode bit field mask in I2C config register
|
||||
* @i2c_mcode_mask: MCODE field mask for I2C config register
|
||||
*
|
||||
@ -52,6 +53,7 @@ struct omap_vc_common {
|
||||
u8 cmd_ret_shift;
|
||||
u8 cmd_off_shift;
|
||||
u8 i2c_cfg_reg;
|
||||
u8 i2c_cfg_clear_mask;
|
||||
u8 i2c_cfg_hsen_mask;
|
||||
u8 i2c_mcode_mask;
|
||||
};
|
||||
|
@ -40,6 +40,7 @@ static struct omap_vc_common omap3_vc_common = {
|
||||
.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT,
|
||||
.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT,
|
||||
.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT,
|
||||
.i2c_cfg_clear_mask = OMAP3430_SREN_MASK | OMAP3430_HSEN_MASK,
|
||||
.i2c_cfg_hsen_mask = OMAP3430_HSEN_MASK,
|
||||
.i2c_cfg_reg = OMAP3_PRM_VC_I2C_CFG_OFFSET,
|
||||
.i2c_mcode_mask = OMAP3430_MCODE_MASK,
|
||||
|
@ -42,6 +42,7 @@ static const struct omap_vc_common omap4_vc_common = {
|
||||
.cmd_ret_shift = OMAP4430_RET_SHIFT,
|
||||
.cmd_off_shift = OMAP4430_OFF_SHIFT,
|
||||
.i2c_cfg_reg = OMAP4_PRM_VC_CFG_I2C_MODE_OFFSET,
|
||||
.i2c_cfg_clear_mask = OMAP4430_SRMODEEN_MASK | OMAP4430_HSMODEEN_MASK,
|
||||
.i2c_cfg_hsen_mask = OMAP4430_HSMODEEN_MASK,
|
||||
.i2c_mcode_mask = OMAP4430_HSMCODE_MASK,
|
||||
};
|
||||
|
@ -691,4 +691,13 @@ config SHARPSL_PM_MAX1111
|
||||
config PXA310_ULPI
|
||||
bool
|
||||
|
||||
config PXA_SYSTEMS_CPLDS
|
||||
tristate "Motherboard cplds"
|
||||
default ARCH_LUBBOCK || MACH_MAINSTONE
|
||||
help
|
||||
This driver supports the Lubbock and Mainstone multifunction chip
|
||||
found on the pxa25x development platform system (Lubbock) and pxa27x
|
||||
development platform system (Mainstone). This IO board supports the
|
||||
interrupts handling, ethernet controller, flash chips, etc ...
|
||||
|
||||
endif
|
||||
|
@ -90,4 +90,5 @@ obj-$(CONFIG_MACH_RAUMFELD_CONNECTOR) += raumfeld.o
|
||||
obj-$(CONFIG_MACH_RAUMFELD_SPEAKER) += raumfeld.o
|
||||
obj-$(CONFIG_MACH_ZIPIT2) += z2.o
|
||||
|
||||
obj-$(CONFIG_PXA_SYSTEMS_CPLDS) += pxa_cplds_irqs.o
|
||||
obj-$(CONFIG_TOSA_BT) += tosa-bt.o
|
||||
|
@ -37,7 +37,9 @@
|
||||
#define LUB_GP __LUB_REG(LUBBOCK_FPGA_PHYS + 0x100)
|
||||
|
||||
/* Board specific IRQs */
|
||||
#define LUBBOCK_IRQ(x) (IRQ_BOARD_START + (x))
|
||||
#define LUBBOCK_NR_IRQS IRQ_BOARD_START
|
||||
|
||||
#define LUBBOCK_IRQ(x) (LUBBOCK_NR_IRQS + (x))
|
||||
#define LUBBOCK_SD_IRQ LUBBOCK_IRQ(0)
|
||||
#define LUBBOCK_SA1111_IRQ LUBBOCK_IRQ(1)
|
||||
#define LUBBOCK_USB_IRQ LUBBOCK_IRQ(2) /* usb connect */
|
||||
@ -47,8 +49,7 @@
|
||||
#define LUBBOCK_USB_DISC_IRQ LUBBOCK_IRQ(6) /* usb disconnect */
|
||||
#define LUBBOCK_LAST_IRQ LUBBOCK_IRQ(6)
|
||||
|
||||
#define LUBBOCK_SA1111_IRQ_BASE (IRQ_BOARD_START + 16)
|
||||
#define LUBBOCK_NR_IRQS (IRQ_BOARD_START + 16 + 55)
|
||||
#define LUBBOCK_SA1111_IRQ_BASE (LUBBOCK_NR_IRQS + 32)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void lubbock_set_misc_wr(unsigned int mask, unsigned int set);
|
||||
|
@ -120,7 +120,9 @@
|
||||
#define MST_PCMCIA_PWR_VCC_50 0x4 /* voltage VCC = 5.0V */
|
||||
|
||||
/* board specific IRQs */
|
||||
#define MAINSTONE_IRQ(x) (IRQ_BOARD_START + (x))
|
||||
#define MAINSTONE_NR_IRQS IRQ_BOARD_START
|
||||
|
||||
#define MAINSTONE_IRQ(x) (MAINSTONE_NR_IRQS + (x))
|
||||
#define MAINSTONE_MMC_IRQ MAINSTONE_IRQ(0)
|
||||
#define MAINSTONE_USIM_IRQ MAINSTONE_IRQ(1)
|
||||
#define MAINSTONE_USBC_IRQ MAINSTONE_IRQ(2)
|
||||
@ -136,6 +138,4 @@
|
||||
#define MAINSTONE_S1_STSCHG_IRQ MAINSTONE_IRQ(14)
|
||||
#define MAINSTONE_S1_IRQ MAINSTONE_IRQ(15)
|
||||
|
||||
#define MAINSTONE_NR_IRQS (IRQ_BOARD_START + 16)
|
||||
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
@ -123,84 +124,6 @@ void lubbock_set_misc_wr(unsigned int mask, unsigned int set)
|
||||
}
|
||||
EXPORT_SYMBOL(lubbock_set_misc_wr);
|
||||
|
||||
static unsigned long lubbock_irq_enabled;
|
||||
|
||||
static void lubbock_mask_irq(struct irq_data *d)
|
||||
{
|
||||
int lubbock_irq = (d->irq - LUBBOCK_IRQ(0));
|
||||
LUB_IRQ_MASK_EN = (lubbock_irq_enabled &= ~(1 << lubbock_irq));
|
||||
}
|
||||
|
||||
static void lubbock_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
int lubbock_irq = (d->irq - LUBBOCK_IRQ(0));
|
||||
/* the irq can be acknowledged only if deasserted, so it's done here */
|
||||
LUB_IRQ_SET_CLR &= ~(1 << lubbock_irq);
|
||||
LUB_IRQ_MASK_EN = (lubbock_irq_enabled |= (1 << lubbock_irq));
|
||||
}
|
||||
|
||||
static struct irq_chip lubbock_irq_chip = {
|
||||
.name = "FPGA",
|
||||
.irq_ack = lubbock_mask_irq,
|
||||
.irq_mask = lubbock_mask_irq,
|
||||
.irq_unmask = lubbock_unmask_irq,
|
||||
};
|
||||
|
||||
static void lubbock_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned long pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
|
||||
do {
|
||||
/* clear our parent irq */
|
||||
desc->irq_data.chip->irq_ack(&desc->irq_data);
|
||||
if (likely(pending)) {
|
||||
irq = LUBBOCK_IRQ(0) + __ffs(pending);
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
pending = LUB_IRQ_SET_CLR & lubbock_irq_enabled;
|
||||
} while (pending);
|
||||
}
|
||||
|
||||
static void __init lubbock_init_irq(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
pxa25x_init_irq();
|
||||
|
||||
/* setup extra lubbock irqs */
|
||||
for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
|
||||
irq_set_chip_and_handler(irq, &lubbock_irq_chip,
|
||||
handle_level_irq);
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
|
||||
irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), lubbock_irq_handler);
|
||||
irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static void lubbock_irq_resume(void)
|
||||
{
|
||||
LUB_IRQ_MASK_EN = lubbock_irq_enabled;
|
||||
}
|
||||
|
||||
static struct syscore_ops lubbock_irq_syscore_ops = {
|
||||
.resume = lubbock_irq_resume,
|
||||
};
|
||||
|
||||
static int __init lubbock_irq_device_init(void)
|
||||
{
|
||||
if (machine_is_lubbock()) {
|
||||
register_syscore_ops(&lubbock_irq_syscore_ops);
|
||||
return 0;
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
device_initcall(lubbock_irq_device_init);
|
||||
|
||||
#endif
|
||||
|
||||
static int lubbock_udc_is_connected(void)
|
||||
{
|
||||
return (LUB_MISC_RD & (1 << 9)) == 0;
|
||||
@ -383,11 +306,38 @@ static struct platform_device lubbock_flash_device[2] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource lubbock_cplds_resources[] = {
|
||||
[0] = {
|
||||
.start = LUBBOCK_FPGA_PHYS + 0xc0,
|
||||
.end = LUBBOCK_FPGA_PHYS + 0xe0 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = PXA_GPIO_TO_IRQ(0),
|
||||
.end = PXA_GPIO_TO_IRQ(0),
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
|
||||
},
|
||||
[2] = {
|
||||
.start = LUBBOCK_IRQ(0),
|
||||
.end = LUBBOCK_IRQ(6),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device lubbock_cplds_device = {
|
||||
.name = "pxa_cplds_irqs",
|
||||
.id = -1,
|
||||
.resource = &lubbock_cplds_resources[0],
|
||||
.num_resources = 3,
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device *devices[] __initdata = {
|
||||
&sa1111_device,
|
||||
&smc91x_device,
|
||||
&lubbock_flash_device[0],
|
||||
&lubbock_flash_device[1],
|
||||
&lubbock_cplds_device,
|
||||
};
|
||||
|
||||
static struct pxafb_mode_info sharp_lm8v31_mode = {
|
||||
@ -648,7 +598,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)")
|
||||
/* Maintainer: MontaVista Software Inc. */
|
||||
.map_io = lubbock_map_io,
|
||||
.nr_irqs = LUBBOCK_NR_IRQS,
|
||||
.init_irq = lubbock_init_irq,
|
||||
.init_irq = pxa25x_init_irq,
|
||||
.handle_irq = pxa25x_handle_irq,
|
||||
.init_time = pxa_timer_init,
|
||||
.init_machine = lubbock_init,
|
||||
|
@ -13,6 +13,7 @@
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
@ -122,92 +123,6 @@ static unsigned long mainstone_pin_config[] = {
|
||||
GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH,
|
||||
};
|
||||
|
||||
static unsigned long mainstone_irq_enabled;
|
||||
|
||||
static void mainstone_mask_irq(struct irq_data *d)
|
||||
{
|
||||
int mainstone_irq = (d->irq - MAINSTONE_IRQ(0));
|
||||
MST_INTMSKENA = (mainstone_irq_enabled &= ~(1 << mainstone_irq));
|
||||
}
|
||||
|
||||
static void mainstone_unmask_irq(struct irq_data *d)
|
||||
{
|
||||
int mainstone_irq = (d->irq - MAINSTONE_IRQ(0));
|
||||
/* the irq can be acknowledged only if deasserted, so it's done here */
|
||||
MST_INTSETCLR &= ~(1 << mainstone_irq);
|
||||
MST_INTMSKENA = (mainstone_irq_enabled |= (1 << mainstone_irq));
|
||||
}
|
||||
|
||||
static struct irq_chip mainstone_irq_chip = {
|
||||
.name = "FPGA",
|
||||
.irq_ack = mainstone_mask_irq,
|
||||
.irq_mask = mainstone_mask_irq,
|
||||
.irq_unmask = mainstone_unmask_irq,
|
||||
};
|
||||
|
||||
static void mainstone_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
{
|
||||
unsigned long pending = MST_INTSETCLR & mainstone_irq_enabled;
|
||||
do {
|
||||
/* clear useless edge notification */
|
||||
desc->irq_data.chip->irq_ack(&desc->irq_data);
|
||||
if (likely(pending)) {
|
||||
irq = MAINSTONE_IRQ(0) + __ffs(pending);
|
||||
generic_handle_irq(irq);
|
||||
}
|
||||
pending = MST_INTSETCLR & mainstone_irq_enabled;
|
||||
} while (pending);
|
||||
}
|
||||
|
||||
static void __init mainstone_init_irq(void)
|
||||
{
|
||||
int irq;
|
||||
|
||||
pxa27x_init_irq();
|
||||
|
||||
/* setup extra Mainstone irqs */
|
||||
for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
|
||||
irq_set_chip_and_handler(irq, &mainstone_irq_chip,
|
||||
handle_level_irq);
|
||||
if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
|
||||
else
|
||||
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
|
||||
}
|
||||
set_irq_flags(MAINSTONE_IRQ(8), 0);
|
||||
set_irq_flags(MAINSTONE_IRQ(12), 0);
|
||||
|
||||
MST_INTMSKENA = 0;
|
||||
MST_INTSETCLR = 0;
|
||||
|
||||
irq_set_chained_handler(PXA_GPIO_TO_IRQ(0), mainstone_irq_handler);
|
||||
irq_set_irq_type(PXA_GPIO_TO_IRQ(0), IRQ_TYPE_EDGE_FALLING);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static void mainstone_irq_resume(void)
|
||||
{
|
||||
MST_INTMSKENA = mainstone_irq_enabled;
|
||||
}
|
||||
|
||||
static struct syscore_ops mainstone_irq_syscore_ops = {
|
||||
.resume = mainstone_irq_resume,
|
||||
};
|
||||
|
||||
static int __init mainstone_irq_device_init(void)
|
||||
{
|
||||
if (machine_is_mainstone())
|
||||
register_syscore_ops(&mainstone_irq_syscore_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
device_initcall(mainstone_irq_device_init);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
static struct resource smc91x_resources[] = {
|
||||
[0] = {
|
||||
.start = (MST_ETH_PHYS + 0x300),
|
||||
@ -487,11 +402,37 @@ static struct platform_device mst_gpio_keys_device = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct resource mst_cplds_resources[] = {
|
||||
[0] = {
|
||||
.start = MST_FPGA_PHYS + 0xc0,
|
||||
.end = MST_FPGA_PHYS + 0xe0 - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = PXA_GPIO_TO_IRQ(0),
|
||||
.end = PXA_GPIO_TO_IRQ(0),
|
||||
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
|
||||
},
|
||||
[2] = {
|
||||
.start = MAINSTONE_IRQ(0),
|
||||
.end = MAINSTONE_IRQ(15),
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static struct platform_device mst_cplds_device = {
|
||||
.name = "pxa_cplds_irqs",
|
||||
.id = -1,
|
||||
.resource = &mst_cplds_resources[0],
|
||||
.num_resources = 3,
|
||||
};
|
||||
|
||||
static struct platform_device *platform_devices[] __initdata = {
|
||||
&smc91x_device,
|
||||
&mst_flash_device[0],
|
||||
&mst_flash_device[1],
|
||||
&mst_gpio_keys_device,
|
||||
&mst_cplds_device,
|
||||
};
|
||||
|
||||
static struct pxaohci_platform_data mainstone_ohci_platform_data = {
|
||||
@ -718,7 +659,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)")
|
||||
.atag_offset = 0x100, /* BLOB boot parameter setting */
|
||||
.map_io = mainstone_map_io,
|
||||
.nr_irqs = MAINSTONE_NR_IRQS,
|
||||
.init_irq = mainstone_init_irq,
|
||||
.init_irq = pxa27x_init_irq,
|
||||
.handle_irq = pxa27x_handle_irq,
|
||||
.init_time = pxa_timer_init,
|
||||
.init_machine = mainstone_init,
|
||||
|
200
arch/arm/mach-pxa/pxa_cplds_irqs.c
Normal file
200
arch/arm/mach-pxa/pxa_cplds_irqs.c
Normal file
@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Intel Reference Systems cplds
|
||||
*
|
||||
* Copyright (C) 2014 Robert Jarzmik
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Cplds motherboard driver, supporting lubbock and mainstone SoC board.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#define FPGA_IRQ_MASK_EN 0x0
|
||||
#define FPGA_IRQ_SET_CLR 0x10
|
||||
|
||||
#define CPLDS_NB_IRQ 32
|
||||
|
||||
struct cplds {
|
||||
void __iomem *base;
|
||||
int irq;
|
||||
unsigned int irq_mask;
|
||||
struct gpio_desc *gpio0;
|
||||
struct irq_domain *irqdomain;
|
||||
};
|
||||
|
||||
static irqreturn_t cplds_irq_handler(int in_irq, void *d)
|
||||
{
|
||||
struct cplds *fpga = d;
|
||||
unsigned long pending;
|
||||
unsigned int bit;
|
||||
|
||||
pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
|
||||
for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
|
||||
generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void cplds_irq_mask_ack(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int set, bit = BIT(cplds_irq);
|
||||
|
||||
fpga->irq_mask &= ~bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
set = readl(fpga->base + FPGA_IRQ_SET_CLR);
|
||||
writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
}
|
||||
|
||||
static void cplds_irq_unmask(struct irq_data *d)
|
||||
{
|
||||
struct cplds *fpga = irq_data_get_irq_chip_data(d);
|
||||
unsigned int cplds_irq = irqd_to_hwirq(d);
|
||||
unsigned int bit = BIT(cplds_irq);
|
||||
|
||||
fpga->irq_mask |= bit;
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
}
|
||||
|
||||
static struct irq_chip cplds_irq_chip = {
|
||||
.name = "pxa_cplds",
|
||||
.irq_mask_ack = cplds_irq_mask_ack,
|
||||
.irq_unmask = cplds_irq_unmask,
|
||||
.flags = IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
|
||||
};
|
||||
|
||||
static int cplds_irq_domain_map(struct irq_domain *d, unsigned int irq,
|
||||
irq_hw_number_t hwirq)
|
||||
{
|
||||
struct cplds *fpga = d->host_data;
|
||||
|
||||
irq_set_chip_and_handler(irq, &cplds_irq_chip, handle_level_irq);
|
||||
irq_set_chip_data(irq, fpga);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct irq_domain_ops cplds_irq_domain_ops = {
|
||||
.xlate = irq_domain_xlate_twocell,
|
||||
.map = cplds_irq_domain_map,
|
||||
};
|
||||
|
||||
static int cplds_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct cplds *fpga = platform_get_drvdata(pdev);
|
||||
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cplds_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct cplds *fpga;
|
||||
int ret;
|
||||
unsigned int base_irq = 0;
|
||||
unsigned long irqflags = 0;
|
||||
|
||||
fpga = devm_kzalloc(&pdev->dev, sizeof(*fpga), GFP_KERNEL);
|
||||
if (!fpga)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (res) {
|
||||
fpga->irq = (unsigned int)res->start;
|
||||
irqflags = res->flags;
|
||||
}
|
||||
if (!fpga->irq)
|
||||
return -ENODEV;
|
||||
|
||||
base_irq = platform_get_irq(pdev, 1);
|
||||
if (base_irq < 0)
|
||||
base_irq = 0;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
fpga->base = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (IS_ERR(fpga->base))
|
||||
return PTR_ERR(fpga->base);
|
||||
|
||||
platform_set_drvdata(pdev, fpga);
|
||||
|
||||
writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
|
||||
writel(0, fpga->base + FPGA_IRQ_SET_CLR);
|
||||
|
||||
ret = devm_request_irq(&pdev->dev, fpga->irq, cplds_irq_handler,
|
||||
irqflags, dev_name(&pdev->dev), fpga);
|
||||
if (ret == -ENOSYS)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "couldn't request main irq%d: %d\n",
|
||||
fpga->irq, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
irq_set_irq_wake(fpga->irq, 1);
|
||||
fpga->irqdomain = irq_domain_add_linear(pdev->dev.of_node,
|
||||
CPLDS_NB_IRQ,
|
||||
&cplds_irq_domain_ops, fpga);
|
||||
if (!fpga->irqdomain)
|
||||
return -ENODEV;
|
||||
|
||||
if (base_irq) {
|
||||
ret = irq_create_strict_mappings(fpga->irqdomain, base_irq, 0,
|
||||
CPLDS_NB_IRQ);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "couldn't create the irq mapping %d..%d\n",
|
||||
base_irq, base_irq + CPLDS_NB_IRQ);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cplds_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cplds *fpga = platform_get_drvdata(pdev);
|
||||
|
||||
irq_set_chip_and_handler(fpga->irq, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id cplds_id_table[] = {
|
||||
{ .compatible = "intel,lubbock-cplds-irqs", },
|
||||
{ .compatible = "intel,mainstone-cplds-irqs", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, cplds_id_table);
|
||||
|
||||
static struct platform_driver cplds_driver = {
|
||||
.driver = {
|
||||
.name = "pxa_cplds_irqs",
|
||||
.of_match_table = of_match_ptr(cplds_id_table),
|
||||
},
|
||||
.probe = cplds_probe,
|
||||
.remove = cplds_remove,
|
||||
.resume = cplds_resume,
|
||||
};
|
||||
|
||||
module_platform_driver(cplds_driver);
|
||||
|
||||
MODULE_DESCRIPTION("PXA Cplds interrupts driver");
|
||||
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
|
||||
MODULE_LICENSE("GPL");
|
@ -44,9 +44,11 @@ static void __iomem *rk3288_bootram_base;
|
||||
static phys_addr_t rk3288_bootram_phy;
|
||||
|
||||
static struct regmap *pmu_regmap;
|
||||
static struct regmap *grf_regmap;
|
||||
static struct regmap *sgrf_regmap;
|
||||
|
||||
static u32 rk3288_pmu_pwr_mode_con;
|
||||
static u32 rk3288_grf_soc_con0;
|
||||
static u32 rk3288_sgrf_soc_con0;
|
||||
|
||||
static inline u32 rk3288_l2_config(void)
|
||||
@ -70,11 +72,25 @@ static void rk3288_slp_mode_set(int level)
|
||||
{
|
||||
u32 mode_set, mode_set1;
|
||||
|
||||
regmap_read(grf_regmap, RK3288_GRF_SOC_CON0, &rk3288_grf_soc_con0);
|
||||
|
||||
regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
|
||||
|
||||
regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
|
||||
&rk3288_pmu_pwr_mode_con);
|
||||
|
||||
/*
|
||||
* We need set this bit GRF_FORCE_JTAG here, for the debug module,
|
||||
* otherwise, it may become inaccessible after resume.
|
||||
* This creates a potential security issue, as the sdmmc pins may
|
||||
* accept jtag data for a short time during resume if no card is
|
||||
* inserted.
|
||||
* But this is of course also true for the regular boot, before we
|
||||
* turn of the jtag/sdmmc autodetect.
|
||||
*/
|
||||
regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, GRF_FORCE_JTAG |
|
||||
GRF_FORCE_JTAG_WRITE);
|
||||
|
||||
/*
|
||||
* SGRF_FAST_BOOT_EN - system to boot from FAST_BOOT_ADDR
|
||||
* PCLK_WDT_GATE - disable WDT during suspend.
|
||||
@ -83,6 +99,13 @@ static void rk3288_slp_mode_set(int level)
|
||||
SGRF_PCLK_WDT_GATE | SGRF_FAST_BOOT_EN
|
||||
| SGRF_PCLK_WDT_GATE_WRITE | SGRF_FAST_BOOT_EN_WRITE);
|
||||
|
||||
/*
|
||||
* The dapswjdp can not auto reset before resume, that cause it may
|
||||
* access some illegal address during resume. Let's disable it before
|
||||
* suspend, and the MASKROM will enable it back.
|
||||
*/
|
||||
regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, SGRF_DAPDEVICEEN_WRITE);
|
||||
|
||||
/* booting address of resuming system is from this register value */
|
||||
regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
|
||||
rk3288_bootram_phy);
|
||||
@ -128,6 +151,9 @@ static void rk3288_slp_mode_set_resume(void)
|
||||
regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
|
||||
rk3288_sgrf_soc_con0 | SGRF_PCLK_WDT_GATE_WRITE
|
||||
| SGRF_FAST_BOOT_EN_WRITE);
|
||||
|
||||
regmap_write(grf_regmap, RK3288_GRF_SOC_CON0, rk3288_grf_soc_con0 |
|
||||
GRF_FORCE_JTAG_WRITE);
|
||||
}
|
||||
|
||||
static int rockchip_lpmode_enter(unsigned long arg)
|
||||
@ -186,6 +212,13 @@ static int rk3288_suspend_init(struct device_node *np)
|
||||
return PTR_ERR(pmu_regmap);
|
||||
}
|
||||
|
||||
grf_regmap = syscon_regmap_lookup_by_compatible(
|
||||
"rockchip,rk3288-grf");
|
||||
if (IS_ERR(grf_regmap)) {
|
||||
pr_err("%s: could not find grf regmap\n", __func__);
|
||||
return PTR_ERR(pmu_regmap);
|
||||
}
|
||||
|
||||
sram_np = of_find_compatible_node(NULL, NULL,
|
||||
"rockchip,rk3288-pmu-sram");
|
||||
if (!sram_np) {
|
||||
|
@ -48,6 +48,10 @@ static inline void rockchip_suspend_init(void)
|
||||
#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44
|
||||
#define RK3288_PMU_PWRMODE_CON1 0x90
|
||||
|
||||
#define RK3288_GRF_SOC_CON0 0x244
|
||||
#define GRF_FORCE_JTAG BIT(12)
|
||||
#define GRF_FORCE_JTAG_WRITE BIT(28)
|
||||
|
||||
#define RK3288_SGRF_SOC_CON0 (0x0000)
|
||||
#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
|
||||
#define SGRF_PCLK_WDT_GATE BIT(6)
|
||||
@ -55,6 +59,10 @@ static inline void rockchip_suspend_init(void)
|
||||
#define SGRF_FAST_BOOT_EN BIT(8)
|
||||
#define SGRF_FAST_BOOT_EN_WRITE BIT(24)
|
||||
|
||||
#define RK3288_SGRF_CPU_CON0 (0x40)
|
||||
#define SGRF_DAPDEVICEEN BIT(0)
|
||||
#define SGRF_DAPDEVICEEN_WRITE BIT(16)
|
||||
|
||||
#define RK3288_CRU_MODE_CON 0x50
|
||||
#define RK3288_CRU_SEL0_CON 0x60
|
||||
#define RK3288_CRU_SEL1_CON 0x64
|
||||
|
@ -30,11 +30,30 @@
|
||||
#include "pm.h"
|
||||
|
||||
#define RK3288_GRF_SOC_CON0 0x244
|
||||
#define RK3288_TIMER6_7_PHYS 0xff810000
|
||||
|
||||
static void __init rockchip_timer_init(void)
|
||||
{
|
||||
if (of_machine_is_compatible("rockchip,rk3288")) {
|
||||
struct regmap *grf;
|
||||
void __iomem *reg_base;
|
||||
|
||||
/*
|
||||
* Most/all uboot versions for rk3288 don't enable timer7
|
||||
* which is needed for the architected timer to work.
|
||||
* So make sure it is running during early boot.
|
||||
*/
|
||||
reg_base = ioremap(RK3288_TIMER6_7_PHYS, SZ_16K);
|
||||
if (reg_base) {
|
||||
writel(0, reg_base + 0x30);
|
||||
writel(0xffffffff, reg_base + 0x20);
|
||||
writel(0xffffffff, reg_base + 0x24);
|
||||
writel(1, reg_base + 0x30);
|
||||
dsb();
|
||||
iounmap(reg_base);
|
||||
} else {
|
||||
pr_err("rockchip: could not map timer7 registers\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable auto jtag/sdmmc switching that causes issues
|
||||
|
@ -1878,7 +1878,7 @@ struct dma_map_ops iommu_coherent_ops = {
|
||||
* arm_iommu_attach_device function.
|
||||
*/
|
||||
struct dma_iommu_mapping *
|
||||
arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
|
||||
arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, u64 size)
|
||||
{
|
||||
unsigned int bits = size >> PAGE_SHIFT;
|
||||
unsigned int bitmap_size = BITS_TO_LONGS(bits) * sizeof(long);
|
||||
@ -1886,6 +1886,10 @@ arm_iommu_create_mapping(struct bus_type *bus, dma_addr_t base, size_t size)
|
||||
int extensions = 1;
|
||||
int err = -ENOMEM;
|
||||
|
||||
/* currently only 32-bit DMA address space is supported */
|
||||
if (size > DMA_BIT_MASK(32) + 1)
|
||||
return ERR_PTR(-ERANGE);
|
||||
|
||||
if (!bitmap_size)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
@ -2057,13 +2061,6 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
|
||||
if (!iommu)
|
||||
return false;
|
||||
|
||||
/*
|
||||
* currently arm_iommu_create_mapping() takes a max of size_t
|
||||
* for size param. So check this limit for now.
|
||||
*/
|
||||
if (size > SIZE_MAX)
|
||||
return false;
|
||||
|
||||
mapping = arm_iommu_create_mapping(dev->bus, dma_base, size);
|
||||
if (IS_ERR(mapping)) {
|
||||
pr_warn("Failed to create %llu-byte IOMMU mapping for device %s\n",
|
||||
|
@ -22,8 +22,6 @@
|
||||
*
|
||||
* These are the low level assembler for performing cache and TLB
|
||||
* functions on the arm1020.
|
||||
*
|
||||
* CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -22,8 +22,6 @@
|
||||
*
|
||||
* These are the low level assembler for performing cache and TLB
|
||||
* functions on the arm1020e.
|
||||
*
|
||||
* CONFIG_CPU_ARM1020_CPU_IDLE -> nohlt
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -441,9 +441,6 @@ ENTRY(cpu_arm925_set_pte_ext)
|
||||
.type __arm925_setup, #function
|
||||
__arm925_setup:
|
||||
mov r0, #0
|
||||
#if defined(CONFIG_CPU_ICACHE_STREAMING_DISABLE)
|
||||
orr r0,r0,#1 << 7
|
||||
#endif
|
||||
|
||||
/* Transparent on, D-cache clean & flush mode. See NOTE2 above */
|
||||
orr r0,r0,#1 << 1 @ transparent mode on
|
||||
|
@ -602,7 +602,6 @@ __\name\()_proc_info:
|
||||
PMD_SECT_AP_WRITE | \
|
||||
PMD_SECT_AP_READ
|
||||
initfn __feroceon_setup, __\name\()_proc_info
|
||||
.long __feroceon_setup
|
||||
.long cpu_arch_name
|
||||
.long cpu_elf_name
|
||||
.long HWCAP_SWP|HWCAP_HALF|HWCAP_THUMB|HWCAP_FAST_MULT|HWCAP_EDSP
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/gfp.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/memblock.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
@ -21,6 +22,20 @@
|
||||
#include <asm/xen/hypercall.h>
|
||||
#include <asm/xen/interface.h>
|
||||
|
||||
unsigned long xen_get_swiotlb_free_pages(unsigned int order)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
gfp_t flags = __GFP_NOWARN;
|
||||
|
||||
for_each_memblock(memory, reg) {
|
||||
if (reg->base < (phys_addr_t)0xffffffff) {
|
||||
flags |= __GFP_DMA;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return __get_free_pages(flags, order);
|
||||
}
|
||||
|
||||
enum dma_cache_op {
|
||||
DMA_UNMAP,
|
||||
DMA_MAP,
|
||||
|
@ -45,7 +45,7 @@ static volatile unsigned long flushcache_cpumask = 0;
|
||||
/*
|
||||
* For flush_tlb_others()
|
||||
*/
|
||||
static volatile cpumask_t flush_cpumask;
|
||||
static cpumask_t flush_cpumask;
|
||||
static struct mm_struct *flush_mm;
|
||||
static struct vm_area_struct *flush_vma;
|
||||
static volatile unsigned long flush_va;
|
||||
@ -415,7 +415,7 @@ static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
|
||||
*/
|
||||
send_IPI_mask(&cpumask, INVALIDATE_TLB_IPI, 0);
|
||||
|
||||
while (!cpumask_empty((cpumask_t*)&flush_cpumask)) {
|
||||
while (!cpumask_empty(&flush_cpumask)) {
|
||||
/* nothing. lockup detection does not belong here */
|
||||
mb();
|
||||
}
|
||||
@ -468,7 +468,7 @@ void smp_invalidate_interrupt(void)
|
||||
__flush_tlb_page(va);
|
||||
}
|
||||
}
|
||||
cpumask_clear_cpu(cpu_id, (cpumask_t*)&flush_cpumask);
|
||||
cpumask_clear_cpu(cpu_id, &flush_cpumask);
|
||||
}
|
||||
|
||||
/*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*/
|
||||
|
@ -1109,6 +1109,8 @@ struct boot_params *make_boot_params(struct efi_config *c)
|
||||
if (!cmdline_ptr)
|
||||
goto fail;
|
||||
hdr->cmd_line_ptr = (unsigned long)cmdline_ptr;
|
||||
/* Fill in upper bits of command line address, NOP on 32 bit */
|
||||
boot_params->ext_cmd_line_ptr = (u64)(unsigned long)cmdline_ptr >> 32;
|
||||
|
||||
hdr->ramdisk_image = 0;
|
||||
hdr->ramdisk_size = 0;
|
||||
|
@ -50,7 +50,7 @@ extern const struct hypervisor_x86 *x86_hyper;
|
||||
/* Recognized hypervisors */
|
||||
extern const struct hypervisor_x86 x86_hyper_vmware;
|
||||
extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
|
||||
extern const struct hypervisor_x86 x86_hyper_xen_hvm;
|
||||
extern const struct hypervisor_x86 x86_hyper_xen;
|
||||
extern const struct hypervisor_x86 x86_hyper_kvm;
|
||||
|
||||
extern void init_hypervisor(struct cpuinfo_x86 *c);
|
||||
|
@ -169,7 +169,7 @@ static inline int arch_spin_is_contended(arch_spinlock_t *lock)
|
||||
struct __raw_tickets tmp = READ_ONCE(lock->tickets);
|
||||
|
||||
tmp.head &= ~TICKET_SLOWPATH_FLAG;
|
||||
return (tmp.tail - tmp.head) > TICKET_LOCK_INC;
|
||||
return (__ticket_t)(tmp.tail - tmp.head) > TICKET_LOCK_INC;
|
||||
}
|
||||
#define arch_spin_is_contended arch_spin_is_contended
|
||||
|
||||
|
@ -269,4 +269,9 @@ static inline bool xen_arch_need_swiotlb(struct device *dev,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline unsigned long xen_get_swiotlb_free_pages(unsigned int order)
|
||||
{
|
||||
return __get_free_pages(__GFP_NOWARN, order);
|
||||
}
|
||||
|
||||
#endif /* _ASM_X86_XEN_PAGE_H */
|
||||
|
@ -27,8 +27,8 @@
|
||||
|
||||
static const __initconst struct hypervisor_x86 * const hypervisors[] =
|
||||
{
|
||||
#ifdef CONFIG_XEN_PVHVM
|
||||
&x86_hyper_xen_hvm,
|
||||
#ifdef CONFIG_XEN
|
||||
&x86_hyper_xen,
|
||||
#endif
|
||||
&x86_hyper_vmware,
|
||||
&x86_hyper_ms_hyperv,
|
||||
|
@ -2533,34 +2533,6 @@ ssize_t intel_event_sysfs_show(char *page, u64 config)
|
||||
return x86_event_sysfs_show(page, config, event);
|
||||
}
|
||||
|
||||
static __initconst const struct x86_pmu core_pmu = {
|
||||
.name = "core",
|
||||
.handle_irq = x86_pmu_handle_irq,
|
||||
.disable_all = x86_pmu_disable_all,
|
||||
.enable_all = core_pmu_enable_all,
|
||||
.enable = core_pmu_enable_event,
|
||||
.disable = x86_pmu_disable_event,
|
||||
.hw_config = x86_pmu_hw_config,
|
||||
.schedule_events = x86_schedule_events,
|
||||
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
|
||||
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
|
||||
.event_map = intel_pmu_event_map,
|
||||
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
|
||||
.apic = 1,
|
||||
/*
|
||||
* Intel PMCs cannot be accessed sanely above 32 bit width,
|
||||
* so we install an artificial 1<<31 period regardless of
|
||||
* the generic event period:
|
||||
*/
|
||||
.max_period = (1ULL << 31) - 1,
|
||||
.get_event_constraints = intel_get_event_constraints,
|
||||
.put_event_constraints = intel_put_event_constraints,
|
||||
.event_constraints = intel_core_event_constraints,
|
||||
.guest_get_msrs = core_guest_get_msrs,
|
||||
.format_attrs = intel_arch_formats_attr,
|
||||
.events_sysfs_show = intel_event_sysfs_show,
|
||||
};
|
||||
|
||||
struct intel_shared_regs *allocate_shared_regs(int cpu)
|
||||
{
|
||||
struct intel_shared_regs *regs;
|
||||
@ -2743,6 +2715,44 @@ static struct attribute *intel_arch3_formats_attr[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static __initconst const struct x86_pmu core_pmu = {
|
||||
.name = "core",
|
||||
.handle_irq = x86_pmu_handle_irq,
|
||||
.disable_all = x86_pmu_disable_all,
|
||||
.enable_all = core_pmu_enable_all,
|
||||
.enable = core_pmu_enable_event,
|
||||
.disable = x86_pmu_disable_event,
|
||||
.hw_config = x86_pmu_hw_config,
|
||||
.schedule_events = x86_schedule_events,
|
||||
.eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
|
||||
.perfctr = MSR_ARCH_PERFMON_PERFCTR0,
|
||||
.event_map = intel_pmu_event_map,
|
||||
.max_events = ARRAY_SIZE(intel_perfmon_event_map),
|
||||
.apic = 1,
|
||||
/*
|
||||
* Intel PMCs cannot be accessed sanely above 32-bit width,
|
||||
* so we install an artificial 1<<31 period regardless of
|
||||
* the generic event period:
|
||||
*/
|
||||
.max_period = (1ULL<<31) - 1,
|
||||
.get_event_constraints = intel_get_event_constraints,
|
||||
.put_event_constraints = intel_put_event_constraints,
|
||||
.event_constraints = intel_core_event_constraints,
|
||||
.guest_get_msrs = core_guest_get_msrs,
|
||||
.format_attrs = intel_arch_formats_attr,
|
||||
.events_sysfs_show = intel_event_sysfs_show,
|
||||
|
||||
/*
|
||||
* Virtual (or funny metal) CPU can define x86_pmu.extra_regs
|
||||
* together with PMU version 1 and thus be using core_pmu with
|
||||
* shared_regs. We need following callbacks here to allocate
|
||||
* it properly.
|
||||
*/
|
||||
.cpu_prepare = intel_pmu_cpu_prepare,
|
||||
.cpu_starting = intel_pmu_cpu_starting,
|
||||
.cpu_dying = intel_pmu_cpu_dying,
|
||||
};
|
||||
|
||||
static __initconst const struct x86_pmu intel_pmu = {
|
||||
.name = "Intel",
|
||||
.handle_irq = intel_pmu_handle_irq,
|
||||
|
@ -1,6 +1,13 @@
|
||||
/* Nehalem/SandBridge/Haswell uncore support */
|
||||
#include "perf_event_intel_uncore.h"
|
||||
|
||||
/* Uncore IMC PCI IDs */
|
||||
#define PCI_DEVICE_ID_INTEL_SNB_IMC 0x0100
|
||||
#define PCI_DEVICE_ID_INTEL_IVB_IMC 0x0154
|
||||
#define PCI_DEVICE_ID_INTEL_IVB_E3_IMC 0x0150
|
||||
#define PCI_DEVICE_ID_INTEL_HSW_IMC 0x0c00
|
||||
#define PCI_DEVICE_ID_INTEL_HSW_U_IMC 0x0a04
|
||||
|
||||
/* SNB event control */
|
||||
#define SNB_UNC_CTL_EV_SEL_MASK 0x000000ff
|
||||
#define SNB_UNC_CTL_UMASK_MASK 0x0000ff00
|
||||
@ -472,6 +479,10 @@ static const struct pci_device_id hsw_uncore_pci_ids[] = {
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_IMC),
|
||||
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
|
||||
},
|
||||
{ /* IMC */
|
||||
PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_U_IMC),
|
||||
.driver_data = UNCORE_PCI_DEV_DATA(SNB_PCI_UNCORE_IMC, 0),
|
||||
},
|
||||
{ /* end: all zeroes */ },
|
||||
};
|
||||
|
||||
@ -502,6 +513,7 @@ static const struct imc_uncore_pci_dev desktop_imc_pci_ids[] = {
|
||||
IMC_DEV(IVB_IMC, &ivb_uncore_pci_driver), /* 3rd Gen Core processor */
|
||||
IMC_DEV(IVB_E3_IMC, &ivb_uncore_pci_driver), /* Xeon E3-1200 v2/3rd Gen Core processor */
|
||||
IMC_DEV(HSW_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core Processor */
|
||||
IMC_DEV(HSW_U_IMC, &hsw_uncore_pci_driver), /* 4th Gen Core ULT Mobile Processor */
|
||||
{ /* end marker */ }
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ __visible DEFINE_PER_CPU_SHARED_ALIGNED(struct tss_struct, cpu_tss) = {
|
||||
.io_bitmap = { [0 ... IO_BITMAP_LONGS] = ~0 },
|
||||
#endif
|
||||
};
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(cpu_tss);
|
||||
EXPORT_PER_CPU_SYMBOL(cpu_tss);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static DEFINE_PER_CPU(unsigned char, is_idle);
|
||||
@ -156,11 +156,13 @@ void flush_thread(void)
|
||||
/* FPU state will be reallocated lazily at the first use. */
|
||||
drop_fpu(tsk);
|
||||
free_thread_xstate(tsk);
|
||||
} else if (!used_math()) {
|
||||
/* kthread execs. TODO: cleanup this horror. */
|
||||
if (WARN_ON(init_fpu(tsk)))
|
||||
force_sig(SIGKILL, tsk);
|
||||
user_fpu_begin();
|
||||
} else {
|
||||
if (!tsk_used_math(tsk)) {
|
||||
/* kthread execs. TODO: cleanup this horror. */
|
||||
if (WARN_ON(init_fpu(tsk)))
|
||||
force_sig(SIGKILL, tsk);
|
||||
user_fpu_begin();
|
||||
}
|
||||
restore_init_xstate();
|
||||
}
|
||||
}
|
||||
|
@ -351,18 +351,20 @@ int arch_ioremap_pmd_supported(void)
|
||||
*/
|
||||
void *xlate_dev_mem_ptr(phys_addr_t phys)
|
||||
{
|
||||
void *addr;
|
||||
unsigned long start = phys & PAGE_MASK;
|
||||
unsigned long start = phys & PAGE_MASK;
|
||||
unsigned long offset = phys & ~PAGE_MASK;
|
||||
unsigned long vaddr;
|
||||
|
||||
/* If page is RAM, we can use __va. Otherwise ioremap and unmap. */
|
||||
if (page_is_ram(start >> PAGE_SHIFT))
|
||||
return __va(phys);
|
||||
|
||||
addr = (void __force *)ioremap_cache(start, PAGE_SIZE);
|
||||
if (addr)
|
||||
addr = (void *)((unsigned long)addr | (phys & ~PAGE_MASK));
|
||||
vaddr = (unsigned long)ioremap_cache(start, PAGE_SIZE);
|
||||
/* Only add the offset on success and return NULL if the ioremap() failed: */
|
||||
if (vaddr)
|
||||
vaddr += offset;
|
||||
|
||||
return addr;
|
||||
return (void *)vaddr;
|
||||
}
|
||||
|
||||
void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr)
|
||||
|
@ -325,6 +325,26 @@ static void release_pci_root_info(struct pci_host_bridge *bridge)
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
/*
|
||||
* An IO port or MMIO resource assigned to a PCI host bridge may be
|
||||
* consumed by the host bridge itself or available to its child
|
||||
* bus/devices. The ACPI specification defines a bit (Producer/Consumer)
|
||||
* to tell whether the resource is consumed by the host bridge itself,
|
||||
* but firmware hasn't used that bit consistently, so we can't rely on it.
|
||||
*
|
||||
* On x86 and IA64 platforms, all IO port and MMIO resources are assumed
|
||||
* to be available to child bus/devices except one special case:
|
||||
* IO port [0xCF8-0xCFF] is consumed by the host bridge itself
|
||||
* to access PCI configuration space.
|
||||
*
|
||||
* So explicitly filter out PCI CFG IO ports[0xCF8-0xCFF].
|
||||
*/
|
||||
static bool resource_is_pcicfg_ioport(struct resource *res)
|
||||
{
|
||||
return (res->flags & IORESOURCE_IO) &&
|
||||
res->start == 0xCF8 && res->end == 0xCFF;
|
||||
}
|
||||
|
||||
static void probe_pci_root_info(struct pci_root_info *info,
|
||||
struct acpi_device *device,
|
||||
int busnum, int domain,
|
||||
@ -346,8 +366,8 @@ static void probe_pci_root_info(struct pci_root_info *info,
|
||||
"no IO and memory resources present in _CRS\n");
|
||||
else
|
||||
resource_list_for_each_entry_safe(entry, tmp, list) {
|
||||
if ((entry->res->flags & IORESOURCE_WINDOW) == 0 ||
|
||||
(entry->res->flags & IORESOURCE_DISABLED))
|
||||
if ((entry->res->flags & IORESOURCE_DISABLED) ||
|
||||
resource_is_pcicfg_ioport(entry->res))
|
||||
resource_list_destroy_entry(entry);
|
||||
else
|
||||
entry->res->name = info->name;
|
||||
|
@ -1760,6 +1760,9 @@ static struct notifier_block xen_hvm_cpu_notifier = {
|
||||
|
||||
static void __init xen_hvm_guest_init(void)
|
||||
{
|
||||
if (xen_pv_domain())
|
||||
return;
|
||||
|
||||
init_hvm_pv_info();
|
||||
|
||||
xen_hvm_init_shared_info();
|
||||
@ -1775,6 +1778,7 @@ static void __init xen_hvm_guest_init(void)
|
||||
xen_hvm_init_time_ops();
|
||||
xen_hvm_init_mmu_ops();
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool xen_nopv = false;
|
||||
static __init int xen_parse_nopv(char *arg)
|
||||
@ -1784,14 +1788,11 @@ static __init int xen_parse_nopv(char *arg)
|
||||
}
|
||||
early_param("xen_nopv", xen_parse_nopv);
|
||||
|
||||
static uint32_t __init xen_hvm_platform(void)
|
||||
static uint32_t __init xen_platform(void)
|
||||
{
|
||||
if (xen_nopv)
|
||||
return 0;
|
||||
|
||||
if (xen_pv_domain())
|
||||
return 0;
|
||||
|
||||
return xen_cpuid_base();
|
||||
}
|
||||
|
||||
@ -1809,11 +1810,19 @@ bool xen_hvm_need_lapic(void)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);
|
||||
|
||||
const struct hypervisor_x86 x86_hyper_xen_hvm __refconst = {
|
||||
.name = "Xen HVM",
|
||||
.detect = xen_hvm_platform,
|
||||
static void xen_set_cpu_features(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (xen_pv_domain())
|
||||
clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
|
||||
}
|
||||
|
||||
const struct hypervisor_x86 x86_hyper_xen = {
|
||||
.name = "Xen",
|
||||
.detect = xen_platform,
|
||||
#ifdef CONFIG_XEN_PVHVM
|
||||
.init_platform = xen_hvm_guest_init,
|
||||
.x2apic_available = xen_x2apic_para_available,
|
||||
};
|
||||
EXPORT_SYMBOL(x86_hyper_xen_hvm);
|
||||
#endif
|
||||
.x2apic_available = xen_x2apic_para_available,
|
||||
.set_cpu_features = xen_set_cpu_features,
|
||||
};
|
||||
EXPORT_SYMBOL(x86_hyper_xen);
|
||||
|
@ -88,7 +88,17 @@ static void xen_vcpu_notify_restore(void *data)
|
||||
tick_resume_local();
|
||||
}
|
||||
|
||||
static void xen_vcpu_notify_suspend(void *data)
|
||||
{
|
||||
tick_suspend_local();
|
||||
}
|
||||
|
||||
void xen_arch_resume(void)
|
||||
{
|
||||
on_each_cpu(xen_vcpu_notify_restore, NULL, 1);
|
||||
}
|
||||
|
||||
void xen_arch_suspend(void)
|
||||
{
|
||||
on_each_cpu(xen_vcpu_notify_suspend, NULL, 1);
|
||||
}
|
||||
|
@ -552,6 +552,8 @@ void blk_cleanup_queue(struct request_queue *q)
|
||||
q->queue_lock = &q->__queue_lock;
|
||||
spin_unlock_irq(lock);
|
||||
|
||||
bdi_destroy(&q->backing_dev_info);
|
||||
|
||||
/* @q is and will stay empty, shutdown and put */
|
||||
blk_put_queue(q);
|
||||
}
|
||||
|
@ -677,8 +677,11 @@ static void blk_mq_rq_timer(unsigned long priv)
|
||||
data.next = blk_rq_timeout(round_jiffies_up(data.next));
|
||||
mod_timer(&q->timeout, data.next);
|
||||
} else {
|
||||
queue_for_each_hw_ctx(q, hctx, i)
|
||||
blk_mq_tag_idle(hctx);
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
/* the hctx may be unmapped, so check it here */
|
||||
if (blk_mq_hw_queue_mapped(hctx))
|
||||
blk_mq_tag_idle(hctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -855,6 +858,16 @@ static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx)
|
||||
spin_lock(&hctx->lock);
|
||||
list_splice(&rq_list, &hctx->dispatch);
|
||||
spin_unlock(&hctx->lock);
|
||||
/*
|
||||
* the queue is expected stopped with BLK_MQ_RQ_QUEUE_BUSY, but
|
||||
* it's possible the queue is stopped and restarted again
|
||||
* before this. Queue restart will dispatch requests. And since
|
||||
* requests in rq_list aren't added into hctx->dispatch yet,
|
||||
* the requests in rq_list might get lost.
|
||||
*
|
||||
* blk_mq_run_hw_queue() already checks the STOPPED bit
|
||||
**/
|
||||
blk_mq_run_hw_queue(hctx, true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1571,22 +1584,6 @@ static int blk_mq_hctx_cpu_offline(struct blk_mq_hw_ctx *hctx, int cpu)
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int blk_mq_hctx_cpu_online(struct blk_mq_hw_ctx *hctx, int cpu)
|
||||
{
|
||||
struct request_queue *q = hctx->queue;
|
||||
struct blk_mq_tag_set *set = q->tag_set;
|
||||
|
||||
if (set->tags[hctx->queue_num])
|
||||
return NOTIFY_OK;
|
||||
|
||||
set->tags[hctx->queue_num] = blk_mq_init_rq_map(set, hctx->queue_num);
|
||||
if (!set->tags[hctx->queue_num])
|
||||
return NOTIFY_STOP;
|
||||
|
||||
hctx->tags = set->tags[hctx->queue_num];
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static int blk_mq_hctx_notify(void *data, unsigned long action,
|
||||
unsigned int cpu)
|
||||
{
|
||||
@ -1594,8 +1591,11 @@ static int blk_mq_hctx_notify(void *data, unsigned long action,
|
||||
|
||||
if (action == CPU_DEAD || action == CPU_DEAD_FROZEN)
|
||||
return blk_mq_hctx_cpu_offline(hctx, cpu);
|
||||
else if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN)
|
||||
return blk_mq_hctx_cpu_online(hctx, cpu);
|
||||
|
||||
/*
|
||||
* In case of CPU online, tags may be reallocated
|
||||
* in blk_mq_map_swqueue() after mapping is updated.
|
||||
*/
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
@ -1775,6 +1775,7 @@ static void blk_mq_map_swqueue(struct request_queue *q)
|
||||
unsigned int i;
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
struct blk_mq_ctx *ctx;
|
||||
struct blk_mq_tag_set *set = q->tag_set;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
cpumask_clear(hctx->cpumask);
|
||||
@ -1803,16 +1804,20 @@ static void blk_mq_map_swqueue(struct request_queue *q)
|
||||
* disable it and free the request entries.
|
||||
*/
|
||||
if (!hctx->nr_ctx) {
|
||||
struct blk_mq_tag_set *set = q->tag_set;
|
||||
|
||||
if (set->tags[i]) {
|
||||
blk_mq_free_rq_map(set, set->tags[i], i);
|
||||
set->tags[i] = NULL;
|
||||
hctx->tags = NULL;
|
||||
}
|
||||
hctx->tags = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* unmapped hw queue can be remapped after CPU topo changed */
|
||||
if (!set->tags[i])
|
||||
set->tags[i] = blk_mq_init_rq_map(set, i);
|
||||
hctx->tags = set->tags[i];
|
||||
WARN_ON(!hctx->tags);
|
||||
|
||||
/*
|
||||
* Set the map size to the number of mapped software queues.
|
||||
* This is more accurate and more efficient than looping
|
||||
@ -2090,9 +2095,16 @@ static int blk_mq_queue_reinit_notify(struct notifier_block *nb,
|
||||
*/
|
||||
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||
blk_mq_freeze_queue_start(q);
|
||||
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||
list_for_each_entry(q, &all_q_list, all_q_node) {
|
||||
blk_mq_freeze_queue_wait(q);
|
||||
|
||||
/*
|
||||
* timeout handler can't touch hw queue during the
|
||||
* reinitialization
|
||||
*/
|
||||
del_timer_sync(&q->timeout);
|
||||
}
|
||||
|
||||
list_for_each_entry(q, &all_q_list, all_q_node)
|
||||
blk_mq_queue_reinit(q);
|
||||
|
||||
|
@ -522,8 +522,6 @@ static void blk_release_queue(struct kobject *kobj)
|
||||
|
||||
blk_trace_shutdown(q);
|
||||
|
||||
bdi_destroy(&q->backing_dev_info);
|
||||
|
||||
ida_simple_remove(&blk_queue_ida, q->id);
|
||||
call_rcu(&q->rcu_head, blk_free_queue_rcu);
|
||||
}
|
||||
|
@ -221,8 +221,8 @@ bounce:
|
||||
if (page_to_pfn(page) <= queue_bounce_pfn(q) && !force)
|
||||
continue;
|
||||
|
||||
inc_zone_page_state(to->bv_page, NR_BOUNCE);
|
||||
to->bv_page = mempool_alloc(pool, q->bounce_gfp);
|
||||
inc_zone_page_state(to->bv_page, NR_BOUNCE);
|
||||
|
||||
if (rw == WRITE) {
|
||||
char *vto, *vfrom;
|
||||
|
@ -157,7 +157,7 @@ struct elevator_queue *elevator_alloc(struct request_queue *q,
|
||||
|
||||
eq = kzalloc_node(sizeof(*eq), GFP_KERNEL, q->node);
|
||||
if (unlikely(!eq))
|
||||
goto err;
|
||||
return NULL;
|
||||
|
||||
eq->type = e;
|
||||
kobject_init(&eq->kobj, &elv_ktype);
|
||||
@ -165,10 +165,6 @@ struct elevator_queue *elevator_alloc(struct request_queue *q,
|
||||
hash_init(eq->hash);
|
||||
|
||||
return eq;
|
||||
err:
|
||||
kfree(eq);
|
||||
elevator_put(e);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(elevator_alloc);
|
||||
|
||||
|
@ -304,6 +304,8 @@ static const struct acpi_device_id acpi_pnp_device_ids[] = {
|
||||
{"PNPb006"},
|
||||
/* cs423x-pnpbios */
|
||||
{"CSC0100"},
|
||||
{"CSC0103"},
|
||||
{"CSC0110"},
|
||||
{"CSC0000"},
|
||||
{"GIM0100"}, /* Guillemot Turtlebeach something appears to be cs4232 compatible */
|
||||
/* es18xx-pnpbios */
|
||||
|
@ -102,19 +102,12 @@ const struct acpi_predefined_names acpi_gbl_pre_defined_names[] = {
|
||||
{"_SB_", ACPI_TYPE_DEVICE, NULL},
|
||||
{"_SI_", ACPI_TYPE_LOCAL_SCOPE, NULL},
|
||||
{"_TZ_", ACPI_TYPE_DEVICE, NULL},
|
||||
/*
|
||||
* March, 2015:
|
||||
* The _REV object is in the process of being deprecated, because
|
||||
* other ACPI implementations permanently return 2. Thus, it
|
||||
* has little or no value. Return 2 for compatibility with
|
||||
* other ACPI implementations.
|
||||
*/
|
||||
{"_REV", ACPI_TYPE_INTEGER, ACPI_CAST_PTR(char, 2)},
|
||||
{"_REV", ACPI_TYPE_INTEGER, (char *)ACPI_CA_SUPPORT_LEVEL},
|
||||
{"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME},
|
||||
{"_GL_", ACPI_TYPE_MUTEX, ACPI_CAST_PTR(char, 1)},
|
||||
{"_GL_", ACPI_TYPE_MUTEX, (char *)1},
|
||||
|
||||
#if !defined (ACPI_NO_METHOD_EXECUTION) || defined (ACPI_CONSTANT_EVAL_ONLY)
|
||||
{"_OSI", ACPI_TYPE_METHOD, ACPI_CAST_PTR(char, 1)},
|
||||
{"_OSI", ACPI_TYPE_METHOD, (char *)1},
|
||||
#endif
|
||||
|
||||
/* Table terminator */
|
||||
|
@ -573,7 +573,7 @@ EXPORT_SYMBOL_GPL(acpi_dev_get_resources);
|
||||
* @ares: Input ACPI resource object.
|
||||
* @types: Valid resource types of IORESOURCE_XXX
|
||||
*
|
||||
* This is a hepler function to support acpi_dev_get_resources(), which filters
|
||||
* This is a helper function to support acpi_dev_get_resources(), which filters
|
||||
* ACPI resource objects according to resource types.
|
||||
*/
|
||||
int acpi_dev_filter_resource_type(struct acpi_resource *ares,
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/dmi.h>
|
||||
#include "sbshc.h"
|
||||
|
||||
#define PREFIX "ACPI: "
|
||||
@ -87,6 +88,8 @@ enum acpi_smb_offset {
|
||||
ACPI_SMB_ALARM_DATA = 0x26, /* 2 bytes alarm data */
|
||||
};
|
||||
|
||||
static bool macbook;
|
||||
|
||||
static inline int smb_hc_read(struct acpi_smb_hc *hc, u8 address, u8 *data)
|
||||
{
|
||||
return ec_read(hc->offset + address, data);
|
||||
@ -132,6 +135,8 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
|
||||
}
|
||||
|
||||
mutex_lock(&hc->lock);
|
||||
if (macbook)
|
||||
udelay(5);
|
||||
if (smb_hc_read(hc, ACPI_SMB_PROTOCOL, &temp))
|
||||
goto end;
|
||||
if (temp) {
|
||||
@ -257,12 +262,29 @@ extern int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit,
|
||||
acpi_handle handle, acpi_ec_query_func func,
|
||||
void *data);
|
||||
|
||||
static int macbook_dmi_match(const struct dmi_system_id *d)
|
||||
{
|
||||
pr_debug("Detected MacBook, enabling workaround\n");
|
||||
macbook = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dmi_system_id acpi_smbus_dmi_table[] = {
|
||||
{ macbook_dmi_match, "Apple MacBook", {
|
||||
DMI_MATCH(DMI_BOARD_VENDOR, "Apple"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "MacBook") },
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
static int acpi_smbus_hc_add(struct acpi_device *device)
|
||||
{
|
||||
int status;
|
||||
unsigned long long val;
|
||||
struct acpi_smb_hc *hc;
|
||||
|
||||
dmi_check_system(acpi_smbus_dmi_table);
|
||||
|
||||
if (!device)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1620,8 +1620,8 @@ out:
|
||||
|
||||
static void loop_remove(struct loop_device *lo)
|
||||
{
|
||||
del_gendisk(lo->lo_disk);
|
||||
blk_cleanup_queue(lo->lo_queue);
|
||||
del_gendisk(lo->lo_disk);
|
||||
blk_mq_free_tag_set(&lo->tag_set);
|
||||
put_disk(lo->lo_disk);
|
||||
kfree(lo);
|
||||
|
@ -944,7 +944,8 @@ static int nvme_trans_ext_inq_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
static int nvme_trans_bdev_limits_page(struct nvme_ns *ns, struct sg_io_hdr *hdr,
|
||||
u8 *inq_response, int alloc_len)
|
||||
{
|
||||
__be32 max_sectors = cpu_to_be32(queue_max_hw_sectors(ns->queue));
|
||||
__be32 max_sectors = cpu_to_be32(
|
||||
nvme_block_nr(ns, queue_max_hw_sectors(ns->queue)));
|
||||
__be32 max_discard = cpu_to_be32(ns->queue->limits.max_discard_sectors);
|
||||
__be32 discard_desc_count = cpu_to_be32(0x100);
|
||||
|
||||
|
@ -265,17 +265,6 @@ static void put_persistent_gnt(struct xen_blkif *blkif,
|
||||
atomic_dec(&blkif->persistent_gnt_in_use);
|
||||
}
|
||||
|
||||
static void free_persistent_gnts_unmap_callback(int result,
|
||||
struct gntab_unmap_queue_data *data)
|
||||
{
|
||||
struct completion *c = data->data;
|
||||
|
||||
/* BUG_ON used to reproduce existing behaviour,
|
||||
but is this the best way to deal with this? */
|
||||
BUG_ON(result);
|
||||
complete(c);
|
||||
}
|
||||
|
||||
static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
|
||||
unsigned int num)
|
||||
{
|
||||
@ -285,12 +274,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
|
||||
struct rb_node *n;
|
||||
int segs_to_unmap = 0;
|
||||
struct gntab_unmap_queue_data unmap_data;
|
||||
struct completion unmap_completion;
|
||||
|
||||
init_completion(&unmap_completion);
|
||||
|
||||
unmap_data.data = &unmap_completion;
|
||||
unmap_data.done = &free_persistent_gnts_unmap_callback;
|
||||
unmap_data.pages = pages;
|
||||
unmap_data.unmap_ops = unmap;
|
||||
unmap_data.kunmap_ops = NULL;
|
||||
@ -310,8 +294,7 @@ static void free_persistent_gnts(struct xen_blkif *blkif, struct rb_root *root,
|
||||
!rb_next(&persistent_gnt->node)) {
|
||||
|
||||
unmap_data.count = segs_to_unmap;
|
||||
gnttab_unmap_refs_async(&unmap_data);
|
||||
wait_for_completion(&unmap_completion);
|
||||
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
|
||||
|
||||
put_free_pages(blkif, pages, segs_to_unmap);
|
||||
segs_to_unmap = 0;
|
||||
@ -329,8 +312,13 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
|
||||
struct gnttab_unmap_grant_ref unmap[BLKIF_MAX_SEGMENTS_PER_REQUEST];
|
||||
struct page *pages[BLKIF_MAX_SEGMENTS_PER_REQUEST];
|
||||
struct persistent_gnt *persistent_gnt;
|
||||
int ret, segs_to_unmap = 0;
|
||||
int segs_to_unmap = 0;
|
||||
struct xen_blkif *blkif = container_of(work, typeof(*blkif), persistent_purge_work);
|
||||
struct gntab_unmap_queue_data unmap_data;
|
||||
|
||||
unmap_data.pages = pages;
|
||||
unmap_data.unmap_ops = unmap;
|
||||
unmap_data.kunmap_ops = NULL;
|
||||
|
||||
while(!list_empty(&blkif->persistent_purge_list)) {
|
||||
persistent_gnt = list_first_entry(&blkif->persistent_purge_list,
|
||||
@ -346,17 +334,16 @@ void xen_blkbk_unmap_purged_grants(struct work_struct *work)
|
||||
pages[segs_to_unmap] = persistent_gnt->page;
|
||||
|
||||
if (++segs_to_unmap == BLKIF_MAX_SEGMENTS_PER_REQUEST) {
|
||||
ret = gnttab_unmap_refs(unmap, NULL, pages,
|
||||
segs_to_unmap);
|
||||
BUG_ON(ret);
|
||||
unmap_data.count = segs_to_unmap;
|
||||
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
|
||||
put_free_pages(blkif, pages, segs_to_unmap);
|
||||
segs_to_unmap = 0;
|
||||
}
|
||||
kfree(persistent_gnt);
|
||||
}
|
||||
if (segs_to_unmap > 0) {
|
||||
ret = gnttab_unmap_refs(unmap, NULL, pages, segs_to_unmap);
|
||||
BUG_ON(ret);
|
||||
unmap_data.count = segs_to_unmap;
|
||||
BUG_ON(gnttab_unmap_refs_sync(&unmap_data));
|
||||
put_free_pages(blkif, pages, segs_to_unmap);
|
||||
}
|
||||
}
|
||||
|
@ -74,6 +74,27 @@ static inline struct zram *dev_to_zram(struct device *dev)
|
||||
return (struct zram *)dev_to_disk(dev)->private_data;
|
||||
}
|
||||
|
||||
static ssize_t compact_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t len)
|
||||
{
|
||||
unsigned long nr_migrated;
|
||||
struct zram *zram = dev_to_zram(dev);
|
||||
struct zram_meta *meta;
|
||||
|
||||
down_read(&zram->init_lock);
|
||||
if (!init_done(zram)) {
|
||||
up_read(&zram->init_lock);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
meta = zram->meta;
|
||||
nr_migrated = zs_compact(meta->mem_pool);
|
||||
atomic64_add(nr_migrated, &zram->stats.num_migrated);
|
||||
up_read(&zram->init_lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t disksize_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
@ -1038,6 +1059,7 @@ static const struct block_device_operations zram_devops = {
|
||||
.owner = THIS_MODULE
|
||||
};
|
||||
|
||||
static DEVICE_ATTR_WO(compact);
|
||||
static DEVICE_ATTR_RW(disksize);
|
||||
static DEVICE_ATTR_RO(initstate);
|
||||
static DEVICE_ATTR_WO(reset);
|
||||
@ -1114,6 +1136,7 @@ static struct attribute *zram_disk_attrs[] = {
|
||||
&dev_attr_num_writes.attr,
|
||||
&dev_attr_failed_reads.attr,
|
||||
&dev_attr_failed_writes.attr,
|
||||
&dev_attr_compact.attr,
|
||||
&dev_attr_invalid_io.attr,
|
||||
&dev_attr_notify_free.attr,
|
||||
&dev_attr_zero_pages.attr,
|
||||
|
@ -660,7 +660,7 @@ validate_group(struct perf_event *event)
|
||||
* Initialise the fake PMU. We only need to populate the
|
||||
* used_mask for the purposes of validation.
|
||||
*/
|
||||
.used_mask = CPU_BITS_NONE,
|
||||
.used_mask = { 0 },
|
||||
};
|
||||
|
||||
if (!validate_event(event->pmu, &fake_pmu, leader))
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* OMAP L3 Interconnect error handling driver
|
||||
*
|
||||
* Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
* Sricharan <r.sricharan@ti.com>
|
||||
*
|
||||
@ -233,7 +233,8 @@ static irqreturn_t l3_interrupt_handler(int irq, void *_l3)
|
||||
}
|
||||
|
||||
static const struct of_device_id l3_noc_match[] = {
|
||||
{.compatible = "ti,omap4-l3-noc", .data = &omap_l3_data},
|
||||
{.compatible = "ti,omap4-l3-noc", .data = &omap4_l3_data},
|
||||
{.compatible = "ti,omap5-l3-noc", .data = &omap5_l3_data},
|
||||
{.compatible = "ti,dra7-l3-noc", .data = &dra_l3_data},
|
||||
{.compatible = "ti,am4372-l3-noc", .data = &am4372_l3_data},
|
||||
{},
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* OMAP L3 Interconnect error handling driver header
|
||||
*
|
||||
* Copyright (C) 2011-2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Copyright (C) 2011-2015 Texas Instruments Incorporated - http://www.ti.com/
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
* sricharan <r.sricharan@ti.com>
|
||||
*
|
||||
@ -175,16 +175,14 @@ static struct l3_flagmux_data omap_l3_flagmux_clk2 = {
|
||||
};
|
||||
|
||||
|
||||
static struct l3_target_data omap_l3_target_data_clk3[] = {
|
||||
{0x0100, "EMUSS",},
|
||||
{0x0300, "DEBUG SOURCE",},
|
||||
{0x0, "HOST CLK3",},
|
||||
static struct l3_target_data omap4_l3_target_data_clk3[] = {
|
||||
{0x0100, "DEBUGSS",},
|
||||
};
|
||||
|
||||
static struct l3_flagmux_data omap_l3_flagmux_clk3 = {
|
||||
static struct l3_flagmux_data omap4_l3_flagmux_clk3 = {
|
||||
.offset = 0x0200,
|
||||
.l3_targ = omap_l3_target_data_clk3,
|
||||
.num_targ_data = ARRAY_SIZE(omap_l3_target_data_clk3),
|
||||
.l3_targ = omap4_l3_target_data_clk3,
|
||||
.num_targ_data = ARRAY_SIZE(omap4_l3_target_data_clk3),
|
||||
};
|
||||
|
||||
static struct l3_masters_data omap_l3_masters[] = {
|
||||
@ -215,21 +213,49 @@ static struct l3_masters_data omap_l3_masters[] = {
|
||||
{ 0x32, "USBHOSTFS"}
|
||||
};
|
||||
|
||||
static struct l3_flagmux_data *omap_l3_flagmux[] = {
|
||||
static struct l3_flagmux_data *omap4_l3_flagmux[] = {
|
||||
&omap_l3_flagmux_clk1,
|
||||
&omap_l3_flagmux_clk2,
|
||||
&omap_l3_flagmux_clk3,
|
||||
&omap4_l3_flagmux_clk3,
|
||||
};
|
||||
|
||||
static const struct omap_l3 omap_l3_data = {
|
||||
.l3_flagmux = omap_l3_flagmux,
|
||||
.num_modules = ARRAY_SIZE(omap_l3_flagmux),
|
||||
static const struct omap_l3 omap4_l3_data = {
|
||||
.l3_flagmux = omap4_l3_flagmux,
|
||||
.num_modules = ARRAY_SIZE(omap4_l3_flagmux),
|
||||
.l3_masters = omap_l3_masters,
|
||||
.num_masters = ARRAY_SIZE(omap_l3_masters),
|
||||
/* The 6 MSBs of register field used to distinguish initiator */
|
||||
.mst_addr_mask = 0xFC,
|
||||
};
|
||||
|
||||
/* OMAP5 data */
|
||||
static struct l3_target_data omap5_l3_target_data_clk3[] = {
|
||||
{0x0100, "L3INSTR",},
|
||||
{0x0300, "DEBUGSS",},
|
||||
{0x0, "HOSTCLK3",},
|
||||
};
|
||||
|
||||
static struct l3_flagmux_data omap5_l3_flagmux_clk3 = {
|
||||
.offset = 0x0200,
|
||||
.l3_targ = omap5_l3_target_data_clk3,
|
||||
.num_targ_data = ARRAY_SIZE(omap5_l3_target_data_clk3),
|
||||
};
|
||||
|
||||
static struct l3_flagmux_data *omap5_l3_flagmux[] = {
|
||||
&omap_l3_flagmux_clk1,
|
||||
&omap_l3_flagmux_clk2,
|
||||
&omap5_l3_flagmux_clk3,
|
||||
};
|
||||
|
||||
static const struct omap_l3 omap5_l3_data = {
|
||||
.l3_flagmux = omap5_l3_flagmux,
|
||||
.num_modules = ARRAY_SIZE(omap5_l3_flagmux),
|
||||
.l3_masters = omap_l3_masters,
|
||||
.num_masters = ARRAY_SIZE(omap_l3_masters),
|
||||
/* The 6 MSBs of register field used to distinguish initiator */
|
||||
.mst_addr_mask = 0x7E0,
|
||||
};
|
||||
|
||||
/* DRA7 data */
|
||||
static struct l3_target_data dra_l3_target_data_clk1[] = {
|
||||
{0x2a00, "AES1",},
|
||||
@ -274,7 +300,7 @@ static struct l3_flagmux_data dra_l3_flagmux_clk1 = {
|
||||
|
||||
static struct l3_target_data dra_l3_target_data_clk2[] = {
|
||||
{0x0, "HOST CLK1",},
|
||||
{0x0, "HOST CLK2",},
|
||||
{0x800000, "HOST CLK2",},
|
||||
{0xdead, L3_TARGET_NOT_SUPPORTED,},
|
||||
{0x3400, "SHA2_2",},
|
||||
{0x0900, "BB2D",},
|
||||
|
@ -57,7 +57,7 @@ static void bcm63xx_rng_cleanup(struct hwrng *rng)
|
||||
val &= ~RNG_EN;
|
||||
__raw_writel(val, priv->regs + RNG_CTRL);
|
||||
|
||||
clk_didsable_unprepare(prov->clk);
|
||||
clk_disable_unprepare(priv->clk);
|
||||
}
|
||||
|
||||
static int bcm63xx_rng_data_present(struct hwrng *rng, int wait)
|
||||
@ -97,14 +97,14 @@ static int bcm63xx_rng_probe(struct platform_device *pdev)
|
||||
priv->rng.name = pdev->name;
|
||||
priv->rng.init = bcm63xx_rng_init;
|
||||
priv->rng.cleanup = bcm63xx_rng_cleanup;
|
||||
prov->rng.data_present = bcm63xx_rng_data_present;
|
||||
priv->rng.data_present = bcm63xx_rng_data_present;
|
||||
priv->rng.data_read = bcm63xx_rng_data_read;
|
||||
|
||||
priv->clk = devm_clk_get(&pdev->dev, "ipsec");
|
||||
if (IS_ERR(priv->clk)) {
|
||||
error = PTR_ERR(priv->clk);
|
||||
dev_err(&pdev->dev, "no clock for device: %d\n", error);
|
||||
return error;
|
||||
ret = PTR_ERR(priv->clk);
|
||||
dev_err(&pdev->dev, "no clock for device: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, r->start,
|
||||
@ -120,11 +120,11 @@ static int bcm63xx_rng_probe(struct platform_device *pdev)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
error = devm_hwrng_register(&pdev->dev, &priv->rng);
|
||||
if (error) {
|
||||
ret = devm_hwrng_register(&pdev->dev, &priv->rng);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register rng device: %d\n",
|
||||
error);
|
||||
return error;
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(&pdev->dev, "registered RNG driver\n");
|
||||
|
@ -2000,7 +2000,7 @@ static int smi_ipmb_proc_show(struct seq_file *m, void *v)
|
||||
seq_printf(m, " %x", intf->channels[i].address);
|
||||
seq_putc(m, '\n');
|
||||
|
||||
return seq_has_overflowed(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
|
||||
@ -2023,7 +2023,7 @@ static int smi_version_proc_show(struct seq_file *m, void *v)
|
||||
ipmi_version_major(&intf->bmc->id),
|
||||
ipmi_version_minor(&intf->bmc->id));
|
||||
|
||||
return seq_has_overflowed(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smi_version_proc_open(struct inode *inode, struct file *file)
|
||||
|
@ -942,8 +942,7 @@ static void sender(void *send_info,
|
||||
* If we are running to completion, start it and run
|
||||
* transactions until everything is clear.
|
||||
*/
|
||||
smi_info->curr_msg = msg;
|
||||
smi_info->waiting_msg = NULL;
|
||||
smi_info->waiting_msg = msg;
|
||||
|
||||
/*
|
||||
* Run to completion means we are single-threaded, no
|
||||
@ -2244,7 +2243,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev,
|
||||
acpi_handle handle;
|
||||
acpi_status status;
|
||||
unsigned long long tmp;
|
||||
int rv;
|
||||
int rv = -EINVAL;
|
||||
|
||||
acpi_dev = pnp_acpi_device(dev);
|
||||
if (!acpi_dev)
|
||||
@ -2262,8 +2261,10 @@ static int ipmi_pnp_probe(struct pnp_dev *dev,
|
||||
|
||||
/* _IFT tells us the interface type: KCS, BT, etc */
|
||||
status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp);
|
||||
if (ACPI_FAILURE(status))
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(&dev->dev, "Could not find ACPI IPMI interface type\n");
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
switch (tmp) {
|
||||
case 1:
|
||||
@ -2276,6 +2277,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev,
|
||||
info->si_type = SI_BT;
|
||||
break;
|
||||
case 4: /* SSIF, just ignore */
|
||||
rv = -ENODEV;
|
||||
goto err_free;
|
||||
default:
|
||||
dev_info(&dev->dev, "unknown IPMI type %lld\n", tmp);
|
||||
@ -2336,7 +2338,7 @@ static int ipmi_pnp_probe(struct pnp_dev *dev,
|
||||
|
||||
err_free:
|
||||
kfree(info);
|
||||
return -EINVAL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
static void ipmi_pnp_remove(struct pnp_dev *dev)
|
||||
@ -3080,7 +3082,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v)
|
||||
|
||||
seq_printf(m, "%s\n", si_to_str[smi->si_type]);
|
||||
|
||||
return seq_has_overflowed(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smi_type_proc_open(struct inode *inode, struct file *file)
|
||||
@ -3153,7 +3155,7 @@ static int smi_params_proc_show(struct seq_file *m, void *v)
|
||||
smi->irq,
|
||||
smi->slave_addr);
|
||||
|
||||
return seq_has_overflowed(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smi_params_proc_open(struct inode *inode, struct file *file)
|
||||
|
@ -31,7 +31,6 @@
|
||||
* interface into the I2C driver, I believe.
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#if defined(MODVERSIONS)
|
||||
#include <linux/modversions.h>
|
||||
#endif
|
||||
@ -166,6 +165,9 @@ enum ssif_stat_indexes {
|
||||
/* Number of watchdog pretimeouts. */
|
||||
SSIF_STAT_watchdog_pretimeouts,
|
||||
|
||||
/* Number of alers received. */
|
||||
SSIF_STAT_alerts,
|
||||
|
||||
/* Always add statistics before this value, it must be last. */
|
||||
SSIF_NUM_STATS
|
||||
};
|
||||
@ -214,7 +216,16 @@ struct ssif_info {
|
||||
#define WDT_PRE_TIMEOUT_INT 0x08
|
||||
unsigned char msg_flags;
|
||||
|
||||
u8 global_enables;
|
||||
bool has_event_buffer;
|
||||
bool supports_alert;
|
||||
|
||||
/*
|
||||
* Used to tell what we should do with alerts. If we are
|
||||
* waiting on a response, read the data immediately.
|
||||
*/
|
||||
bool got_alert;
|
||||
bool waiting_alert;
|
||||
|
||||
/*
|
||||
* If set to true, this will request events the next time the
|
||||
@ -478,13 +489,13 @@ static int ipmi_ssif_thread(void *data)
|
||||
|
||||
if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) {
|
||||
result = i2c_smbus_write_block_data(
|
||||
ssif_info->client, SSIF_IPMI_REQUEST,
|
||||
ssif_info->client, ssif_info->i2c_command,
|
||||
ssif_info->i2c_data[0],
|
||||
ssif_info->i2c_data + 1);
|
||||
ssif_info->done_handler(ssif_info, result, NULL, 0);
|
||||
} else {
|
||||
result = i2c_smbus_read_block_data(
|
||||
ssif_info->client, SSIF_IPMI_RESPONSE,
|
||||
ssif_info->client, ssif_info->i2c_command,
|
||||
ssif_info->i2c_data);
|
||||
if (result < 0)
|
||||
ssif_info->done_handler(ssif_info, result,
|
||||
@ -518,15 +529,12 @@ static int ssif_i2c_send(struct ssif_info *ssif_info,
|
||||
static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
unsigned char *data, unsigned int len);
|
||||
|
||||
static void retry_timeout(unsigned long data)
|
||||
static void start_get(struct ssif_info *ssif_info)
|
||||
{
|
||||
struct ssif_info *ssif_info = (void *) data;
|
||||
int rv;
|
||||
|
||||
if (ssif_info->stopping)
|
||||
return;
|
||||
|
||||
ssif_info->rtc_us_timer = 0;
|
||||
ssif_info->multi_pos = 0;
|
||||
|
||||
rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ,
|
||||
SSIF_IPMI_RESPONSE,
|
||||
@ -540,6 +548,46 @@ static void retry_timeout(unsigned long data)
|
||||
}
|
||||
}
|
||||
|
||||
static void retry_timeout(unsigned long data)
|
||||
{
|
||||
struct ssif_info *ssif_info = (void *) data;
|
||||
unsigned long oflags, *flags;
|
||||
bool waiting;
|
||||
|
||||
if (ssif_info->stopping)
|
||||
return;
|
||||
|
||||
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
||||
waiting = ssif_info->waiting_alert;
|
||||
ssif_info->waiting_alert = false;
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
|
||||
if (waiting)
|
||||
start_get(ssif_info);
|
||||
}
|
||||
|
||||
|
||||
static void ssif_alert(struct i2c_client *client, unsigned int data)
|
||||
{
|
||||
struct ssif_info *ssif_info = i2c_get_clientdata(client);
|
||||
unsigned long oflags, *flags;
|
||||
bool do_get = false;
|
||||
|
||||
ssif_inc_stat(ssif_info, alerts);
|
||||
|
||||
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
||||
if (ssif_info->waiting_alert) {
|
||||
ssif_info->waiting_alert = false;
|
||||
del_timer(&ssif_info->retry_timer);
|
||||
do_get = true;
|
||||
} else if (ssif_info->curr_msg) {
|
||||
ssif_info->got_alert = true;
|
||||
}
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
if (do_get)
|
||||
start_get(ssif_info);
|
||||
}
|
||||
|
||||
static int start_resend(struct ssif_info *ssif_info);
|
||||
|
||||
static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
@ -559,9 +607,12 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
if (ssif_info->retries_left > 0) {
|
||||
ssif_inc_stat(ssif_info, receive_retries);
|
||||
|
||||
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
||||
ssif_info->waiting_alert = true;
|
||||
ssif_info->rtc_us_timer = SSIF_MSG_USEC;
|
||||
mod_timer(&ssif_info->retry_timer,
|
||||
jiffies + SSIF_MSG_JIFFIES);
|
||||
ssif_info->rtc_us_timer = SSIF_MSG_USEC;
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -581,9 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
ssif_inc_stat(ssif_info, received_message_parts);
|
||||
|
||||
/* Remove the multi-part read marker. */
|
||||
for (i = 0; i < (len-2); i++)
|
||||
ssif_info->data[i] = data[i+2];
|
||||
len -= 2;
|
||||
for (i = 0; i < len; i++)
|
||||
ssif_info->data[i] = data[i+2];
|
||||
ssif_info->multi_len = len;
|
||||
ssif_info->multi_pos = 1;
|
||||
|
||||
@ -610,9 +661,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
goto continue_op;
|
||||
}
|
||||
|
||||
blocknum = data[ssif_info->multi_len];
|
||||
blocknum = data[0];
|
||||
|
||||
if (ssif_info->multi_len+len-1 > IPMI_MAX_MSG_LENGTH) {
|
||||
if (ssif_info->multi_len + len - 1 > IPMI_MAX_MSG_LENGTH) {
|
||||
/* Received message too big, abort the operation. */
|
||||
result = -E2BIG;
|
||||
if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
|
||||
@ -622,15 +673,15 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
}
|
||||
|
||||
/* Remove the blocknum from the data. */
|
||||
for (i = 0; i < (len-1); i++)
|
||||
ssif_info->data[i+ssif_info->multi_len] = data[i+1];
|
||||
len--;
|
||||
for (i = 0; i < len; i++)
|
||||
ssif_info->data[i + ssif_info->multi_len] = data[i + 1];
|
||||
ssif_info->multi_len += len;
|
||||
if (blocknum == 0xff) {
|
||||
/* End of read */
|
||||
len = ssif_info->multi_len;
|
||||
data = ssif_info->data;
|
||||
} else if ((blocknum+1) != ssif_info->multi_pos) {
|
||||
} else if (blocknum + 1 != ssif_info->multi_pos) {
|
||||
/*
|
||||
* Out of sequence block, just abort. Block
|
||||
* numbers start at zero for the second block,
|
||||
@ -650,7 +701,7 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
|
||||
if (rv < 0) {
|
||||
if (ssif_info->ssif_debug & SSIF_DEBUG_MSG)
|
||||
pr_info(PFX
|
||||
"Error from i2c_non_blocking_op(2)\n");
|
||||
"Error from ssif_i2c_send\n");
|
||||
|
||||
result = -EIO;
|
||||
} else
|
||||
@ -830,7 +881,11 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
||||
}
|
||||
|
||||
if (ssif_info->multi_data) {
|
||||
/* In the middle of a multi-data write. */
|
||||
/*
|
||||
* In the middle of a multi-data write. See the comment
|
||||
* in the SSIF_MULTI_n_PART case in the probe function
|
||||
* for details on the intricacies of this.
|
||||
*/
|
||||
int left;
|
||||
|
||||
ssif_inc_stat(ssif_info, sent_messages_parts);
|
||||
@ -864,15 +919,32 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
|
||||
msg_done_handler(ssif_info, -EIO, NULL, 0);
|
||||
}
|
||||
} else {
|
||||
unsigned long oflags, *flags;
|
||||
bool got_alert;
|
||||
|
||||
ssif_inc_stat(ssif_info, sent_messages);
|
||||
ssif_inc_stat(ssif_info, sent_messages_parts);
|
||||
|
||||
/* Wait a jiffie then request the next message */
|
||||
ssif_info->retries_left = SSIF_RECV_RETRIES;
|
||||
ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC;
|
||||
mod_timer(&ssif_info->retry_timer,
|
||||
jiffies + SSIF_MSG_PART_JIFFIES);
|
||||
return;
|
||||
flags = ipmi_ssif_lock_cond(ssif_info, &oflags);
|
||||
got_alert = ssif_info->got_alert;
|
||||
if (got_alert) {
|
||||
ssif_info->got_alert = false;
|
||||
ssif_info->waiting_alert = false;
|
||||
}
|
||||
|
||||
if (got_alert) {
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
/* The alert already happened, try now. */
|
||||
retry_timeout((unsigned long) ssif_info);
|
||||
} else {
|
||||
/* Wait a jiffie then request the next message */
|
||||
ssif_info->waiting_alert = true;
|
||||
ssif_info->retries_left = SSIF_RECV_RETRIES;
|
||||
ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC;
|
||||
mod_timer(&ssif_info->retry_timer,
|
||||
jiffies + SSIF_MSG_PART_JIFFIES);
|
||||
ipmi_ssif_unlock_cond(ssif_info, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -881,6 +953,8 @@ static int start_resend(struct ssif_info *ssif_info)
|
||||
int rv;
|
||||
int command;
|
||||
|
||||
ssif_info->got_alert = false;
|
||||
|
||||
if (ssif_info->data_len > 32) {
|
||||
command = SSIF_IPMI_MULTI_PART_REQUEST_START;
|
||||
ssif_info->multi_data = ssif_info->data;
|
||||
@ -915,7 +989,7 @@ static int start_send(struct ssif_info *ssif_info,
|
||||
return -E2BIG;
|
||||
|
||||
ssif_info->retries_left = SSIF_SEND_RETRIES;
|
||||
memcpy(ssif_info->data+1, data, len);
|
||||
memcpy(ssif_info->data + 1, data, len);
|
||||
ssif_info->data_len = len;
|
||||
return start_resend(ssif_info);
|
||||
}
|
||||
@ -1200,7 +1274,7 @@ static int smi_type_proc_show(struct seq_file *m, void *v)
|
||||
{
|
||||
seq_puts(m, "ssif\n");
|
||||
|
||||
return seq_has_overflowed(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smi_type_proc_open(struct inode *inode, struct file *file)
|
||||
@ -1243,6 +1317,8 @@ static int smi_stats_proc_show(struct seq_file *m, void *v)
|
||||
ssif_get_stat(ssif_info, events));
|
||||
seq_printf(m, "watchdog_pretimeouts: %u\n",
|
||||
ssif_get_stat(ssif_info, watchdog_pretimeouts));
|
||||
seq_printf(m, "alerts: %u\n",
|
||||
ssif_get_stat(ssif_info, alerts));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1258,6 +1334,23 @@ static const struct file_operations smi_stats_proc_ops = {
|
||||
.release = single_release,
|
||||
};
|
||||
|
||||
static int strcmp_nospace(char *s1, char *s2)
|
||||
{
|
||||
while (*s1 && *s2) {
|
||||
while (isspace(*s1))
|
||||
s1++;
|
||||
while (isspace(*s2))
|
||||
s2++;
|
||||
if (*s1 > *s2)
|
||||
return 1;
|
||||
if (*s1 < *s2)
|
||||
return -1;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct ssif_addr_info *ssif_info_find(unsigned short addr,
|
||||
char *adapter_name,
|
||||
bool match_null_name)
|
||||
@ -1272,8 +1365,10 @@ restart:
|
||||
/* One is NULL and one is not */
|
||||
continue;
|
||||
}
|
||||
if (strcmp(info->adapter_name, adapter_name))
|
||||
/* Names to not match */
|
||||
if (adapter_name &&
|
||||
strcmp_nospace(info->adapter_name,
|
||||
adapter_name))
|
||||
/* Names do not match */
|
||||
continue;
|
||||
}
|
||||
found = info;
|
||||
@ -1306,6 +1401,12 @@ static bool check_acpi(struct ssif_info *ssif_info, struct device *dev)
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Global enables we care about.
|
||||
*/
|
||||
#define GLOBAL_ENABLES_MASK (IPMI_BMC_EVT_MSG_BUFF | IPMI_BMC_RCV_MSG_INTR | \
|
||||
IPMI_BMC_EVT_MSG_INTR)
|
||||
|
||||
static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
{
|
||||
unsigned char msg[3];
|
||||
@ -1391,13 +1492,33 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
break;
|
||||
|
||||
case SSIF_MULTI_2_PART:
|
||||
if (ssif_info->max_xmit_msg_size > 64)
|
||||
ssif_info->max_xmit_msg_size = 64;
|
||||
if (ssif_info->max_xmit_msg_size > 63)
|
||||
ssif_info->max_xmit_msg_size = 63;
|
||||
if (ssif_info->max_recv_msg_size > 62)
|
||||
ssif_info->max_recv_msg_size = 62;
|
||||
break;
|
||||
|
||||
case SSIF_MULTI_n_PART:
|
||||
/*
|
||||
* The specification is rather confusing at
|
||||
* this point, but I think I understand what
|
||||
* is meant. At least I have a workable
|
||||
* solution. With multi-part messages, you
|
||||
* cannot send a message that is a multiple of
|
||||
* 32-bytes in length, because the start and
|
||||
* middle messages are 32-bytes and the end
|
||||
* message must be at least one byte. You
|
||||
* can't fudge on an extra byte, that would
|
||||
* screw up things like fru data writes. So
|
||||
* we limit the length to 63 bytes. That way
|
||||
* a 32-byte message gets sent as a single
|
||||
* part. A larger message will be a 32-byte
|
||||
* start and the next message is always going
|
||||
* to be 1-31 bytes in length. Not ideal, but
|
||||
* it should work.
|
||||
*/
|
||||
if (ssif_info->max_xmit_msg_size > 63)
|
||||
ssif_info->max_xmit_msg_size = 63;
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -1407,7 +1528,7 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
} else {
|
||||
no_support:
|
||||
/* Assume no multi-part or PEC support */
|
||||
pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n",
|
||||
pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n",
|
||||
rv, len, resp[2]);
|
||||
|
||||
ssif_info->max_xmit_msg_size = 32;
|
||||
@ -1436,6 +1557,8 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
goto found;
|
||||
}
|
||||
|
||||
ssif_info->global_enables = resp[3];
|
||||
|
||||
if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) {
|
||||
ssif_info->has_event_buffer = true;
|
||||
/* buffer is already enabled, nothing to do. */
|
||||
@ -1444,18 +1567,37 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
||||
|
||||
msg[0] = IPMI_NETFN_APP_REQUEST << 2;
|
||||
msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
|
||||
msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF;
|
||||
msg[2] = ssif_info->global_enables | IPMI_BMC_EVT_MSG_BUFF;
|
||||
rv = do_cmd(client, 3, msg, &len, resp);
|
||||
if (rv || (len < 2)) {
|
||||
pr_warn(PFX "Error getting global enables: %d %d %2.2x\n",
|
||||
pr_warn(PFX "Error setting global enables: %d %d %2.2x\n",
|
||||
rv, len, resp[2]);
|
||||
rv = 0; /* Not fatal */
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (resp[2] == 0)
|
||||
if (resp[2] == 0) {
|
||||
/* A successful return means the event buffer is supported. */
|
||||
ssif_info->has_event_buffer = true;
|
||||
ssif_info->global_enables |= IPMI_BMC_EVT_MSG_BUFF;
|
||||
}
|
||||
|
||||
msg[0] = IPMI_NETFN_APP_REQUEST << 2;
|
||||
msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
|
||||
msg[2] = ssif_info->global_enables | IPMI_BMC_RCV_MSG_INTR;
|
||||
rv = do_cmd(client, 3, msg, &len, resp);
|
||||
if (rv || (len < 2)) {
|
||||
pr_warn(PFX "Error setting global enables: %d %d %2.2x\n",
|
||||
rv, len, resp[2]);
|
||||
rv = 0; /* Not fatal */
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (resp[2] == 0) {
|
||||
/* A successful return means the alert is supported. */
|
||||
ssif_info->supports_alert = true;
|
||||
ssif_info->global_enables |= IPMI_BMC_RCV_MSG_INTR;
|
||||
}
|
||||
|
||||
found:
|
||||
ssif_info->intf_num = atomic_inc_return(&next_intf);
|
||||
@ -1813,6 +1955,7 @@ static struct i2c_driver ssif_i2c_driver = {
|
||||
},
|
||||
.probe = ssif_probe,
|
||||
.remove = ssif_remove,
|
||||
.alert = ssif_alert,
|
||||
.id_table = ssif_id,
|
||||
.detect = ssif_detect
|
||||
};
|
||||
@ -1832,7 +1975,7 @@ static int init_ipmi_ssif(void)
|
||||
rv = new_ssif_client(addr[i], adapter_name[i],
|
||||
dbg[i], slave_addrs[i],
|
||||
SI_HARDCODED);
|
||||
if (!rv)
|
||||
if (rv)
|
||||
pr_err(PFX
|
||||
"Couldn't add hardcoded device at addr 0x%x\n",
|
||||
addr[i]);
|
||||
|
@ -120,7 +120,8 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
|
||||
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
|
||||
if (!entry) {
|
||||
kset_unregister(map_kset);
|
||||
return entry;
|
||||
map_kset = NULL;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
memcpy(&entry->md, efi_runtime_map + nr * efi_memdesc_size,
|
||||
@ -132,6 +133,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)
|
||||
if (ret) {
|
||||
kobject_put(&entry->kobj);
|
||||
kset_unregister(map_kset);
|
||||
map_kset = NULL;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
@ -195,8 +197,6 @@ out_add_entry:
|
||||
entry = *(map_entries + j);
|
||||
kobject_put(&entry->kobj);
|
||||
}
|
||||
if (map_kset)
|
||||
kset_unregister(map_kset);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
@ -1054,38 +1054,8 @@ static void omap_gpio_mod_init(struct gpio_bank *bank)
|
||||
dev_err(bank->dev, "Could not get gpio dbck\n");
|
||||
}
|
||||
|
||||
static void
|
||||
omap_mpuio_alloc_gc(struct gpio_bank *bank, unsigned int irq_start,
|
||||
unsigned int num)
|
||||
{
|
||||
struct irq_chip_generic *gc;
|
||||
struct irq_chip_type *ct;
|
||||
|
||||
gc = irq_alloc_generic_chip("MPUIO", 1, irq_start, bank->base,
|
||||
handle_simple_irq);
|
||||
if (!gc) {
|
||||
dev_err(bank->dev, "Memory alloc failed for gc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ct = gc->chip_types;
|
||||
|
||||
/* NOTE: No ack required, reading IRQ status clears it. */
|
||||
ct->chip.irq_mask = irq_gc_mask_set_bit;
|
||||
ct->chip.irq_unmask = irq_gc_mask_clr_bit;
|
||||
ct->chip.irq_set_type = omap_gpio_irq_type;
|
||||
|
||||
if (bank->regs->wkup_en)
|
||||
ct->chip.irq_set_wake = omap_gpio_wake_enable;
|
||||
|
||||
ct->regs.mask = OMAP_MPUIO_GPIO_INT / bank->stride;
|
||||
irq_setup_generic_chip(gc, IRQ_MSK(num), IRQ_GC_INIT_MASK_CACHE,
|
||||
IRQ_NOREQUEST | IRQ_NOPROBE, 0);
|
||||
}
|
||||
|
||||
static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
{
|
||||
int j;
|
||||
static int gpio;
|
||||
int irq_base = 0;
|
||||
int ret;
|
||||
@ -1132,6 +1102,15 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* MPUIO is a bit different, reading IRQ status clears it */
|
||||
if (bank->is_mpuio) {
|
||||
irqc->irq_ack = dummy_irq_chip.irq_ack;
|
||||
irqc->irq_mask = irq_gc_mask_set_bit;
|
||||
irqc->irq_unmask = irq_gc_mask_clr_bit;
|
||||
if (!bank->regs->wkup_en)
|
||||
irqc->irq_set_wake = NULL;
|
||||
}
|
||||
|
||||
ret = gpiochip_irqchip_add(&bank->chip, irqc,
|
||||
irq_base, omap_gpio_irq_handler,
|
||||
IRQ_TYPE_NONE);
|
||||
@ -1145,15 +1124,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct irq_chip *irqc)
|
||||
gpiochip_set_chained_irqchip(&bank->chip, irqc,
|
||||
bank->irq, omap_gpio_irq_handler);
|
||||
|
||||
for (j = 0; j < bank->width; j++) {
|
||||
int irq = irq_find_mapping(bank->chip.irqdomain, j);
|
||||
if (bank->is_mpuio) {
|
||||
omap_mpuio_alloc_gc(bank, irq, bank->width);
|
||||
irq_set_chip_and_handler(irq, NULL, NULL);
|
||||
set_irq_flags(irq, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -550,7 +550,7 @@ acpi_gpio_adr_space_handler(u32 function, acpi_physical_address address,
|
||||
|
||||
length = min(agpio->pin_table_length, (u16)(pin_index + bits));
|
||||
for (i = pin_index; i < length; ++i) {
|
||||
unsigned pin = agpio->pin_table[i];
|
||||
int pin = agpio->pin_table[i];
|
||||
struct acpi_gpio_connection *conn;
|
||||
struct gpio_desc *desc;
|
||||
bool found;
|
||||
|
@ -551,6 +551,7 @@ static struct class gpio_class = {
|
||||
*/
|
||||
int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
{
|
||||
struct gpio_chip *chip;
|
||||
unsigned long flags;
|
||||
int status;
|
||||
const char *ioname = NULL;
|
||||
@ -568,8 +569,16 @@ int gpiod_export(struct gpio_desc *desc, bool direction_may_change)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
chip = desc->chip;
|
||||
|
||||
mutex_lock(&sysfs_lock);
|
||||
|
||||
/* check if chip is being removed */
|
||||
if (!chip || !chip->exported) {
|
||||
status = -ENODEV;
|
||||
goto fail_unlock;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&gpio_lock, flags);
|
||||
if (!test_bit(FLAG_REQUESTED, &desc->flags) ||
|
||||
test_bit(FLAG_EXPORT, &desc->flags)) {
|
||||
@ -783,12 +792,15 @@ void gpiochip_unexport(struct gpio_chip *chip)
|
||||
{
|
||||
int status;
|
||||
struct device *dev;
|
||||
struct gpio_desc *desc;
|
||||
unsigned int i;
|
||||
|
||||
mutex_lock(&sysfs_lock);
|
||||
dev = class_find_device(&gpio_class, NULL, chip, match_export);
|
||||
if (dev) {
|
||||
put_device(dev);
|
||||
device_unregister(dev);
|
||||
/* prevent further gpiod exports */
|
||||
chip->exported = false;
|
||||
status = 0;
|
||||
} else
|
||||
@ -797,6 +809,13 @@ void gpiochip_unexport(struct gpio_chip *chip)
|
||||
|
||||
if (status)
|
||||
chip_dbg(chip, "%s: status %d\n", __func__, status);
|
||||
|
||||
/* unregister gpiod class devices owned by sysfs */
|
||||
for (i = 0; i < chip->ngpio; i++) {
|
||||
desc = &chip->desc[i];
|
||||
if (test_and_clear_bit(FLAG_SYSFS, &desc->flags))
|
||||
gpiod_free(desc);
|
||||
}
|
||||
}
|
||||
|
||||
static int __init gpiolib_sysfs_init(void)
|
||||
|
@ -430,9 +430,10 @@ static int unregister_process_nocpsch(struct device_queue_manager *dqm,
|
||||
|
||||
BUG_ON(!dqm || !qpd);
|
||||
|
||||
BUG_ON(!list_empty(&qpd->queues_list));
|
||||
pr_debug("In func %s\n", __func__);
|
||||
|
||||
pr_debug("kfd: In func %s\n", __func__);
|
||||
pr_debug("qpd->queues_list is %s\n",
|
||||
list_empty(&qpd->queues_list) ? "empty" : "not empty");
|
||||
|
||||
retval = 0;
|
||||
mutex_lock(&dqm->lock);
|
||||
@ -882,6 +883,8 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
init_sdma_vm(dqm, q, qpd);
|
||||
|
||||
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
|
||||
&q->gart_mqd_addr, &q->properties);
|
||||
if (retval != 0)
|
||||
|
@ -728,9 +728,9 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
|
||||
sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute",
|
||||
dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz(
|
||||
dev->gpu->kgd));
|
||||
|
||||
sysfs_show_64bit_prop(buffer, "local_mem_size",
|
||||
dev->gpu->kfd2kgd->get_vmem_size(
|
||||
dev->gpu->kgd));
|
||||
(unsigned long long int) 0);
|
||||
|
||||
sysfs_show_32bit_prop(buffer, "fw_version",
|
||||
dev->gpu->kfd2kgd->get_fw_version(
|
||||
|
@ -131,12 +131,11 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc)
|
||||
|
||||
/* Reinitialize corresponding vblank timestamp if high-precision query
|
||||
* available. Skip this step if query unsupported or failed. Will
|
||||
* reinitialize delayed at next vblank interrupt in that case.
|
||||
* reinitialize delayed at next vblank interrupt in that case and
|
||||
* assign 0 for now, to mark the vblanktimestamp as invalid.
|
||||
*/
|
||||
if (rc) {
|
||||
tslot = atomic_read(&vblank->count) + diff;
|
||||
vblanktimestamp(dev, crtc, tslot) = t_vblank;
|
||||
}
|
||||
tslot = atomic_read(&vblank->count) + diff;
|
||||
vblanktimestamp(dev, crtc, tslot) = rc ? t_vblank : (struct timeval) {0, 0};
|
||||
|
||||
smp_mb__before_atomic();
|
||||
atomic_add(diff, &vblank->count);
|
||||
|
@ -13635,9 +13635,6 @@ static const struct intel_dmi_quirk intel_dmi_quirks[] = {
|
||||
};
|
||||
|
||||
static struct intel_quirk intel_quirks[] = {
|
||||
/* HP Mini needs pipe A force quirk (LP: #322104) */
|
||||
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
|
||||
|
||||
/* Toshiba Protege R-205, S-209 needs pipe A force quirk */
|
||||
{ 0x2592, 0x1179, 0x0001, quirk_pipea_force },
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user