Merge branch 'fixes' into misc
This commit is contained in:
commit
e7ca7f9fa2
145 changed files with 1044 additions and 778 deletions
|
@ -1,13 +1,16 @@
|
|||
== Amlogic Meson pinmux controller ==
|
||||
|
||||
Required properties for the root node:
|
||||
- compatible: "amlogic,meson8-pinctrl" or "amlogic,meson8b-pinctrl"
|
||||
- compatible: one of "amlogic,meson8-cbus-pinctrl"
|
||||
"amlogic,meson8b-cbus-pinctrl"
|
||||
"amlogic,meson8-aobus-pinctrl"
|
||||
"amlogic,meson8b-aobus-pinctrl"
|
||||
- reg: address and size of registers controlling irq functionality
|
||||
|
||||
=== GPIO sub-nodes ===
|
||||
|
||||
The 2 power domains of the controller (regular and always-on) are
|
||||
represented as sub-nodes and each of them acts as a GPIO controller.
|
||||
The GPIO bank for the controller is represented as a sub-node and it acts as a
|
||||
GPIO controller.
|
||||
|
||||
Required properties for sub-nodes are:
|
||||
- reg: should contain address and size for mux, pull-enable, pull and
|
||||
|
@ -18,10 +21,6 @@ Required properties for sub-nodes are:
|
|||
- gpio-controller: identifies the node as a gpio controller
|
||||
- #gpio-cells: must be 2
|
||||
|
||||
Valid sub-node names are:
|
||||
- "banks" for the regular domain
|
||||
- "ao-bank" for the always-on domain
|
||||
|
||||
=== Other sub-nodes ===
|
||||
|
||||
Child nodes without the "gpio-controller" represent some desired
|
||||
|
@ -45,7 +44,7 @@ pinctrl-bindings.txt
|
|||
=== Example ===
|
||||
|
||||
pinctrl: pinctrl@c1109880 {
|
||||
compatible = "amlogic,meson8-pinctrl";
|
||||
compatible = "amlogic,meson8-cbus-pinctrl";
|
||||
reg = <0xc1109880 0x10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
@ -61,15 +60,6 @@ pinctrl-bindings.txt
|
|||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpio_ao: ao-bank@c1108030 {
|
||||
reg = <0xc8100014 0x4>,
|
||||
<0xc810002c 0x4>,
|
||||
<0xc8100024 0x8>;
|
||||
reg-names = "mux", "pull", "gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
nand {
|
||||
mux {
|
||||
groups = "nand_io", "nand_io_ce0", "nand_io_ce1",
|
||||
|
@ -79,18 +69,4 @@ pinctrl-bindings.txt
|
|||
function = "nand";
|
||||
};
|
||||
};
|
||||
|
||||
uart_ao_a {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a", "uart_rx_ao_a",
|
||||
"uart_cts_ao_a", "uart_rts_ao_a";
|
||||
function = "uart_ao";
|
||||
};
|
||||
|
||||
conf {
|
||||
pins = "GPIOAO_0", "GPIOAO_1",
|
||||
"GPIOAO_2", "GPIOAO_3";
|
||||
bias-disable;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4077,6 +4077,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||
sector if the number is odd);
|
||||
i = IGNORE_DEVICE (don't bind to this
|
||||
device);
|
||||
j = NO_REPORT_LUNS (don't use report luns
|
||||
command, uas only);
|
||||
l = NOT_LOCKABLE (don't try to lock and
|
||||
unlock ejectable media);
|
||||
m = MAX_SECTORS_64 (don't transfer more
|
||||
|
|
|
@ -43,7 +43,7 @@ For the gadget two work under Windows two conditions have to be met:
|
|||
First of all, Windows need to detect the gadget as an USB composite
|
||||
gadget which on its own have some conditions[4]. If they are met,
|
||||
Windows lets USB Generic Parent Driver[5] handle the device which then
|
||||
tries to much drivers for each individual interface (sort of, don't
|
||||
tries to match drivers for each individual interface (sort of, don't
|
||||
get into too many details).
|
||||
|
||||
The good news is: you do not have to worry about most of the
|
||||
|
|
27
Documentation/x86/protection-keys.txt
Normal file
27
Documentation/x86/protection-keys.txt
Normal file
|
@ -0,0 +1,27 @@
|
|||
Memory Protection Keys for Userspace (PKU aka PKEYs) is a CPU feature
|
||||
which will be found on future Intel CPUs.
|
||||
|
||||
Memory Protection Keys provides a mechanism for enforcing page-based
|
||||
protections, but without requiring modification of the page tables
|
||||
when an application changes protection domains. It works by
|
||||
dedicating 4 previously ignored bits in each page table entry to a
|
||||
"protection key", giving 16 possible keys.
|
||||
|
||||
There is also a new user-accessible register (PKRU) with two separate
|
||||
bits (Access Disable and Write Disable) for each key. Being a CPU
|
||||
register, PKRU is inherently thread-local, potentially giving each
|
||||
thread a different set of protections from every other thread.
|
||||
|
||||
There are two new instructions (RDPKRU/WRPKRU) for reading and writing
|
||||
to the new register. The feature is only available in 64-bit mode,
|
||||
even though there is theoretically space in the PAE PTEs. These
|
||||
permissions are enforced on data access only and have no effect on
|
||||
instruction fetches.
|
||||
|
||||
=========================== Config Option ===========================
|
||||
|
||||
This config option adds approximately 1.5kb of text. and 50 bytes of
|
||||
data to the executable. A workload which does large O_DIRECT reads
|
||||
of holes in XFS files was run to exercise get_user_pages_fast(). No
|
||||
performance delta was observed with the config option
|
||||
enabled or disabled.
|
|
@ -6252,8 +6252,8 @@ S: Maintained
|
|||
F: tools/testing/selftests
|
||||
|
||||
KERNEL VIRTUAL MACHINE (KVM)
|
||||
M: Gleb Natapov <gleb@kernel.org>
|
||||
M: Paolo Bonzini <pbonzini@redhat.com>
|
||||
M: Radim Krčmář <rkrcmar@redhat.com>
|
||||
L: kvm@vger.kernel.org
|
||||
W: http://www.linux-kvm.org
|
||||
T: git git://git.kernel.org/pub/scm/virt/kvm/kvm.git
|
||||
|
|
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 4
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 0
|
||||
EXTRAVERSION = -rc3
|
||||
EXTRAVERSION = -rc4
|
||||
NAME = Blurry Fish Butt
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
|
|
@ -470,9 +470,12 @@
|
|||
};
|
||||
|
||||
&cpsw_emac0 {
|
||||
phy_id = <&davinci_mdio>, <0>;
|
||||
phy-mode = "rmii";
|
||||
dual_emac_res_vlan = <1>;
|
||||
fixed-link {
|
||||
speed = <100>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
&cpsw_emac1 {
|
||||
|
|
|
@ -207,7 +207,7 @@
|
|||
ti,tptcs = <&edma_tptc0 7>, <&edma_tptc1 5>,
|
||||
<&edma_tptc2 0>;
|
||||
|
||||
ti,edma-memcpy-channels = <32 33>;
|
||||
ti,edma-memcpy-channels = <58 59>;
|
||||
};
|
||||
|
||||
edma_tptc0: tptc@49800000 {
|
||||
|
|
|
@ -794,3 +794,8 @@
|
|||
tx-num-evt = <32>;
|
||||
rx-num-evt = <32>;
|
||||
};
|
||||
|
||||
&synctimer_32kclk {
|
||||
assigned-clocks = <&mux_synctimer32k_ck>;
|
||||
assigned-clock-parents = <&clkdiv32k_ick>;
|
||||
};
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
};
|
||||
|
||||
/* USB part of the eSATA/USB 2.0 port */
|
||||
usb@50000 {
|
||||
usb@58000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
|
|
|
@ -91,8 +91,8 @@
|
|||
clock-frequency = <141666666>;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@c1109880 {
|
||||
compatible = "amlogic,meson8-pinctrl";
|
||||
pinctrl_cbus: pinctrl@c1109880 {
|
||||
compatible = "amlogic,meson8-cbus-pinctrl";
|
||||
reg = <0xc1109880 0x10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
@ -108,29 +108,6 @@
|
|||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
gpio_ao: ao-bank@c1108030 {
|
||||
reg = <0xc8100014 0x4>,
|
||||
<0xc810002c 0x4>,
|
||||
<0xc8100024 0x8>;
|
||||
reg-names = "mux", "pull", "gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
uart_ao_a_pins: uart_ao_a {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a", "uart_rx_ao_a";
|
||||
function = "uart_ao";
|
||||
};
|
||||
};
|
||||
|
||||
i2c_ao_pins: i2c_mst_ao {
|
||||
mux {
|
||||
groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao";
|
||||
function = "i2c_mst_ao";
|
||||
};
|
||||
};
|
||||
|
||||
spi_nor_pins: nor {
|
||||
mux {
|
||||
groups = "nor_d", "nor_q", "nor_c", "nor_cs";
|
||||
|
@ -157,4 +134,34 @@
|
|||
};
|
||||
};
|
||||
|
||||
pinctrl_aobus: pinctrl@c8100084 {
|
||||
compatible = "amlogic,meson8-aobus-pinctrl";
|
||||
reg = <0xc8100084 0xc>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
gpio_ao: ao-bank@c1108030 {
|
||||
reg = <0xc8100014 0x4>,
|
||||
<0xc810002c 0x4>,
|
||||
<0xc8100024 0x8>;
|
||||
reg-names = "mux", "pull", "gpio";
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
|
||||
uart_ao_a_pins: uart_ao_a {
|
||||
mux {
|
||||
groups = "uart_tx_ao_a", "uart_rx_ao_a";
|
||||
function = "uart_ao";
|
||||
};
|
||||
};
|
||||
|
||||
i2c_ao_pins: i2c_mst_ao {
|
||||
mux {
|
||||
groups = "i2c_mst_sck_ao", "i2c_mst_sda_ao";
|
||||
function = "i2c_mst_ao";
|
||||
};
|
||||
};
|
||||
};
|
||||
}; /* end of / */
|
||||
|
|
|
@ -155,8 +155,8 @@
|
|||
reg = <0xc1108000 0x4>, <0xc1104000 0x460>;
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@c1109880 {
|
||||
compatible = "amlogic,meson8b-pinctrl";
|
||||
pinctrl_cbus: pinctrl@c1109880 {
|
||||
compatible = "amlogic,meson8b-cbus-pinctrl";
|
||||
reg = <0xc1109880 0x10>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
@ -171,6 +171,14 @@
|
|||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl_aobus: pinctrl@c8100084 {
|
||||
compatible = "amlogic,meson8b-aobus-pinctrl";
|
||||
reg = <0xc8100084 0xc>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
gpio_ao: ao-bank@c1108030 {
|
||||
reg = <0xc8100014 0x4>,
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
compatible = "arm,cortex-a9-twd-timer";
|
||||
clocks = <&mpu_periphclk>;
|
||||
reg = <0x48240600 0x20>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_LEVEL_HIGH)>;
|
||||
interrupts = <GIC_PPI 13 (GIC_CPU_MASK_RAW(3) | IRQ_TYPE_EDGE_RISING)>;
|
||||
interrupt-parent = <&gic>;
|
||||
};
|
||||
|
||||
|
|
|
@ -63,6 +63,9 @@ CONFIG_INPUT_TOUCHSCREEN=y
|
|||
CONFIG_TOUCHSCREEN_BU21013=y
|
||||
CONFIG_INPUT_MISC=y
|
||||
CONFIG_INPUT_AB8500_PONKEY=y
|
||||
CONFIG_RMI4_CORE=y
|
||||
CONFIG_RMI4_I2C=y
|
||||
CONFIG_RMI4_F11=y
|
||||
# CONFIG_SERIO is not set
|
||||
CONFIG_VT_HW_CONSOLE_BINDING=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
|
|
|
@ -1112,10 +1112,17 @@ static void __init hyp_cpu_pm_init(void)
|
|||
{
|
||||
cpu_pm_register_notifier(&hyp_init_cpu_pm_nb);
|
||||
}
|
||||
static void __init hyp_cpu_pm_exit(void)
|
||||
{
|
||||
cpu_pm_unregister_notifier(&hyp_init_cpu_pm_nb);
|
||||
}
|
||||
#else
|
||||
static inline void hyp_cpu_pm_init(void)
|
||||
{
|
||||
}
|
||||
static inline void hyp_cpu_pm_exit(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void teardown_common_resources(void)
|
||||
|
@ -1141,9 +1148,7 @@ static int init_subsystems(void)
|
|||
/*
|
||||
* Register CPU Hotplug notifier
|
||||
*/
|
||||
cpu_notifier_register_begin();
|
||||
err = __register_cpu_notifier(&hyp_init_cpu_nb);
|
||||
cpu_notifier_register_done();
|
||||
err = register_cpu_notifier(&hyp_init_cpu_nb);
|
||||
if (err) {
|
||||
kvm_err("Cannot register KVM init CPU notifier (%d)\n", err);
|
||||
return err;
|
||||
|
@ -1193,6 +1198,8 @@ static void teardown_hyp_mode(void)
|
|||
free_hyp_pgds();
|
||||
for_each_possible_cpu(cpu)
|
||||
free_page(per_cpu(kvm_arm_hyp_stack_page, cpu));
|
||||
unregister_cpu_notifier(&hyp_init_cpu_nb);
|
||||
hyp_cpu_pm_exit();
|
||||
}
|
||||
|
||||
static int init_vhe_mode(void)
|
||||
|
|
|
@ -669,9 +669,9 @@ void __init dra7xxx_check_revision(void)
|
|||
case 0:
|
||||
omap_revision = DRA722_REV_ES1_0;
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
/* If we have no new revisions */
|
||||
omap_revision = DRA722_REV_ES1_0;
|
||||
omap_revision = DRA722_REV_ES2_0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -368,6 +368,7 @@ void __init omap5_map_io(void)
|
|||
void __init dra7xx_map_io(void)
|
||||
{
|
||||
iotable_init(dra7xx_io_desc, ARRAY_SIZE(dra7xx_io_desc));
|
||||
omap_barriers_init();
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
|
|
|
@ -1416,9 +1416,7 @@ static void _enable_sysc(struct omap_hwmod *oh)
|
|||
(sf & SYSC_HAS_CLOCKACTIVITY))
|
||||
_set_clockactivity(oh, oh->class->sysc->clockact, &v);
|
||||
|
||||
/* If the cached value is the same as the new value, skip the write */
|
||||
if (oh->_sysc_cache != v)
|
||||
_write_sysconfig(v, oh);
|
||||
_write_sysconfig(v, oh);
|
||||
|
||||
/*
|
||||
* Set the autoidle bit only after setting the smartidle bit
|
||||
|
@ -1481,7 +1479,9 @@ static void _idle_sysc(struct omap_hwmod *oh)
|
|||
_set_master_standbymode(oh, idlemode, &v);
|
||||
}
|
||||
|
||||
_write_sysconfig(v, oh);
|
||||
/* If the cached value is the same as the new value, skip the write */
|
||||
if (oh->_sysc_cache != v)
|
||||
_write_sysconfig(v, oh);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -582,9 +582,11 @@ static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
|
|||
.user = OCP_USER_MPU,
|
||||
};
|
||||
|
||||
/* USB needs udelay 1 after reset at least on hp t410, use 2 for margin */
|
||||
static struct omap_hwmod_class_sysconfig dm81xx_usbhsotg_sysc = {
|
||||
.rev_offs = 0x0,
|
||||
.sysc_offs = 0x10,
|
||||
.srst_udelay = 2,
|
||||
.sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
|
||||
SYSC_HAS_SOFTRESET,
|
||||
.idlemodes = SIDLE_SMART | MSTANDBY_FORCE | MSTANDBY_SMART,
|
||||
|
|
|
@ -489,6 +489,7 @@ IS_OMAP_TYPE(3430, 0x3430)
|
|||
#define DRA752_REV_ES2_0 (DRA7XX_CLASS | (0x52 << 16) | (0x20 << 8))
|
||||
#define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8))
|
||||
#define DRA722_REV_ES1_0 (DRA7XX_CLASS | (0x22 << 16) | (0x10 << 8))
|
||||
#define DRA722_REV_ES2_0 (DRA7XX_CLASS | (0x22 << 16) | (0x20 << 8))
|
||||
|
||||
void omap2xxx_check_revision(void);
|
||||
void omap3xxx_check_revision(void);
|
||||
|
|
|
@ -1235,5 +1235,6 @@ static struct platform_device pxa2xx_pxa_dma = {
|
|||
void __init pxa2xx_set_dmac_info(int nb_channels, int nb_requestors)
|
||||
{
|
||||
pxa_dma_pdata.dma_channels = nb_channels;
|
||||
pxa_dma_pdata.nb_requestors = nb_requestors;
|
||||
pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata);
|
||||
}
|
||||
|
|
|
@ -61,10 +61,7 @@ config SA1100_H3100
|
|||
select MFD_IPAQ_MICRO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
H3100 handheld computer. Information about this machine and the
|
||||
Linux port to this machine can be found at:
|
||||
|
||||
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3100>
|
||||
H3100 handheld computer.
|
||||
|
||||
config SA1100_H3600
|
||||
bool "Compaq iPAQ H3600/H3700"
|
||||
|
@ -73,10 +70,7 @@ config SA1100_H3600
|
|||
select MFD_IPAQ_MICRO
|
||||
help
|
||||
Say Y here if you intend to run this kernel on the Compaq iPAQ
|
||||
H3600 handheld computer. Information about this machine and the
|
||||
Linux port to this machine can be found at:
|
||||
|
||||
<http://www.handhelds.org/Compaq/index.html#iPAQ_H3600>
|
||||
H3600 and H3700 handheld computers.
|
||||
|
||||
config SA1100_BADGE4
|
||||
bool "HP Labs BadgePAD 4"
|
||||
|
|
|
@ -120,7 +120,7 @@ static int __init uniphier_smp_prepare_trampoline(unsigned int max_cpus)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, sizeof(SZ_4));
|
||||
uniphier_smp_rom_boot_rsv2 = ioremap(rom_rsv2_phys, SZ_4);
|
||||
if (!uniphier_smp_rom_boot_rsv2) {
|
||||
pr_err("failed to map ROM_BOOT_RSV2 register\n");
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -108,12 +108,15 @@
|
|||
reg = <0x0 0x30000000 0x0 0x10000000>;
|
||||
reg-names = "PCI ECAM";
|
||||
|
||||
/* IO 0x4000_0000 - 0x4001_0000 */
|
||||
ranges = <0x01000000 0 0x40000000 0 0x40000000 0 0x00010000
|
||||
/* MEM 0x4800_0000 - 0x5000_0000 */
|
||||
0x02000000 0 0x48000000 0 0x48000000 0 0x08000000
|
||||
/* MEM64 pref 0x6_0000_0000 - 0x7_0000_0000 */
|
||||
0x43000000 6 0x00000000 6 0x00000000 1 0x00000000>;
|
||||
/*
|
||||
* PCI ranges:
|
||||
* IO no supported
|
||||
* MEM 0x4000_0000 - 0x6000_0000
|
||||
* MEM64 pref 0x40_0000_0000 - 0x60_0000_0000
|
||||
*/
|
||||
ranges =
|
||||
<0x02000000 0 0x40000000 0 0x40000000 0 0x20000000
|
||||
0x43000000 0x40 0x00000000 0x40 0x00000000 0x20 0x00000000>;
|
||||
interrupt-map-mask = <0 0 0 7>;
|
||||
interrupt-map =
|
||||
/* addr pin ic icaddr icintr */
|
||||
|
|
|
@ -151,8 +151,7 @@
|
|||
*/
|
||||
#define VTCR_EL2_FLAGS (VTCR_EL2_TG0_64K | VTCR_EL2_SH0_INNER | \
|
||||
VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
|
||||
VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
|
||||
VTCR_EL2_RES1)
|
||||
VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1)
|
||||
#define VTTBR_X (38 - VTCR_EL2_T0SZ_40B)
|
||||
#else
|
||||
/*
|
||||
|
@ -163,8 +162,7 @@
|
|||
*/
|
||||
#define VTCR_EL2_FLAGS (VTCR_EL2_TG0_4K | VTCR_EL2_SH0_INNER | \
|
||||
VTCR_EL2_ORGN0_WBWA | VTCR_EL2_IRGN0_WBWA | \
|
||||
VTCR_EL2_SL0_LVL1 | VTCR_EL2_T0SZ_40B | \
|
||||
VTCR_EL2_RES1)
|
||||
VTCR_EL2_SL0_LVL1 | VTCR_EL2_RES1)
|
||||
#define VTTBR_X (37 - VTCR_EL2_T0SZ_40B)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ extern void __vgic_v3_init_lrs(void);
|
|||
|
||||
extern u32 __kvm_get_mdcr_el2(void);
|
||||
|
||||
extern void __init_stage2_translation(void);
|
||||
extern u32 __init_stage2_translation(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -369,11 +369,12 @@ int kvm_arm_vcpu_arch_get_attr(struct kvm_vcpu *vcpu,
|
|||
int kvm_arm_vcpu_arch_has_attr(struct kvm_vcpu *vcpu,
|
||||
struct kvm_device_attr *attr);
|
||||
|
||||
/* #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__) */
|
||||
|
||||
static inline void __cpu_init_stage2(void)
|
||||
{
|
||||
kvm_call_hyp(__init_stage2_translation);
|
||||
u32 parange = kvm_call_hyp(__init_stage2_translation);
|
||||
|
||||
WARN_ONCE(parange < 40,
|
||||
"PARange is %d bits, unsupported configuration!", parange);
|
||||
}
|
||||
|
||||
#endif /* __ARM64_KVM_HOST_H__ */
|
||||
|
|
|
@ -20,9 +20,10 @@
|
|||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_hyp.h>
|
||||
|
||||
void __hyp_text __init_stage2_translation(void)
|
||||
u32 __hyp_text __init_stage2_translation(void)
|
||||
{
|
||||
u64 val = VTCR_EL2_FLAGS;
|
||||
u64 parange;
|
||||
u64 tmp;
|
||||
|
||||
/*
|
||||
|
@ -30,7 +31,39 @@ void __hyp_text __init_stage2_translation(void)
|
|||
* bits in VTCR_EL2. Amusingly, the PARange is 4 bits, while
|
||||
* PS is only 3. Fortunately, bit 19 is RES0 in VTCR_EL2...
|
||||
*/
|
||||
val |= (read_sysreg(id_aa64mmfr0_el1) & 7) << 16;
|
||||
parange = read_sysreg(id_aa64mmfr0_el1) & 7;
|
||||
val |= parange << 16;
|
||||
|
||||
/* Compute the actual PARange... */
|
||||
switch (parange) {
|
||||
case 0:
|
||||
parange = 32;
|
||||
break;
|
||||
case 1:
|
||||
parange = 36;
|
||||
break;
|
||||
case 2:
|
||||
parange = 40;
|
||||
break;
|
||||
case 3:
|
||||
parange = 42;
|
||||
break;
|
||||
case 4:
|
||||
parange = 44;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
parange = 48;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* ... and clamp it to 40 bits, unless we have some braindead
|
||||
* HW that implements less than that. In all cases, we'll
|
||||
* return that value for the rest of the kernel to decide what
|
||||
* to do.
|
||||
*/
|
||||
val |= 64 - (parange > 40 ? 40 : parange);
|
||||
|
||||
/*
|
||||
* Read the VMIDBits bits from ID_AA64MMFR1_EL1 and set the VS
|
||||
|
@ -42,4 +75,6 @@ void __hyp_text __init_stage2_translation(void)
|
|||
VTCR_EL2_VS_8BIT;
|
||||
|
||||
write_sysreg(val, vtcr_el2);
|
||||
|
||||
return parange;
|
||||
}
|
||||
|
|
|
@ -158,11 +158,6 @@ static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
static struct bus_type mcfgpio_subsys = {
|
||||
.name = "gpio",
|
||||
.dev_name = "gpio",
|
||||
};
|
||||
|
||||
static struct gpio_chip mcfgpio_chip = {
|
||||
.label = "mcfgpio",
|
||||
.request = mcfgpio_request,
|
||||
|
@ -178,8 +173,7 @@ static struct gpio_chip mcfgpio_chip = {
|
|||
|
||||
static int __init mcfgpio_sysinit(void)
|
||||
{
|
||||
gpiochip_add_data(&mcfgpio_chip, NULL);
|
||||
return subsys_system_register(&mcfgpio_subsys, NULL);
|
||||
return gpiochip_add_data(&mcfgpio_chip, NULL);
|
||||
}
|
||||
|
||||
core_initcall(mcfgpio_sysinit);
|
||||
|
|
|
@ -4,8 +4,8 @@ config PARISC
|
|||
select ARCH_MIGHT_HAVE_PC_PARPORT
|
||||
select HAVE_IDE
|
||||
select HAVE_OPROFILE
|
||||
select HAVE_FUNCTION_TRACER if 64BIT
|
||||
select HAVE_FUNCTION_GRAPH_TRACER if 64BIT
|
||||
select HAVE_FUNCTION_TRACER
|
||||
select HAVE_FUNCTION_GRAPH_TRACER
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
select RTC_CLASS
|
||||
select RTC_DRV_GENERIC
|
||||
|
|
|
@ -2,9 +2,13 @@ menu "Kernel hacking"
|
|||
|
||||
source "lib/Kconfig.debug"
|
||||
|
||||
config TRACE_IRQFLAGS_SUPPORT
|
||||
def_bool y
|
||||
|
||||
config DEBUG_RODATA
|
||||
bool "Write protect kernel read-only data structures"
|
||||
depends on DEBUG_KERNEL
|
||||
default y
|
||||
help
|
||||
Mark the kernel read-only data as write-protected in the pagetables,
|
||||
in order to catch accidental (and incorrect) writes to such const
|
||||
|
|
|
@ -62,9 +62,7 @@ cflags-y += -mdisable-fpregs
|
|||
|
||||
# Without this, "ld -r" results in .text sections that are too big
|
||||
# (> 0x40000) for branches to reach stubs.
|
||||
ifndef CONFIG_FUNCTION_TRACER
|
||||
cflags-y += -ffunction-sections
|
||||
endif
|
||||
cflags-y += -ffunction-sections
|
||||
|
||||
# Use long jumps instead of long branches (needed if your linker fails to
|
||||
# link a too big vmlinux executable). Not enabled for building modules.
|
||||
|
|
|
@ -4,23 +4,7 @@
|
|||
#ifndef __ASSEMBLY__
|
||||
extern void mcount(void);
|
||||
|
||||
/*
|
||||
* Stack of return addresses for functions of a thread.
|
||||
* Used in struct thread_info
|
||||
*/
|
||||
struct ftrace_ret_stack {
|
||||
unsigned long ret;
|
||||
unsigned long func;
|
||||
unsigned long long calltime;
|
||||
};
|
||||
|
||||
/*
|
||||
* Primary handler of a function return.
|
||||
* It relays on ftrace_return_to_handler.
|
||||
* Defined in entry.S
|
||||
*/
|
||||
extern void return_to_handler(void);
|
||||
|
||||
#define MCOUNT_INSN_SIZE 4
|
||||
|
||||
extern unsigned long return_address(unsigned int);
|
||||
|
||||
|
|
|
@ -15,11 +15,7 @@ ifdef CONFIG_FUNCTION_TRACER
|
|||
# Do not profile debug and lowlevel utilities
|
||||
CFLAGS_REMOVE_ftrace.o = -pg
|
||||
CFLAGS_REMOVE_cache.o = -pg
|
||||
CFLAGS_REMOVE_irq.o = -pg
|
||||
CFLAGS_REMOVE_pacache.o = -pg
|
||||
CFLAGS_REMOVE_perf.o = -pg
|
||||
CFLAGS_REMOVE_traps.o = -pg
|
||||
CFLAGS_REMOVE_unaligned.o = -pg
|
||||
CFLAGS_REMOVE_unwind.o = -pg
|
||||
endif
|
||||
|
||||
|
|
|
@ -1970,43 +1970,98 @@ pt_regs_ok:
|
|||
b intr_restore
|
||||
copy %r25,%r16
|
||||
|
||||
.import schedule,code
|
||||
syscall_do_resched:
|
||||
BL schedule,%r2
|
||||
load32 syscall_check_resched,%r2 /* if resched, we start over again */
|
||||
load32 schedule,%r19
|
||||
bv %r0(%r19) /* jumps to schedule() */
|
||||
#ifdef CONFIG_64BIT
|
||||
ldo -16(%r30),%r29 /* Reference param save area */
|
||||
#else
|
||||
nop
|
||||
#endif
|
||||
b syscall_check_resched /* if resched, we start over again */
|
||||
nop
|
||||
ENDPROC(syscall_exit)
|
||||
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
|
||||
.import ftrace_function_trampoline,code
|
||||
ENTRY(_mcount)
|
||||
copy %r3, %arg2
|
||||
.align L1_CACHE_BYTES
|
||||
.globl mcount
|
||||
.type mcount, @function
|
||||
ENTRY(mcount)
|
||||
_mcount:
|
||||
.export _mcount,data
|
||||
.proc
|
||||
.callinfo caller,frame=0
|
||||
.entry
|
||||
/*
|
||||
* The 64bit mcount() function pointer needs 4 dwords, of which the
|
||||
* first two are free. We optimize it here and put 2 instructions for
|
||||
* calling mcount(), and 2 instructions for ftrace_stub(). That way we
|
||||
* have all on one L1 cacheline.
|
||||
*/
|
||||
b ftrace_function_trampoline
|
||||
nop
|
||||
ENDPROC(_mcount)
|
||||
|
||||
ENTRY(return_to_handler)
|
||||
load32 return_trampoline, %rp
|
||||
copy %ret0, %arg0
|
||||
copy %ret1, %arg1
|
||||
b ftrace_return_to_handler
|
||||
nop
|
||||
return_trampoline:
|
||||
copy %ret0, %rp
|
||||
copy %r23, %ret0
|
||||
copy %r24, %ret1
|
||||
|
||||
.globl ftrace_stub
|
||||
copy %r3, %arg2 /* caller original %sp */
|
||||
ftrace_stub:
|
||||
.globl ftrace_stub
|
||||
.type ftrace_stub, @function
|
||||
#ifdef CONFIG_64BIT
|
||||
bve (%rp)
|
||||
#else
|
||||
bv %r0(%rp)
|
||||
#endif
|
||||
nop
|
||||
#ifdef CONFIG_64BIT
|
||||
.dword mcount
|
||||
.dword 0 /* code in head.S puts value of global gp here */
|
||||
#endif
|
||||
.exit
|
||||
.procend
|
||||
ENDPROC(mcount)
|
||||
|
||||
.align 8
|
||||
.globl return_to_handler
|
||||
.type return_to_handler, @function
|
||||
ENTRY(return_to_handler)
|
||||
.proc
|
||||
.callinfo caller,frame=FRAME_SIZE
|
||||
.entry
|
||||
.export parisc_return_to_handler,data
|
||||
parisc_return_to_handler:
|
||||
copy %r3,%r1
|
||||
STREG %r0,-RP_OFFSET(%sp) /* store 0 as %rp */
|
||||
copy %sp,%r3
|
||||
STREGM %r1,FRAME_SIZE(%sp)
|
||||
STREG %ret0,8(%r3)
|
||||
STREG %ret1,16(%r3)
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
loadgp
|
||||
#endif
|
||||
|
||||
/* call ftrace_return_to_handler(0) */
|
||||
#ifdef CONFIG_64BIT
|
||||
ldo -16(%sp),%ret1 /* Reference param save area */
|
||||
#endif
|
||||
BL ftrace_return_to_handler,%r2
|
||||
ldi 0,%r26
|
||||
copy %ret0,%rp
|
||||
|
||||
/* restore original return values */
|
||||
LDREG 8(%r3),%ret0
|
||||
LDREG 16(%r3),%ret1
|
||||
|
||||
/* return from function */
|
||||
#ifdef CONFIG_64BIT
|
||||
bve (%rp)
|
||||
#else
|
||||
bv %r0(%rp)
|
||||
#endif
|
||||
LDREGM -FRAME_SIZE(%sp),%r3
|
||||
.exit
|
||||
.procend
|
||||
ENDPROC(return_to_handler)
|
||||
|
||||
#endif /* CONFIG_FUNCTION_TRACER */
|
||||
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Code for tracing calls in Linux kernel.
|
||||
* Copyright (C) 2009 Helge Deller <deller@gmx.de>
|
||||
* Copyright (C) 2009-2016 Helge Deller <deller@gmx.de>
|
||||
*
|
||||
* based on code for x86 which is:
|
||||
* Copyright (C) 2007-2008 Steven Rostedt <srostedt@redhat.com>
|
||||
|
@ -13,104 +13,21 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/ftrace.h>
|
||||
|
||||
#include <asm/assembly.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/ftrace.h>
|
||||
|
||||
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
|
||||
/* Add a function return address to the trace stack on thread info.*/
|
||||
static int push_return_trace(unsigned long ret, unsigned long long time,
|
||||
unsigned long func, int *depth)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (!current->ret_stack)
|
||||
return -EBUSY;
|
||||
|
||||
/* The return trace stack is full */
|
||||
if (current->curr_ret_stack == FTRACE_RETFUNC_DEPTH - 1) {
|
||||
atomic_inc(¤t->trace_overrun);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
index = ++current->curr_ret_stack;
|
||||
barrier();
|
||||
current->ret_stack[index].ret = ret;
|
||||
current->ret_stack[index].func = func;
|
||||
current->ret_stack[index].calltime = time;
|
||||
*depth = index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Retrieve a function return address to the trace stack on thread info.*/
|
||||
static void pop_return_trace(struct ftrace_graph_ret *trace, unsigned long *ret)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = current->curr_ret_stack;
|
||||
|
||||
if (unlikely(index < 0)) {
|
||||
ftrace_graph_stop();
|
||||
WARN_ON(1);
|
||||
/* Might as well panic, otherwise we have no where to go */
|
||||
*ret = (unsigned long)
|
||||
dereference_function_descriptor(&panic);
|
||||
return;
|
||||
}
|
||||
|
||||
*ret = current->ret_stack[index].ret;
|
||||
trace->func = current->ret_stack[index].func;
|
||||
trace->calltime = current->ret_stack[index].calltime;
|
||||
trace->overrun = atomic_read(¤t->trace_overrun);
|
||||
trace->depth = index;
|
||||
barrier();
|
||||
current->curr_ret_stack--;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the trace to the ring-buffer.
|
||||
* @return the original return address.
|
||||
*/
|
||||
unsigned long ftrace_return_to_handler(unsigned long retval0,
|
||||
unsigned long retval1)
|
||||
{
|
||||
struct ftrace_graph_ret trace;
|
||||
unsigned long ret;
|
||||
|
||||
pop_return_trace(&trace, &ret);
|
||||
trace.rettime = local_clock();
|
||||
ftrace_graph_return(&trace);
|
||||
|
||||
if (unlikely(!ret)) {
|
||||
ftrace_graph_stop();
|
||||
WARN_ON(1);
|
||||
/* Might as well panic. What else to do? */
|
||||
ret = (unsigned long)
|
||||
dereference_function_descriptor(&panic);
|
||||
}
|
||||
|
||||
/* HACK: we hand over the old functions' return values
|
||||
in %r23 and %r24. Assembly in entry.S will take care
|
||||
and move those to their final registers %ret0 and %ret1 */
|
||||
asm( "copy %0, %%r23 \n\t"
|
||||
"copy %1, %%r24 \n" : : "r" (retval0), "r" (retval1) );
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook the return address and push it in the stack of return addrs
|
||||
* in current thread info.
|
||||
*/
|
||||
void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
||||
static void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
||||
{
|
||||
unsigned long old;
|
||||
unsigned long long calltime;
|
||||
struct ftrace_graph_ent trace;
|
||||
extern int parisc_return_to_handler;
|
||||
|
||||
if (unlikely(ftrace_graph_is_dead()))
|
||||
return;
|
||||
|
@ -119,64 +36,47 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr)
|
|||
return;
|
||||
|
||||
old = *parent;
|
||||
*parent = (unsigned long)
|
||||
dereference_function_descriptor(&return_to_handler);
|
||||
|
||||
if (unlikely(!__kernel_text_address(old))) {
|
||||
ftrace_graph_stop();
|
||||
*parent = old;
|
||||
WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
|
||||
calltime = local_clock();
|
||||
|
||||
if (push_return_trace(old, calltime,
|
||||
self_addr, &trace.depth) == -EBUSY) {
|
||||
*parent = old;
|
||||
return;
|
||||
}
|
||||
|
||||
trace.func = self_addr;
|
||||
trace.depth = current->curr_ret_stack + 1;
|
||||
|
||||
/* Only trace if the calling function expects to */
|
||||
if (!ftrace_graph_entry(&trace)) {
|
||||
current->curr_ret_stack--;
|
||||
*parent = old;
|
||||
}
|
||||
}
|
||||
if (!ftrace_graph_entry(&trace))
|
||||
return;
|
||||
|
||||
if (ftrace_push_return_trace(old, self_addr, &trace.depth,
|
||||
0 ) == -EBUSY)
|
||||
return;
|
||||
|
||||
/* activate parisc_return_to_handler() as return point */
|
||||
*parent = (unsigned long) &parisc_return_to_handler;
|
||||
}
|
||||
#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
|
||||
|
||||
|
||||
void ftrace_function_trampoline(unsigned long parent,
|
||||
void notrace ftrace_function_trampoline(unsigned long parent,
|
||||
unsigned long self_addr,
|
||||
unsigned long org_sp_gr3)
|
||||
{
|
||||
extern ftrace_func_t ftrace_trace_function;
|
||||
extern ftrace_func_t ftrace_trace_function; /* depends on CONFIG_DYNAMIC_FTRACE */
|
||||
extern int ftrace_graph_entry_stub(struct ftrace_graph_ent *trace);
|
||||
|
||||
if (ftrace_trace_function != ftrace_stub) {
|
||||
ftrace_trace_function(parent, self_addr);
|
||||
/* struct ftrace_ops *op, struct pt_regs *regs); */
|
||||
ftrace_trace_function(parent, self_addr, NULL, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
||||
if (ftrace_graph_entry && ftrace_graph_return) {
|
||||
unsigned long sp;
|
||||
if (ftrace_graph_return != (trace_func_graph_ret_t) ftrace_stub ||
|
||||
ftrace_graph_entry != ftrace_graph_entry_stub) {
|
||||
unsigned long *parent_rp;
|
||||
|
||||
asm volatile ("copy %%r30, %0" : "=r"(sp));
|
||||
/* sanity check: is stack pointer which we got from
|
||||
assembler function in entry.S in a reasonable
|
||||
range compared to current stack pointer? */
|
||||
if ((sp - org_sp_gr3) > 0x400)
|
||||
return;
|
||||
|
||||
/* calculate pointer to %rp in stack */
|
||||
parent_rp = (unsigned long *) org_sp_gr3 - 0x10;
|
||||
parent_rp = (unsigned long *) (org_sp_gr3 - RP_OFFSET);
|
||||
/* sanity check: parent_rp should hold parent */
|
||||
if (*parent_rp != parent)
|
||||
return;
|
||||
|
||||
|
||||
prepare_ftrace_return(parent_rp, self_addr);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -129,6 +129,15 @@ $pgt_fill_loop:
|
|||
/* And the stack pointer too */
|
||||
ldo THREAD_SZ_ALGN(%r6),%sp
|
||||
|
||||
#if defined(CONFIG_64BIT) && defined(CONFIG_FUNCTION_TRACER)
|
||||
.import _mcount,data
|
||||
/* initialize mcount FPTR */
|
||||
/* Get the global data pointer */
|
||||
loadgp
|
||||
load32 PA(_mcount), %r10
|
||||
std %dp,0x18(%r10)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Set the smp rendezvous address into page zero.
|
||||
** It would be safer to do this in init_smp_config() but
|
||||
|
|
|
@ -34,11 +34,6 @@ enum {
|
|||
DECLARE_PER_CPU(int, cpu_state);
|
||||
|
||||
void smp_message_recv(unsigned int msg);
|
||||
void smp_timer_broadcast(const struct cpumask *mask);
|
||||
|
||||
void local_timer_interrupt(void);
|
||||
void local_timer_setup(unsigned int cpu);
|
||||
void local_timer_stop(unsigned int cpu);
|
||||
|
||||
void arch_send_call_function_single_ipi(int cpu);
|
||||
void arch_send_call_function_ipi_mask(const struct cpumask *mask);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#define mc_capable() (1)
|
||||
|
||||
const struct cpumask *cpu_coregroup_mask(unsigned int cpu);
|
||||
const struct cpumask *cpu_coregroup_mask(int cpu);
|
||||
|
||||
extern cpumask_t cpu_core_map[NR_CPUS];
|
||||
|
||||
|
|
|
@ -73,8 +73,6 @@ static void shx3_prepare_cpus(unsigned int max_cpus)
|
|||
{
|
||||
int i;
|
||||
|
||||
local_timer_setup(0);
|
||||
|
||||
BUILD_BUG_ON(SMP_MSG_NR >= 8);
|
||||
|
||||
for (i = 0; i < SMP_MSG_NR; i++)
|
||||
|
|
|
@ -21,7 +21,7 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
|
|||
cpumask_t cpu_core_map[NR_CPUS];
|
||||
EXPORT_SYMBOL(cpu_core_map);
|
||||
|
||||
static cpumask_t cpu_coregroup_map(unsigned int cpu)
|
||||
static cpumask_t cpu_coregroup_map(int cpu)
|
||||
{
|
||||
/*
|
||||
* Presently all SH-X3 SMP cores are multi-cores, so just keep it
|
||||
|
@ -30,7 +30,7 @@ static cpumask_t cpu_coregroup_map(unsigned int cpu)
|
|||
return *cpu_possible_mask;
|
||||
}
|
||||
|
||||
const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
|
||||
const struct cpumask *cpu_coregroup_mask(int cpu)
|
||||
{
|
||||
return &cpu_core_map[cpu];
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \
|
|||
vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4
|
||||
|
||||
KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2
|
||||
KBUILD_CFLAGS += -fno-strict-aliasing -fPIC
|
||||
KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC)
|
||||
KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING
|
||||
cflags-$(CONFIG_X86_32) := -march=i386
|
||||
cflags-$(CONFIG_X86_64) := -mcmodel=small
|
||||
|
@ -40,6 +40,18 @@ GCOV_PROFILE := n
|
|||
UBSAN_SANITIZE :=n
|
||||
|
||||
LDFLAGS := -m elf_$(UTS_MACHINE)
|
||||
ifeq ($(CONFIG_RELOCATABLE),y)
|
||||
# If kernel is relocatable, build compressed kernel as PIE.
|
||||
ifeq ($(CONFIG_X86_32),y)
|
||||
LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker)
|
||||
else
|
||||
# To build 64-bit compressed kernel as PIE, we disable relocation
|
||||
# overflow check to avoid relocation overflow error with a new linker
|
||||
# command-line option, -z noreloc-overflow.
|
||||
LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \
|
||||
&& echo "-z noreloc-overflow -pie --no-dynamic-linker")
|
||||
endif
|
||||
endif
|
||||
LDFLAGS_vmlinux := -T
|
||||
|
||||
hostprogs-y := mkpiggy
|
||||
|
|
|
@ -31,6 +31,34 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
/*
|
||||
* The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X
|
||||
* relocation to get the symbol address in PIC. When the compressed x86
|
||||
* kernel isn't built as PIC, the linker optimizes R_386_GOT32X
|
||||
* relocations to their fixed symbol addresses. However, when the
|
||||
* compressed x86 kernel is loaded at a different address, it leads
|
||||
* to the following load failure:
|
||||
*
|
||||
* Failed to allocate space for phdrs
|
||||
*
|
||||
* during the decompression stage.
|
||||
*
|
||||
* If the compressed x86 kernel is relocatable at run-time, it should be
|
||||
* compiled with -fPIE, instead of -fPIC, if possible and should be built as
|
||||
* Position Independent Executable (PIE) so that linker won't optimize
|
||||
* R_386_GOT32X relocation to its fixed symbol address. Older
|
||||
* linkers generate R_386_32 relocations against locally defined symbols,
|
||||
* _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less
|
||||
* optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle
|
||||
* R_386_32 relocations when relocating the kernel. To generate
|
||||
* R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as
|
||||
* hidden:
|
||||
*/
|
||||
.hidden _bss
|
||||
.hidden _ebss
|
||||
.hidden _got
|
||||
.hidden _egot
|
||||
|
||||
__HEAD
|
||||
ENTRY(startup_32)
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
|
|
|
@ -33,6 +33,14 @@
|
|||
#include <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
/*
|
||||
* Locally defined symbols should be marked hidden:
|
||||
*/
|
||||
.hidden _bss
|
||||
.hidden _ebss
|
||||
.hidden _got
|
||||
.hidden _egot
|
||||
|
||||
__HEAD
|
||||
.code32
|
||||
ENTRY(startup_32)
|
||||
|
|
|
@ -29,7 +29,7 @@ static char gen_pool_buf[MCE_POOLSZ];
|
|||
void mce_gen_pool_process(void)
|
||||
{
|
||||
struct llist_node *head;
|
||||
struct mce_evt_llist *node;
|
||||
struct mce_evt_llist *node, *tmp;
|
||||
struct mce *mce;
|
||||
|
||||
head = llist_del_all(&mce_event_llist);
|
||||
|
@ -37,7 +37,7 @@ void mce_gen_pool_process(void)
|
|||
return;
|
||||
|
||||
head = llist_reverse_order(head);
|
||||
llist_for_each_entry(node, head, llnode) {
|
||||
llist_for_each_entry_safe(node, tmp, head, llnode) {
|
||||
mce = &node->mce;
|
||||
atomic_notifier_call_chain(&x86_mce_decoder_chain, 0, mce);
|
||||
gen_pool_free(mce_evt_pool, (unsigned long)node, sizeof(*node));
|
||||
|
|
|
@ -146,6 +146,31 @@ int default_check_phys_apicid_present(int phys_apicid)
|
|||
|
||||
struct boot_params boot_params;
|
||||
|
||||
/*
|
||||
* Machine setup..
|
||||
*/
|
||||
static struct resource data_resource = {
|
||||
.name = "Kernel data",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
|
||||
};
|
||||
|
||||
static struct resource code_resource = {
|
||||
.name = "Kernel code",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
|
||||
};
|
||||
|
||||
static struct resource bss_resource = {
|
||||
.name = "Kernel bss",
|
||||
.start = 0,
|
||||
.end = 0,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/* cpu data as detected by the assembly code in head.S */
|
||||
struct cpuinfo_x86 new_cpu_data = {
|
||||
|
@ -924,6 +949,13 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
mpx_mm_init(&init_mm);
|
||||
|
||||
code_resource.start = __pa_symbol(_text);
|
||||
code_resource.end = __pa_symbol(_etext)-1;
|
||||
data_resource.start = __pa_symbol(_etext);
|
||||
data_resource.end = __pa_symbol(_edata)-1;
|
||||
bss_resource.start = __pa_symbol(__bss_start);
|
||||
bss_resource.end = __pa_symbol(__bss_stop)-1;
|
||||
|
||||
#ifdef CONFIG_CMDLINE_BOOL
|
||||
#ifdef CONFIG_CMDLINE_OVERRIDE
|
||||
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
|
||||
|
@ -987,6 +1019,11 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
x86_init.resources.probe_roms();
|
||||
|
||||
/* after parse_early_param, so could debug it */
|
||||
insert_resource(&iomem_resource, &code_resource);
|
||||
insert_resource(&iomem_resource, &data_resource);
|
||||
insert_resource(&iomem_resource, &bss_resource);
|
||||
|
||||
e820_add_kernel_range();
|
||||
trim_bios_range();
|
||||
#ifdef CONFIG_X86_32
|
||||
|
|
|
@ -534,6 +534,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function,
|
|||
do_cpuid_1_ent(&entry[i], function, idx);
|
||||
if (idx == 1) {
|
||||
entry[i].eax &= kvm_cpuid_D_1_eax_x86_features;
|
||||
cpuid_mask(&entry[i].eax, CPUID_D_1_EAX);
|
||||
entry[i].ebx = 0;
|
||||
if (entry[i].eax & (F(XSAVES)|F(XSAVEC)))
|
||||
entry[i].ebx =
|
||||
|
|
|
@ -173,10 +173,9 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
|
|||
int index = (pfec >> 1) +
|
||||
(smap >> (X86_EFLAGS_AC_BIT - PFERR_RSVD_BIT + 1));
|
||||
bool fault = (mmu->permissions[index] >> pte_access) & 1;
|
||||
u32 errcode = PFERR_PRESENT_MASK;
|
||||
|
||||
WARN_ON(pfec & (PFERR_PK_MASK | PFERR_RSVD_MASK));
|
||||
pfec |= PFERR_PRESENT_MASK;
|
||||
|
||||
if (unlikely(mmu->pkru_mask)) {
|
||||
u32 pkru_bits, offset;
|
||||
|
||||
|
@ -189,15 +188,15 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
|
|||
pkru_bits = (kvm_read_pkru(vcpu) >> (pte_pkey * 2)) & 3;
|
||||
|
||||
/* clear present bit, replace PFEC.RSVD with ACC_USER_MASK. */
|
||||
offset = pfec - 1 +
|
||||
offset = (pfec & ~1) +
|
||||
((pte_access & PT_USER_MASK) << (PFERR_RSVD_BIT - PT_USER_SHIFT));
|
||||
|
||||
pkru_bits &= mmu->pkru_mask >> offset;
|
||||
pfec |= -pkru_bits & PFERR_PK_MASK;
|
||||
errcode |= -pkru_bits & PFERR_PK_MASK;
|
||||
fault |= (pkru_bits != 0);
|
||||
}
|
||||
|
||||
return -(uint32_t)fault & pfec;
|
||||
return -(u32)fault & errcode;
|
||||
}
|
||||
|
||||
void kvm_mmu_invalidate_zap_all_pages(struct kvm *kvm);
|
||||
|
|
|
@ -360,7 +360,7 @@ retry_walk:
|
|||
goto error;
|
||||
|
||||
if (unlikely(is_rsvd_bits_set(mmu, pte, walker->level))) {
|
||||
errcode |= PFERR_RSVD_MASK | PFERR_PRESENT_MASK;
|
||||
errcode = PFERR_RSVD_MASK | PFERR_PRESENT_MASK;
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
@ -700,7 +700,6 @@ static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
|
|||
if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
|
||||
return 1;
|
||||
}
|
||||
kvm_put_guest_xcr0(vcpu);
|
||||
vcpu->arch.xcr0 = xcr0;
|
||||
|
||||
if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
|
||||
|
@ -6590,8 +6589,6 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
|||
kvm_x86_ops->prepare_guest_switch(vcpu);
|
||||
if (vcpu->fpu_active)
|
||||
kvm_load_guest_fpu(vcpu);
|
||||
kvm_load_guest_xcr0(vcpu);
|
||||
|
||||
vcpu->mode = IN_GUEST_MODE;
|
||||
|
||||
srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
|
||||
|
@ -6618,6 +6615,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
|||
goto cancel_injection;
|
||||
}
|
||||
|
||||
kvm_load_guest_xcr0(vcpu);
|
||||
|
||||
if (req_immediate_exit)
|
||||
smp_send_reschedule(vcpu->cpu);
|
||||
|
||||
|
@ -6667,6 +6666,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
|
|||
vcpu->mode = OUTSIDE_GUEST_MODE;
|
||||
smp_wmb();
|
||||
|
||||
kvm_put_guest_xcr0(vcpu);
|
||||
|
||||
/* Interrupt is enabled by handle_external_intr() */
|
||||
kvm_x86_ops->handle_external_intr(vcpu);
|
||||
|
||||
|
@ -7314,7 +7315,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
|
|||
* and assume host would use all available bits.
|
||||
* Guest xcr0 would be loaded later.
|
||||
*/
|
||||
kvm_put_guest_xcr0(vcpu);
|
||||
vcpu->guest_fpu_loaded = 1;
|
||||
__kernel_fpu_begin();
|
||||
__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state);
|
||||
|
@ -7323,8 +7323,6 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
|
|||
|
||||
void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
kvm_put_guest_xcr0(vcpu);
|
||||
|
||||
if (!vcpu->guest_fpu_loaded) {
|
||||
vcpu->fpu_counter = 0;
|
||||
return;
|
||||
|
|
|
@ -361,15 +361,20 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
|
|||
goto out_del;
|
||||
}
|
||||
|
||||
err = hd_ref_init(p);
|
||||
if (err) {
|
||||
if (flags & ADDPART_FLAG_WHOLEDISK)
|
||||
goto out_remove_file;
|
||||
goto out_del;
|
||||
}
|
||||
|
||||
/* everything is up and running, commence */
|
||||
rcu_assign_pointer(ptbl->part[partno], p);
|
||||
|
||||
/* suppress uevent if the disk suppresses it */
|
||||
if (!dev_get_uevent_suppress(ddev))
|
||||
kobject_uevent(&pdev->kobj, KOBJ_ADD);
|
||||
|
||||
if (!hd_ref_init(p))
|
||||
return p;
|
||||
return p;
|
||||
|
||||
out_free_info:
|
||||
free_part_info(p);
|
||||
|
@ -378,6 +383,8 @@ out_free_stats:
|
|||
out_free:
|
||||
kfree(p);
|
||||
return ERR_PTR(err);
|
||||
out_remove_file:
|
||||
device_remove_file(pdev, &dev_attr_whole_disk);
|
||||
out_del:
|
||||
kobject_put(p->holder_dir);
|
||||
device_del(pdev);
|
||||
|
|
|
@ -488,6 +488,12 @@ static int lo_rw_aio(struct loop_device *lo, struct loop_cmd *cmd,
|
|||
bvec = __bvec_iter_bvec(bio->bi_io_vec, bio->bi_iter);
|
||||
iov_iter_bvec(&iter, ITER_BVEC | rw, bvec,
|
||||
bio_segments(bio), blk_rq_bytes(cmd->rq));
|
||||
/*
|
||||
* This bio may be started from the middle of the 'bvec'
|
||||
* because of bio splitting, so offset from the bvec must
|
||||
* be passed to iov iterator
|
||||
*/
|
||||
iter.iov_offset = bio->bi_iter.bi_bvec_done;
|
||||
|
||||
cmd->iocb.ki_pos = pos;
|
||||
cmd->iocb.ki_filp = file;
|
||||
|
|
|
@ -972,7 +972,7 @@ int mvebu_mbus_get_dram_win_info(phys_addr_t phyaddr, u8 *target, u8 *attr)
|
|||
}
|
||||
}
|
||||
|
||||
pr_err("invalid dram address 0x%x\n", phyaddr);
|
||||
pr_err("invalid dram address %pa\n", &phyaddr);
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mvebu_mbus_get_dram_win_info);
|
||||
|
|
|
@ -108,7 +108,7 @@ static int uniphier_system_bus_check_overlap(
|
|||
|
||||
for (i = 0; i < ARRAY_SIZE(priv->bank); i++) {
|
||||
for (j = i + 1; j < ARRAY_SIZE(priv->bank); j++) {
|
||||
if (priv->bank[i].end > priv->bank[j].base ||
|
||||
if (priv->bank[i].end > priv->bank[j].base &&
|
||||
priv->bank[i].base < priv->bank[j].end) {
|
||||
dev_err(priv->dev,
|
||||
"region overlap between bank%d and bank%d\n",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/clk.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hw_random.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#define RNG_CTRL 0x00
|
||||
#define RNG_EN (1 << 0)
|
||||
|
|
|
@ -130,26 +130,14 @@ static void dwc_desc_put(struct dw_dma_chan *dwc, struct dw_desc *desc)
|
|||
static void dwc_initialize(struct dw_dma_chan *dwc)
|
||||
{
|
||||
struct dw_dma *dw = to_dw_dma(dwc->chan.device);
|
||||
struct dw_dma_slave *dws = dwc->chan.private;
|
||||
u32 cfghi = DWC_CFGH_FIFO_MODE;
|
||||
u32 cfglo = DWC_CFGL_CH_PRIOR(dwc->priority);
|
||||
|
||||
if (dwc->initialized == true)
|
||||
return;
|
||||
|
||||
if (dws) {
|
||||
/*
|
||||
* We need controller-specific data to set up slave
|
||||
* transfers.
|
||||
*/
|
||||
BUG_ON(!dws->dma_dev || dws->dma_dev != dw->dma.dev);
|
||||
|
||||
cfghi |= DWC_CFGH_DST_PER(dws->dst_id);
|
||||
cfghi |= DWC_CFGH_SRC_PER(dws->src_id);
|
||||
} else {
|
||||
cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
|
||||
cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
|
||||
}
|
||||
cfghi |= DWC_CFGH_DST_PER(dwc->dst_id);
|
||||
cfghi |= DWC_CFGH_SRC_PER(dwc->src_id);
|
||||
|
||||
channel_writel(dwc, CFG_LO, cfglo);
|
||||
channel_writel(dwc, CFG_HI, cfghi);
|
||||
|
@ -941,7 +929,7 @@ bool dw_dma_filter(struct dma_chan *chan, void *param)
|
|||
struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
|
||||
struct dw_dma_slave *dws = param;
|
||||
|
||||
if (!dws || dws->dma_dev != chan->device->dev)
|
||||
if (dws->dma_dev != chan->device->dev)
|
||||
return false;
|
||||
|
||||
/* We have to copy data since dws can be temporary storage */
|
||||
|
@ -1165,6 +1153,14 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
|
|||
* doesn't mean what you think it means), and status writeback.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We need controller-specific data to set up slave transfers.
|
||||
*/
|
||||
if (chan->private && !dw_dma_filter(chan, chan->private)) {
|
||||
dev_warn(chan2dev(chan), "Wrong controller-specific data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Enable controller here if needed */
|
||||
if (!dw->in_use)
|
||||
dw_dma_on(dw);
|
||||
|
@ -1226,6 +1222,14 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
|
|||
spin_lock_irqsave(&dwc->lock, flags);
|
||||
list_splice_init(&dwc->free_list, &list);
|
||||
dwc->descs_allocated = 0;
|
||||
|
||||
/* Clear custom channel configuration */
|
||||
dwc->src_id = 0;
|
||||
dwc->dst_id = 0;
|
||||
|
||||
dwc->src_master = 0;
|
||||
dwc->dst_master = 0;
|
||||
|
||||
dwc->initialized = false;
|
||||
|
||||
/* Disable interrupts */
|
||||
|
|
|
@ -1238,6 +1238,7 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
|
|||
struct edma_desc *edesc;
|
||||
dma_addr_t src_addr, dst_addr;
|
||||
enum dma_slave_buswidth dev_width;
|
||||
bool use_intermediate = false;
|
||||
u32 burst;
|
||||
int i, ret, nslots;
|
||||
|
||||
|
@ -1279,8 +1280,21 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
|
|||
* but the synchronization is difficult to achieve with Cyclic and
|
||||
* cannot be guaranteed, so we error out early.
|
||||
*/
|
||||
if (nslots > MAX_NR_SG)
|
||||
return NULL;
|
||||
if (nslots > MAX_NR_SG) {
|
||||
/*
|
||||
* If the burst and period sizes are the same, we can put
|
||||
* the full buffer into a single period and activate
|
||||
* intermediate interrupts. This will produce interrupts
|
||||
* after each burst, which is also after each desired period.
|
||||
*/
|
||||
if (burst == period_len) {
|
||||
period_len = buf_len;
|
||||
nslots = 2;
|
||||
use_intermediate = true;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
edesc = kzalloc(sizeof(*edesc) + nslots * sizeof(edesc->pset[0]),
|
||||
GFP_ATOMIC);
|
||||
|
@ -1358,8 +1372,13 @@ static struct dma_async_tx_descriptor *edma_prep_dma_cyclic(
|
|||
/*
|
||||
* Enable period interrupt only if it is requested
|
||||
*/
|
||||
if (tx_flags & DMA_PREP_INTERRUPT)
|
||||
if (tx_flags & DMA_PREP_INTERRUPT) {
|
||||
edesc->pset[i].param.opt |= TCINTEN;
|
||||
|
||||
/* Also enable intermediate interrupts if necessary */
|
||||
if (use_intermediate)
|
||||
edesc->pset[i].param.opt |= ITCINTEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Place the cyclic channel to highest priority queue */
|
||||
|
@ -1570,32 +1589,6 @@ static irqreturn_t dma_ccerr_handler(int irq, void *data)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void edma_tc_set_pm_state(struct edma_tc *tc, bool enable)
|
||||
{
|
||||
struct platform_device *tc_pdev;
|
||||
int ret;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_OF) || !tc)
|
||||
return;
|
||||
|
||||
tc_pdev = of_find_device_by_node(tc->node);
|
||||
if (!tc_pdev) {
|
||||
pr_err("%s: TPTC device is not found\n", __func__);
|
||||
return;
|
||||
}
|
||||
if (!pm_runtime_enabled(&tc_pdev->dev))
|
||||
pm_runtime_enable(&tc_pdev->dev);
|
||||
|
||||
if (enable)
|
||||
ret = pm_runtime_get_sync(&tc_pdev->dev);
|
||||
else
|
||||
ret = pm_runtime_put_sync(&tc_pdev->dev);
|
||||
|
||||
if (ret < 0)
|
||||
pr_err("%s: pm_runtime_%s_sync() failed for %s\n", __func__,
|
||||
enable ? "get" : "put", dev_name(&tc_pdev->dev));
|
||||
}
|
||||
|
||||
/* Alloc channel resources */
|
||||
static int edma_alloc_chan_resources(struct dma_chan *chan)
|
||||
{
|
||||
|
@ -1632,8 +1625,6 @@ static int edma_alloc_chan_resources(struct dma_chan *chan)
|
|||
EDMA_CHAN_SLOT(echan->ch_num), chan->chan_id,
|
||||
echan->hw_triggered ? "HW" : "SW");
|
||||
|
||||
edma_tc_set_pm_state(echan->tc, true);
|
||||
|
||||
return 0;
|
||||
|
||||
err_slot:
|
||||
|
@ -1670,7 +1661,6 @@ static void edma_free_chan_resources(struct dma_chan *chan)
|
|||
echan->alloced = false;
|
||||
}
|
||||
|
||||
edma_tc_set_pm_state(echan->tc, false);
|
||||
echan->tc = NULL;
|
||||
echan->hw_triggered = false;
|
||||
|
||||
|
@ -2417,10 +2407,8 @@ static int edma_pm_suspend(struct device *dev)
|
|||
int i;
|
||||
|
||||
for (i = 0; i < ecc->num_channels; i++) {
|
||||
if (echan[i].alloced) {
|
||||
if (echan[i].alloced)
|
||||
edma_setup_interrupt(&echan[i], false);
|
||||
edma_tc_set_pm_state(echan[i].tc, false);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2450,8 +2438,6 @@ static int edma_pm_resume(struct device *dev)
|
|||
|
||||
/* Set up channel -> slot mapping for the entry slot */
|
||||
edma_set_chmap(&echan[i], echan[i].slot[0]);
|
||||
|
||||
edma_tc_set_pm_state(echan[i].tc, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2475,7 +2461,8 @@ static struct platform_driver edma_driver = {
|
|||
|
||||
static int edma_tptc_probe(struct platform_device *pdev)
|
||||
{
|
||||
return 0;
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
return pm_runtime_get_sync(&pdev->dev);
|
||||
}
|
||||
|
||||
static struct platform_driver edma_tptc_driver = {
|
||||
|
|
|
@ -64,10 +64,10 @@ static void hsu_dma_chan_start(struct hsu_dma_chan *hsuc)
|
|||
|
||||
if (hsuc->direction == DMA_MEM_TO_DEV) {
|
||||
bsr = config->dst_maxburst;
|
||||
mtsr = config->dst_addr_width;
|
||||
mtsr = config->src_addr_width;
|
||||
} else if (hsuc->direction == DMA_DEV_TO_MEM) {
|
||||
bsr = config->src_maxburst;
|
||||
mtsr = config->src_addr_width;
|
||||
mtsr = config->dst_addr_width;
|
||||
}
|
||||
|
||||
hsu_chan_disable(hsuc);
|
||||
|
@ -135,7 +135,7 @@ static u32 hsu_dma_chan_get_sr(struct hsu_dma_chan *hsuc)
|
|||
sr = hsu_chan_readl(hsuc, HSU_CH_SR);
|
||||
spin_unlock_irqrestore(&hsuc->vchan.lock, flags);
|
||||
|
||||
return sr;
|
||||
return sr & ~(HSU_CH_SR_DESCE_ANY | HSU_CH_SR_CDESC_ANY);
|
||||
}
|
||||
|
||||
irqreturn_t hsu_dma_irq(struct hsu_dma_chip *chip, unsigned short nr)
|
||||
|
@ -254,10 +254,13 @@ static void hsu_dma_issue_pending(struct dma_chan *chan)
|
|||
static size_t hsu_dma_active_desc_size(struct hsu_dma_chan *hsuc)
|
||||
{
|
||||
struct hsu_dma_desc *desc = hsuc->desc;
|
||||
size_t bytes = desc->length;
|
||||
size_t bytes = 0;
|
||||
int i;
|
||||
|
||||
i = desc->active % HSU_DMA_CHAN_NR_DESC;
|
||||
for (i = desc->active; i < desc->nents; i++)
|
||||
bytes += desc->sg[i].len;
|
||||
|
||||
i = HSU_DMA_CHAN_NR_DESC - 1;
|
||||
do {
|
||||
bytes += hsu_chan_readl(hsuc, HSU_CH_DxTSR(i));
|
||||
} while (--i >= 0);
|
||||
|
|
|
@ -41,6 +41,9 @@
|
|||
#define HSU_CH_SR_DESCTO(x) BIT(8 + (x))
|
||||
#define HSU_CH_SR_DESCTO_ANY (BIT(11) | BIT(10) | BIT(9) | BIT(8))
|
||||
#define HSU_CH_SR_CHE BIT(15)
|
||||
#define HSU_CH_SR_DESCE(x) BIT(16 + (x))
|
||||
#define HSU_CH_SR_DESCE_ANY (BIT(19) | BIT(18) | BIT(17) | BIT(16))
|
||||
#define HSU_CH_SR_CDESC_ANY (BIT(31) | BIT(30))
|
||||
|
||||
/* Bits in HSU_CH_CR */
|
||||
#define HSU_CH_CR_CHA BIT(0)
|
||||
|
|
|
@ -48,6 +48,7 @@ struct omap_chan {
|
|||
unsigned dma_sig;
|
||||
bool cyclic;
|
||||
bool paused;
|
||||
bool running;
|
||||
|
||||
int dma_ch;
|
||||
struct omap_desc *desc;
|
||||
|
@ -294,6 +295,8 @@ static void omap_dma_start(struct omap_chan *c, struct omap_desc *d)
|
|||
|
||||
/* Enable channel */
|
||||
omap_dma_chan_write(c, CCR, d->ccr | CCR_ENABLE);
|
||||
|
||||
c->running = true;
|
||||
}
|
||||
|
||||
static void omap_dma_stop(struct omap_chan *c)
|
||||
|
@ -355,6 +358,8 @@ static void omap_dma_stop(struct omap_chan *c)
|
|||
|
||||
omap_dma_chan_write(c, CLNK_CTRL, val);
|
||||
}
|
||||
|
||||
c->running = false;
|
||||
}
|
||||
|
||||
static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
|
||||
|
@ -673,15 +678,20 @@ static enum dma_status omap_dma_tx_status(struct dma_chan *chan,
|
|||
struct omap_chan *c = to_omap_dma_chan(chan);
|
||||
struct virt_dma_desc *vd;
|
||||
enum dma_status ret;
|
||||
uint32_t ccr;
|
||||
unsigned long flags;
|
||||
|
||||
ccr = omap_dma_chan_read(c, CCR);
|
||||
/* The channel is no longer active, handle the completion right away */
|
||||
if (!(ccr & CCR_ENABLE))
|
||||
omap_dma_callback(c->dma_ch, 0, c);
|
||||
|
||||
ret = dma_cookie_status(chan, cookie, txstate);
|
||||
|
||||
if (!c->paused && c->running) {
|
||||
uint32_t ccr = omap_dma_chan_read(c, CCR);
|
||||
/*
|
||||
* The channel is no longer active, set the return value
|
||||
* accordingly
|
||||
*/
|
||||
if (!(ccr & CCR_ENABLE))
|
||||
ret = DMA_COMPLETE;
|
||||
}
|
||||
|
||||
if (ret == DMA_COMPLETE || !txstate)
|
||||
return ret;
|
||||
|
||||
|
@ -945,9 +955,7 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_memcpy(
|
|||
d->ccr = c->ccr;
|
||||
d->ccr |= CCR_DST_AMODE_POSTINC | CCR_SRC_AMODE_POSTINC;
|
||||
|
||||
d->cicr = CICR_DROP_IE;
|
||||
if (tx_flags & DMA_PREP_INTERRUPT)
|
||||
d->cicr |= CICR_FRAME_IE;
|
||||
d->cicr = CICR_DROP_IE | CICR_FRAME_IE;
|
||||
|
||||
d->csdp = data_type;
|
||||
|
||||
|
|
|
@ -1236,7 +1236,7 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
|
|||
struct xilinx_vdma_device *xdev = ofdma->of_dma_data;
|
||||
int chan_id = dma_spec->args[0];
|
||||
|
||||
if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE)
|
||||
if (chan_id >= XILINX_VDMA_MAX_CHANS_PER_DEVICE || !xdev->chan[chan_id])
|
||||
return NULL;
|
||||
|
||||
return dma_get_slave_channel(&xdev->chan[chan_id]->common);
|
||||
|
|
|
@ -348,8 +348,7 @@ static int palmas_usb_probe(struct platform_device *pdev)
|
|||
palmas_vbus_irq_handler,
|
||||
IRQF_TRIGGER_FALLING |
|
||||
IRQF_TRIGGER_RISING |
|
||||
IRQF_ONESHOT |
|
||||
IRQF_EARLY_RESUME,
|
||||
IRQF_ONESHOT,
|
||||
"palmas_usb_vbus",
|
||||
palmas_usb);
|
||||
if (status < 0) {
|
||||
|
|
|
@ -203,7 +203,19 @@ void __init efi_init(void)
|
|||
|
||||
reserve_regions();
|
||||
early_memunmap(memmap.map, params.mmap_size);
|
||||
memblock_mark_nomap(params.mmap & PAGE_MASK,
|
||||
PAGE_ALIGN(params.mmap_size +
|
||||
(params.mmap & ~PAGE_MASK)));
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARM)) {
|
||||
/*
|
||||
* ARM currently does not allow ioremap_cache() to be called on
|
||||
* memory regions that are covered by struct page. So remove the
|
||||
* UEFI memory map from the linear mapping.
|
||||
*/
|
||||
memblock_mark_nomap(params.mmap & PAGE_MASK,
|
||||
PAGE_ALIGN(params.mmap_size +
|
||||
(params.mmap & ~PAGE_MASK)));
|
||||
} else {
|
||||
memblock_reserve(params.mmap & PAGE_MASK,
|
||||
PAGE_ALIGN(params.mmap_size +
|
||||
(params.mmap & ~PAGE_MASK)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2034,6 +2034,7 @@ struct amdgpu_device {
|
|||
|
||||
/* tracking pinned memory */
|
||||
u64 vram_pin_size;
|
||||
u64 invisible_pin_size;
|
||||
u64 gart_pin_size;
|
||||
|
||||
/* amdkfd interface */
|
||||
|
|
|
@ -384,7 +384,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
|
|||
vram_gtt.vram_size = adev->mc.real_vram_size;
|
||||
vram_gtt.vram_size -= adev->vram_pin_size;
|
||||
vram_gtt.vram_cpu_accessible_size = adev->mc.visible_vram_size;
|
||||
vram_gtt.vram_cpu_accessible_size -= adev->vram_pin_size;
|
||||
vram_gtt.vram_cpu_accessible_size -= (adev->vram_pin_size - adev->invisible_pin_size);
|
||||
vram_gtt.gtt_size = adev->mc.gtt_size;
|
||||
vram_gtt.gtt_size -= adev->gart_pin_size;
|
||||
return copy_to_user(out, &vram_gtt,
|
||||
|
|
|
@ -424,9 +424,11 @@ int amdgpu_bo_pin_restricted(struct amdgpu_bo *bo, u32 domain,
|
|||
bo->pin_count = 1;
|
||||
if (gpu_addr != NULL)
|
||||
*gpu_addr = amdgpu_bo_gpu_offset(bo);
|
||||
if (domain == AMDGPU_GEM_DOMAIN_VRAM)
|
||||
if (domain == AMDGPU_GEM_DOMAIN_VRAM) {
|
||||
bo->adev->vram_pin_size += amdgpu_bo_size(bo);
|
||||
else
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
|
||||
bo->adev->invisible_pin_size += amdgpu_bo_size(bo);
|
||||
} else
|
||||
bo->adev->gart_pin_size += amdgpu_bo_size(bo);
|
||||
} else {
|
||||
dev_err(bo->adev->dev, "%p pin failed\n", bo);
|
||||
|
@ -456,9 +458,11 @@ int amdgpu_bo_unpin(struct amdgpu_bo *bo)
|
|||
}
|
||||
r = ttm_bo_validate(&bo->tbo, &bo->placement, false, false);
|
||||
if (likely(r == 0)) {
|
||||
if (bo->tbo.mem.mem_type == TTM_PL_VRAM)
|
||||
if (bo->tbo.mem.mem_type == TTM_PL_VRAM) {
|
||||
bo->adev->vram_pin_size -= amdgpu_bo_size(bo);
|
||||
else
|
||||
if (bo->flags & AMDGPU_GEM_CREATE_NO_CPU_ACCESS)
|
||||
bo->adev->invisible_pin_size -= amdgpu_bo_size(bo);
|
||||
} else
|
||||
bo->adev->gart_pin_size -= amdgpu_bo_size(bo);
|
||||
} else {
|
||||
dev_err(bo->adev->dev, "%p validate failed for unpin\n", bo);
|
||||
|
|
|
@ -307,7 +307,7 @@ static int tonga_ih_sw_fini(void *handle)
|
|||
|
||||
amdgpu_irq_fini(adev);
|
||||
amdgpu_ih_ring_fini(adev);
|
||||
amdgpu_irq_add_domain(adev);
|
||||
amdgpu_irq_remove_domain(adev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -205,7 +205,7 @@ static const struct drm_display_mode drm_dmt_modes[] = {
|
|||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
|
||||
/* 0x0f - 1024x768@43Hz, interlace */
|
||||
{ DRM_MODE("1024x768i", DRM_MODE_TYPE_DRIVER, 44900, 1024, 1032,
|
||||
1208, 1264, 0, 768, 768, 772, 817, 0,
|
||||
1208, 1264, 0, 768, 768, 776, 817, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC |
|
||||
DRM_MODE_FLAG_INTERLACE) },
|
||||
/* 0x10 - 1024x768@60Hz */
|
||||
|
@ -522,12 +522,12 @@ static const struct drm_display_mode edid_est_modes[] = {
|
|||
720, 840, 0, 480, 481, 484, 500, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@75Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 31500, 640, 664,
|
||||
704, 832, 0, 480, 489, 491, 520, 0,
|
||||
704, 832, 0, 480, 489, 492, 520, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@72Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 30240, 640, 704,
|
||||
768, 864, 0, 480, 483, 486, 525, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@67Hz */
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25200, 640, 656,
|
||||
{ DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656,
|
||||
752, 800, 0, 480, 490, 492, 525, 0,
|
||||
DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, /* 640x480@60Hz */
|
||||
{ DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 35500, 720, 738,
|
||||
|
@ -539,7 +539,7 @@ static const struct drm_display_mode edid_est_modes[] = {
|
|||
{ DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 135000, 1280, 1296,
|
||||
1440, 1688, 0, 1024, 1025, 1028, 1066, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1280x1024@75Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78800, 1024, 1040,
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 78750, 1024, 1040,
|
||||
1136, 1312, 0, 768, 769, 772, 800, 0,
|
||||
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 1024x768@75Hz */
|
||||
{ DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 75000, 1024, 1048,
|
||||
|
@ -2241,7 +2241,7 @@ drm_est3_modes(struct drm_connector *connector, struct detailed_timing *timing)
|
|||
{
|
||||
int i, j, m, modes = 0;
|
||||
struct drm_display_mode *mode;
|
||||
u8 *est = ((u8 *)timing) + 5;
|
||||
u8 *est = ((u8 *)timing) + 6;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
for (j = 7; j >= 0; j--) {
|
||||
|
|
|
@ -94,7 +94,7 @@ comment "Sub-drivers"
|
|||
|
||||
config DRM_EXYNOS_G2D
|
||||
bool "G2D"
|
||||
depends on !VIDEO_SAMSUNG_S5P_G2D
|
||||
depends on VIDEO_SAMSUNG_S5P_G2D=n
|
||||
select FRAME_VECTOR
|
||||
help
|
||||
Choose this option if you want to use Exynos G2D for DRM.
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
# Makefile for the drm device driver. This driver provides support for the
|
||||
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
|
||||
|
||||
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fbdev.o \
|
||||
exynos_drm_fb.o exynos_drm_gem.o exynos_drm_core.o \
|
||||
exynos_drm_plane.o
|
||||
exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \
|
||||
exynos_drm_gem.o exynos_drm_core.o exynos_drm_plane.o
|
||||
|
||||
exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o
|
||||
exynosdrm-$(CONFIG_DRM_EXYNOS_IOMMU) += exynos_drm_iommu.o
|
||||
exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
|
||||
exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o
|
||||
|
|
|
@ -101,7 +101,7 @@ int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file)
|
|||
return 0;
|
||||
|
||||
err:
|
||||
list_for_each_entry_reverse(subdrv, &subdrv->list, list) {
|
||||
list_for_each_entry_continue_reverse(subdrv, &exynos_drm_subdrv_list, list) {
|
||||
if (subdrv->close)
|
||||
subdrv->close(dev, subdrv->dev, file);
|
||||
}
|
||||
|
|
|
@ -199,17 +199,6 @@ dma_addr_t exynos_drm_fb_dma_addr(struct drm_framebuffer *fb, int index)
|
|||
return exynos_fb->dma_addr[index];
|
||||
}
|
||||
|
||||
static void exynos_drm_output_poll_changed(struct drm_device *dev)
|
||||
{
|
||||
struct exynos_drm_private *private = dev->dev_private;
|
||||
struct drm_fb_helper *fb_helper = private->fb_helper;
|
||||
|
||||
if (fb_helper)
|
||||
drm_fb_helper_hotplug_event(fb_helper);
|
||||
else
|
||||
exynos_drm_fbdev_init(dev);
|
||||
}
|
||||
|
||||
static const struct drm_mode_config_funcs exynos_drm_mode_config_funcs = {
|
||||
.fb_create = exynos_user_fb_create,
|
||||
.output_poll_changed = exynos_drm_output_poll_changed,
|
||||
|
|
|
@ -317,3 +317,14 @@ void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
|
|||
|
||||
drm_fb_helper_restore_fbdev_mode_unlocked(private->fb_helper);
|
||||
}
|
||||
|
||||
void exynos_drm_output_poll_changed(struct drm_device *dev)
|
||||
{
|
||||
struct exynos_drm_private *private = dev->dev_private;
|
||||
struct drm_fb_helper *fb_helper = private->fb_helper;
|
||||
|
||||
if (fb_helper)
|
||||
drm_fb_helper_hotplug_event(fb_helper);
|
||||
else
|
||||
exynos_drm_fbdev_init(dev);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,30 @@
|
|||
#ifndef _EXYNOS_DRM_FBDEV_H_
|
||||
#define _EXYNOS_DRM_FBDEV_H_
|
||||
|
||||
#ifdef CONFIG_DRM_FBDEV_EMULATION
|
||||
|
||||
int exynos_drm_fbdev_init(struct drm_device *dev);
|
||||
int exynos_drm_fbdev_reinit(struct drm_device *dev);
|
||||
void exynos_drm_fbdev_fini(struct drm_device *dev);
|
||||
void exynos_drm_fbdev_restore_mode(struct drm_device *dev);
|
||||
void exynos_drm_output_poll_changed(struct drm_device *dev);
|
||||
|
||||
#else
|
||||
|
||||
static inline int exynos_drm_fbdev_init(struct drm_device *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void exynos_drm_fbdev_fini(struct drm_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void exynos_drm_fbdev_restore_mode(struct drm_device *dev)
|
||||
{
|
||||
}
|
||||
|
||||
#define exynos_drm_output_poll_changed (NULL)
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -888,7 +888,7 @@ static void fimd_dp_clock_enable(struct exynos_drm_crtc *crtc, bool enable)
|
|||
* clock. On these SoCs the bootloader may enable it but any
|
||||
* power domain off/on will reset it to disable state.
|
||||
*/
|
||||
if (ctx->driver_data != &exynos5_fimd_driver_data ||
|
||||
if (ctx->driver_data != &exynos5_fimd_driver_data &&
|
||||
ctx->driver_data != &exynos5420_fimd_driver_data)
|
||||
return;
|
||||
|
||||
|
|
|
@ -129,7 +129,7 @@ static void mic_set_path(struct exynos_mic *mic, bool enable)
|
|||
} else
|
||||
val &= ~(MIC0_RGB_MUX | MIC0_I80_MUX | MIC0_ON_MUX);
|
||||
|
||||
regmap_write(mic->sysreg, DSD_CFG_MUX, val);
|
||||
ret = regmap_write(mic->sysreg, DSD_CFG_MUX, val);
|
||||
if (ret)
|
||||
DRM_ERROR("mic: Failed to read system register\n");
|
||||
}
|
||||
|
@ -457,6 +457,7 @@ static int exynos_mic_probe(struct platform_device *pdev)
|
|||
"samsung,disp-syscon");
|
||||
if (IS_ERR(mic->sysreg)) {
|
||||
DRM_ERROR("mic: Failed to get system register.\n");
|
||||
ret = PTR_ERR(mic->sysreg);
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include <drm/exynos_drm.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/exynos_drm.h>
|
||||
#include "exynos_drm_drv.h"
|
||||
#include "exynos_drm_crtc.h"
|
||||
#include "exynos_drm_fb.h"
|
||||
|
@ -57,11 +58,12 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
|
|||
}
|
||||
|
||||
static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
|
||||
|
||||
{
|
||||
struct drm_plane_state *state = &exynos_state->base;
|
||||
struct drm_crtc *crtc = exynos_state->base.crtc;
|
||||
struct drm_display_mode *mode = &crtc->state->adjusted_mode;
|
||||
struct drm_crtc *crtc = state->crtc;
|
||||
struct drm_crtc_state *crtc_state =
|
||||
drm_atomic_get_existing_crtc_state(state->state, crtc);
|
||||
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
|
||||
int crtc_x, crtc_y;
|
||||
unsigned int crtc_w, crtc_h;
|
||||
unsigned int src_x, src_y;
|
||||
|
|
|
@ -758,10 +758,10 @@ static int i915_drm_resume(struct drm_device *dev)
|
|||
dev_priv->display.hpd_irq_setup(dev);
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
intel_display_resume(dev);
|
||||
|
||||
intel_dp_mst_resume(dev);
|
||||
|
||||
intel_display_resume(dev);
|
||||
|
||||
/*
|
||||
* ... but also need to make sure that hotplug processing
|
||||
* doesn't cause havoc. Like in the driver load code we don't
|
||||
|
|
|
@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
|
|||
/* IRQs are synced during runtime_suspend, we don't require a wakeref */
|
||||
disable_rpm_wakeref_asserts(dev_priv);
|
||||
|
||||
for (;;) {
|
||||
do {
|
||||
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
|
||||
iir = I915_READ(VLV_IIR);
|
||||
|
||||
|
@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
|
|||
|
||||
I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
|
||||
POSTING_READ(GEN8_MASTER_IRQ);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
enable_rpm_wakeref_asserts(dev_priv);
|
||||
|
||||
|
|
|
@ -506,6 +506,8 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||
struct intel_connector *intel_connector = to_intel_connector(connector);
|
||||
struct drm_device *dev = connector->dev;
|
||||
|
||||
intel_connector->unregister(intel_connector);
|
||||
|
||||
/* need to nuke the connector */
|
||||
drm_modeset_lock_all(dev);
|
||||
if (connector->state->crtc) {
|
||||
|
@ -519,11 +521,7 @@ static void intel_dp_destroy_mst_connector(struct drm_dp_mst_topology_mgr *mgr,
|
|||
|
||||
WARN(ret, "Disabling mst crtc failed with %i\n", ret);
|
||||
}
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
||||
intel_connector->unregister(intel_connector);
|
||||
|
||||
drm_modeset_lock_all(dev);
|
||||
intel_connector_remove_from_fbdev(intel_connector);
|
||||
drm_connector_cleanup(connector);
|
||||
drm_modeset_unlock_all(dev);
|
||||
|
|
|
@ -478,11 +478,8 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val,
|
|||
* and as part of the cleanup in the hw state restore we also redisable
|
||||
* the vga plane.
|
||||
*/
|
||||
if (!HAS_PCH_SPLIT(dev)) {
|
||||
drm_modeset_lock_all(dev);
|
||||
if (!HAS_PCH_SPLIT(dev))
|
||||
intel_display_resume(dev);
|
||||
drm_modeset_unlock_all(dev);
|
||||
}
|
||||
|
||||
dev_priv->modeset_restore = MODESET_DONE;
|
||||
|
||||
|
|
|
@ -375,10 +375,15 @@ static int qxl_crtc_cursor_set2(struct drm_crtc *crtc,
|
|||
|
||||
qxl_bo_kunmap(user_bo);
|
||||
|
||||
qcrtc->cur_x += qcrtc->hot_spot_x - hot_x;
|
||||
qcrtc->cur_y += qcrtc->hot_spot_y - hot_y;
|
||||
qcrtc->hot_spot_x = hot_x;
|
||||
qcrtc->hot_spot_y = hot_y;
|
||||
|
||||
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
|
||||
cmd->type = QXL_CURSOR_SET;
|
||||
cmd->u.set.position.x = qcrtc->cur_x;
|
||||
cmd->u.set.position.y = qcrtc->cur_y;
|
||||
cmd->u.set.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
|
||||
cmd->u.set.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
|
||||
|
||||
cmd->u.set.shape = qxl_bo_physical_address(qdev, cursor_bo, 0);
|
||||
|
||||
|
@ -441,8 +446,8 @@ static int qxl_crtc_cursor_move(struct drm_crtc *crtc,
|
|||
|
||||
cmd = (struct qxl_cursor_cmd *)qxl_release_map(qdev, release);
|
||||
cmd->type = QXL_CURSOR_MOVE;
|
||||
cmd->u.position.x = qcrtc->cur_x;
|
||||
cmd->u.position.y = qcrtc->cur_y;
|
||||
cmd->u.position.x = qcrtc->cur_x + qcrtc->hot_spot_x;
|
||||
cmd->u.position.y = qcrtc->cur_y + qcrtc->hot_spot_y;
|
||||
qxl_release_unmap(qdev, release, &cmd->release_info);
|
||||
|
||||
qxl_push_cursor_ring_release(qdev, release, QXL_CMD_CURSOR, false);
|
||||
|
|
|
@ -135,6 +135,8 @@ struct qxl_crtc {
|
|||
int index;
|
||||
int cur_x;
|
||||
int cur_y;
|
||||
int hot_spot_x;
|
||||
int hot_spot_y;
|
||||
};
|
||||
|
||||
struct qxl_output {
|
||||
|
|
|
@ -109,6 +109,8 @@
|
|||
#define NI_DP_MSE_SAT2 0x7398
|
||||
|
||||
#define NI_DP_MSE_SAT_UPDATE 0x739c
|
||||
# define NI_DP_MSE_SAT_UPDATE_MASK 0x3
|
||||
# define NI_DP_MSE_16_MTP_KEEPOUT 0x100
|
||||
|
||||
#define NI_DIG_BE_CNTL 0x7140
|
||||
# define NI_DIG_FE_SOURCE_SELECT(x) (((x) & 0x7f) << 8)
|
||||
|
|
|
@ -89,8 +89,16 @@ static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary,
|
|||
WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1);
|
||||
|
||||
do {
|
||||
unsigned value1, value2;
|
||||
udelay(10);
|
||||
temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset);
|
||||
} while ((temp & 0x1) && retries++ < 10000);
|
||||
|
||||
value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK;
|
||||
value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT;
|
||||
|
||||
if (!value1 && !value2)
|
||||
break;
|
||||
} while (retries++ < 50);
|
||||
|
||||
if (retries == 10000)
|
||||
DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset);
|
||||
|
@ -150,7 +158,7 @@ static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, uint32_t y)
|
||||
static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp)
|
||||
{
|
||||
struct drm_device *dev = mst->base.dev;
|
||||
struct radeon_device *rdev = dev->dev_private;
|
||||
|
@ -158,6 +166,8 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui
|
|||
uint32_t val, temp;
|
||||
uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe);
|
||||
int retries = 0;
|
||||
uint32_t x = drm_fixp2int(avg_time_slots_per_mtp);
|
||||
uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26);
|
||||
|
||||
val = NI_DP_MSE_RATE_X(x) | NI_DP_MSE_RATE_Y(y);
|
||||
|
||||
|
@ -165,6 +175,7 @@ static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, uint32_t x, ui
|
|||
|
||||
do {
|
||||
temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset);
|
||||
udelay(10);
|
||||
} while ((temp & 0x1) && (retries++ < 10000));
|
||||
|
||||
if (retries >= 10000)
|
||||
|
@ -246,14 +257,8 @@ radeon_dp_mst_connector_destroy(struct drm_connector *connector)
|
|||
kfree(radeon_connector);
|
||||
}
|
||||
|
||||
static int radeon_connector_dpms(struct drm_connector *connector, int mode)
|
||||
{
|
||||
DRM_DEBUG_KMS("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = {
|
||||
.dpms = radeon_connector_dpms,
|
||||
.dpms = drm_helper_connector_dpms,
|
||||
.detect = radeon_dp_mst_detect,
|
||||
.fill_modes = drm_helper_probe_single_connector_modes,
|
||||
.destroy = radeon_dp_mst_connector_destroy,
|
||||
|
@ -394,7 +399,7 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||
struct drm_crtc *crtc;
|
||||
struct radeon_crtc *radeon_crtc;
|
||||
int ret, slots;
|
||||
|
||||
s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp;
|
||||
if (!ASIC_IS_DCE5(rdev)) {
|
||||
DRM_ERROR("got mst dpms on non-DCE5\n");
|
||||
return;
|
||||
|
@ -456,7 +461,11 @@ radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode)
|
|||
|
||||
mst_enc->enc_active = true;
|
||||
radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary);
|
||||
radeon_dp_mst_set_vcp_size(radeon_encoder, slots, 0);
|
||||
|
||||
fixed_pbn = drm_int2fixp(mst_enc->pbn);
|
||||
fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div);
|
||||
avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot);
|
||||
radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp);
|
||||
|
||||
atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON, 0,
|
||||
mst_enc->fe);
|
||||
|
|
|
@ -331,7 +331,7 @@ void set_interrupt(struct lg_cpu *cpu, unsigned int irq)
|
|||
* Actually now I think of it, it's possible that Ron *is* half the Plan 9
|
||||
* userbase. Oh well.
|
||||
*/
|
||||
static bool could_be_syscall(unsigned int num)
|
||||
bool could_be_syscall(unsigned int num)
|
||||
{
|
||||
/* Normal Linux IA32_SYSCALL_VECTOR or reserved vector? */
|
||||
return num == IA32_SYSCALL_VECTOR || num == syscall_vector;
|
||||
|
@ -416,6 +416,10 @@ bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
|
|||
*
|
||||
* This routine indicates if a particular trap number could be delivered
|
||||
* directly.
|
||||
*
|
||||
* Unfortunately, Linux 4.6 started using an interrupt gate instead of a
|
||||
* trap gate for syscalls, so this trick is ineffective. See Mastery for
|
||||
* how we could do this anyway...
|
||||
*/
|
||||
static bool direct_trap(unsigned int num)
|
||||
{
|
||||
|
|
|
@ -167,6 +167,7 @@ void guest_set_clockevent(struct lg_cpu *cpu, unsigned long delta);
|
|||
bool send_notify_to_eventfd(struct lg_cpu *cpu);
|
||||
void init_clockdev(struct lg_cpu *cpu);
|
||||
bool check_syscall_vector(struct lguest *lg);
|
||||
bool could_be_syscall(unsigned int num);
|
||||
int init_interrupts(void);
|
||||
void free_interrupts(void);
|
||||
|
||||
|
|
|
@ -429,8 +429,12 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
|
|||
return;
|
||||
break;
|
||||
case 32 ... 255:
|
||||
/* This might be a syscall. */
|
||||
if (could_be_syscall(cpu->regs->trapnum))
|
||||
break;
|
||||
|
||||
/*
|
||||
* These values mean a real interrupt occurred, in which case
|
||||
* Other values mean a real interrupt occurred, in which case
|
||||
* the Host handler has already been run. We just do a
|
||||
* friendly check if another process should now be run, then
|
||||
* return to run the Guest again.
|
||||
|
|
|
@ -46,7 +46,6 @@ static ssize_t mbox_test_signal_write(struct file *filp,
|
|||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct mbox_test_device *tdev = filp->private_data;
|
||||
int ret;
|
||||
|
||||
if (!tdev->tx_channel) {
|
||||
dev_err(tdev->dev, "Channel cannot do Tx\n");
|
||||
|
@ -60,17 +59,20 @@ static ssize_t mbox_test_signal_write(struct file *filp,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
|
||||
if (!tdev->signal)
|
||||
return -ENOMEM;
|
||||
/* Only allocate memory if we need to */
|
||||
if (!tdev->signal) {
|
||||
tdev->signal = kzalloc(MBOX_MAX_SIG_LEN, GFP_KERNEL);
|
||||
if (!tdev->signal)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = copy_from_user(tdev->signal, userbuf, count);
|
||||
if (ret) {
|
||||
if (copy_from_user(tdev->signal, userbuf, count)) {
|
||||
kfree(tdev->signal);
|
||||
tdev->signal = NULL;
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return ret < 0 ? ret : count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations mbox_test_signal_ops = {
|
||||
|
|
|
@ -189,8 +189,8 @@ static int slimpro_mbox_probe(struct platform_device *pdev)
|
|||
int i;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(struct slimpro_mbox), GFP_KERNEL);
|
||||
if (IS_ERR(ctx))
|
||||
return PTR_ERR(ctx);
|
||||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, ctx);
|
||||
|
||||
|
|
|
@ -375,13 +375,13 @@ struct mbox_chan *mbox_request_channel_byname(struct mbox_client *cl,
|
|||
|
||||
if (!np) {
|
||||
dev_err(cl->dev, "%s() currently only supports DT\n", __func__);
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
if (!of_get_property(np, "mbox-names", NULL)) {
|
||||
dev_err(cl->dev,
|
||||
"%s() requires an \"mbox-names\" property\n", __func__);
|
||||
return ERR_PTR(-ENOSYS);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
of_property_for_each_string(np, "mbox-names", prop, mbox_name) {
|
||||
|
|
|
@ -867,39 +867,55 @@ static int blocks_are_unmapped_or_clean(struct dm_cache_metadata *cmd,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define WRITE_LOCK(cmd) \
|
||||
down_write(&cmd->root_lock); \
|
||||
if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
|
||||
up_write(&cmd->root_lock); \
|
||||
return -EINVAL; \
|
||||
static bool cmd_write_lock(struct dm_cache_metadata *cmd)
|
||||
{
|
||||
down_write(&cmd->root_lock);
|
||||
if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) {
|
||||
up_write(&cmd->root_lock);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define WRITE_LOCK_VOID(cmd) \
|
||||
down_write(&cmd->root_lock); \
|
||||
if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
|
||||
up_write(&cmd->root_lock); \
|
||||
return; \
|
||||
}
|
||||
#define WRITE_LOCK(cmd) \
|
||||
do { \
|
||||
if (!cmd_write_lock((cmd))) \
|
||||
return -EINVAL; \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_LOCK_VOID(cmd) \
|
||||
do { \
|
||||
if (!cmd_write_lock((cmd))) \
|
||||
return; \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_UNLOCK(cmd) \
|
||||
up_write(&cmd->root_lock)
|
||||
up_write(&(cmd)->root_lock)
|
||||
|
||||
#define READ_LOCK(cmd) \
|
||||
down_read(&cmd->root_lock); \
|
||||
if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
|
||||
up_read(&cmd->root_lock); \
|
||||
return -EINVAL; \
|
||||
static bool cmd_read_lock(struct dm_cache_metadata *cmd)
|
||||
{
|
||||
down_read(&cmd->root_lock);
|
||||
if (cmd->fail_io) {
|
||||
up_read(&cmd->root_lock);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define READ_LOCK_VOID(cmd) \
|
||||
down_read(&cmd->root_lock); \
|
||||
if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \
|
||||
up_read(&cmd->root_lock); \
|
||||
return; \
|
||||
}
|
||||
#define READ_LOCK(cmd) \
|
||||
do { \
|
||||
if (!cmd_read_lock((cmd))) \
|
||||
return -EINVAL; \
|
||||
} while(0)
|
||||
|
||||
#define READ_LOCK_VOID(cmd) \
|
||||
do { \
|
||||
if (!cmd_read_lock((cmd))) \
|
||||
return; \
|
||||
} while(0)
|
||||
|
||||
#define READ_UNLOCK(cmd) \
|
||||
up_read(&cmd->root_lock)
|
||||
up_read(&(cmd)->root_lock)
|
||||
|
||||
int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size)
|
||||
{
|
||||
|
|
|
@ -1662,8 +1662,10 @@ static int __clone_and_map_data_bio(struct clone_info *ci, struct dm_target *ti,
|
|||
tio = alloc_tio(ci, ti, target_bio_nr);
|
||||
tio->len_ptr = len;
|
||||
r = clone_bio(tio, bio, sector, *len);
|
||||
if (r < 0)
|
||||
if (r < 0) {
|
||||
free_tio(ci->md, tio);
|
||||
break;
|
||||
}
|
||||
__map_bio(tio);
|
||||
}
|
||||
|
||||
|
|
|
@ -458,8 +458,10 @@ static void lkdtm_do_action(enum ctype which)
|
|||
break;
|
||||
|
||||
val = kmalloc(len, GFP_KERNEL);
|
||||
if (!val)
|
||||
if (!val) {
|
||||
kfree(base);
|
||||
break;
|
||||
}
|
||||
|
||||
*val = 0x12345678;
|
||||
base[offset] = *val;
|
||||
|
@ -498,14 +500,17 @@ static void lkdtm_do_action(enum ctype which)
|
|||
}
|
||||
case CT_READ_BUDDY_AFTER_FREE: {
|
||||
unsigned long p = __get_free_page(GFP_KERNEL);
|
||||
int saw, *val = kmalloc(1024, GFP_KERNEL);
|
||||
int saw, *val;
|
||||
int *base;
|
||||
|
||||
if (!p)
|
||||
break;
|
||||
|
||||
if (!val)
|
||||
val = kmalloc(1024, GFP_KERNEL);
|
||||
if (!val) {
|
||||
free_page(p);
|
||||
break;
|
||||
}
|
||||
|
||||
base = (int *)p;
|
||||
|
||||
|
|
|
@ -86,7 +86,6 @@ static int max_devices;
|
|||
|
||||
/* TODO: Replace these with struct ida */
|
||||
static DECLARE_BITMAP(dev_use, MAX_DEVICES);
|
||||
static DECLARE_BITMAP(name_use, MAX_DEVICES);
|
||||
|
||||
/*
|
||||
* There is one mmc_blk_data per slot.
|
||||
|
@ -105,7 +104,6 @@ struct mmc_blk_data {
|
|||
unsigned int usage;
|
||||
unsigned int read_only;
|
||||
unsigned int part_type;
|
||||
unsigned int name_idx;
|
||||
unsigned int reset_done;
|
||||
#define MMC_BLK_READ BIT(0)
|
||||
#define MMC_BLK_WRITE BIT(1)
|
||||
|
@ -2202,19 +2200,6 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
|
|||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* !subname implies we are creating main mmc_blk_data that will be
|
||||
* associated with mmc_card with dev_set_drvdata. Due to device
|
||||
* partitions, devidx will not coincide with a per-physical card
|
||||
* index anymore so we keep track of a name index.
|
||||
*/
|
||||
if (!subname) {
|
||||
md->name_idx = find_first_zero_bit(name_use, max_devices);
|
||||
__set_bit(md->name_idx, name_use);
|
||||
} else
|
||||
md->name_idx = ((struct mmc_blk_data *)
|
||||
dev_to_disk(parent)->private_data)->name_idx;
|
||||
|
||||
md->area_type = area_type;
|
||||
|
||||
/*
|
||||
|
@ -2264,7 +2249,7 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
|
|||
*/
|
||||
|
||||
snprintf(md->disk->disk_name, sizeof(md->disk->disk_name),
|
||||
"mmcblk%u%s", md->name_idx, subname ? subname : "");
|
||||
"mmcblk%u%s", card->host->index, subname ? subname : "");
|
||||
|
||||
if (mmc_card_mmc(card))
|
||||
blk_queue_logical_block_size(md->queue.queue,
|
||||
|
@ -2418,7 +2403,6 @@ static void mmc_blk_remove_parts(struct mmc_card *card,
|
|||
struct list_head *pos, *q;
|
||||
struct mmc_blk_data *part_md;
|
||||
|
||||
__clear_bit(md->name_idx, name_use);
|
||||
list_for_each_safe(pos, q, &md->part) {
|
||||
part_md = list_entry(pos, struct mmc_blk_data, part);
|
||||
list_del(pos);
|
||||
|
|
|
@ -382,14 +382,6 @@ static const struct sdhci_tegra_soc_data soc_data_tegra114 = {
|
|||
.pdata = &sdhci_tegra114_pdata,
|
||||
};
|
||||
|
||||
static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
|
||||
.pdata = &sdhci_tegra114_pdata,
|
||||
.nvquirks = NVQUIRK_ENABLE_SDR50 |
|
||||
NVQUIRK_ENABLE_DDR50 |
|
||||
NVQUIRK_ENABLE_SDR104 |
|
||||
NVQUIRK_HAS_PADCALIB,
|
||||
};
|
||||
|
||||
static const struct sdhci_pltfm_data sdhci_tegra210_pdata = {
|
||||
.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL |
|
||||
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
|
||||
|
@ -407,7 +399,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
|
|||
|
||||
static const struct of_device_id sdhci_tegra_dt_match[] = {
|
||||
{ .compatible = "nvidia,tegra210-sdhci", .data = &soc_data_tegra210 },
|
||||
{ .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra124 },
|
||||
{ .compatible = "nvidia,tegra124-sdhci", .data = &soc_data_tegra114 },
|
||||
{ .compatible = "nvidia,tegra114-sdhci", .data = &soc_data_tegra114 },
|
||||
{ .compatible = "nvidia,tegra30-sdhci", .data = &soc_data_tegra30 },
|
||||
{ .compatible = "nvidia,tegra20-sdhci", .data = &soc_data_tegra20 },
|
||||
|
|
|
@ -4009,7 +4009,6 @@ static int nand_dt_init(struct nand_chip *chip)
|
|||
* This is the first phase of the normal nand_scan() function. It reads the
|
||||
* flash ID and sets up MTD fields accordingly.
|
||||
*
|
||||
* The mtd->owner field must be set to the module of the caller.
|
||||
*/
|
||||
int nand_scan_ident(struct mtd_info *mtd, int maxchips,
|
||||
struct nand_flash_dev *table)
|
||||
|
@ -4429,19 +4428,12 @@ EXPORT_SYMBOL(nand_scan_tail);
|
|||
*
|
||||
* This fills out all the uninitialized function pointers with the defaults.
|
||||
* The flash ID is read and the mtd/chip structures are filled with the
|
||||
* appropriate values. The mtd->owner field must be set to the module of the
|
||||
* caller.
|
||||
* appropriate values.
|
||||
*/
|
||||
int nand_scan(struct mtd_info *mtd, int maxchips)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Many callers got this wrong, so check for it for a while... */
|
||||
if (!mtd->owner && caller_is_module()) {
|
||||
pr_crit("%s called with NULL mtd->owner!\n", __func__);
|
||||
BUG();
|
||||
}
|
||||
|
||||
ret = nand_scan_ident(mtd, maxchips, NULL);
|
||||
if (!ret)
|
||||
ret = nand_scan_tail(mtd);
|
||||
|
|
|
@ -103,6 +103,20 @@ static int pmem_do_bvec(struct pmem_device *pmem, struct page *page,
|
|||
flush_dcache_page(page);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Note that we write the data both before and after
|
||||
* clearing poison. The write before clear poison
|
||||
* handles situations where the latest written data is
|
||||
* preserved and the clear poison operation simply marks
|
||||
* the address range as valid without changing the data.
|
||||
* In this case application software can assume that an
|
||||
* interrupted write will either return the new good
|
||||
* data or an error.
|
||||
*
|
||||
* However, if pmem_clear_poison() leaves the data in an
|
||||
* indeterminate state we need to perform the write
|
||||
* after clear poison.
|
||||
*/
|
||||
flush_dcache_page(page);
|
||||
memcpy_to_pmem(pmem_addr, mem + off, len);
|
||||
if (unlikely(bad_pmem)) {
|
||||
|
|
|
@ -1478,8 +1478,7 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
|
|||
if (result > 0) {
|
||||
dev_err(dev->ctrl.device,
|
||||
"Could not set queue count (%d)\n", result);
|
||||
nr_io_queues = 0;
|
||||
result = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dev->cmb && NVME_CMB_SQS(dev->cmbsz)) {
|
||||
|
@ -1513,7 +1512,9 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)
|
|||
* If we enable msix early due to not intx, disable it again before
|
||||
* setting up the full range we need.
|
||||
*/
|
||||
if (!pdev->irq)
|
||||
if (pdev->msi_enabled)
|
||||
pci_disable_msi(pdev);
|
||||
else if (pdev->msix_enabled)
|
||||
pci_disable_msix(pdev);
|
||||
|
||||
for (i = 0; i < nr_io_queues; i++)
|
||||
|
@ -1696,7 +1697,6 @@ static int nvme_pci_enable(struct nvme_dev *dev)
|
|||
if (pci_enable_device_mem(pdev))
|
||||
return result;
|
||||
|
||||
dev->entry[0].vector = pdev->irq;
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (dma_set_mask_and_coherent(dev->dev, DMA_BIT_MASK(64)) &&
|
||||
|
@ -1709,13 +1709,18 @@ static int nvme_pci_enable(struct nvme_dev *dev)
|
|||
}
|
||||
|
||||
/*
|
||||
* Some devices don't advertse INTx interrupts, pre-enable a single
|
||||
* MSIX vec for setup. We'll adjust this later.
|
||||
* Some devices and/or platforms don't advertise or work with INTx
|
||||
* interrupts. Pre-enable a single MSIX or MSI vec for setup. We'll
|
||||
* adjust this later.
|
||||
*/
|
||||
if (!pdev->irq) {
|
||||
result = pci_enable_msix(pdev, dev->entry, 1);
|
||||
if (result < 0)
|
||||
goto disable;
|
||||
if (pci_enable_msix(pdev, dev->entry, 1)) {
|
||||
pci_enable_msi(pdev);
|
||||
dev->entry[0].vector = pdev->irq;
|
||||
}
|
||||
|
||||
if (!dev->entry[0].vector) {
|
||||
result = -ENODEV;
|
||||
goto disable;
|
||||
}
|
||||
|
||||
cap = lo_hi_readq(dev->bar + NVME_REG_CAP);
|
||||
|
@ -1859,6 +1864,9 @@ static void nvme_reset_work(struct work_struct *work)
|
|||
if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
|
||||
nvme_dev_disable(dev, false);
|
||||
|
||||
if (test_bit(NVME_CTRL_REMOVING, &dev->flags))
|
||||
goto out;
|
||||
|
||||
set_bit(NVME_CTRL_RESETTING, &dev->flags);
|
||||
|
||||
result = nvme_pci_enable(dev);
|
||||
|
@ -2078,11 +2086,10 @@ static void nvme_remove(struct pci_dev *pdev)
|
|||
{
|
||||
struct nvme_dev *dev = pci_get_drvdata(pdev);
|
||||
|
||||
del_timer_sync(&dev->watchdog_timer);
|
||||
|
||||
set_bit(NVME_CTRL_REMOVING, &dev->flags);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
flush_work(&dev->async_work);
|
||||
flush_work(&dev->reset_work);
|
||||
flush_work(&dev->scan_work);
|
||||
nvme_remove_namespaces(&dev->ctrl);
|
||||
nvme_uninit_ctrl(&dev->ctrl);
|
||||
|
|
|
@ -636,7 +636,7 @@ static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
|
|||
u8 *data = (u8 *) buf;
|
||||
|
||||
/* Several chips lock up trying to read undefined config space */
|
||||
if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0)
|
||||
if (file_ns_capable(filp, &init_user_ns, CAP_SYS_ADMIN))
|
||||
size = dev->cfg_size;
|
||||
else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
|
||||
size = 128;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue