Merge tag 'nand/for-4.20' of git://git.infradead.org/linux-mtd into mtd/next
NAND core changes: - Two batchs of cleanups of the NAND API, including: * Deprecating a lot of interfaces (now replaced by ->exec_op()). * Moving code in separate drivers (JEDEC, ONFI), in private files (internals), in platform drivers, etc. * Functions/structures reordering. * Exclusive use of the nand_chip structure instead of the MTD one all across the subsystem. - Addition of the nand_wait_readrdy/rdy_op() helpers. Raw NAND controllers drivers changes: - Various coccinelle patches. - Marvell: * Use regmap_update_bits() for syscon access. * More documentation. * BCH failure path rework. * More layouts to be supported. * IRQ handler complete() condition fixed. - Fsl_ifc: * SRAM initialization fixed for newer controller versions. - Denali: * Fix licenses mismatch and use a SPDX tag. * Set SPARE_AREA_SKIP_BYTES register to 8 if unset. - Qualcomm: * Do not include dma-direct.h. - Docg4: * Removed. - Ams-delta: * Use of a GPIO lookup table * Internal machinery changes. Raw NAND chip drivers changes: - Toshiba: * Add support for Toshiba memory BENAND * Pass a single nand_chip object to the status helper. - ESMT: * New driver to retrieve the ECC requirements from the 5th ID byte.
This commit is contained in:
@@ -73,3 +73,12 @@ KernelVersion: 3.0
|
|||||||
Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
Contact: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
|
||||||
Description:
|
Description:
|
||||||
Number of sectors written by the frontend.
|
Number of sectors written by the frontend.
|
||||||
|
|
||||||
|
What: /sys/bus/xen-backend/devices/*/state
|
||||||
|
Date: August 2018
|
||||||
|
KernelVersion: 4.19
|
||||||
|
Contact: Joe Jin <joe.jin@oracle.com>
|
||||||
|
Description:
|
||||||
|
The state of the device. One of: 'Unknown',
|
||||||
|
'Initialising', 'Initialised', 'Connected', 'Closing',
|
||||||
|
'Closed', 'Reconfiguring', 'Reconfigured'.
|
||||||
|
@@ -15,3 +15,13 @@ Description:
|
|||||||
blkback. If the frontend tries to use more than
|
blkback. If the frontend tries to use more than
|
||||||
max_persistent_grants, the LRU kicks in and starts
|
max_persistent_grants, the LRU kicks in and starts
|
||||||
removing 5% of max_persistent_grants every 100ms.
|
removing 5% of max_persistent_grants every 100ms.
|
||||||
|
|
||||||
|
What: /sys/module/xen_blkback/parameters/persistent_grant_unused_seconds
|
||||||
|
Date: August 2018
|
||||||
|
KernelVersion: 4.19
|
||||||
|
Contact: Roger Pau Monné <roger.pau@citrix.com>
|
||||||
|
Description:
|
||||||
|
How long a persistent grant is allowed to remain
|
||||||
|
allocated without being in use. The time is in
|
||||||
|
seconds, 0 means indefinitely long.
|
||||||
|
The default is 60 seconds.
|
||||||
|
@@ -200,7 +200,7 @@ prctl(PR_SVE_SET_VL, unsigned long arg)
|
|||||||
thread.
|
thread.
|
||||||
|
|
||||||
* Changing the vector length causes all of P0..P15, FFR and all bits of
|
* Changing the vector length causes all of P0..P15, FFR and all bits of
|
||||||
Z0..V31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
|
Z0..Z31 except for Z0 bits [127:0] .. Z31 bits [127:0] to become
|
||||||
unspecified. Calling PR_SVE_SET_VL with vl equal to the thread's current
|
unspecified. Calling PR_SVE_SET_VL with vl equal to the thread's current
|
||||||
vector length, or calling PR_SVE_SET_VL with the PR_SVE_SET_VL_ONEXEC
|
vector length, or calling PR_SVE_SET_VL with the PR_SVE_SET_VL_ONEXEC
|
||||||
flag, does not constitute a change to the vector length for this purpose.
|
flag, does not constitute a change to the vector length for this purpose.
|
||||||
@@ -500,7 +500,7 @@ References
|
|||||||
[2] arch/arm64/include/uapi/asm/ptrace.h
|
[2] arch/arm64/include/uapi/asm/ptrace.h
|
||||||
AArch64 Linux ptrace ABI definitions
|
AArch64 Linux ptrace ABI definitions
|
||||||
|
|
||||||
[3] linux/Documentation/arm64/cpu-feature-registers.txt
|
[3] Documentation/arm64/cpu-feature-registers.txt
|
||||||
|
|
||||||
[4] ARM IHI0055C
|
[4] ARM IHI0055C
|
||||||
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
|
http://infocenter.arm.com/help/topic/com.arm.doc.ihi0055c/IHI0055C_beta_aapcs64.pdf
|
||||||
|
@@ -11,7 +11,7 @@ The RISC-V supervisor ISA manual specifies three interrupt sources that are
|
|||||||
attached to every HLIC: software interrupts, the timer interrupt, and external
|
attached to every HLIC: software interrupts, the timer interrupt, and external
|
||||||
interrupts. Software interrupts are used to send IPIs between cores. The
|
interrupts. Software interrupts are used to send IPIs between cores. The
|
||||||
timer interrupt comes from an architecturally mandated real-time timer that is
|
timer interrupt comes from an architecturally mandated real-time timer that is
|
||||||
controller via Supervisor Binary Interface (SBI) calls and CSR reads. External
|
controlled via Supervisor Binary Interface (SBI) calls and CSR reads. External
|
||||||
interrupts connect all other device interrupts to the HLIC, which are routed
|
interrupts connect all other device interrupts to the HLIC, which are routed
|
||||||
via the platform-level interrupt controller (PLIC).
|
via the platform-level interrupt controller (PLIC).
|
||||||
|
|
||||||
@@ -25,7 +25,15 @@ in the system.
|
|||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible : "riscv,cpu-intc"
|
- compatible : "riscv,cpu-intc"
|
||||||
- #interrupt-cells : should be <1>
|
- #interrupt-cells : should be <1>. The interrupt sources are defined by the
|
||||||
|
RISC-V supervisor ISA manual, with only the following three interrupts being
|
||||||
|
defined for supervisor mode:
|
||||||
|
- Source 1 is the supervisor software interrupt, which can be sent by an SBI
|
||||||
|
call and is reserved for use by software.
|
||||||
|
- Source 5 is the supervisor timer interrupt, which can be configured by
|
||||||
|
SBI calls and implements a one-shot timer.
|
||||||
|
- Source 9 is the supervisor external interrupt, which chains to all other
|
||||||
|
device interrupts.
|
||||||
- interrupt-controller : Identifies the node as an interrupt controller
|
- interrupt-controller : Identifies the node as an interrupt controller
|
||||||
|
|
||||||
Furthermore, this interrupt-controller MUST be embedded inside the cpu
|
Furthermore, this interrupt-controller MUST be embedded inside the cpu
|
||||||
@@ -38,7 +46,7 @@ An example device tree entry for a HLIC is show below.
|
|||||||
...
|
...
|
||||||
cpu1-intc: interrupt-controller {
|
cpu1-intc: interrupt-controller {
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
compatible = "riscv,cpu-intc", "sifive,fu540-c000-cpu-intc";
|
compatible = "sifive,fu540-c000-cpu-intc", "riscv,cpu-intc";
|
||||||
interrupt-controller;
|
interrupt-controller;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@@ -7,6 +7,7 @@ Required properties:
|
|||||||
Examples with soctypes are:
|
Examples with soctypes are:
|
||||||
- "renesas,r8a7743-wdt" (RZ/G1M)
|
- "renesas,r8a7743-wdt" (RZ/G1M)
|
||||||
- "renesas,r8a7745-wdt" (RZ/G1E)
|
- "renesas,r8a7745-wdt" (RZ/G1E)
|
||||||
|
- "renesas,r8a774a1-wdt" (RZ/G2M)
|
||||||
- "renesas,r8a7790-wdt" (R-Car H2)
|
- "renesas,r8a7790-wdt" (R-Car H2)
|
||||||
- "renesas,r8a7791-wdt" (R-Car M2-W)
|
- "renesas,r8a7791-wdt" (R-Car M2-W)
|
||||||
- "renesas,r8a7792-wdt" (R-Car V2H)
|
- "renesas,r8a7792-wdt" (R-Car V2H)
|
||||||
@@ -21,8 +22,8 @@ Required properties:
|
|||||||
- "renesas,r7s72100-wdt" (RZ/A1)
|
- "renesas,r7s72100-wdt" (RZ/A1)
|
||||||
The generic compatible string must be:
|
The generic compatible string must be:
|
||||||
- "renesas,rza-wdt" for RZ/A
|
- "renesas,rza-wdt" for RZ/A
|
||||||
- "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G
|
- "renesas,rcar-gen2-wdt" for R-Car Gen2 and RZ/G1
|
||||||
- "renesas,rcar-gen3-wdt" for R-Car Gen3
|
- "renesas,rcar-gen3-wdt" for R-Car Gen3 and RZ/G2
|
||||||
|
|
||||||
- reg : Should contain WDT registers location and length
|
- reg : Should contain WDT registers location and length
|
||||||
- clocks : the clock feeding the watchdog timer.
|
- clocks : the clock feeding the watchdog timer.
|
||||||
|
@@ -180,10 +180,10 @@ by a chip select decoder.
|
|||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
struct nand_chip *this = mtd_to_nand(mtd);
|
||||||
switch(cmd){
|
switch(cmd){
|
||||||
case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break;
|
case NAND_CTL_SETCLE: this->legacy.IO_ADDR_W |= CLE_ADRR_BIT; break;
|
||||||
case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break;
|
case NAND_CTL_CLRCLE: this->legacy.IO_ADDR_W &= ~CLE_ADRR_BIT; break;
|
||||||
case NAND_CTL_SETALE: this->IO_ADDR_W |= ALE_ADRR_BIT; break;
|
case NAND_CTL_SETALE: this->legacy.IO_ADDR_W |= ALE_ADRR_BIT; break;
|
||||||
case NAND_CTL_CLRALE: this->IO_ADDR_W &= ~ALE_ADRR_BIT; break;
|
case NAND_CTL_CLRALE: this->legacy.IO_ADDR_W &= ~ALE_ADRR_BIT; break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ to read back the state of the pin. The function has no arguments and
|
|||||||
should return 0, if the device is busy (R/B pin is low) and 1, if the
|
should return 0, if the device is busy (R/B pin is low) and 1, if the
|
||||||
device is ready (R/B pin is high). If the hardware interface does not
|
device is ready (R/B pin is high). If the hardware interface does not
|
||||||
give access to the ready busy pin, then the function must not be defined
|
give access to the ready busy pin, then the function must not be defined
|
||||||
and the function pointer this->dev_ready is set to NULL.
|
and the function pointer this->legacy.dev_ready is set to NULL.
|
||||||
|
|
||||||
Init function
|
Init function
|
||||||
-------------
|
-------------
|
||||||
@@ -235,18 +235,18 @@ necessary information about the device.
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set address of NAND IO lines */
|
/* Set address of NAND IO lines */
|
||||||
this->IO_ADDR_R = baseaddr;
|
this->legacy.IO_ADDR_R = baseaddr;
|
||||||
this->IO_ADDR_W = baseaddr;
|
this->legacy.IO_ADDR_W = baseaddr;
|
||||||
/* Reference hardware control function */
|
/* Reference hardware control function */
|
||||||
this->hwcontrol = board_hwcontrol;
|
this->hwcontrol = board_hwcontrol;
|
||||||
/* Set command delay time, see datasheet for correct value */
|
/* Set command delay time, see datasheet for correct value */
|
||||||
this->chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
|
this->legacy.chip_delay = CHIP_DEPENDEND_COMMAND_DELAY;
|
||||||
/* Assign the device ready function, if available */
|
/* Assign the device ready function, if available */
|
||||||
this->dev_ready = board_dev_ready;
|
this->legacy.dev_ready = board_dev_ready;
|
||||||
this->eccmode = NAND_ECC_SOFT;
|
this->eccmode = NAND_ECC_SOFT;
|
||||||
|
|
||||||
/* Scan to find existence of the device */
|
/* Scan to find existence of the device */
|
||||||
if (nand_scan (board_mtd, 1)) {
|
if (nand_scan (this, 1)) {
|
||||||
err = -ENXIO;
|
err = -ENXIO;
|
||||||
goto out_ior;
|
goto out_ior;
|
||||||
}
|
}
|
||||||
@@ -277,7 +277,7 @@ unregisters the partitions in the MTD layer.
|
|||||||
static void __exit board_cleanup (void)
|
static void __exit board_cleanup (void)
|
||||||
{
|
{
|
||||||
/* Release resources, unregister device */
|
/* Release resources, unregister device */
|
||||||
nand_release (board_mtd);
|
nand_release (mtd_to_nand(board_mtd));
|
||||||
|
|
||||||
/* unmap physical address */
|
/* unmap physical address */
|
||||||
iounmap(baseaddr);
|
iounmap(baseaddr);
|
||||||
@@ -336,17 +336,17 @@ connected to an address decoder.
|
|||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
struct nand_chip *this = mtd_to_nand(mtd);
|
||||||
|
|
||||||
/* Deselect all chips */
|
/* Deselect all chips */
|
||||||
this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
|
this->legacy.IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK;
|
||||||
this->IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
|
this->legacy.IO_ADDR_W &= ~BOARD_NAND_ADDR_MASK;
|
||||||
switch (chip) {
|
switch (chip) {
|
||||||
case 0:
|
case 0:
|
||||||
this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
|
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIP0;
|
||||||
this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
|
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIP0;
|
||||||
break;
|
break;
|
||||||
....
|
....
|
||||||
case n:
|
case n:
|
||||||
this->IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
|
this->legacy.IO_ADDR_R |= BOARD_NAND_ADDR_CHIPn;
|
||||||
this->IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
|
this->legacy.IO_ADDR_W |= BOARD_NAND_ADDR_CHIPn;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ Supported chips:
|
|||||||
Datasheet: Publicly available at the Texas Instruments website
|
Datasheet: Publicly available at the Texas Instruments website
|
||||||
http://www.ti.com/
|
http://www.ti.com/
|
||||||
|
|
||||||
Author: Lothar Felten <l-felten@ti.com>
|
Author: Lothar Felten <lothar.felten@gmail.com>
|
||||||
|
|
||||||
Description
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
@@ -50,10 +50,14 @@ bounce buffer. But you don't need to care about that detail, just use the
|
|||||||
returned buffer. If NULL is returned, the threshold was not met or a bounce
|
returned buffer. If NULL is returned, the threshold was not met or a bounce
|
||||||
buffer could not be allocated. Fall back to PIO in that case.
|
buffer could not be allocated. Fall back to PIO in that case.
|
||||||
|
|
||||||
In any case, a buffer obtained from above needs to be released. It ensures data
|
In any case, a buffer obtained from above needs to be released. Another helper
|
||||||
is copied back to the message and a potentially used bounce buffer is freed::
|
function ensures a potentially used bounce buffer is freed::
|
||||||
|
|
||||||
i2c_release_dma_safe_msg_buf(msg, dma_buf);
|
i2c_put_dma_safe_msg_buf(dma_buf, msg, xferred);
|
||||||
|
|
||||||
|
The last argument 'xferred' controls if the buffer is synced back to the
|
||||||
|
message or not. No syncing is needed in cases setting up DMA had an error and
|
||||||
|
there was no data transferred.
|
||||||
|
|
||||||
The bounce buffer handling from the core is generic and simple. It will always
|
The bounce buffer handling from the core is generic and simple. It will always
|
||||||
allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
|
allocate a new bounce buffer. If you want a more sophisticated handling (e.g.
|
||||||
|
@@ -1,113 +0,0 @@
|
|||||||
|
|
||||||
About this document
|
|
||||||
===================
|
|
||||||
|
|
||||||
Some notes about Marvell's NAND controller available in PXA and Armada 370/XP
|
|
||||||
SoC (aka NFCv1 and NFCv2), with an emphasis on the latter.
|
|
||||||
|
|
||||||
NFCv2 controller background
|
|
||||||
===========================
|
|
||||||
|
|
||||||
The controller has a 2176 bytes FIFO buffer. Therefore, in order to support
|
|
||||||
larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of
|
|
||||||
chunked transfers.
|
|
||||||
|
|
||||||
For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below)
|
|
||||||
we'll have this layout in the pages:
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
| 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... |
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
The driver reads the data and spare portions independently and builds an internal
|
|
||||||
buffer with this layout (in the 4 KiB page case):
|
|
||||||
|
|
||||||
------------------------------------------
|
|
||||||
| 4096B data | 64B spare |
|
|
||||||
------------------------------------------
|
|
||||||
|
|
||||||
Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC'
|
|
||||||
OOB, one per chunk read.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
| 4096B data | 32B spare | 30B ECC | 32B spare | 30B ECC |
|
|
||||||
-------------------------------------------------------------------
|
|
||||||
|
|
||||||
So, in order to achieve reading (for instance), we issue several READ0 commands
|
|
||||||
(with some additional controller-specific magic) and read two chunks of 2080B
|
|
||||||
(2048 data + 32 spare) each.
|
|
||||||
The driver accommodates this data to expose the NAND core a contiguous buffer
|
|
||||||
(4096 data + spare) or (4096 + spare + ECC + spare + ECC).
|
|
||||||
|
|
||||||
ECC
|
|
||||||
===
|
|
||||||
|
|
||||||
The controller has built-in hardware ECC capabilities. In addition it is
|
|
||||||
configurable between two modes: 1) Hamming, 2) BCH.
|
|
||||||
|
|
||||||
Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way
|
|
||||||
the controller is configured to transfer the data.
|
|
||||||
|
|
||||||
In the BCH mode the ECC code will be calculated for each transferred chunk
|
|
||||||
and expected to be located (when reading/programming) right after the spare
|
|
||||||
bytes as the figure above shows.
|
|
||||||
|
|
||||||
So, repeating the above scheme, a 2048B data chunk will be followed by 32B
|
|
||||||
spare, and then the ECC controller will read/write the ECC code (30B in
|
|
||||||
this case):
|
|
||||||
|
|
||||||
------------------------------------
|
|
||||||
| 2048B data | 32B spare | 30B ECC |
|
|
||||||
------------------------------------
|
|
||||||
|
|
||||||
If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long.
|
|
||||||
If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block.
|
|
||||||
So in Hamming mode, a 2048B page will have a 24B ECC.
|
|
||||||
|
|
||||||
Despite all of the above, the controller requires the driver to only read or
|
|
||||||
write in multiples of 8-bytes, because the data buffer is 64-bits.
|
|
||||||
|
|
||||||
OOB
|
|
||||||
===
|
|
||||||
|
|
||||||
Because of the above scheme, and because the "spare" OOB is really located in
|
|
||||||
the middle of a page, spare OOB cannot be read or write independently of the
|
|
||||||
data area. In other words, in order to read the OOB (aka READOOB), the entire
|
|
||||||
page (aka READ0) has to be read.
|
|
||||||
|
|
||||||
In the same sense, in order to write to the spare OOB the driver has to write
|
|
||||||
an *entire* page.
|
|
||||||
|
|
||||||
Factory bad blocks handling
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Given the ECC BCH requires to layout the device's pages in a split
|
|
||||||
data/OOB/data/OOB way, the controller has a view of the flash page that's
|
|
||||||
different from the specified (aka the manufacturer's) view. In other words,
|
|
||||||
|
|
||||||
Factory view:
|
|
||||||
|
|
||||||
-----------------------------------------------
|
|
||||||
| Data |x OOB |
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
Driver's view:
|
|
||||||
|
|
||||||
-----------------------------------------------
|
|
||||||
| Data | OOB | Data x | OOB |
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
It can be seen from the above, that the factory bad block marker must be
|
|
||||||
searched within the 'data' region, and not in the usual OOB region.
|
|
||||||
|
|
||||||
In addition, this means under regular usage the driver will write such
|
|
||||||
position (since it belongs to the data region) and every used block is
|
|
||||||
likely to be marked as bad.
|
|
||||||
|
|
||||||
For this reason, marking the block as bad in the OOB is explicitly
|
|
||||||
disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale
|
|
||||||
for this is that there's no point in marking a block as bad, because good
|
|
||||||
blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage.
|
|
||||||
|
|
||||||
Instead, the driver relies on the bad block table alone, and should only perform
|
|
||||||
the bad block scan on the very first time (when the device hasn't been used).
|
|
@@ -8255,9 +8255,9 @@ F: drivers/ata/pata_arasan_cf.c
|
|||||||
|
|
||||||
LIBATA PATA DRIVERS
|
LIBATA PATA DRIVERS
|
||||||
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
|
M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
|
||||||
M: Jens Axboe <kernel.dk>
|
M: Jens Axboe <axboe@kernel.dk>
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/ata/pata_*.c
|
F: drivers/ata/pata_*.c
|
||||||
F: drivers/ata/ata_generic.c
|
F: drivers/ata/ata_generic.c
|
||||||
@@ -8275,7 +8275,7 @@ LIBATA SATA AHCI PLATFORM devices support
|
|||||||
M: Hans de Goede <hdegoede@redhat.com>
|
M: Hans de Goede <hdegoede@redhat.com>
|
||||||
M: Jens Axboe <axboe@kernel.dk>
|
M: Jens Axboe <axboe@kernel.dk>
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/ata/ahci_platform.c
|
F: drivers/ata/ahci_platform.c
|
||||||
F: drivers/ata/libahci_platform.c
|
F: drivers/ata/libahci_platform.c
|
||||||
@@ -8291,7 +8291,7 @@ F: drivers/ata/sata_promise.*
|
|||||||
LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
|
LIBATA SUBSYSTEM (Serial and Parallel ATA drivers)
|
||||||
M: Jens Axboe <axboe@kernel.dk>
|
M: Jens Axboe <axboe@kernel.dk>
|
||||||
L: linux-ide@vger.kernel.org
|
L: linux-ide@vger.kernel.org
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/ata/
|
F: drivers/ata/
|
||||||
F: include/linux/ata.h
|
F: include/linux/ata.h
|
||||||
|
5
Makefile
5
Makefile
@@ -2,7 +2,7 @@
|
|||||||
VERSION = 4
|
VERSION = 4
|
||||||
PATCHLEVEL = 19
|
PATCHLEVEL = 19
|
||||||
SUBLEVEL = 0
|
SUBLEVEL = 0
|
||||||
EXTRAVERSION = -rc1
|
EXTRAVERSION = -rc2
|
||||||
NAME = Merciless Moray
|
NAME = Merciless Moray
|
||||||
|
|
||||||
# *DOCUMENTATION*
|
# *DOCUMENTATION*
|
||||||
@@ -807,6 +807,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
|
|||||||
# disable pointer signed / unsigned warnings in gcc 4.0
|
# disable pointer signed / unsigned warnings in gcc 4.0
|
||||||
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
|
KBUILD_CFLAGS += $(call cc-disable-warning, pointer-sign)
|
||||||
|
|
||||||
|
# disable stringop warnings in gcc 8+
|
||||||
|
KBUILD_CFLAGS += $(call cc-disable-warning, stringop-truncation)
|
||||||
|
|
||||||
# disable invalid "can't wrap" optimizations for signed / pointers
|
# disable invalid "can't wrap" optimizations for signed / pointers
|
||||||
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
|
KBUILD_CFLAGS += $(call cc-option,-fno-strict-overflow)
|
||||||
|
|
||||||
|
0
arch/arm/boot/dts/am335x-osd3358-sm-red.dts
Executable file → Normal file
0
arch/arm/boot/dts/am335x-osd3358-sm-red.dts
Executable file → Normal file
@@ -469,6 +469,7 @@
|
|||||||
ti,hwmods = "rtc";
|
ti,hwmods = "rtc";
|
||||||
clocks = <&clk_32768_ck>;
|
clocks = <&clk_32768_ck>;
|
||||||
clock-names = "int-clk";
|
clock-names = "int-clk";
|
||||||
|
system-power-controller;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -13,6 +13,43 @@
|
|||||||
reg = <0x40000000 0x08000000>;
|
reg = <0x40000000 0x08000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
reg_vddio_sd0: regulator-vddio-sd0 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "vddio-sd0";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio1 29 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_lcd_3v3: regulator-lcd-3v3 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "lcd-3v3";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio1 18 0>;
|
||||||
|
enable-active-high;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_lcd_5v: regulator-lcd-5v {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "lcd-5v";
|
||||||
|
regulator-min-microvolt = <5000000>;
|
||||||
|
regulator-max-microvolt = <5000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
panel {
|
||||||
|
compatible = "sii,43wvf1g";
|
||||||
|
backlight = <&backlight_display>;
|
||||||
|
dvdd-supply = <®_lcd_3v3>;
|
||||||
|
avdd-supply = <®_lcd_5v>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
panel_in: endpoint {
|
||||||
|
remote-endpoint = <&display_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
apb@80000000 {
|
apb@80000000 {
|
||||||
apbh@80000000 {
|
apbh@80000000 {
|
||||||
gpmi-nand@8000c000 {
|
gpmi-nand@8000c000 {
|
||||||
@@ -52,31 +89,11 @@
|
|||||||
lcdif@80030000 {
|
lcdif@80030000 {
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&lcdif_24bit_pins_a>;
|
pinctrl-0 = <&lcdif_24bit_pins_a>;
|
||||||
lcd-supply = <®_lcd_3v3>;
|
|
||||||
display = <&display0>;
|
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
display0: display0 {
|
port {
|
||||||
bits-per-pixel = <32>;
|
display_out: endpoint {
|
||||||
bus-width = <24>;
|
remote-endpoint = <&panel_in>;
|
||||||
|
|
||||||
display-timings {
|
|
||||||
native-mode = <&timing0>;
|
|
||||||
timing0: timing0 {
|
|
||||||
clock-frequency = <9200000>;
|
|
||||||
hactive = <480>;
|
|
||||||
vactive = <272>;
|
|
||||||
hback-porch = <15>;
|
|
||||||
hfront-porch = <8>;
|
|
||||||
vback-porch = <12>;
|
|
||||||
vfront-porch = <4>;
|
|
||||||
hsync-len = <1>;
|
|
||||||
vsync-len = <1>;
|
|
||||||
hsync-active = <0>;
|
|
||||||
vsync-active = <0>;
|
|
||||||
de-active = <1>;
|
|
||||||
pixelclk-active = <0>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -118,32 +135,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
regulators {
|
backlight_display: backlight {
|
||||||
compatible = "simple-bus";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
reg_vddio_sd0: regulator@0 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <0>;
|
|
||||||
regulator-name = "vddio-sd0";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio1 29 0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_lcd_3v3: regulator@1 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <1>;
|
|
||||||
regulator-name = "lcd-3v3";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio1 18 0>;
|
|
||||||
enable-active-high;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
backlight {
|
|
||||||
compatible = "pwm-backlight";
|
compatible = "pwm-backlight";
|
||||||
pwms = <&pwm 2 5000000>;
|
pwms = <&pwm 2 5000000>;
|
||||||
brightness-levels = <0 4 8 16 32 64 128 255>;
|
brightness-levels = <0 4 8 16 32 64 128 255>;
|
||||||
|
@@ -13,6 +13,87 @@
|
|||||||
reg = <0x40000000 0x08000000>;
|
reg = <0x40000000 0x08000000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
reg_3p3v: regulator-3p3v {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "3P3V";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
regulator-always-on;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_vddio_sd0: regulator-vddio-sd0 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "vddio-sd0";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio3 28 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_fec_3v3: regulator-fec-3v3 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "fec-3v3";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio2 15 0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_usb0_vbus: regulator-usb0-vbus {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "usb0_vbus";
|
||||||
|
regulator-min-microvolt = <5000000>;
|
||||||
|
regulator-max-microvolt = <5000000>;
|
||||||
|
gpio = <&gpio3 9 0>;
|
||||||
|
enable-active-high;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_usb1_vbus: regulator-usb1-vbus {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "usb1_vbus";
|
||||||
|
regulator-min-microvolt = <5000000>;
|
||||||
|
regulator-max-microvolt = <5000000>;
|
||||||
|
gpio = <&gpio3 8 0>;
|
||||||
|
enable-active-high;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_lcd_3v3: regulator-lcd-3v3 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "lcd-3v3";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio3 30 0>;
|
||||||
|
enable-active-high;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_can_3v3: regulator-can-3v3 {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "can-3v3";
|
||||||
|
regulator-min-microvolt = <3300000>;
|
||||||
|
regulator-max-microvolt = <3300000>;
|
||||||
|
gpio = <&gpio2 13 0>;
|
||||||
|
enable-active-high;
|
||||||
|
};
|
||||||
|
|
||||||
|
reg_lcd_5v: regulator-lcd-5v {
|
||||||
|
compatible = "regulator-fixed";
|
||||||
|
regulator-name = "lcd-5v";
|
||||||
|
regulator-min-microvolt = <5000000>;
|
||||||
|
regulator-max-microvolt = <5000000>;
|
||||||
|
};
|
||||||
|
|
||||||
|
panel {
|
||||||
|
compatible = "sii,43wvf1g";
|
||||||
|
backlight = <&backlight_display>;
|
||||||
|
dvdd-supply = <®_lcd_3v3>;
|
||||||
|
avdd-supply = <®_lcd_5v>;
|
||||||
|
|
||||||
|
port {
|
||||||
|
panel_in: endpoint {
|
||||||
|
remote-endpoint = <&display_out>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
apb@80000000 {
|
apb@80000000 {
|
||||||
apbh@80000000 {
|
apbh@80000000 {
|
||||||
gpmi-nand@8000c000 {
|
gpmi-nand@8000c000 {
|
||||||
@@ -116,31 +197,11 @@
|
|||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&lcdif_24bit_pins_a
|
pinctrl-0 = <&lcdif_24bit_pins_a
|
||||||
&lcdif_pins_evk>;
|
&lcdif_pins_evk>;
|
||||||
lcd-supply = <®_lcd_3v3>;
|
|
||||||
display = <&display0>;
|
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
display0: display0 {
|
port {
|
||||||
bits-per-pixel = <32>;
|
display_out: endpoint {
|
||||||
bus-width = <24>;
|
remote-endpoint = <&panel_in>;
|
||||||
|
|
||||||
display-timings {
|
|
||||||
native-mode = <&timing0>;
|
|
||||||
timing0: timing0 {
|
|
||||||
clock-frequency = <33500000>;
|
|
||||||
hactive = <800>;
|
|
||||||
vactive = <480>;
|
|
||||||
hback-porch = <89>;
|
|
||||||
hfront-porch = <164>;
|
|
||||||
vback-porch = <23>;
|
|
||||||
vfront-porch = <10>;
|
|
||||||
hsync-len = <10>;
|
|
||||||
vsync-len = <10>;
|
|
||||||
hsync-active = <0>;
|
|
||||||
vsync-active = <0>;
|
|
||||||
de-active = <1>;
|
|
||||||
pixelclk-active = <0>;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -269,80 +330,6 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
regulators {
|
|
||||||
compatible = "simple-bus";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <0>;
|
|
||||||
|
|
||||||
reg_3p3v: regulator@0 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <0>;
|
|
||||||
regulator-name = "3P3V";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
regulator-always-on;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_vddio_sd0: regulator@1 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <1>;
|
|
||||||
regulator-name = "vddio-sd0";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio3 28 0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_fec_3v3: regulator@2 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <2>;
|
|
||||||
regulator-name = "fec-3v3";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio2 15 0>;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_usb0_vbus: regulator@3 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <3>;
|
|
||||||
regulator-name = "usb0_vbus";
|
|
||||||
regulator-min-microvolt = <5000000>;
|
|
||||||
regulator-max-microvolt = <5000000>;
|
|
||||||
gpio = <&gpio3 9 0>;
|
|
||||||
enable-active-high;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_usb1_vbus: regulator@4 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <4>;
|
|
||||||
regulator-name = "usb1_vbus";
|
|
||||||
regulator-min-microvolt = <5000000>;
|
|
||||||
regulator-max-microvolt = <5000000>;
|
|
||||||
gpio = <&gpio3 8 0>;
|
|
||||||
enable-active-high;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_lcd_3v3: regulator@5 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <5>;
|
|
||||||
regulator-name = "lcd-3v3";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio3 30 0>;
|
|
||||||
enable-active-high;
|
|
||||||
};
|
|
||||||
|
|
||||||
reg_can_3v3: regulator@6 {
|
|
||||||
compatible = "regulator-fixed";
|
|
||||||
reg = <6>;
|
|
||||||
regulator-name = "can-3v3";
|
|
||||||
regulator-min-microvolt = <3300000>;
|
|
||||||
regulator-max-microvolt = <3300000>;
|
|
||||||
gpio = <&gpio2 13 0>;
|
|
||||||
enable-active-high;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
sound {
|
sound {
|
||||||
compatible = "fsl,imx28-evk-sgtl5000",
|
compatible = "fsl,imx28-evk-sgtl5000",
|
||||||
"fsl,mxs-audio-sgtl5000";
|
"fsl,mxs-audio-sgtl5000";
|
||||||
@@ -363,7 +350,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
backlight {
|
backlight_display: backlight {
|
||||||
compatible = "pwm-backlight";
|
compatible = "pwm-backlight";
|
||||||
pwms = <&pwm 2 5000000>;
|
pwms = <&pwm 2 5000000>;
|
||||||
brightness-levels = <0 4 8 16 32 64 128 255>;
|
brightness-levels = <0 4 8 16 32 64 128 255>;
|
||||||
|
@@ -126,10 +126,14 @@
|
|||||||
interrupt-names = "msi";
|
interrupt-names = "msi";
|
||||||
#interrupt-cells = <1>;
|
#interrupt-cells = <1>;
|
||||||
interrupt-map-mask = <0 0 0 0x7>;
|
interrupt-map-mask = <0 0 0 0x7>;
|
||||||
interrupt-map = <0 0 0 1 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
|
/*
|
||||||
<0 0 0 2 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
* Reference manual lists pci irqs incorrectly
|
||||||
<0 0 0 3 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
* Real hardware ordering is same as imx6: D+MSI, C, B, A
|
||||||
<0 0 0 4 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
|
*/
|
||||||
|
interrupt-map = <0 0 0 1 &intc GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<0 0 0 2 &intc GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<0 0 0 3 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
|
||||||
|
<0 0 0 4 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
|
||||||
clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
|
clocks = <&clks IMX7D_PCIE_CTRL_ROOT_CLK>,
|
||||||
<&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
|
<&clks IMX7D_PLL_ENET_MAIN_100M_CLK>,
|
||||||
<&clks IMX7D_PCIE_PHY_ROOT_CLK>;
|
<&clks IMX7D_PCIE_PHY_ROOT_CLK>;
|
||||||
|
@@ -354,7 +354,7 @@
|
|||||||
&mmc2 {
|
&mmc2 {
|
||||||
vmmc-supply = <&vsdio>;
|
vmmc-supply = <&vsdio>;
|
||||||
bus-width = <8>;
|
bus-width = <8>;
|
||||||
non-removable;
|
ti,non-removable;
|
||||||
};
|
};
|
||||||
|
|
||||||
&mmc3 {
|
&mmc3 {
|
||||||
@@ -621,15 +621,6 @@
|
|||||||
OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1) /* abe_mcbsp3_fsx */
|
OMAP4_IOPAD(0x10c, PIN_INPUT | MUX_MODE1) /* abe_mcbsp3_fsx */
|
||||||
>;
|
>;
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
&omap4_pmx_wkup {
|
|
||||||
usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
|
|
||||||
/* gpio_wk0 */
|
|
||||||
pinctrl-single,pins = <
|
|
||||||
OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
|
|
||||||
>;
|
|
||||||
};
|
|
||||||
|
|
||||||
vibrator_direction_pin: pinmux_vibrator_direction_pin {
|
vibrator_direction_pin: pinmux_vibrator_direction_pin {
|
||||||
pinctrl-single,pins = <
|
pinctrl-single,pins = <
|
||||||
@@ -644,6 +635,15 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&omap4_pmx_wkup {
|
||||||
|
usb_gpio_mux_sel2: pinmux_usb_gpio_mux_sel2_pins {
|
||||||
|
/* gpio_wk0 */
|
||||||
|
pinctrl-single,pins = <
|
||||||
|
OMAP4_IOPAD(0x040, PIN_OUTPUT_PULLDOWN | MUX_MODE3)
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
|
* As uart1 is wired to mdm6600 with rts and cts, we can use the cts pin for
|
||||||
* uart1 wakeirq.
|
* uart1 wakeirq.
|
||||||
|
@@ -257,6 +257,7 @@ CONFIG_IMX_IPUV3_CORE=y
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_LVDS=y
|
CONFIG_DRM_PANEL_LVDS=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
||||||
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
|
||||||
CONFIG_DRM_DW_HDMI_CEC=y
|
CONFIG_DRM_DW_HDMI_CEC=y
|
||||||
CONFIG_DRM_IMX=y
|
CONFIG_DRM_IMX=y
|
||||||
|
@@ -95,6 +95,7 @@ CONFIG_MFD_MXS_LRADC=y
|
|||||||
CONFIG_REGULATOR=y
|
CONFIG_REGULATOR=y
|
||||||
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
CONFIG_REGULATOR_FIXED_VOLTAGE=y
|
||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
|
CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
|
||||||
CONFIG_DRM_MXSFB=y
|
CONFIG_DRM_MXSFB=y
|
||||||
CONFIG_FB_MODE_HELPERS=y
|
CONFIG_FB_MODE_HELPERS=y
|
||||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||||
|
@@ -5,19 +5,19 @@ CONFIG_HIGH_RES_TIMERS=y
|
|||||||
CONFIG_LOG_BUF_SHIFT=14
|
CONFIG_LOG_BUF_SHIFT=14
|
||||||
CONFIG_BLK_DEV_INITRD=y
|
CONFIG_BLK_DEV_INITRD=y
|
||||||
CONFIG_SLAB=y
|
CONFIG_SLAB=y
|
||||||
CONFIG_MODULES=y
|
|
||||||
CONFIG_MODULE_UNLOAD=y
|
|
||||||
CONFIG_PARTITION_ADVANCED=y
|
|
||||||
# CONFIG_ARCH_MULTI_V7 is not set
|
# CONFIG_ARCH_MULTI_V7 is not set
|
||||||
CONFIG_ARCH_VERSATILE=y
|
CONFIG_ARCH_VERSATILE=y
|
||||||
CONFIG_AEABI=y
|
CONFIG_AEABI=y
|
||||||
CONFIG_OABI_COMPAT=y
|
CONFIG_OABI_COMPAT=y
|
||||||
CONFIG_CMA=y
|
|
||||||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||||
CONFIG_CMDLINE="root=1f03 mem=32M"
|
CONFIG_CMDLINE="root=1f03 mem=32M"
|
||||||
CONFIG_FPE_NWFPE=y
|
CONFIG_FPE_NWFPE=y
|
||||||
CONFIG_VFP=y
|
CONFIG_VFP=y
|
||||||
|
CONFIG_MODULES=y
|
||||||
|
CONFIG_MODULE_UNLOAD=y
|
||||||
|
CONFIG_PARTITION_ADVANCED=y
|
||||||
|
CONFIG_CMA=y
|
||||||
CONFIG_NET=y
|
CONFIG_NET=y
|
||||||
CONFIG_PACKET=y
|
CONFIG_PACKET=y
|
||||||
CONFIG_UNIX=y
|
CONFIG_UNIX=y
|
||||||
@@ -59,6 +59,7 @@ CONFIG_GPIO_PL061=y
|
|||||||
CONFIG_DRM=y
|
CONFIG_DRM=y
|
||||||
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
CONFIG_DRM_PANEL_ARM_VERSATILE=y
|
||||||
CONFIG_DRM_PANEL_SIMPLE=y
|
CONFIG_DRM_PANEL_SIMPLE=y
|
||||||
|
CONFIG_DRM_DUMB_VGA_DAC=y
|
||||||
CONFIG_DRM_PL111=y
|
CONFIG_DRM_PL111=y
|
||||||
CONFIG_FB_MODE_HELPERS=y
|
CONFIG_FB_MODE_HELPERS=y
|
||||||
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
CONFIG_BACKLIGHT_LCD_SUPPORT=y
|
||||||
@@ -89,9 +90,10 @@ CONFIG_NFSD=y
|
|||||||
CONFIG_NFSD_V3=y
|
CONFIG_NFSD_V3=y
|
||||||
CONFIG_NLS_CODEPAGE_850=m
|
CONFIG_NLS_CODEPAGE_850=m
|
||||||
CONFIG_NLS_ISO8859_1=m
|
CONFIG_NLS_ISO8859_1=m
|
||||||
|
CONFIG_FONTS=y
|
||||||
|
CONFIG_FONT_ACORN_8x8=y
|
||||||
|
CONFIG_DEBUG_FS=y
|
||||||
CONFIG_MAGIC_SYSRQ=y
|
CONFIG_MAGIC_SYSRQ=y
|
||||||
CONFIG_DEBUG_KERNEL=y
|
CONFIG_DEBUG_KERNEL=y
|
||||||
CONFIG_DEBUG_USER=y
|
CONFIG_DEBUG_USER=y
|
||||||
CONFIG_DEBUG_LL=y
|
CONFIG_DEBUG_LL=y
|
||||||
CONFIG_FONTS=y
|
|
||||||
CONFIG_FONT_ACORN_8x8=y
|
|
||||||
|
@@ -23,8 +23,7 @@
|
|||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/fb.h>
|
#include <linux/fb.h>
|
||||||
|
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <linux/platform_data/video-ep93xx.h>
|
#include <linux/platform_data/video-ep93xx.h>
|
||||||
@@ -43,12 +42,11 @@
|
|||||||
#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
|
#define SNAPPERCL15_NAND_CEN (1 << 11) /* Chip enable (active low) */
|
||||||
#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
|
#define SNAPPERCL15_NAND_RDY (1 << 14) /* Device ready */
|
||||||
|
|
||||||
#define NAND_CTRL_ADDR(chip) (chip->IO_ADDR_W + 0x40)
|
#define NAND_CTRL_ADDR(chip) (chip->legacy.IO_ADDR_W + 0x40)
|
||||||
|
|
||||||
static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
static void snappercl15_nand_cmd_ctrl(struct nand_chip *chip, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
|
||||||
static u16 nand_state = SNAPPERCL15_NAND_WPN;
|
static u16 nand_state = SNAPPERCL15_NAND_WPN;
|
||||||
u16 set;
|
u16 set;
|
||||||
|
|
||||||
@@ -70,13 +68,12 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
__raw_writew((cmd & 0xff) | nand_state, chip->IO_ADDR_W);
|
__raw_writew((cmd & 0xff) | nand_state,
|
||||||
|
chip->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snappercl15_nand_dev_ready(struct mtd_info *mtd)
|
static int snappercl15_nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
|
||||||
|
|
||||||
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
|
return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,8 +16,7 @@
|
|||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
#include <linux/spi/flash.h>
|
#include <linux/spi/flash.h>
|
||||||
#include <linux/spi/mmc_spi.h>
|
#include <linux/spi/mmc_spi.h>
|
||||||
@@ -76,13 +75,11 @@ static void __init ts72xx_map_io(void)
|
|||||||
#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
|
#define TS72XX_NAND_CONTROL_ADDR_LINE 22 /* 0xN0400000 */
|
||||||
#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
|
#define TS72XX_NAND_BUSY_ADDR_LINE 23 /* 0xN0800000 */
|
||||||
|
|
||||||
static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
|
static void ts72xx_nand_hwcontrol(struct nand_chip *chip,
|
||||||
int cmd, unsigned int ctrl)
|
int cmd, unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
|
||||||
|
|
||||||
if (ctrl & NAND_CTRL_CHANGE) {
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
void __iomem *addr = chip->IO_ADDR_R;
|
void __iomem *addr = chip->legacy.IO_ADDR_R;
|
||||||
unsigned char bits;
|
unsigned char bits;
|
||||||
|
|
||||||
addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
|
addr += (1 << TS72XX_NAND_CONTROL_ADDR_LINE);
|
||||||
@@ -96,13 +93,12 @@ static void ts72xx_nand_hwcontrol(struct mtd_info *mtd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
__raw_writeb(cmd, chip->IO_ADDR_W);
|
__raw_writeb(cmd, chip->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ts72xx_nand_device_ready(struct mtd_info *mtd)
|
static int ts72xx_nand_device_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
void __iomem *addr = chip->legacy.IO_ADDR_R;
|
||||||
void __iomem *addr = chip->IO_ADDR_R;
|
|
||||||
|
|
||||||
addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
|
addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE);
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@
|
|||||||
#include <linux/memory.h>
|
#include <linux/memory.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
@@ -129,30 +129,29 @@ static void qong_init_nor_mtd(void)
|
|||||||
/*
|
/*
|
||||||
* Hardware specific access to control-lines
|
* Hardware specific access to control-lines
|
||||||
*/
|
*/
|
||||||
static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
static void qong_nand_cmd_ctrl(struct nand_chip *nand_chip, int cmd,
|
||||||
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *nand_chip = mtd_to_nand(mtd);
|
|
||||||
|
|
||||||
if (cmd == NAND_CMD_NONE)
|
if (cmd == NAND_CMD_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctrl & NAND_CLE)
|
if (ctrl & NAND_CLE)
|
||||||
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24));
|
writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 24));
|
||||||
else
|
else
|
||||||
writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23));
|
writeb(cmd, nand_chip->legacy.IO_ADDR_W + (1 << 23));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read the Device Ready pin.
|
* Read the Device Ready pin.
|
||||||
*/
|
*/
|
||||||
static int qong_nand_device_ready(struct mtd_info *mtd)
|
static int qong_nand_device_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
|
return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qong_nand_select_chip(struct mtd_info *mtd, int chip)
|
static void qong_nand_select_chip(struct nand_chip *chip, int cs)
|
||||||
{
|
{
|
||||||
if (chip >= 0)
|
if (cs >= 0)
|
||||||
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
|
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0);
|
||||||
else
|
else
|
||||||
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
|
gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1);
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/rawnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <asm/types.h>
|
#include <asm/types.h>
|
||||||
@@ -75,9 +76,8 @@ static struct mtd_partition ixdp425_partitions[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
ixdp425_flash_nand_cmd_ctrl(struct nand_chip *this, int cmd, unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
|
||||||
int offset = (int)nand_get_controller_data(this);
|
int offset = (int)nand_get_controller_data(this);
|
||||||
|
|
||||||
if (ctrl & NAND_CTRL_CHANGE) {
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
@@ -93,7 +93,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
writeb(cmd, this->IO_ADDR_W + offset);
|
writeb(cmd, this->legacy.IO_ADDR_W + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_nand_data ixdp425_flash_nand_data = {
|
static struct platform_nand_data ixdp425_flash_nand_data = {
|
||||||
|
@@ -16,8 +16,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/smc91x.h>
|
#include <linux/smc91x.h>
|
||||||
@@ -186,7 +185,7 @@ static struct platform_device nor_device = {
|
|||||||
|
|
||||||
#define FSAMPLE_NAND_RB_GPIO_PIN 62
|
#define FSAMPLE_NAND_RB_GPIO_PIN 62
|
||||||
|
|
||||||
static int nand_dev_ready(struct mtd_info *mtd)
|
static int nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN);
|
return gpio_get_value(FSAMPLE_NAND_RB_GPIO_PIN);
|
||||||
}
|
}
|
||||||
|
@@ -24,8 +24,7 @@
|
|||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/mfd/tps65010.h>
|
#include <linux/mfd/tps65010.h>
|
||||||
@@ -182,7 +181,7 @@ static struct mtd_partition h2_nand_partitions[] = {
|
|||||||
|
|
||||||
#define H2_NAND_RB_GPIO_PIN 62
|
#define H2_NAND_RB_GPIO_PIN 62
|
||||||
|
|
||||||
static int h2_nand_dev_ready(struct mtd_info *mtd)
|
static int h2_nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(H2_NAND_RB_GPIO_PIN);
|
return gpio_get_value(H2_NAND_RB_GPIO_PIN);
|
||||||
}
|
}
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
@@ -185,7 +185,7 @@ static struct mtd_partition nand_partitions[] = {
|
|||||||
|
|
||||||
#define H3_NAND_RB_GPIO_PIN 10
|
#define H3_NAND_RB_GPIO_PIN 10
|
||||||
|
|
||||||
static int nand_dev_ready(struct mtd_info *mtd)
|
static int nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(H3_NAND_RB_GPIO_PIN);
|
return gpio_get_value(H3_NAND_RB_GPIO_PIN);
|
||||||
}
|
}
|
||||||
|
@@ -20,9 +20,8 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
void omap1_nand_cmd_ctl(struct nand_chip *this, int cmd, unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
|
||||||
unsigned long mask;
|
unsigned long mask;
|
||||||
|
|
||||||
if (cmd == NAND_CMD_NONE)
|
if (cmd == NAND_CMD_NONE)
|
||||||
@@ -32,6 +31,6 @@ void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|||||||
if (ctrl & NAND_ALE)
|
if (ctrl & NAND_ALE)
|
||||||
mask |= 0x04;
|
mask |= 0x04;
|
||||||
|
|
||||||
writeb(cmd, this->IO_ADDR_W + mask);
|
writeb(cmd, this->legacy.IO_ADDR_W + mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,8 +16,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/smc91x.h>
|
#include <linux/smc91x.h>
|
||||||
@@ -144,7 +143,7 @@ static struct platform_device nor_device = {
|
|||||||
|
|
||||||
#define P2_NAND_RB_GPIO_PIN 62
|
#define P2_NAND_RB_GPIO_PIN 62
|
||||||
|
|
||||||
static int nand_dev_ready(struct mtd_info *mtd)
|
static int nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(P2_NAND_RB_GPIO_PIN);
|
return gpio_get_value(P2_NAND_RB_GPIO_PIN);
|
||||||
}
|
}
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#ifndef __ARCH_ARM_MACH_OMAP1_COMMON_H
|
#ifndef __ARCH_ARM_MACH_OMAP1_COMMON_H
|
||||||
#define __ARCH_ARM_MACH_OMAP1_COMMON_H
|
#define __ARCH_ARM_MACH_OMAP1_COMMON_H
|
||||||
|
|
||||||
#include <linux/mtd/mtd.h>
|
|
||||||
#include <linux/platform_data/i2c-omap.h>
|
#include <linux/platform_data/i2c-omap.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
|
||||||
@@ -82,7 +81,8 @@ void omap1_restart(enum reboot_mode, const char *);
|
|||||||
|
|
||||||
extern void __init omap_check_revision(void);
|
extern void __init omap_check_revision(void);
|
||||||
|
|
||||||
extern void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
|
struct nand_chip;
|
||||||
|
extern void omap1_nand_cmd_ctl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl);
|
unsigned int ctrl);
|
||||||
|
|
||||||
extern void omap1_timer_init(void);
|
extern void omap1_timer_init(void);
|
||||||
|
@@ -2160,6 +2160,37 @@ static int of_dev_hwmod_lookup(struct device_node *np,
|
|||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* omap_hwmod_fix_mpu_rt_idx - fix up mpu_rt_idx register offsets
|
||||||
|
*
|
||||||
|
* @oh: struct omap_hwmod *
|
||||||
|
* @np: struct device_node *
|
||||||
|
*
|
||||||
|
* Fix up module register offsets for modules with mpu_rt_idx.
|
||||||
|
* Only needed for cpsw with interconnect target module defined
|
||||||
|
* in device tree while still using legacy hwmod platform data
|
||||||
|
* for rev, sysc and syss registers.
|
||||||
|
*
|
||||||
|
* Can be removed when all cpsw hwmod platform data has been
|
||||||
|
* dropped.
|
||||||
|
*/
|
||||||
|
static void omap_hwmod_fix_mpu_rt_idx(struct omap_hwmod *oh,
|
||||||
|
struct device_node *np,
|
||||||
|
struct resource *res)
|
||||||
|
{
|
||||||
|
struct device_node *child = NULL;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
child = of_get_next_child(np, child);
|
||||||
|
if (!child)
|
||||||
|
return;
|
||||||
|
|
||||||
|
error = of_address_to_resource(child, oh->mpu_rt_idx, res);
|
||||||
|
if (error)
|
||||||
|
pr_err("%s: error mapping mpu_rt_idx: %i\n",
|
||||||
|
__func__, error);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* omap_hwmod_parse_module_range - map module IO range from device tree
|
* omap_hwmod_parse_module_range - map module IO range from device tree
|
||||||
* @oh: struct omap_hwmod *
|
* @oh: struct omap_hwmod *
|
||||||
@@ -2220,7 +2251,13 @@ int omap_hwmod_parse_module_range(struct omap_hwmod *oh,
|
|||||||
size = be32_to_cpup(ranges);
|
size = be32_to_cpup(ranges);
|
||||||
|
|
||||||
pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
|
pr_debug("omap_hwmod: %s %s at 0x%llx size 0x%llx\n",
|
||||||
oh->name, np->name, base, size);
|
oh ? oh->name : "", np->name, base, size);
|
||||||
|
|
||||||
|
if (oh && oh->mpu_rt_idx) {
|
||||||
|
omap_hwmod_fix_mpu_rt_idx(oh, np, res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
res->start = base;
|
res->start = base;
|
||||||
res->end = base + size - 1;
|
res->end = base + size - 1;
|
||||||
|
@@ -16,8 +16,7 @@
|
|||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mv643xx_eth.h>
|
#include <linux/mv643xx_eth.h>
|
||||||
#include <linux/ata_platform.h>
|
#include <linux/ata_platform.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/timeriomem-rng.h>
|
#include <linux/timeriomem-rng.h>
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
@@ -131,11 +130,9 @@ static void ts78xx_ts_rtc_unload(void)
|
|||||||
* NAND_CLE: bit 1 -> bit 1
|
* NAND_CLE: bit 1 -> bit 1
|
||||||
* NAND_ALE: bit 2 -> bit 0
|
* NAND_ALE: bit 2 -> bit 0
|
||||||
*/
|
*/
|
||||||
static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
static void ts78xx_ts_nand_cmd_ctrl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
|
||||||
|
|
||||||
if (ctrl & NAND_CTRL_CHANGE) {
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
unsigned char bits;
|
unsigned char bits;
|
||||||
|
|
||||||
@@ -147,19 +144,18 @@ static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
writeb(cmd, this->IO_ADDR_W);
|
writeb(cmd, this->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd)
|
static int ts78xx_ts_nand_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return readb(TS_NAND_CTRL) & 0x20;
|
return readb(TS_NAND_CTRL) & 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
|
static void ts78xx_ts_nand_write_buf(struct nand_chip *chip,
|
||||||
const uint8_t *buf, int len)
|
const uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
void __iomem *io_base = chip->legacy.IO_ADDR_W;
|
||||||
void __iomem *io_base = chip->IO_ADDR_W;
|
|
||||||
unsigned long off = ((unsigned long)buf & 3);
|
unsigned long off = ((unsigned long)buf & 3);
|
||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
@@ -182,11 +178,10 @@ static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd,
|
|||||||
writesb(io_base, buf, len);
|
writesb(io_base, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd,
|
static void ts78xx_ts_nand_read_buf(struct nand_chip *chip,
|
||||||
uint8_t *buf, int len)
|
uint8_t *buf, int len)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
void __iomem *io_base = chip->legacy.IO_ADDR_R;
|
||||||
void __iomem *io_base = chip->IO_ADDR_R;
|
|
||||||
unsigned long off = ((unsigned long)buf & 3);
|
unsigned long off = ((unsigned long)buf & 3);
|
||||||
int sz;
|
int sz;
|
||||||
|
|
||||||
|
@@ -25,11 +25,10 @@
|
|||||||
#include <linux/ioport.h>
|
#include <linux/ioport.h>
|
||||||
#include <linux/ucb1400.h>
|
#include <linux/ucb1400.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/platform_data/pcf857x.h>
|
#include <linux/platform_data/pcf857x.h>
|
||||||
#include <linux/platform_data/i2c-pxa.h>
|
#include <linux/platform_data/i2c-pxa.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/regulator/max1586.h>
|
#include <linux/regulator/max1586.h>
|
||||||
|
|
||||||
@@ -571,9 +570,9 @@ static inline void balloon3_i2c_init(void) {}
|
|||||||
* NAND
|
* NAND
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
#if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
||||||
static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
static void balloon3_nand_cmd_ctl(struct nand_chip *this, int cmd,
|
||||||
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
|
||||||
uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
|
uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0;
|
||||||
|
|
||||||
if (ctrl & NAND_CTRL_CHANGE) {
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
@@ -597,10 +596,10 @@ static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ct
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
writeb(cmd, this->IO_ADDR_W);
|
writeb(cmd, this->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
|
static void balloon3_nand_select_chip(struct nand_chip *this, int chip)
|
||||||
{
|
{
|
||||||
if (chip < 0 || chip > 3)
|
if (chip < 0 || chip > 3)
|
||||||
return;
|
return;
|
||||||
@@ -616,7 +615,7 @@ static void balloon3_nand_select_chip(struct mtd_info *mtd, int chip)
|
|||||||
BALLOON3_NAND_CONTROL_REG);
|
BALLOON3_NAND_CONTROL_REG);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int balloon3_nand_dev_ready(struct mtd_info *mtd)
|
static int balloon3_nand_dev_ready(struct nand_chip *this)
|
||||||
{
|
{
|
||||||
return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
|
return __raw_readl(BALLOON3_NAND_STAT_REG) & BALLOON3_NAND_STAT_RNB;
|
||||||
}
|
}
|
||||||
|
@@ -15,8 +15,7 @@
|
|||||||
|
|
||||||
#include <linux/dm9000.h>
|
#include <linux/dm9000.h>
|
||||||
#include <linux/platform_data/rtc-v3020.h>
|
#include <linux/platform_data/rtc-v3020.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
#include <linux/gpio_keys.h>
|
#include <linux/gpio_keys.h>
|
||||||
@@ -285,11 +284,10 @@ static void nand_cs_off(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* hardware specific access to control-lines */
|
/* hardware specific access to control-lines */
|
||||||
static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
|
static void em_x270_nand_cmd_ctl(struct nand_chip *this, int dat,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W;
|
||||||
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
|
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
|
|
||||||
@@ -309,15 +307,15 @@ static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
this->IO_ADDR_W = (void __iomem *)nandaddr;
|
this->legacy.IO_ADDR_W = (void __iomem *)nandaddr;
|
||||||
if (dat != NAND_CMD_NONE)
|
if (dat != NAND_CMD_NONE)
|
||||||
writel(dat, this->IO_ADDR_W);
|
writel(dat, this->legacy.IO_ADDR_W);
|
||||||
|
|
||||||
dsb();
|
dsb();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read device ready pin */
|
/* read device ready pin */
|
||||||
static int em_x270_nand_device_ready(struct mtd_info *mtd)
|
static int em_x270_nand_device_ready(struct nand_chip *this)
|
||||||
{
|
{
|
||||||
dsb();
|
dsb();
|
||||||
|
|
||||||
|
@@ -403,36 +403,6 @@ static void __init palmtreo_leds_init(void)
|
|||||||
platform_device_register(&palmtreo_leds);
|
platform_device_register(&palmtreo_leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* diskonchip docg4 flash
|
|
||||||
******************************************************************************/
|
|
||||||
#if defined(CONFIG_MACH_TREO680)
|
|
||||||
/* REVISIT: does the centro have this device also? */
|
|
||||||
#if IS_ENABLED(CONFIG_MTD_NAND_DOCG4)
|
|
||||||
static struct resource docg4_resources[] = {
|
|
||||||
{
|
|
||||||
.start = 0x00000000,
|
|
||||||
.end = 0x00001FFF,
|
|
||||||
.flags = IORESOURCE_MEM,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct platform_device treo680_docg4_flash = {
|
|
||||||
.name = "docg4",
|
|
||||||
.id = -1,
|
|
||||||
.resource = docg4_resources,
|
|
||||||
.num_resources = ARRAY_SIZE(docg4_resources),
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init treo680_docg4_flash_init(void)
|
|
||||||
{
|
|
||||||
platform_device_register(&treo680_docg4_flash);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline void treo680_docg4_flash_init(void) {}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Machine init
|
* Machine init
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
@@ -517,7 +487,6 @@ static void __init treo680_init(void)
|
|||||||
treo680_gpio_init();
|
treo680_gpio_init();
|
||||||
palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
|
palm27x_mmc_init(GPIO_NR_TREO_SD_DETECT_N, GPIO_NR_TREO680_SD_READONLY,
|
||||||
GPIO_NR_TREO680_SD_POWER, 0);
|
GPIO_NR_TREO680_SD_POWER, 0);
|
||||||
treo680_docg4_flash_init();
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -28,8 +28,7 @@
|
|||||||
#include <linux/wm97xx.h>
|
#include <linux/wm97xx.h>
|
||||||
#include <linux/power_supply.h>
|
#include <linux/power_supply.h>
|
||||||
#include <linux/usb/gpio_vbus.h>
|
#include <linux/usb/gpio_vbus.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
|
|
||||||
@@ -247,11 +246,10 @@ static inline void palmtx_keys_init(void) {}
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
|
#if defined(CONFIG_MTD_NAND_PLATFORM) || \
|
||||||
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
|
||||||
static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd,
|
static void palmtx_nand_cmd_ctl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
char __iomem *nandaddr = this->legacy.IO_ADDR_W;
|
||||||
char __iomem *nandaddr = this->IO_ADDR_W;
|
|
||||||
|
|
||||||
if (cmd == NAND_CMD_NONE)
|
if (cmd == NAND_CMD_NONE)
|
||||||
return;
|
return;
|
||||||
|
@@ -763,7 +763,6 @@ config NEED_PER_CPU_EMBED_FIRST_CHUNK
|
|||||||
|
|
||||||
config HOLES_IN_ZONE
|
config HOLES_IN_ZONE
|
||||||
def_bool y
|
def_bool y
|
||||||
depends on NUMA
|
|
||||||
|
|
||||||
source kernel/Kconfig.hz
|
source kernel/Kconfig.hz
|
||||||
|
|
||||||
|
@@ -38,6 +38,7 @@ CONFIG_ARCH_BCM_IPROC=y
|
|||||||
CONFIG_ARCH_BERLIN=y
|
CONFIG_ARCH_BERLIN=y
|
||||||
CONFIG_ARCH_BRCMSTB=y
|
CONFIG_ARCH_BRCMSTB=y
|
||||||
CONFIG_ARCH_EXYNOS=y
|
CONFIG_ARCH_EXYNOS=y
|
||||||
|
CONFIG_ARCH_K3=y
|
||||||
CONFIG_ARCH_LAYERSCAPE=y
|
CONFIG_ARCH_LAYERSCAPE=y
|
||||||
CONFIG_ARCH_LG1K=y
|
CONFIG_ARCH_LG1K=y
|
||||||
CONFIG_ARCH_HISI=y
|
CONFIG_ARCH_HISI=y
|
||||||
@@ -605,6 +606,8 @@ CONFIG_ARCH_TEGRA_132_SOC=y
|
|||||||
CONFIG_ARCH_TEGRA_210_SOC=y
|
CONFIG_ARCH_TEGRA_210_SOC=y
|
||||||
CONFIG_ARCH_TEGRA_186_SOC=y
|
CONFIG_ARCH_TEGRA_186_SOC=y
|
||||||
CONFIG_ARCH_TEGRA_194_SOC=y
|
CONFIG_ARCH_TEGRA_194_SOC=y
|
||||||
|
CONFIG_ARCH_K3_AM6_SOC=y
|
||||||
|
CONFIG_SOC_TI=y
|
||||||
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
|
CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y
|
||||||
CONFIG_EXTCON_USB_GPIO=y
|
CONFIG_EXTCON_USB_GPIO=y
|
||||||
CONFIG_EXTCON_USBC_CROS_EC=y
|
CONFIG_EXTCON_USBC_CROS_EC=y
|
||||||
|
@@ -417,7 +417,7 @@ static int gcm_encrypt(struct aead_request *req)
|
|||||||
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
|
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
|
||||||
put_unaligned_be32(2, iv + GCM_IV_SIZE);
|
put_unaligned_be32(2, iv + GCM_IV_SIZE);
|
||||||
|
|
||||||
while (walk.nbytes >= AES_BLOCK_SIZE) {
|
while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
|
||||||
int blocks = walk.nbytes / AES_BLOCK_SIZE;
|
int blocks = walk.nbytes / AES_BLOCK_SIZE;
|
||||||
u8 *dst = walk.dst.virt.addr;
|
u8 *dst = walk.dst.virt.addr;
|
||||||
u8 *src = walk.src.virt.addr;
|
u8 *src = walk.src.virt.addr;
|
||||||
@@ -437,11 +437,18 @@ static int gcm_encrypt(struct aead_request *req)
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
err = skcipher_walk_done(&walk,
|
err = skcipher_walk_done(&walk,
|
||||||
walk.nbytes % AES_BLOCK_SIZE);
|
walk.nbytes % (2 * AES_BLOCK_SIZE));
|
||||||
}
|
}
|
||||||
if (walk.nbytes)
|
if (walk.nbytes) {
|
||||||
__aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv,
|
__aes_arm64_encrypt(ctx->aes_key.key_enc, ks, iv,
|
||||||
nrounds);
|
nrounds);
|
||||||
|
if (walk.nbytes > AES_BLOCK_SIZE) {
|
||||||
|
crypto_inc(iv, AES_BLOCK_SIZE);
|
||||||
|
__aes_arm64_encrypt(ctx->aes_key.key_enc,
|
||||||
|
ks + AES_BLOCK_SIZE, iv,
|
||||||
|
nrounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the tail */
|
/* handle the tail */
|
||||||
@@ -545,7 +552,7 @@ static int gcm_decrypt(struct aead_request *req)
|
|||||||
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
|
__aes_arm64_encrypt(ctx->aes_key.key_enc, tag, iv, nrounds);
|
||||||
put_unaligned_be32(2, iv + GCM_IV_SIZE);
|
put_unaligned_be32(2, iv + GCM_IV_SIZE);
|
||||||
|
|
||||||
while (walk.nbytes >= AES_BLOCK_SIZE) {
|
while (walk.nbytes >= (2 * AES_BLOCK_SIZE)) {
|
||||||
int blocks = walk.nbytes / AES_BLOCK_SIZE;
|
int blocks = walk.nbytes / AES_BLOCK_SIZE;
|
||||||
u8 *dst = walk.dst.virt.addr;
|
u8 *dst = walk.dst.virt.addr;
|
||||||
u8 *src = walk.src.virt.addr;
|
u8 *src = walk.src.virt.addr;
|
||||||
@@ -564,11 +571,21 @@ static int gcm_decrypt(struct aead_request *req)
|
|||||||
} while (--blocks > 0);
|
} while (--blocks > 0);
|
||||||
|
|
||||||
err = skcipher_walk_done(&walk,
|
err = skcipher_walk_done(&walk,
|
||||||
walk.nbytes % AES_BLOCK_SIZE);
|
walk.nbytes % (2 * AES_BLOCK_SIZE));
|
||||||
}
|
}
|
||||||
if (walk.nbytes)
|
if (walk.nbytes) {
|
||||||
|
if (walk.nbytes > AES_BLOCK_SIZE) {
|
||||||
|
u8 *iv2 = iv + AES_BLOCK_SIZE;
|
||||||
|
|
||||||
|
memcpy(iv2, iv, AES_BLOCK_SIZE);
|
||||||
|
crypto_inc(iv2, AES_BLOCK_SIZE);
|
||||||
|
|
||||||
|
__aes_arm64_encrypt(ctx->aes_key.key_enc, iv2,
|
||||||
|
iv2, nrounds);
|
||||||
|
}
|
||||||
__aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv,
|
__aes_arm64_encrypt(ctx->aes_key.key_enc, iv, iv,
|
||||||
nrounds);
|
nrounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle the tail */
|
/* handle the tail */
|
||||||
|
@@ -69,5 +69,5 @@ static void __exit sm4_ce_mod_fini(void)
|
|||||||
crypto_unregister_alg(&sm4_ce_alg);
|
crypto_unregister_alg(&sm4_ce_alg);
|
||||||
}
|
}
|
||||||
|
|
||||||
module_cpu_feature_match(SM3, sm4_ce_mod_init);
|
module_cpu_feature_match(SM4, sm4_ce_mod_init);
|
||||||
module_exit(sm4_ce_mod_fini);
|
module_exit(sm4_ce_mod_fini);
|
||||||
|
@@ -98,11 +98,10 @@ static time64_t pmu_read_time(void)
|
|||||||
|
|
||||||
if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
|
if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
|
||||||
return 0;
|
return 0;
|
||||||
while (!req.complete)
|
pmu_wait_complete(&req);
|
||||||
pmu_poll();
|
|
||||||
|
|
||||||
time = (u32)((req.reply[1] << 24) | (req.reply[2] << 16) |
|
time = (u32)((req.reply[0] << 24) | (req.reply[1] << 16) |
|
||||||
(req.reply[3] << 8) | req.reply[4]);
|
(req.reply[2] << 8) | req.reply[3]);
|
||||||
|
|
||||||
return time - RTC_OFFSET;
|
return time - RTC_OFFSET;
|
||||||
}
|
}
|
||||||
@@ -116,8 +115,7 @@ static void pmu_write_time(time64_t time)
|
|||||||
(data >> 24) & 0xFF, (data >> 16) & 0xFF,
|
(data >> 24) & 0xFF, (data >> 16) & 0xFF,
|
||||||
(data >> 8) & 0xFF, data & 0xFF) < 0)
|
(data >> 8) & 0xFF, data & 0xFF) < 0)
|
||||||
return;
|
return;
|
||||||
while (!req.complete)
|
pmu_wait_complete(&req);
|
||||||
pmu_poll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static __u8 pmu_read_pram(int offset)
|
static __u8 pmu_read_pram(int offset)
|
||||||
|
@@ -29,8 +29,7 @@
|
|||||||
#include <linux/leds.h>
|
#include <linux/leds.h>
|
||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/serial_8250.h>
|
#include <linux/serial_8250.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
@@ -197,11 +196,10 @@ static struct i2c_board_info db1200_i2c_devs[] __initdata = {
|
|||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
static void au1200_nand_cmd_ctrl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
|
||||||
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
|
|
||||||
|
|
||||||
ioaddr &= 0xffffff00;
|
ioaddr &= 0xffffff00;
|
||||||
|
|
||||||
@@ -213,14 +211,14 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
|||||||
/* assume we want to r/w real data by default */
|
/* assume we want to r/w real data by default */
|
||||||
ioaddr += MEM_STNAND_DATA;
|
ioaddr += MEM_STNAND_DATA;
|
||||||
}
|
}
|
||||||
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
|
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
|
||||||
if (cmd != NAND_CMD_NONE) {
|
if (cmd != NAND_CMD_NONE) {
|
||||||
__raw_writeb(cmd, this->IO_ADDR_W);
|
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int au1200_nand_device_ready(struct mtd_info *mtd)
|
static int au1200_nand_device_ready(struct nand_chip *this)
|
||||||
{
|
{
|
||||||
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,7 @@
|
|||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/smsc911x.h>
|
#include <linux/smsc911x.h>
|
||||||
#include <linux/wm97xx.h>
|
#include <linux/wm97xx.h>
|
||||||
@@ -149,11 +148,10 @@ static void __init db1300_gpio_config(void)
|
|||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
static void au1300_nand_cmd_ctrl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
|
||||||
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
|
|
||||||
|
|
||||||
ioaddr &= 0xffffff00;
|
ioaddr &= 0xffffff00;
|
||||||
|
|
||||||
@@ -165,14 +163,14 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
|||||||
/* assume we want to r/w real data by default */
|
/* assume we want to r/w real data by default */
|
||||||
ioaddr += MEM_STNAND_DATA;
|
ioaddr += MEM_STNAND_DATA;
|
||||||
}
|
}
|
||||||
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
|
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
|
||||||
if (cmd != NAND_CMD_NONE) {
|
if (cmd != NAND_CMD_NONE) {
|
||||||
__raw_writeb(cmd, this->IO_ADDR_W);
|
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int au1300_nand_device_ready(struct mtd_info *mtd)
|
static int au1300_nand_device_ready(struct nand_chip *this)
|
||||||
{
|
{
|
||||||
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
||||||
}
|
}
|
||||||
|
@@ -13,8 +13,7 @@
|
|||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/pm.h>
|
#include <linux/pm.h>
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
@@ -126,11 +125,10 @@ static struct i2c_board_info db1550_i2c_devs[] __initdata = {
|
|||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
|
|
||||||
static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
static void au1550_nand_cmd_ctrl(struct nand_chip *this, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
unsigned long ioaddr = (unsigned long)this->legacy.IO_ADDR_W;
|
||||||
unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
|
|
||||||
|
|
||||||
ioaddr &= 0xffffff00;
|
ioaddr &= 0xffffff00;
|
||||||
|
|
||||||
@@ -142,14 +140,14 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
|
|||||||
/* assume we want to r/w real data by default */
|
/* assume we want to r/w real data by default */
|
||||||
ioaddr += MEM_STNAND_DATA;
|
ioaddr += MEM_STNAND_DATA;
|
||||||
}
|
}
|
||||||
this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
|
this->legacy.IO_ADDR_R = this->legacy.IO_ADDR_W = (void __iomem *)ioaddr;
|
||||||
if (cmd != NAND_CMD_NONE) {
|
if (cmd != NAND_CMD_NONE) {
|
||||||
__raw_writeb(cmd, this->IO_ADDR_W);
|
__raw_writeb(cmd, this->legacy.IO_ADDR_W);
|
||||||
wmb();
|
wmb();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int au1550_nand_device_ready(struct mtd_info *mtd)
|
static int au1550_nand_device_ready(struct nand_chip *this)
|
||||||
{
|
{
|
||||||
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1;
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,7 @@
|
|||||||
|
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
|
|
||||||
#include <asm/netlogic/haldefs.h>
|
#include <asm/netlogic/haldefs.h>
|
||||||
#include <asm/netlogic/xlr/iomap.h>
|
#include <asm/netlogic/xlr/iomap.h>
|
||||||
@@ -92,8 +91,8 @@ struct xlr_nand_flash_priv {
|
|||||||
|
|
||||||
static struct xlr_nand_flash_priv nand_priv;
|
static struct xlr_nand_flash_priv nand_priv;
|
||||||
|
|
||||||
static void xlr_nand_ctrl(struct mtd_info *mtd, int cmd,
|
static void xlr_nand_ctrl(struct nand_chip *chip, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
if (ctrl & NAND_CLE)
|
if (ctrl & NAND_CLE)
|
||||||
nlm_write_reg(nand_priv.flash_mmio,
|
nlm_write_reg(nand_priv.flash_mmio,
|
||||||
|
@@ -30,8 +30,7 @@
|
|||||||
#include <linux/resource.h>
|
#include <linux/resource.h>
|
||||||
#include <linux/serial.h>
|
#include <linux/serial.h>
|
||||||
#include <linux/serial_pnx8xxx.h>
|
#include <linux/serial_pnx8xxx.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
|
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
#include <irq-mapping.h>
|
#include <irq-mapping.h>
|
||||||
@@ -178,10 +177,9 @@ static struct platform_device pnx833x_sata_device = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
pnx833x_flash_nand_cmd_ctrl(struct nand_chip *this, int cmd, unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *this = mtd_to_nand(mtd);
|
unsigned long nandaddr = (unsigned long)this->legacy.IO_ADDR_W;
|
||||||
unsigned long nandaddr = (unsigned long)this->IO_ADDR_W;
|
|
||||||
|
|
||||||
if (cmd == NAND_CMD_NONE)
|
if (cmd == NAND_CMD_NONE)
|
||||||
return;
|
return;
|
||||||
|
@@ -20,9 +20,8 @@
|
|||||||
#include <linux/ctype.h>
|
#include <linux/ctype.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/partitions.h>
|
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/gpio_keys.h>
|
#include <linux/gpio_keys.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
@@ -141,14 +140,13 @@ static struct platform_device cf_slot0 = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Resources and device for NAND */
|
/* Resources and device for NAND */
|
||||||
static int rb532_dev_ready(struct mtd_info *mtd)
|
static int rb532_dev_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(GPIO_RDY);
|
return gpio_get_value(GPIO_RDY);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
static void rb532_cmd_ctrl(struct nand_chip *chip, int cmd, unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
|
||||||
unsigned char orbits, nandbits;
|
unsigned char orbits, nandbits;
|
||||||
|
|
||||||
if (ctrl & NAND_CTRL_CHANGE) {
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
@@ -161,7 +159,7 @@ static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
|||||||
set_latch_u5(orbits, nandbits);
|
set_latch_u5(orbits, nandbits);
|
||||||
}
|
}
|
||||||
if (cmd != NAND_CMD_NONE)
|
if (cmd != NAND_CMD_NONE)
|
||||||
writeb(cmd, chip->IO_ADDR_W);
|
writeb(cmd, chip->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct resource nand_slot0_res[] = {
|
static struct resource nand_slot0_res[] = {
|
||||||
|
@@ -3,15 +3,6 @@
|
|||||||
config TRACE_IRQFLAGS_SUPPORT
|
config TRACE_IRQFLAGS_SUPPORT
|
||||||
def_bool y
|
def_bool y
|
||||||
|
|
||||||
config DEBUG_STACK_USAGE
|
|
||||||
bool "Enable stack utilization instrumentation"
|
|
||||||
depends on DEBUG_KERNEL
|
|
||||||
help
|
|
||||||
Enables the display of the minimum amount of free stack which each
|
|
||||||
task has ever had available in the sysrq-T and sysrq-P debug output.
|
|
||||||
|
|
||||||
This option will slow down process creation somewhat.
|
|
||||||
|
|
||||||
config EARLY_PRINTK
|
config EARLY_PRINTK
|
||||||
bool "Activate early kernel debugging"
|
bool "Activate early kernel debugging"
|
||||||
default y
|
default y
|
||||||
|
@@ -177,7 +177,6 @@ config PPC
|
|||||||
select HAVE_ARCH_KGDB
|
select HAVE_ARCH_KGDB
|
||||||
select HAVE_ARCH_MMAP_RND_BITS
|
select HAVE_ARCH_MMAP_RND_BITS
|
||||||
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
|
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
|
||||||
select HAVE_ARCH_PREL32_RELOCATIONS
|
|
||||||
select HAVE_ARCH_SECCOMP_FILTER
|
select HAVE_ARCH_SECCOMP_FILTER
|
||||||
select HAVE_ARCH_TRACEHOOK
|
select HAVE_ARCH_TRACEHOOK
|
||||||
select HAVE_CBPF_JIT if !PPC64
|
select HAVE_CBPF_JIT if !PPC64
|
||||||
|
@@ -14,6 +14,10 @@
|
|||||||
#ifndef _ASM_RISCV_TLB_H
|
#ifndef _ASM_RISCV_TLB_H
|
||||||
#define _ASM_RISCV_TLB_H
|
#define _ASM_RISCV_TLB_H
|
||||||
|
|
||||||
|
struct mmu_gather;
|
||||||
|
|
||||||
|
static void tlb_flush(struct mmu_gather *tlb);
|
||||||
|
|
||||||
#include <asm-generic/tlb.h>
|
#include <asm-generic/tlb.h>
|
||||||
|
|
||||||
static inline void tlb_flush(struct mmu_gather *tlb)
|
static inline void tlb_flush(struct mmu_gather *tlb)
|
||||||
|
@@ -65,24 +65,11 @@ SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
|
|||||||
SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
|
SYSCALL_DEFINE3(riscv_flush_icache, uintptr_t, start, uintptr_t, end,
|
||||||
uintptr_t, flags)
|
uintptr_t, flags)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
struct mm_struct *mm = current->mm;
|
|
||||||
bool local = (flags & SYS_RISCV_FLUSH_ICACHE_LOCAL) != 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check the reserved flags. */
|
/* Check the reserved flags. */
|
||||||
if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL))
|
if (unlikely(flags & ~SYS_RISCV_FLUSH_ICACHE_ALL))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/*
|
flush_icache_mm(current->mm, flags & SYS_RISCV_FLUSH_ICACHE_LOCAL);
|
||||||
* Without CONFIG_SMP flush_icache_mm is a just a flush_icache_all(),
|
|
||||||
* which generates unused variable warnings all over this function.
|
|
||||||
*/
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
flush_icache_mm(mm, local);
|
|
||||||
#else
|
|
||||||
flush_icache_all();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#include <linux/mmc/host.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/mtd/physmap.h>
|
#include <linux/mtd/physmap.h>
|
||||||
#include <linux/mfd/tmio.h>
|
#include <linux/mfd/tmio.h>
|
||||||
#include <linux/mtd/rawnand.h>
|
#include <linux/mtd/platnand.h>
|
||||||
#include <linux/i2c.h>
|
#include <linux/i2c.h>
|
||||||
#include <linux/regulator/fixed.h>
|
#include <linux/regulator/fixed.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/machine.h>
|
||||||
@@ -165,23 +165,21 @@ static struct mtd_partition migor_nand_flash_partitions[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd,
|
static void migor_nand_flash_cmd_ctl(struct nand_chip *chip, int cmd,
|
||||||
unsigned int ctrl)
|
unsigned int ctrl)
|
||||||
{
|
{
|
||||||
struct nand_chip *chip = mtd_to_nand(mtd);
|
|
||||||
|
|
||||||
if (cmd == NAND_CMD_NONE)
|
if (cmd == NAND_CMD_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (ctrl & NAND_CLE)
|
if (ctrl & NAND_CLE)
|
||||||
writeb(cmd, chip->IO_ADDR_W + 0x00400000);
|
writeb(cmd, chip->legacy.IO_ADDR_W + 0x00400000);
|
||||||
else if (ctrl & NAND_ALE)
|
else if (ctrl & NAND_ALE)
|
||||||
writeb(cmd, chip->IO_ADDR_W + 0x00800000);
|
writeb(cmd, chip->legacy.IO_ADDR_W + 0x00800000);
|
||||||
else
|
else
|
||||||
writeb(cmd, chip->IO_ADDR_W);
|
writeb(cmd, chip->legacy.IO_ADDR_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int migor_nand_flash_ready(struct mtd_info *mtd)
|
static int migor_nand_flash_ready(struct nand_chip *chip)
|
||||||
{
|
{
|
||||||
return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
|
return gpio_get_value(GPIO_PTA1); /* NAND_RBn */
|
||||||
}
|
}
|
||||||
|
@@ -2843,7 +2843,7 @@ config X86_SYSFB
|
|||||||
This option, if enabled, marks VGA/VBE/EFI framebuffers as generic
|
This option, if enabled, marks VGA/VBE/EFI framebuffers as generic
|
||||||
framebuffers so the new generic system-framebuffer drivers can be
|
framebuffers so the new generic system-framebuffer drivers can be
|
||||||
used on x86. If the framebuffer is not compatible with the generic
|
used on x86. If the framebuffer is not compatible with the generic
|
||||||
modes, it is adverticed as fallback platform framebuffer so legacy
|
modes, it is advertised as fallback platform framebuffer so legacy
|
||||||
drivers like efifb, vesafb and uvesafb can pick it up.
|
drivers like efifb, vesafb and uvesafb can pick it up.
|
||||||
If this option is not selected, all system framebuffers are always
|
If this option is not selected, all system framebuffers are always
|
||||||
marked as fallback platform framebuffers as usual.
|
marked as fallback platform framebuffers as usual.
|
||||||
|
@@ -175,22 +175,6 @@ ifdef CONFIG_FUNCTION_GRAPH_TRACER
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef CC_HAVE_ASM_GOTO
|
|
||||||
$(error Compiler lacks asm-goto support.)
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
|
||||||
# Jump labels need '-maccumulate-outgoing-args' for gcc < 4.5.2 to prevent a
|
|
||||||
# GCC bug (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46226). There's no way
|
|
||||||
# to test for this bug at compile-time because the test case needs to execute,
|
|
||||||
# which is a no-go for cross compilers. So check the GCC version instead.
|
|
||||||
#
|
|
||||||
ifdef CONFIG_JUMP_LABEL
|
|
||||||
ifneq ($(ACCUMULATE_OUTGOING_ARGS), 1)
|
|
||||||
ACCUMULATE_OUTGOING_ARGS = $(call cc-if-fullversion, -lt, 040502, 1)
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
|
ifeq ($(ACCUMULATE_OUTGOING_ARGS), 1)
|
||||||
# This compiler flag is not supported by Clang:
|
# This compiler flag is not supported by Clang:
|
||||||
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
|
KBUILD_CFLAGS += $(call cc-option,-maccumulate-outgoing-args,)
|
||||||
@@ -312,6 +296,13 @@ PHONY += vdso_install
|
|||||||
vdso_install:
|
vdso_install:
|
||||||
$(Q)$(MAKE) $(build)=arch/x86/entry/vdso $@
|
$(Q)$(MAKE) $(build)=arch/x86/entry/vdso $@
|
||||||
|
|
||||||
|
archprepare: checkbin
|
||||||
|
checkbin:
|
||||||
|
ifndef CC_HAVE_ASM_GOTO
|
||||||
|
@echo Compiler lacks asm-goto support.
|
||||||
|
@exit 1
|
||||||
|
endif
|
||||||
|
|
||||||
archclean:
|
archclean:
|
||||||
$(Q)rm -rf $(objtree)/arch/i386
|
$(Q)rm -rf $(objtree)/arch/i386
|
||||||
$(Q)rm -rf $(objtree)/arch/x86_64
|
$(Q)rm -rf $(objtree)/arch/x86_64
|
||||||
|
@@ -223,34 +223,34 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
|
|||||||
pcmpeqd TWOONE(%rip), \TMP2
|
pcmpeqd TWOONE(%rip), \TMP2
|
||||||
pand POLY(%rip), \TMP2
|
pand POLY(%rip), \TMP2
|
||||||
pxor \TMP2, \TMP3
|
pxor \TMP2, \TMP3
|
||||||
movdqa \TMP3, HashKey(%arg2)
|
movdqu \TMP3, HashKey(%arg2)
|
||||||
|
|
||||||
movdqa \TMP3, \TMP5
|
movdqa \TMP3, \TMP5
|
||||||
pshufd $78, \TMP3, \TMP1
|
pshufd $78, \TMP3, \TMP1
|
||||||
pxor \TMP3, \TMP1
|
pxor \TMP3, \TMP1
|
||||||
movdqa \TMP1, HashKey_k(%arg2)
|
movdqu \TMP1, HashKey_k(%arg2)
|
||||||
|
|
||||||
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
||||||
# TMP5 = HashKey^2<<1 (mod poly)
|
# TMP5 = HashKey^2<<1 (mod poly)
|
||||||
movdqa \TMP5, HashKey_2(%arg2)
|
movdqu \TMP5, HashKey_2(%arg2)
|
||||||
# HashKey_2 = HashKey^2<<1 (mod poly)
|
# HashKey_2 = HashKey^2<<1 (mod poly)
|
||||||
pshufd $78, \TMP5, \TMP1
|
pshufd $78, \TMP5, \TMP1
|
||||||
pxor \TMP5, \TMP1
|
pxor \TMP5, \TMP1
|
||||||
movdqa \TMP1, HashKey_2_k(%arg2)
|
movdqu \TMP1, HashKey_2_k(%arg2)
|
||||||
|
|
||||||
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
||||||
# TMP5 = HashKey^3<<1 (mod poly)
|
# TMP5 = HashKey^3<<1 (mod poly)
|
||||||
movdqa \TMP5, HashKey_3(%arg2)
|
movdqu \TMP5, HashKey_3(%arg2)
|
||||||
pshufd $78, \TMP5, \TMP1
|
pshufd $78, \TMP5, \TMP1
|
||||||
pxor \TMP5, \TMP1
|
pxor \TMP5, \TMP1
|
||||||
movdqa \TMP1, HashKey_3_k(%arg2)
|
movdqu \TMP1, HashKey_3_k(%arg2)
|
||||||
|
|
||||||
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7
|
||||||
# TMP5 = HashKey^3<<1 (mod poly)
|
# TMP5 = HashKey^3<<1 (mod poly)
|
||||||
movdqa \TMP5, HashKey_4(%arg2)
|
movdqu \TMP5, HashKey_4(%arg2)
|
||||||
pshufd $78, \TMP5, \TMP1
|
pshufd $78, \TMP5, \TMP1
|
||||||
pxor \TMP5, \TMP1
|
pxor \TMP5, \TMP1
|
||||||
movdqa \TMP1, HashKey_4_k(%arg2)
|
movdqu \TMP1, HashKey_4_k(%arg2)
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
# GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
|
# GCM_INIT initializes a gcm_context struct to prepare for encoding/decoding.
|
||||||
@@ -271,7 +271,7 @@ ALL_F: .octa 0xffffffffffffffffffffffffffffffff
|
|||||||
movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
|
movdqu %xmm0, CurCount(%arg2) # ctx_data.current_counter = iv
|
||||||
|
|
||||||
PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
|
PRECOMPUTE \SUBKEY, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
|
||||||
movdqa HashKey(%arg2), %xmm13
|
movdqu HashKey(%arg2), %xmm13
|
||||||
|
|
||||||
CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
|
CALC_AAD_HASH %xmm13, \AAD, \AADLEN, %xmm0, %xmm1, %xmm2, %xmm3, \
|
||||||
%xmm4, %xmm5, %xmm6
|
%xmm4, %xmm5, %xmm6
|
||||||
@@ -997,7 +997,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
pshufd $78, \XMM5, \TMP6
|
pshufd $78, \XMM5, \TMP6
|
||||||
pxor \XMM5, \TMP6
|
pxor \XMM5, \TMP6
|
||||||
paddd ONE(%rip), \XMM0 # INCR CNT
|
paddd ONE(%rip), \XMM0 # INCR CNT
|
||||||
movdqa HashKey_4(%arg2), \TMP5
|
movdqu HashKey_4(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
|
||||||
movdqa \XMM0, \XMM1
|
movdqa \XMM0, \XMM1
|
||||||
paddd ONE(%rip), \XMM0 # INCR CNT
|
paddd ONE(%rip), \XMM0 # INCR CNT
|
||||||
@@ -1016,7 +1016,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
pxor (%arg1), \XMM2
|
pxor (%arg1), \XMM2
|
||||||
pxor (%arg1), \XMM3
|
pxor (%arg1), \XMM3
|
||||||
pxor (%arg1), \XMM4
|
pxor (%arg1), \XMM4
|
||||||
movdqa HashKey_4_k(%arg2), \TMP5
|
movdqu HashKey_4_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x10(%arg1), \TMP1
|
movaps 0x10(%arg1), \TMP1
|
||||||
AESENC \TMP1, \XMM1 # Round 1
|
AESENC \TMP1, \XMM1 # Round 1
|
||||||
@@ -1031,7 +1031,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM6, \TMP1
|
movdqa \XMM6, \TMP1
|
||||||
pshufd $78, \XMM6, \TMP2
|
pshufd $78, \XMM6, \TMP2
|
||||||
pxor \XMM6, \TMP2
|
pxor \XMM6, \TMP2
|
||||||
movdqa HashKey_3(%arg2), \TMP5
|
movdqu HashKey_3(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
|
||||||
movaps 0x30(%arg1), \TMP3
|
movaps 0x30(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 3
|
AESENC \TMP3, \XMM1 # Round 3
|
||||||
@@ -1044,7 +1044,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
AESENC \TMP3, \XMM2
|
AESENC \TMP3, \XMM2
|
||||||
AESENC \TMP3, \XMM3
|
AESENC \TMP3, \XMM3
|
||||||
AESENC \TMP3, \XMM4
|
AESENC \TMP3, \XMM4
|
||||||
movdqa HashKey_3_k(%arg2), \TMP5
|
movdqu HashKey_3_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x50(%arg1), \TMP3
|
movaps 0x50(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 5
|
AESENC \TMP3, \XMM1 # Round 5
|
||||||
@@ -1058,7 +1058,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM7, \TMP1
|
movdqa \XMM7, \TMP1
|
||||||
pshufd $78, \XMM7, \TMP2
|
pshufd $78, \XMM7, \TMP2
|
||||||
pxor \XMM7, \TMP2
|
pxor \XMM7, \TMP2
|
||||||
movdqa HashKey_2(%arg2), \TMP5
|
movdqu HashKey_2(%arg2), \TMP5
|
||||||
|
|
||||||
# Multiply TMP5 * HashKey using karatsuba
|
# Multiply TMP5 * HashKey using karatsuba
|
||||||
|
|
||||||
@@ -1074,7 +1074,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
AESENC \TMP3, \XMM2
|
AESENC \TMP3, \XMM2
|
||||||
AESENC \TMP3, \XMM3
|
AESENC \TMP3, \XMM3
|
||||||
AESENC \TMP3, \XMM4
|
AESENC \TMP3, \XMM4
|
||||||
movdqa HashKey_2_k(%arg2), \TMP5
|
movdqu HashKey_2_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x80(%arg1), \TMP3
|
movaps 0x80(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 8
|
AESENC \TMP3, \XMM1 # Round 8
|
||||||
@@ -1092,7 +1092,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM8, \TMP1
|
movdqa \XMM8, \TMP1
|
||||||
pshufd $78, \XMM8, \TMP2
|
pshufd $78, \XMM8, \TMP2
|
||||||
pxor \XMM8, \TMP2
|
pxor \XMM8, \TMP2
|
||||||
movdqa HashKey(%arg2), \TMP5
|
movdqu HashKey(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
||||||
movaps 0x90(%arg1), \TMP3
|
movaps 0x90(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 9
|
AESENC \TMP3, \XMM1 # Round 9
|
||||||
@@ -1121,7 +1121,7 @@ aes_loop_par_enc_done\@:
|
|||||||
AESENCLAST \TMP3, \XMM2
|
AESENCLAST \TMP3, \XMM2
|
||||||
AESENCLAST \TMP3, \XMM3
|
AESENCLAST \TMP3, \XMM3
|
||||||
AESENCLAST \TMP3, \XMM4
|
AESENCLAST \TMP3, \XMM4
|
||||||
movdqa HashKey_k(%arg2), \TMP5
|
movdqu HashKey_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movdqu (%arg4,%r11,1), \TMP3
|
movdqu (%arg4,%r11,1), \TMP3
|
||||||
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
|
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
|
||||||
@@ -1205,7 +1205,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
pshufd $78, \XMM5, \TMP6
|
pshufd $78, \XMM5, \TMP6
|
||||||
pxor \XMM5, \TMP6
|
pxor \XMM5, \TMP6
|
||||||
paddd ONE(%rip), \XMM0 # INCR CNT
|
paddd ONE(%rip), \XMM0 # INCR CNT
|
||||||
movdqa HashKey_4(%arg2), \TMP5
|
movdqu HashKey_4(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1
|
||||||
movdqa \XMM0, \XMM1
|
movdqa \XMM0, \XMM1
|
||||||
paddd ONE(%rip), \XMM0 # INCR CNT
|
paddd ONE(%rip), \XMM0 # INCR CNT
|
||||||
@@ -1224,7 +1224,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
pxor (%arg1), \XMM2
|
pxor (%arg1), \XMM2
|
||||||
pxor (%arg1), \XMM3
|
pxor (%arg1), \XMM3
|
||||||
pxor (%arg1), \XMM4
|
pxor (%arg1), \XMM4
|
||||||
movdqa HashKey_4_k(%arg2), \TMP5
|
movdqu HashKey_4_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x10(%arg1), \TMP1
|
movaps 0x10(%arg1), \TMP1
|
||||||
AESENC \TMP1, \XMM1 # Round 1
|
AESENC \TMP1, \XMM1 # Round 1
|
||||||
@@ -1239,7 +1239,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM6, \TMP1
|
movdqa \XMM6, \TMP1
|
||||||
pshufd $78, \XMM6, \TMP2
|
pshufd $78, \XMM6, \TMP2
|
||||||
pxor \XMM6, \TMP2
|
pxor \XMM6, \TMP2
|
||||||
movdqa HashKey_3(%arg2), \TMP5
|
movdqu HashKey_3(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1
|
||||||
movaps 0x30(%arg1), \TMP3
|
movaps 0x30(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 3
|
AESENC \TMP3, \XMM1 # Round 3
|
||||||
@@ -1252,7 +1252,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
AESENC \TMP3, \XMM2
|
AESENC \TMP3, \XMM2
|
||||||
AESENC \TMP3, \XMM3
|
AESENC \TMP3, \XMM3
|
||||||
AESENC \TMP3, \XMM4
|
AESENC \TMP3, \XMM4
|
||||||
movdqa HashKey_3_k(%arg2), \TMP5
|
movdqu HashKey_3_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x50(%arg1), \TMP3
|
movaps 0x50(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 5
|
AESENC \TMP3, \XMM1 # Round 5
|
||||||
@@ -1266,7 +1266,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM7, \TMP1
|
movdqa \XMM7, \TMP1
|
||||||
pshufd $78, \XMM7, \TMP2
|
pshufd $78, \XMM7, \TMP2
|
||||||
pxor \XMM7, \TMP2
|
pxor \XMM7, \TMP2
|
||||||
movdqa HashKey_2(%arg2), \TMP5
|
movdqu HashKey_2(%arg2), \TMP5
|
||||||
|
|
||||||
# Multiply TMP5 * HashKey using karatsuba
|
# Multiply TMP5 * HashKey using karatsuba
|
||||||
|
|
||||||
@@ -1282,7 +1282,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
AESENC \TMP3, \XMM2
|
AESENC \TMP3, \XMM2
|
||||||
AESENC \TMP3, \XMM3
|
AESENC \TMP3, \XMM3
|
||||||
AESENC \TMP3, \XMM4
|
AESENC \TMP3, \XMM4
|
||||||
movdqa HashKey_2_k(%arg2), \TMP5
|
movdqu HashKey_2_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movaps 0x80(%arg1), \TMP3
|
movaps 0x80(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 8
|
AESENC \TMP3, \XMM1 # Round 8
|
||||||
@@ -1300,7 +1300,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation
|
|||||||
movdqa \XMM8, \TMP1
|
movdqa \XMM8, \TMP1
|
||||||
pshufd $78, \XMM8, \TMP2
|
pshufd $78, \XMM8, \TMP2
|
||||||
pxor \XMM8, \TMP2
|
pxor \XMM8, \TMP2
|
||||||
movdqa HashKey(%arg2), \TMP5
|
movdqu HashKey(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
||||||
movaps 0x90(%arg1), \TMP3
|
movaps 0x90(%arg1), \TMP3
|
||||||
AESENC \TMP3, \XMM1 # Round 9
|
AESENC \TMP3, \XMM1 # Round 9
|
||||||
@@ -1329,7 +1329,7 @@ aes_loop_par_dec_done\@:
|
|||||||
AESENCLAST \TMP3, \XMM2
|
AESENCLAST \TMP3, \XMM2
|
||||||
AESENCLAST \TMP3, \XMM3
|
AESENCLAST \TMP3, \XMM3
|
||||||
AESENCLAST \TMP3, \XMM4
|
AESENCLAST \TMP3, \XMM4
|
||||||
movdqa HashKey_k(%arg2), \TMP5
|
movdqu HashKey_k(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movdqu (%arg4,%r11,1), \TMP3
|
movdqu (%arg4,%r11,1), \TMP3
|
||||||
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
|
pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK
|
||||||
@@ -1405,10 +1405,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
|
|||||||
movdqa \XMM1, \TMP6
|
movdqa \XMM1, \TMP6
|
||||||
pshufd $78, \XMM1, \TMP2
|
pshufd $78, \XMM1, \TMP2
|
||||||
pxor \XMM1, \TMP2
|
pxor \XMM1, \TMP2
|
||||||
movdqa HashKey_4(%arg2), \TMP5
|
movdqu HashKey_4(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1
|
||||||
PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0
|
PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0
|
||||||
movdqa HashKey_4_k(%arg2), \TMP4
|
movdqu HashKey_4_k(%arg2), \TMP4
|
||||||
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
movdqa \XMM1, \XMMDst
|
movdqa \XMM1, \XMMDst
|
||||||
movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1
|
movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1
|
||||||
@@ -1418,10 +1418,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
|
|||||||
movdqa \XMM2, \TMP1
|
movdqa \XMM2, \TMP1
|
||||||
pshufd $78, \XMM2, \TMP2
|
pshufd $78, \XMM2, \TMP2
|
||||||
pxor \XMM2, \TMP2
|
pxor \XMM2, \TMP2
|
||||||
movdqa HashKey_3(%arg2), \TMP5
|
movdqu HashKey_3(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
||||||
PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0
|
PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0
|
||||||
movdqa HashKey_3_k(%arg2), \TMP4
|
movdqu HashKey_3_k(%arg2), \TMP4
|
||||||
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
pxor \TMP1, \TMP6
|
pxor \TMP1, \TMP6
|
||||||
pxor \XMM2, \XMMDst
|
pxor \XMM2, \XMMDst
|
||||||
@@ -1433,10 +1433,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
|
|||||||
movdqa \XMM3, \TMP1
|
movdqa \XMM3, \TMP1
|
||||||
pshufd $78, \XMM3, \TMP2
|
pshufd $78, \XMM3, \TMP2
|
||||||
pxor \XMM3, \TMP2
|
pxor \XMM3, \TMP2
|
||||||
movdqa HashKey_2(%arg2), \TMP5
|
movdqu HashKey_2(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
||||||
PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0
|
PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0
|
||||||
movdqa HashKey_2_k(%arg2), \TMP4
|
movdqu HashKey_2_k(%arg2), \TMP4
|
||||||
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
pxor \TMP1, \TMP6
|
pxor \TMP1, \TMP6
|
||||||
pxor \XMM3, \XMMDst
|
pxor \XMM3, \XMMDst
|
||||||
@@ -1446,10 +1446,10 @@ TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst
|
|||||||
movdqa \XMM4, \TMP1
|
movdqa \XMM4, \TMP1
|
||||||
pshufd $78, \XMM4, \TMP2
|
pshufd $78, \XMM4, \TMP2
|
||||||
pxor \XMM4, \TMP2
|
pxor \XMM4, \TMP2
|
||||||
movdqa HashKey(%arg2), \TMP5
|
movdqu HashKey(%arg2), \TMP5
|
||||||
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1
|
||||||
PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0
|
PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0
|
||||||
movdqa HashKey_k(%arg2), \TMP4
|
movdqu HashKey_k(%arg2), \TMP4
|
||||||
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0)
|
||||||
pxor \TMP1, \TMP6
|
pxor \TMP1, \TMP6
|
||||||
pxor \XMM4, \XMMDst
|
pxor \XMM4, \XMMDst
|
||||||
|
@@ -2465,7 +2465,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
|
|||||||
|
|
||||||
perf_callchain_store(entry, regs->ip);
|
perf_callchain_store(entry, regs->ip);
|
||||||
|
|
||||||
if (!current->mm)
|
if (!nmi_uaccess_okay())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (perf_callchain_user32(regs, entry))
|
if (perf_callchain_user32(regs, entry))
|
||||||
|
@@ -33,7 +33,8 @@ extern inline unsigned long native_save_fl(void)
|
|||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void native_restore_fl(unsigned long flags)
|
extern inline void native_restore_fl(unsigned long flags);
|
||||||
|
extern inline void native_restore_fl(unsigned long flags)
|
||||||
{
|
{
|
||||||
asm volatile("push %0 ; popf"
|
asm volatile("push %0 ; popf"
|
||||||
: /* no output */
|
: /* no output */
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
#ifndef _ASM_X86_PGTABLE_3LEVEL_H
|
#ifndef _ASM_X86_PGTABLE_3LEVEL_H
|
||||||
#define _ASM_X86_PGTABLE_3LEVEL_H
|
#define _ASM_X86_PGTABLE_3LEVEL_H
|
||||||
|
|
||||||
|
#include <asm/atomic64_32.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Intel Physical Address Extension (PAE) Mode - three-level page
|
* Intel Physical Address Extension (PAE) Mode - three-level page
|
||||||
* tables on PPro+ CPUs.
|
* tables on PPro+ CPUs.
|
||||||
@@ -150,10 +152,7 @@ static inline pte_t native_ptep_get_and_clear(pte_t *ptep)
|
|||||||
{
|
{
|
||||||
pte_t res;
|
pte_t res;
|
||||||
|
|
||||||
/* xchg acts as a barrier before the setting of the high bits */
|
res.pte = (pteval_t)arch_atomic64_xchg((atomic64_t *)ptep, 0);
|
||||||
res.pte_low = xchg(&ptep->pte_low, 0);
|
|
||||||
res.pte_high = ptep->pte_high;
|
|
||||||
ptep->pte_high = 0;
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@@ -132,6 +132,8 @@ struct cpuinfo_x86 {
|
|||||||
/* Index into per_cpu list: */
|
/* Index into per_cpu list: */
|
||||||
u16 cpu_index;
|
u16 cpu_index;
|
||||||
u32 microcode;
|
u32 microcode;
|
||||||
|
/* Address space bits used by the cache internally */
|
||||||
|
u8 x86_cache_bits;
|
||||||
unsigned initialized : 1;
|
unsigned initialized : 1;
|
||||||
} __randomize_layout;
|
} __randomize_layout;
|
||||||
|
|
||||||
@@ -183,7 +185,7 @@ extern void cpu_detect(struct cpuinfo_x86 *c);
|
|||||||
|
|
||||||
static inline unsigned long long l1tf_pfn_limit(void)
|
static inline unsigned long long l1tf_pfn_limit(void)
|
||||||
{
|
{
|
||||||
return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT);
|
return BIT_ULL(boot_cpu_data.x86_cache_bits - 1 - PAGE_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void early_cpu_init(void);
|
extern void early_cpu_init(void);
|
||||||
|
@@ -39,6 +39,7 @@ extern void do_signal(struct pt_regs *regs);
|
|||||||
|
|
||||||
#define __ARCH_HAS_SA_RESTORER
|
#define __ARCH_HAS_SA_RESTORER
|
||||||
|
|
||||||
|
#include <asm/asm.h>
|
||||||
#include <uapi/asm/sigcontext.h>
|
#include <uapi/asm/sigcontext.h>
|
||||||
|
|
||||||
#ifdef __i386__
|
#ifdef __i386__
|
||||||
@@ -86,9 +87,9 @@ static inline int __const_sigismember(sigset_t *set, int _sig)
|
|||||||
|
|
||||||
static inline int __gen_sigismember(sigset_t *set, int _sig)
|
static inline int __gen_sigismember(sigset_t *set, int _sig)
|
||||||
{
|
{
|
||||||
unsigned char ret;
|
bool ret;
|
||||||
asm("btl %2,%1\n\tsetc %0"
|
asm("btl %2,%1" CC_SET(c)
|
||||||
: "=qm"(ret) : "m"(*set), "Ir"(_sig-1) : "cc");
|
: CC_OUT(c) (ret) : "m"(*set), "Ir"(_sig-1));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -111,6 +111,6 @@ static inline unsigned long caller_frame_pointer(void)
|
|||||||
return (unsigned long)frame;
|
return (unsigned long)frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_opcodes(u8 *rip, const char *loglvl);
|
void show_opcodes(struct pt_regs *regs, const char *loglvl);
|
||||||
void show_ip(struct pt_regs *regs, const char *loglvl);
|
void show_ip(struct pt_regs *regs, const char *loglvl);
|
||||||
#endif /* _ASM_X86_STACKTRACE_H */
|
#endif /* _ASM_X86_STACKTRACE_H */
|
||||||
|
@@ -175,8 +175,16 @@ struct tlb_state {
|
|||||||
* are on. This means that it may not match current->active_mm,
|
* are on. This means that it may not match current->active_mm,
|
||||||
* which will contain the previous user mm when we're in lazy TLB
|
* which will contain the previous user mm when we're in lazy TLB
|
||||||
* mode even if we've already switched back to swapper_pg_dir.
|
* mode even if we've already switched back to swapper_pg_dir.
|
||||||
|
*
|
||||||
|
* During switch_mm_irqs_off(), loaded_mm will be set to
|
||||||
|
* LOADED_MM_SWITCHING during the brief interrupts-off window
|
||||||
|
* when CR3 and loaded_mm would otherwise be inconsistent. This
|
||||||
|
* is for nmi_uaccess_okay()'s benefit.
|
||||||
*/
|
*/
|
||||||
struct mm_struct *loaded_mm;
|
struct mm_struct *loaded_mm;
|
||||||
|
|
||||||
|
#define LOADED_MM_SWITCHING ((struct mm_struct *)1)
|
||||||
|
|
||||||
u16 loaded_mm_asid;
|
u16 loaded_mm_asid;
|
||||||
u16 next_asid;
|
u16 next_asid;
|
||||||
/* last user mm's ctx id */
|
/* last user mm's ctx id */
|
||||||
@@ -246,6 +254,38 @@ struct tlb_state {
|
|||||||
};
|
};
|
||||||
DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
|
DECLARE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Blindly accessing user memory from NMI context can be dangerous
|
||||||
|
* if we're in the middle of switching the current user task or
|
||||||
|
* switching the loaded mm. It can also be dangerous if we
|
||||||
|
* interrupted some kernel code that was temporarily using a
|
||||||
|
* different mm.
|
||||||
|
*/
|
||||||
|
static inline bool nmi_uaccess_okay(void)
|
||||||
|
{
|
||||||
|
struct mm_struct *loaded_mm = this_cpu_read(cpu_tlbstate.loaded_mm);
|
||||||
|
struct mm_struct *current_mm = current->mm;
|
||||||
|
|
||||||
|
VM_WARN_ON_ONCE(!loaded_mm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The condition we want to check is
|
||||||
|
* current_mm->pgd == __va(read_cr3_pa()). This may be slow, though,
|
||||||
|
* if we're running in a VM with shadow paging, and nmi_uaccess_okay()
|
||||||
|
* is supposed to be reasonably fast.
|
||||||
|
*
|
||||||
|
* Instead, we check the almost equivalent but somewhat conservative
|
||||||
|
* condition below, and we rely on the fact that switch_mm_irqs_off()
|
||||||
|
* sets loaded_mm to LOADED_MM_SWITCHING before writing to CR3.
|
||||||
|
*/
|
||||||
|
if (loaded_mm != current_mm)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VM_WARN_ON_ONCE(current_mm->pgd != __va(read_cr3_pa()));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize cr4 shadow for this CPU. */
|
/* Initialize cr4 shadow for this CPU. */
|
||||||
static inline void cr4_init_shadow(void)
|
static inline void cr4_init_shadow(void)
|
||||||
{
|
{
|
||||||
|
@@ -93,7 +93,7 @@ static inline unsigned int __getcpu(void)
|
|||||||
*
|
*
|
||||||
* If RDPID is available, use it.
|
* If RDPID is available, use it.
|
||||||
*/
|
*/
|
||||||
alternative_io ("lsl %[p],%[seg]",
|
alternative_io ("lsl %[seg],%[p]",
|
||||||
".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */
|
".byte 0xf3,0x0f,0xc7,0xf8", /* RDPID %eax/rax */
|
||||||
X86_FEATURE_RDPID,
|
X86_FEATURE_RDPID,
|
||||||
[p] "=a" (p), [seg] "r" (__PER_CPU_SEG));
|
[p] "=a" (p), [seg] "r" (__PER_CPU_SEG));
|
||||||
|
@@ -684,8 +684,6 @@ void *__init_or_module text_poke_early(void *addr, const void *opcode,
|
|||||||
* It means the size must be writable atomically and the address must be aligned
|
* It means the size must be writable atomically and the address must be aligned
|
||||||
* in a way that permits an atomic write. It also makes sure we fit on a single
|
* in a way that permits an atomic write. It also makes sure we fit on a single
|
||||||
* page.
|
* page.
|
||||||
*
|
|
||||||
* Note: Must be called under text_mutex.
|
|
||||||
*/
|
*/
|
||||||
void *text_poke(void *addr, const void *opcode, size_t len)
|
void *text_poke(void *addr, const void *opcode, size_t len)
|
||||||
{
|
{
|
||||||
@@ -700,6 +698,8 @@ void *text_poke(void *addr, const void *opcode, size_t len)
|
|||||||
*/
|
*/
|
||||||
BUG_ON(!after_bootmem);
|
BUG_ON(!after_bootmem);
|
||||||
|
|
||||||
|
lockdep_assert_held(&text_mutex);
|
||||||
|
|
||||||
if (!core_kernel_text((unsigned long)addr)) {
|
if (!core_kernel_text((unsigned long)addr)) {
|
||||||
pages[0] = vmalloc_to_page(addr);
|
pages[0] = vmalloc_to_page(addr);
|
||||||
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
|
pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
|
||||||
@@ -782,8 +782,6 @@ int poke_int3_handler(struct pt_regs *regs)
|
|||||||
* - replace the first byte (int3) by the first byte of
|
* - replace the first byte (int3) by the first byte of
|
||||||
* replacing opcode
|
* replacing opcode
|
||||||
* - sync cores
|
* - sync cores
|
||||||
*
|
|
||||||
* Note: must be called under text_mutex.
|
|
||||||
*/
|
*/
|
||||||
void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
|
void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
|
||||||
{
|
{
|
||||||
@@ -792,6 +790,9 @@ void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
|
|||||||
bp_int3_handler = handler;
|
bp_int3_handler = handler;
|
||||||
bp_int3_addr = (u8 *)addr + sizeof(int3);
|
bp_int3_addr = (u8 *)addr + sizeof(int3);
|
||||||
bp_patching_in_progress = true;
|
bp_patching_in_progress = true;
|
||||||
|
|
||||||
|
lockdep_assert_held(&text_mutex);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Corresponding read barrier in int3 notifier for making sure the
|
* Corresponding read barrier in int3 notifier for making sure the
|
||||||
* in_progress and handler are correctly ordered wrt. patching.
|
* in_progress and handler are correctly ordered wrt. patching.
|
||||||
|
@@ -668,6 +668,45 @@ EXPORT_SYMBOL_GPL(l1tf_mitigation);
|
|||||||
enum vmx_l1d_flush_state l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
|
enum vmx_l1d_flush_state l1tf_vmx_mitigation = VMENTER_L1D_FLUSH_AUTO;
|
||||||
EXPORT_SYMBOL_GPL(l1tf_vmx_mitigation);
|
EXPORT_SYMBOL_GPL(l1tf_vmx_mitigation);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* These CPUs all support 44bits physical address space internally in the
|
||||||
|
* cache but CPUID can report a smaller number of physical address bits.
|
||||||
|
*
|
||||||
|
* The L1TF mitigation uses the top most address bit for the inversion of
|
||||||
|
* non present PTEs. When the installed memory reaches into the top most
|
||||||
|
* address bit due to memory holes, which has been observed on machines
|
||||||
|
* which report 36bits physical address bits and have 32G RAM installed,
|
||||||
|
* then the mitigation range check in l1tf_select_mitigation() triggers.
|
||||||
|
* This is a false positive because the mitigation is still possible due to
|
||||||
|
* the fact that the cache uses 44bit internally. Use the cache bits
|
||||||
|
* instead of the reported physical bits and adjust them on the affected
|
||||||
|
* machines to 44bit if the reported bits are less than 44.
|
||||||
|
*/
|
||||||
|
static void override_cache_bits(struct cpuinfo_x86 *c)
|
||||||
|
{
|
||||||
|
if (c->x86 != 6)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (c->x86_model) {
|
||||||
|
case INTEL_FAM6_NEHALEM:
|
||||||
|
case INTEL_FAM6_WESTMERE:
|
||||||
|
case INTEL_FAM6_SANDYBRIDGE:
|
||||||
|
case INTEL_FAM6_IVYBRIDGE:
|
||||||
|
case INTEL_FAM6_HASWELL_CORE:
|
||||||
|
case INTEL_FAM6_HASWELL_ULT:
|
||||||
|
case INTEL_FAM6_HASWELL_GT3E:
|
||||||
|
case INTEL_FAM6_BROADWELL_CORE:
|
||||||
|
case INTEL_FAM6_BROADWELL_GT3E:
|
||||||
|
case INTEL_FAM6_SKYLAKE_MOBILE:
|
||||||
|
case INTEL_FAM6_SKYLAKE_DESKTOP:
|
||||||
|
case INTEL_FAM6_KABYLAKE_MOBILE:
|
||||||
|
case INTEL_FAM6_KABYLAKE_DESKTOP:
|
||||||
|
if (c->x86_cache_bits < 44)
|
||||||
|
c->x86_cache_bits = 44;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void __init l1tf_select_mitigation(void)
|
static void __init l1tf_select_mitigation(void)
|
||||||
{
|
{
|
||||||
u64 half_pa;
|
u64 half_pa;
|
||||||
@@ -675,6 +714,8 @@ static void __init l1tf_select_mitigation(void)
|
|||||||
if (!boot_cpu_has_bug(X86_BUG_L1TF))
|
if (!boot_cpu_has_bug(X86_BUG_L1TF))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
override_cache_bits(&boot_cpu_data);
|
||||||
|
|
||||||
switch (l1tf_mitigation) {
|
switch (l1tf_mitigation) {
|
||||||
case L1TF_MITIGATION_OFF:
|
case L1TF_MITIGATION_OFF:
|
||||||
case L1TF_MITIGATION_FLUSH_NOWARN:
|
case L1TF_MITIGATION_FLUSH_NOWARN:
|
||||||
@@ -694,11 +735,6 @@ static void __init l1tf_select_mitigation(void)
|
|||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* This is extremely unlikely to happen because almost all
|
|
||||||
* systems have far more MAX_PA/2 than RAM can be fit into
|
|
||||||
* DIMM slots.
|
|
||||||
*/
|
|
||||||
half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT;
|
half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT;
|
||||||
if (e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) {
|
if (e820__mapped_any(half_pa, ULLONG_MAX - half_pa, E820_TYPE_RAM)) {
|
||||||
pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n");
|
pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n");
|
||||||
|
@@ -919,6 +919,7 @@ void get_cpu_address_sizes(struct cpuinfo_x86 *c)
|
|||||||
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
|
else if (cpu_has(c, X86_FEATURE_PAE) || cpu_has(c, X86_FEATURE_PSE36))
|
||||||
c->x86_phys_bits = 36;
|
c->x86_phys_bits = 36;
|
||||||
#endif
|
#endif
|
||||||
|
c->x86_cache_bits = c->x86_phys_bits;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
|
||||||
|
@@ -150,6 +150,9 @@ static bool bad_spectre_microcode(struct cpuinfo_x86 *c)
|
|||||||
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
|
if (cpu_has(c, X86_FEATURE_HYPERVISOR))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (c->x86 != 6)
|
||||||
|
return false;
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
|
for (i = 0; i < ARRAY_SIZE(spectre_bad_microcodes); i++) {
|
||||||
if (c->x86_model == spectre_bad_microcodes[i].model &&
|
if (c->x86_model == spectre_bad_microcodes[i].model &&
|
||||||
c->x86_stepping == spectre_bad_microcodes[i].stepping)
|
c->x86_stepping == spectre_bad_microcodes[i].stepping)
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/nmi.h>
|
#include <linux/nmi.h>
|
||||||
#include <linux/sysfs.h>
|
#include <linux/sysfs.h>
|
||||||
|
#include <linux/kasan.h>
|
||||||
|
|
||||||
#include <asm/cpu_entry_area.h>
|
#include <asm/cpu_entry_area.h>
|
||||||
#include <asm/stacktrace.h>
|
#include <asm/stacktrace.h>
|
||||||
@@ -89,14 +90,24 @@ static void printk_stack_address(unsigned long address, int reliable,
|
|||||||
* Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random
|
* Thus, the 2/3rds prologue and 64 byte OPCODE_BUFSIZE is just a random
|
||||||
* guesstimate in attempt to achieve all of the above.
|
* guesstimate in attempt to achieve all of the above.
|
||||||
*/
|
*/
|
||||||
void show_opcodes(u8 *rip, const char *loglvl)
|
void show_opcodes(struct pt_regs *regs, const char *loglvl)
|
||||||
{
|
{
|
||||||
#define PROLOGUE_SIZE 42
|
#define PROLOGUE_SIZE 42
|
||||||
#define EPILOGUE_SIZE 21
|
#define EPILOGUE_SIZE 21
|
||||||
#define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
|
#define OPCODE_BUFSIZE (PROLOGUE_SIZE + 1 + EPILOGUE_SIZE)
|
||||||
u8 opcodes[OPCODE_BUFSIZE];
|
u8 opcodes[OPCODE_BUFSIZE];
|
||||||
|
unsigned long prologue = regs->ip - PROLOGUE_SIZE;
|
||||||
|
bool bad_ip;
|
||||||
|
|
||||||
if (probe_kernel_read(opcodes, rip - PROLOGUE_SIZE, OPCODE_BUFSIZE)) {
|
/*
|
||||||
|
* Make sure userspace isn't trying to trick us into dumping kernel
|
||||||
|
* memory by pointing the userspace instruction pointer at it.
|
||||||
|
*/
|
||||||
|
bad_ip = user_mode(regs) &&
|
||||||
|
__chk_range_not_ok(prologue, OPCODE_BUFSIZE, TASK_SIZE_MAX);
|
||||||
|
|
||||||
|
if (bad_ip || probe_kernel_read(opcodes, (u8 *)prologue,
|
||||||
|
OPCODE_BUFSIZE)) {
|
||||||
printk("%sCode: Bad RIP value.\n", loglvl);
|
printk("%sCode: Bad RIP value.\n", loglvl);
|
||||||
} else {
|
} else {
|
||||||
printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
|
printk("%sCode: %" __stringify(PROLOGUE_SIZE) "ph <%02x> %"
|
||||||
@@ -112,7 +123,7 @@ void show_ip(struct pt_regs *regs, const char *loglvl)
|
|||||||
#else
|
#else
|
||||||
printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip);
|
printk("%sRIP: %04x:%pS\n", loglvl, (int)regs->cs, (void *)regs->ip);
|
||||||
#endif
|
#endif
|
||||||
show_opcodes((u8 *)regs->ip, loglvl);
|
show_opcodes(regs, loglvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_iret_regs(struct pt_regs *regs)
|
void show_iret_regs(struct pt_regs *regs)
|
||||||
@@ -346,7 +357,10 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
|||||||
* We're not going to return, but we might be on an IST stack or
|
* We're not going to return, but we might be on an IST stack or
|
||||||
* have very little stack space left. Rewind the stack and kill
|
* have very little stack space left. Rewind the stack and kill
|
||||||
* the task.
|
* the task.
|
||||||
|
* Before we rewind the stack, we have to tell KASAN that we're going to
|
||||||
|
* reuse the task stack and that existing poisons are invalid.
|
||||||
*/
|
*/
|
||||||
|
kasan_unpoison_task_stack(current);
|
||||||
rewind_stack_do_exit(signr);
|
rewind_stack_do_exit(signr);
|
||||||
}
|
}
|
||||||
NOKPROBE_SYMBOL(oops_end);
|
NOKPROBE_SYMBOL(oops_end);
|
||||||
|
@@ -7,6 +7,8 @@
|
|||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
|
||||||
|
#include <asm/tlbflush.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We rely on the nested NMI work to allow atomic faults from the NMI path; the
|
* We rely on the nested NMI work to allow atomic faults from the NMI path; the
|
||||||
* nested NMI paths are careful to preserve CR2.
|
* nested NMI paths are careful to preserve CR2.
|
||||||
@@ -19,6 +21,9 @@ copy_from_user_nmi(void *to, const void __user *from, unsigned long n)
|
|||||||
if (__range_not_ok(from, n, TASK_SIZE))
|
if (__range_not_ok(from, n, TASK_SIZE))
|
||||||
return n;
|
return n;
|
||||||
|
|
||||||
|
if (!nmi_uaccess_okay())
|
||||||
|
return n;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even though this function is typically called from NMI/IRQ context
|
* Even though this function is typically called from NMI/IRQ context
|
||||||
* disable pagefaults so that its behaviour is consistent even when
|
* disable pagefaults so that its behaviour is consistent even when
|
||||||
|
@@ -837,7 +837,7 @@ show_signal_msg(struct pt_regs *regs, unsigned long error_code,
|
|||||||
|
|
||||||
printk(KERN_CONT "\n");
|
printk(KERN_CONT "\n");
|
||||||
|
|
||||||
show_opcodes((u8 *)regs->ip, loglvl);
|
show_opcodes(regs, loglvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@@ -1420,6 +1420,29 @@ static int __change_page_attr_set_clr(struct cpa_data *cpa, int checkalias)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Machine check recovery code needs to change cache mode of poisoned
|
||||||
|
* pages to UC to avoid speculative access logging another error. But
|
||||||
|
* passing the address of the 1:1 mapping to set_memory_uc() is a fine
|
||||||
|
* way to encourage a speculative access. So we cheat and flip the top
|
||||||
|
* bit of the address. This works fine for the code that updates the
|
||||||
|
* page tables. But at the end of the process we need to flush the cache
|
||||||
|
* and the non-canonical address causes a #GP fault when used by the
|
||||||
|
* CLFLUSH instruction.
|
||||||
|
*
|
||||||
|
* But in the common case we already have a canonical address. This code
|
||||||
|
* will fix the top bit if needed and is a no-op otherwise.
|
||||||
|
*/
|
||||||
|
static inline unsigned long make_addr_canonical_again(unsigned long addr)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
return (long)(addr << 1) >> 1;
|
||||||
|
#else
|
||||||
|
return addr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int change_page_attr_set_clr(unsigned long *addr, int numpages,
|
static int change_page_attr_set_clr(unsigned long *addr, int numpages,
|
||||||
pgprot_t mask_set, pgprot_t mask_clr,
|
pgprot_t mask_set, pgprot_t mask_clr,
|
||||||
int force_split, int in_flag,
|
int force_split, int in_flag,
|
||||||
@@ -1465,7 +1488,7 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
|
|||||||
* Save address for cache flush. *addr is modified in the call
|
* Save address for cache flush. *addr is modified in the call
|
||||||
* to __change_page_attr_set_clr() below.
|
* to __change_page_attr_set_clr() below.
|
||||||
*/
|
*/
|
||||||
baddr = *addr;
|
baddr = make_addr_canonical_again(*addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Must avoid aliasing mappings in the highmem code */
|
/* Must avoid aliasing mappings in the highmem code */
|
||||||
|
@@ -248,7 +248,7 @@ static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address)
|
|||||||
*
|
*
|
||||||
* Returns a pointer to a PTE on success, or NULL on failure.
|
* Returns a pointer to a PTE on success, or NULL on failure.
|
||||||
*/
|
*/
|
||||||
static __init pte_t *pti_user_pagetable_walk_pte(unsigned long address)
|
static pte_t *pti_user_pagetable_walk_pte(unsigned long address)
|
||||||
{
|
{
|
||||||
gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
|
gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO);
|
||||||
pmd_t *pmd;
|
pmd_t *pmd;
|
||||||
|
@@ -305,6 +305,10 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||||||
|
|
||||||
choose_new_asid(next, next_tlb_gen, &new_asid, &need_flush);
|
choose_new_asid(next, next_tlb_gen, &new_asid, &need_flush);
|
||||||
|
|
||||||
|
/* Let nmi_uaccess_okay() know that we're changing CR3. */
|
||||||
|
this_cpu_write(cpu_tlbstate.loaded_mm, LOADED_MM_SWITCHING);
|
||||||
|
barrier();
|
||||||
|
|
||||||
if (need_flush) {
|
if (need_flush) {
|
||||||
this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
|
this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
|
||||||
this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
|
this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
|
||||||
@@ -335,6 +339,9 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
|
|||||||
if (next != &init_mm)
|
if (next != &init_mm)
|
||||||
this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
|
this_cpu_write(cpu_tlbstate.last_ctx_id, next->context.ctx_id);
|
||||||
|
|
||||||
|
/* Make sure we write CR3 before loaded_mm. */
|
||||||
|
barrier();
|
||||||
|
|
||||||
this_cpu_write(cpu_tlbstate.loaded_mm, next);
|
this_cpu_write(cpu_tlbstate.loaded_mm, next);
|
||||||
this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
|
this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid);
|
||||||
}
|
}
|
||||||
|
@@ -85,14 +85,10 @@ pgd_t * __init efi_call_phys_prolog(void)
|
|||||||
|
|
||||||
void __init efi_call_phys_epilog(pgd_t *save_pgd)
|
void __init efi_call_phys_epilog(pgd_t *save_pgd)
|
||||||
{
|
{
|
||||||
struct desc_ptr gdt_descr;
|
|
||||||
|
|
||||||
gdt_descr.address = (unsigned long)get_cpu_gdt_rw(0);
|
|
||||||
gdt_descr.size = GDT_SIZE - 1;
|
|
||||||
load_gdt(&gdt_descr);
|
|
||||||
|
|
||||||
load_cr3(save_pgd);
|
load_cr3(save_pgd);
|
||||||
__flush_tlb_all();
|
__flush_tlb_all();
|
||||||
|
|
||||||
|
load_fixmap_gdt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init efi_runtime_update_mappings(void)
|
void __init efi_runtime_update_mappings(void)
|
||||||
|
@@ -435,14 +435,13 @@ static void xen_set_pud(pud_t *ptr, pud_t val)
|
|||||||
static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
|
static void xen_set_pte_atomic(pte_t *ptep, pte_t pte)
|
||||||
{
|
{
|
||||||
trace_xen_mmu_set_pte_atomic(ptep, pte);
|
trace_xen_mmu_set_pte_atomic(ptep, pte);
|
||||||
set_64bit((u64 *)ptep, native_pte_val(pte));
|
__xen_set_pte(ptep, pte);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
static void xen_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
|
||||||
{
|
{
|
||||||
trace_xen_mmu_pte_clear(mm, addr, ptep);
|
trace_xen_mmu_pte_clear(mm, addr, ptep);
|
||||||
if (!xen_batched_set_pte(ptep, native_make_pte(0)))
|
__xen_set_pte(ptep, native_make_pte(0));
|
||||||
native_pte_clear(mm, addr, ptep);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xen_pmd_clear(pmd_t *pmdp)
|
static void xen_pmd_clear(pmd_t *pmdp)
|
||||||
@@ -1570,7 +1569,7 @@ static void __init xen_set_pte_init(pte_t *ptep, pte_t pte)
|
|||||||
pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
|
pte = __pte_ma(((pte_val_ma(*ptep) & _PAGE_RW) | ~_PAGE_RW) &
|
||||||
pte_val_ma(pte));
|
pte_val_ma(pte));
|
||||||
#endif
|
#endif
|
||||||
native_set_pte(ptep, pte);
|
__xen_set_pte(ptep, pte);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Early in boot, while setting up the initial pagetable, assume
|
/* Early in boot, while setting up the initial pagetable, assume
|
||||||
@@ -2061,7 +2060,6 @@ void __init xen_relocate_p2m(void)
|
|||||||
pud_t *pud;
|
pud_t *pud;
|
||||||
pgd_t *pgd;
|
pgd_t *pgd;
|
||||||
unsigned long *new_p2m;
|
unsigned long *new_p2m;
|
||||||
int save_pud;
|
|
||||||
|
|
||||||
size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
|
size = PAGE_ALIGN(xen_start_info->nr_pages * sizeof(unsigned long));
|
||||||
n_pte = roundup(size, PAGE_SIZE) >> PAGE_SHIFT;
|
n_pte = roundup(size, PAGE_SIZE) >> PAGE_SHIFT;
|
||||||
@@ -2091,7 +2089,6 @@ void __init xen_relocate_p2m(void)
|
|||||||
|
|
||||||
pgd = __va(read_cr3_pa());
|
pgd = __va(read_cr3_pa());
|
||||||
new_p2m = (unsigned long *)(2 * PGDIR_SIZE);
|
new_p2m = (unsigned long *)(2 * PGDIR_SIZE);
|
||||||
save_pud = n_pud;
|
|
||||||
for (idx_pud = 0; idx_pud < n_pud; idx_pud++) {
|
for (idx_pud = 0; idx_pud < n_pud; idx_pud++) {
|
||||||
pud = early_memremap(pud_phys, PAGE_SIZE);
|
pud = early_memremap(pud_phys, PAGE_SIZE);
|
||||||
clear_page(pud);
|
clear_page(pud);
|
||||||
|
@@ -123,16 +123,11 @@ static void rwb_wake_all(struct rq_wb *rwb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
|
static void wbt_rqw_done(struct rq_wb *rwb, struct rq_wait *rqw,
|
||||||
|
enum wbt_flags wb_acct)
|
||||||
{
|
{
|
||||||
struct rq_wb *rwb = RQWB(rqos);
|
|
||||||
struct rq_wait *rqw;
|
|
||||||
int inflight, limit;
|
int inflight, limit;
|
||||||
|
|
||||||
if (!(wb_acct & WBT_TRACKED))
|
|
||||||
return;
|
|
||||||
|
|
||||||
rqw = get_rq_wait(rwb, wb_acct);
|
|
||||||
inflight = atomic_dec_return(&rqw->inflight);
|
inflight = atomic_dec_return(&rqw->inflight);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -166,10 +161,22 @@ static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
|
|||||||
int diff = limit - inflight;
|
int diff = limit - inflight;
|
||||||
|
|
||||||
if (!inflight || diff >= rwb->wb_background / 2)
|
if (!inflight || diff >= rwb->wb_background / 2)
|
||||||
wake_up(&rqw->wait);
|
wake_up_all(&rqw->wait);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __wbt_done(struct rq_qos *rqos, enum wbt_flags wb_acct)
|
||||||
|
{
|
||||||
|
struct rq_wb *rwb = RQWB(rqos);
|
||||||
|
struct rq_wait *rqw;
|
||||||
|
|
||||||
|
if (!(wb_acct & WBT_TRACKED))
|
||||||
|
return;
|
||||||
|
|
||||||
|
rqw = get_rq_wait(rwb, wb_acct);
|
||||||
|
wbt_rqw_done(rwb, rqw, wb_acct);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called on completion of a request. Note that it's also called when
|
* Called on completion of a request. Note that it's also called when
|
||||||
* a request is merged, when the request gets freed.
|
* a request is merged, when the request gets freed.
|
||||||
@@ -481,6 +488,34 @@ static inline unsigned int get_limit(struct rq_wb *rwb, unsigned long rw)
|
|||||||
return limit;
|
return limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wbt_wait_data {
|
||||||
|
struct wait_queue_entry wq;
|
||||||
|
struct task_struct *task;
|
||||||
|
struct rq_wb *rwb;
|
||||||
|
struct rq_wait *rqw;
|
||||||
|
unsigned long rw;
|
||||||
|
bool got_token;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int wbt_wake_function(struct wait_queue_entry *curr, unsigned int mode,
|
||||||
|
int wake_flags, void *key)
|
||||||
|
{
|
||||||
|
struct wbt_wait_data *data = container_of(curr, struct wbt_wait_data,
|
||||||
|
wq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we fail to get a budget, return -1 to interrupt the wake up
|
||||||
|
* loop in __wake_up_common.
|
||||||
|
*/
|
||||||
|
if (!rq_wait_inc_below(data->rqw, get_limit(data->rwb, data->rw)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data->got_token = true;
|
||||||
|
list_del_init(&curr->entry);
|
||||||
|
wake_up_process(data->task);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Block if we will exceed our limit, or if we are currently waiting for
|
* Block if we will exceed our limit, or if we are currently waiting for
|
||||||
* the timer to kick off queuing again.
|
* the timer to kick off queuing again.
|
||||||
@@ -491,31 +526,52 @@ static void __wbt_wait(struct rq_wb *rwb, enum wbt_flags wb_acct,
|
|||||||
__acquires(lock)
|
__acquires(lock)
|
||||||
{
|
{
|
||||||
struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
|
struct rq_wait *rqw = get_rq_wait(rwb, wb_acct);
|
||||||
DECLARE_WAITQUEUE(wait, current);
|
struct wbt_wait_data data = {
|
||||||
|
.wq = {
|
||||||
|
.func = wbt_wake_function,
|
||||||
|
.entry = LIST_HEAD_INIT(data.wq.entry),
|
||||||
|
},
|
||||||
|
.task = current,
|
||||||
|
.rwb = rwb,
|
||||||
|
.rqw = rqw,
|
||||||
|
.rw = rw,
|
||||||
|
};
|
||||||
bool has_sleeper;
|
bool has_sleeper;
|
||||||
|
|
||||||
has_sleeper = wq_has_sleeper(&rqw->wait);
|
has_sleeper = wq_has_sleeper(&rqw->wait);
|
||||||
if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
|
if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
add_wait_queue_exclusive(&rqw->wait, &wait);
|
prepare_to_wait_exclusive(&rqw->wait, &data.wq, TASK_UNINTERRUPTIBLE);
|
||||||
do {
|
do {
|
||||||
set_current_state(TASK_UNINTERRUPTIBLE);
|
if (data.got_token)
|
||||||
|
|
||||||
if (!has_sleeper && rq_wait_inc_below(rqw, get_limit(rwb, rw)))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!has_sleeper &&
|
||||||
|
rq_wait_inc_below(rqw, get_limit(rwb, rw))) {
|
||||||
|
finish_wait(&rqw->wait, &data.wq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We raced with wbt_wake_function() getting a token,
|
||||||
|
* which means we now have two. Put our local token
|
||||||
|
* and wake anyone else potentially waiting for one.
|
||||||
|
*/
|
||||||
|
if (data.got_token)
|
||||||
|
wbt_rqw_done(rwb, rqw, wb_acct);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (lock) {
|
if (lock) {
|
||||||
spin_unlock_irq(lock);
|
spin_unlock_irq(lock);
|
||||||
io_schedule();
|
io_schedule();
|
||||||
spin_lock_irq(lock);
|
spin_lock_irq(lock);
|
||||||
} else
|
} else
|
||||||
io_schedule();
|
io_schedule();
|
||||||
|
|
||||||
has_sleeper = false;
|
has_sleeper = false;
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
__set_current_state(TASK_RUNNING);
|
finish_wait(&rqw->wait, &data.wq);
|
||||||
remove_wait_queue(&rqw->wait, &wait);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
|
static inline bool wbt_should_throttle(struct rq_wb *rwb, struct bio *bio)
|
||||||
@@ -580,11 +636,6 @@ static void wbt_wait(struct rq_qos *rqos, struct bio *bio, spinlock_t *lock)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_is_kswapd())
|
|
||||||
flags |= WBT_KSWAPD;
|
|
||||||
if (bio_op(bio) == REQ_OP_DISCARD)
|
|
||||||
flags |= WBT_DISCARD;
|
|
||||||
|
|
||||||
__wbt_wait(rwb, flags, bio->bi_opf, lock);
|
__wbt_wait(rwb, flags, bio->bi_opf, lock);
|
||||||
|
|
||||||
if (!blk_stat_is_active(rwb->cb))
|
if (!blk_stat_is_active(rwb->cb))
|
||||||
|
@@ -37,7 +37,7 @@ struct bsg_device {
|
|||||||
struct request_queue *queue;
|
struct request_queue *queue;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct hlist_node dev_list;
|
struct hlist_node dev_list;
|
||||||
atomic_t ref_count;
|
refcount_t ref_count;
|
||||||
char name[20];
|
char name[20];
|
||||||
int max_queue;
|
int max_queue;
|
||||||
};
|
};
|
||||||
@@ -252,7 +252,7 @@ static int bsg_put_device(struct bsg_device *bd)
|
|||||||
|
|
||||||
mutex_lock(&bsg_mutex);
|
mutex_lock(&bsg_mutex);
|
||||||
|
|
||||||
if (!atomic_dec_and_test(&bd->ref_count)) {
|
if (!refcount_dec_and_test(&bd->ref_count)) {
|
||||||
mutex_unlock(&bsg_mutex);
|
mutex_unlock(&bsg_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
|
|||||||
|
|
||||||
bd->queue = rq;
|
bd->queue = rq;
|
||||||
|
|
||||||
atomic_set(&bd->ref_count, 1);
|
refcount_set(&bd->ref_count, 1);
|
||||||
hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
|
hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
|
||||||
|
|
||||||
strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
|
strncpy(bd->name, dev_name(rq->bsg_dev.class_dev), sizeof(bd->name) - 1);
|
||||||
@@ -308,7 +308,7 @@ static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
|
|||||||
|
|
||||||
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
|
hlist_for_each_entry(bd, bsg_dev_idx_hash(minor), dev_list) {
|
||||||
if (bd->queue == q) {
|
if (bd->queue == q) {
|
||||||
atomic_inc(&bd->ref_count);
|
refcount_inc(&bd->ref_count);
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -895,8 +895,7 @@ int elv_register(struct elevator_type *e)
|
|||||||
spin_lock(&elv_list_lock);
|
spin_lock(&elv_list_lock);
|
||||||
if (elevator_find(e->elevator_name, e->uses_mq)) {
|
if (elevator_find(e->elevator_name, e->uses_mq)) {
|
||||||
spin_unlock(&elv_list_lock);
|
spin_unlock(&elv_list_lock);
|
||||||
if (e->icq_cache)
|
kmem_cache_destroy(e->icq_cache);
|
||||||
kmem_cache_destroy(e->icq_cache);
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
list_add_tail(&e->list, &elv_list);
|
list_add_tail(&e->list, &elv_list);
|
||||||
|
@@ -256,14 +256,12 @@ static struct ata_port_operations pata_ftide010_port_ops = {
|
|||||||
.qc_issue = ftide010_qc_issue,
|
.qc_issue = ftide010_qc_issue,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ata_port_info ftide010_port_info[] = {
|
static struct ata_port_info ftide010_port_info = {
|
||||||
{
|
.flags = ATA_FLAG_SLAVE_POSS,
|
||||||
.flags = ATA_FLAG_SLAVE_POSS,
|
.mwdma_mask = ATA_MWDMA2,
|
||||||
.mwdma_mask = ATA_MWDMA2,
|
.udma_mask = ATA_UDMA6,
|
||||||
.udma_mask = ATA_UDMA6,
|
.pio_mask = ATA_PIO4,
|
||||||
.pio_mask = ATA_PIO4,
|
.port_ops = &pata_ftide010_port_ops,
|
||||||
.port_ops = &pata_ftide010_port_ops,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_SATA_GEMINI)
|
#if IS_ENABLED(CONFIG_SATA_GEMINI)
|
||||||
@@ -349,6 +347,7 @@ static int pata_ftide010_gemini_cable_detect(struct ata_port *ap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
||||||
|
struct ata_port_info *pi,
|
||||||
bool is_ata1)
|
bool is_ata1)
|
||||||
{
|
{
|
||||||
struct device *dev = ftide->dev;
|
struct device *dev = ftide->dev;
|
||||||
@@ -373,7 +372,13 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
|||||||
|
|
||||||
/* Flag port as SATA-capable */
|
/* Flag port as SATA-capable */
|
||||||
if (gemini_sata_bridge_enabled(sg, is_ata1))
|
if (gemini_sata_bridge_enabled(sg, is_ata1))
|
||||||
ftide010_port_info[0].flags |= ATA_FLAG_SATA;
|
pi->flags |= ATA_FLAG_SATA;
|
||||||
|
|
||||||
|
/* This device has broken DMA, only PIO works */
|
||||||
|
if (of_machine_is_compatible("itian,sq201")) {
|
||||||
|
pi->mwdma_mask = 0;
|
||||||
|
pi->udma_mask = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We assume that a simple 40-wire cable is used in the PATA mode.
|
* We assume that a simple 40-wire cable is used in the PATA mode.
|
||||||
@@ -435,6 +440,7 @@ static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
static int pata_ftide010_gemini_init(struct ftide010 *ftide,
|
||||||
|
struct ata_port_info *pi,
|
||||||
bool is_ata1)
|
bool is_ata1)
|
||||||
{
|
{
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
@@ -446,7 +452,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
const struct ata_port_info pi = ftide010_port_info[0];
|
struct ata_port_info pi = ftide010_port_info;
|
||||||
const struct ata_port_info *ppi[] = { &pi, NULL };
|
const struct ata_port_info *ppi[] = { &pi, NULL };
|
||||||
struct ftide010 *ftide;
|
struct ftide010 *ftide;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
@@ -490,6 +496,7 @@ static int pata_ftide010_probe(struct platform_device *pdev)
|
|||||||
* are ATA0. This will also set up the cable types.
|
* are ATA0. This will also set up the cable types.
|
||||||
*/
|
*/
|
||||||
ret = pata_ftide010_gemini_init(ftide,
|
ret = pata_ftide010_gemini_init(ftide,
|
||||||
|
&pi,
|
||||||
(res->start == 0x63400000));
|
(res->start == 0x63400000));
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_dis_clk;
|
goto err_dis_clk;
|
||||||
|
@@ -185,7 +185,7 @@ EXPORT_SYMBOL_GPL(of_pm_clk_add_clk);
|
|||||||
int of_pm_clk_add_clks(struct device *dev)
|
int of_pm_clk_add_clks(struct device *dev)
|
||||||
{
|
{
|
||||||
struct clk **clks;
|
struct clk **clks;
|
||||||
unsigned int i, count;
|
int i, count;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!dev || !dev->of_node)
|
if (!dev || !dev->of_node)
|
||||||
|
@@ -83,6 +83,18 @@ module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
|
|||||||
MODULE_PARM_DESC(max_persistent_grants,
|
MODULE_PARM_DESC(max_persistent_grants,
|
||||||
"Maximum number of grants to map persistently");
|
"Maximum number of grants to map persistently");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* How long a persistent grant is allowed to remain allocated without being in
|
||||||
|
* use. The time is in seconds, 0 means indefinitely long.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned int xen_blkif_pgrant_timeout = 60;
|
||||||
|
module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
|
||||||
|
uint, 0644);
|
||||||
|
MODULE_PARM_DESC(persistent_grant_unused_seconds,
|
||||||
|
"Time in seconds an unused persistent grant is allowed to "
|
||||||
|
"remain allocated. Default is 60, 0 means unlimited.");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum number of rings/queues blkback supports, allow as many queues as there
|
* Maximum number of rings/queues blkback supports, allow as many queues as there
|
||||||
* are CPUs if user has not specified a value.
|
* are CPUs if user has not specified a value.
|
||||||
@@ -123,6 +135,13 @@ module_param(log_stats, int, 0644);
|
|||||||
/* Number of free pages to remove on each call to gnttab_free_pages */
|
/* Number of free pages to remove on each call to gnttab_free_pages */
|
||||||
#define NUM_BATCH_FREE_PAGES 10
|
#define NUM_BATCH_FREE_PAGES 10
|
||||||
|
|
||||||
|
static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
|
||||||
|
{
|
||||||
|
return xen_blkif_pgrant_timeout &&
|
||||||
|
(jiffies - persistent_gnt->last_used >=
|
||||||
|
HZ * xen_blkif_pgrant_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
|
static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
@@ -236,8 +255,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bitmap_zero(persistent_gnt->flags, PERSISTENT_GNT_FLAGS_SIZE);
|
persistent_gnt->active = true;
|
||||||
set_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
|
|
||||||
/* Add new node and rebalance tree. */
|
/* Add new node and rebalance tree. */
|
||||||
rb_link_node(&(persistent_gnt->node), parent, new);
|
rb_link_node(&(persistent_gnt->node), parent, new);
|
||||||
rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
|
rb_insert_color(&(persistent_gnt->node), &ring->persistent_gnts);
|
||||||
@@ -261,11 +279,11 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
|
|||||||
else if (gref > data->gnt)
|
else if (gref > data->gnt)
|
||||||
node = node->rb_right;
|
node = node->rb_right;
|
||||||
else {
|
else {
|
||||||
if(test_bit(PERSISTENT_GNT_ACTIVE, data->flags)) {
|
if (data->active) {
|
||||||
pr_alert_ratelimited("requesting a grant already in use\n");
|
pr_alert_ratelimited("requesting a grant already in use\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
set_bit(PERSISTENT_GNT_ACTIVE, data->flags);
|
data->active = true;
|
||||||
atomic_inc(&ring->persistent_gnt_in_use);
|
atomic_inc(&ring->persistent_gnt_in_use);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
@@ -276,10 +294,10 @@ static struct persistent_gnt *get_persistent_gnt(struct xen_blkif_ring *ring,
|
|||||||
static void put_persistent_gnt(struct xen_blkif_ring *ring,
|
static void put_persistent_gnt(struct xen_blkif_ring *ring,
|
||||||
struct persistent_gnt *persistent_gnt)
|
struct persistent_gnt *persistent_gnt)
|
||||||
{
|
{
|
||||||
if(!test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
|
if (!persistent_gnt->active)
|
||||||
pr_alert_ratelimited("freeing a grant already unused\n");
|
pr_alert_ratelimited("freeing a grant already unused\n");
|
||||||
set_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
|
persistent_gnt->last_used = jiffies;
|
||||||
clear_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags);
|
persistent_gnt->active = false;
|
||||||
atomic_dec(&ring->persistent_gnt_in_use);
|
atomic_dec(&ring->persistent_gnt_in_use);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,26 +389,26 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
|
|||||||
struct persistent_gnt *persistent_gnt;
|
struct persistent_gnt *persistent_gnt;
|
||||||
struct rb_node *n;
|
struct rb_node *n;
|
||||||
unsigned int num_clean, total;
|
unsigned int num_clean, total;
|
||||||
bool scan_used = false, clean_used = false;
|
bool scan_used = false;
|
||||||
struct rb_root *root;
|
struct rb_root *root;
|
||||||
|
|
||||||
if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
|
|
||||||
(ring->persistent_gnt_c == xen_blkif_max_pgrants &&
|
|
||||||
!ring->blkif->vbd.overflow_max_grants)) {
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (work_busy(&ring->persistent_purge_work)) {
|
if (work_busy(&ring->persistent_purge_work)) {
|
||||||
pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
|
pr_alert_ratelimited("Scheduled work from previous purge is still busy, cannot purge list\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
|
if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
|
||||||
num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants + num_clean;
|
(ring->persistent_gnt_c == xen_blkif_max_pgrants &&
|
||||||
num_clean = min(ring->persistent_gnt_c, num_clean);
|
!ring->blkif->vbd.overflow_max_grants)) {
|
||||||
if ((num_clean == 0) ||
|
num_clean = 0;
|
||||||
(num_clean > (ring->persistent_gnt_c - atomic_read(&ring->persistent_gnt_in_use))))
|
} else {
|
||||||
goto out;
|
num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
|
||||||
|
num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
|
||||||
|
num_clean;
|
||||||
|
num_clean = min(ring->persistent_gnt_c, num_clean);
|
||||||
|
pr_debug("Going to purge at least %u persistent grants\n",
|
||||||
|
num_clean);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At this point, we can assure that there will be no calls
|
* At this point, we can assure that there will be no calls
|
||||||
@@ -401,9 +419,7 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
|
|||||||
* number of grants.
|
* number of grants.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
total = num_clean;
|
total = 0;
|
||||||
|
|
||||||
pr_debug("Going to purge %u persistent grants\n", num_clean);
|
|
||||||
|
|
||||||
BUG_ON(!list_empty(&ring->persistent_purge_list));
|
BUG_ON(!list_empty(&ring->persistent_purge_list));
|
||||||
root = &ring->persistent_gnts;
|
root = &ring->persistent_gnts;
|
||||||
@@ -412,47 +428,38 @@ purge_list:
|
|||||||
BUG_ON(persistent_gnt->handle ==
|
BUG_ON(persistent_gnt->handle ==
|
||||||
BLKBACK_INVALID_HANDLE);
|
BLKBACK_INVALID_HANDLE);
|
||||||
|
|
||||||
if (clean_used) {
|
if (persistent_gnt->active)
|
||||||
clear_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (!scan_used && !persistent_gnt_timeout(persistent_gnt))
|
||||||
|
|
||||||
if (test_bit(PERSISTENT_GNT_ACTIVE, persistent_gnt->flags))
|
|
||||||
continue;
|
continue;
|
||||||
if (!scan_used &&
|
if (scan_used && total >= num_clean)
|
||||||
(test_bit(PERSISTENT_GNT_WAS_ACTIVE, persistent_gnt->flags)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
rb_erase(&persistent_gnt->node, root);
|
rb_erase(&persistent_gnt->node, root);
|
||||||
list_add(&persistent_gnt->remove_node,
|
list_add(&persistent_gnt->remove_node,
|
||||||
&ring->persistent_purge_list);
|
&ring->persistent_purge_list);
|
||||||
if (--num_clean == 0)
|
total++;
|
||||||
goto finished;
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If we get here it means we also need to start cleaning
|
* Check whether we also need to start cleaning
|
||||||
* grants that were used since last purge in order to cope
|
* grants that were used since last purge in order to cope
|
||||||
* with the requested num
|
* with the requested num
|
||||||
*/
|
*/
|
||||||
if (!scan_used && !clean_used) {
|
if (!scan_used && total < num_clean) {
|
||||||
pr_debug("Still missing %u purged frames\n", num_clean);
|
pr_debug("Still missing %u purged frames\n", num_clean - total);
|
||||||
scan_used = true;
|
scan_used = true;
|
||||||
goto purge_list;
|
goto purge_list;
|
||||||
}
|
}
|
||||||
finished:
|
|
||||||
if (!clean_used) {
|
if (total) {
|
||||||
pr_debug("Finished scanning for grants to clean, removing used flag\n");
|
ring->persistent_gnt_c -= total;
|
||||||
clean_used = true;
|
ring->blkif->vbd.overflow_max_grants = 0;
|
||||||
goto purge_list;
|
|
||||||
|
/* We can defer this work */
|
||||||
|
schedule_work(&ring->persistent_purge_work);
|
||||||
|
pr_debug("Purged %u/%u\n", num_clean, total);
|
||||||
}
|
}
|
||||||
|
|
||||||
ring->persistent_gnt_c -= (total - num_clean);
|
|
||||||
ring->blkif->vbd.overflow_max_grants = 0;
|
|
||||||
|
|
||||||
/* We can defer this work */
|
|
||||||
schedule_work(&ring->persistent_purge_work);
|
|
||||||
pr_debug("Purged %u/%u\n", (total - num_clean), total);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -233,16 +233,6 @@ struct xen_vbd {
|
|||||||
|
|
||||||
struct backend_info;
|
struct backend_info;
|
||||||
|
|
||||||
/* Number of available flags */
|
|
||||||
#define PERSISTENT_GNT_FLAGS_SIZE 2
|
|
||||||
/* This persistent grant is currently in use */
|
|
||||||
#define PERSISTENT_GNT_ACTIVE 0
|
|
||||||
/*
|
|
||||||
* This persistent grant has been used, this flag is set when we remove the
|
|
||||||
* PERSISTENT_GNT_ACTIVE, to know that this grant has been used recently.
|
|
||||||
*/
|
|
||||||
#define PERSISTENT_GNT_WAS_ACTIVE 1
|
|
||||||
|
|
||||||
/* Number of requests that we can fit in a ring */
|
/* Number of requests that we can fit in a ring */
|
||||||
#define XEN_BLKIF_REQS_PER_PAGE 32
|
#define XEN_BLKIF_REQS_PER_PAGE 32
|
||||||
|
|
||||||
@@ -250,7 +240,8 @@ struct persistent_gnt {
|
|||||||
struct page *page;
|
struct page *page;
|
||||||
grant_ref_t gnt;
|
grant_ref_t gnt;
|
||||||
grant_handle_t handle;
|
grant_handle_t handle;
|
||||||
DECLARE_BITMAP(flags, PERSISTENT_GNT_FLAGS_SIZE);
|
unsigned long last_used;
|
||||||
|
bool active;
|
||||||
struct rb_node node;
|
struct rb_node node;
|
||||||
struct list_head remove_node;
|
struct list_head remove_node;
|
||||||
};
|
};
|
||||||
@@ -278,7 +269,6 @@ struct xen_blkif_ring {
|
|||||||
wait_queue_head_t pending_free_wq;
|
wait_queue_head_t pending_free_wq;
|
||||||
|
|
||||||
/* Tree to store persistent grants. */
|
/* Tree to store persistent grants. */
|
||||||
spinlock_t pers_gnts_lock;
|
|
||||||
struct rb_root persistent_gnts;
|
struct rb_root persistent_gnts;
|
||||||
unsigned int persistent_gnt_c;
|
unsigned int persistent_gnt_c;
|
||||||
atomic_t persistent_gnt_in_use;
|
atomic_t persistent_gnt_in_use;
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
|
#include <linux/workqueue.h>
|
||||||
|
|
||||||
#include <xen/xen.h>
|
#include <xen/xen.h>
|
||||||
#include <xen/xenbus.h>
|
#include <xen/xenbus.h>
|
||||||
@@ -121,6 +122,8 @@ static inline struct blkif_req *blkif_req(struct request *rq)
|
|||||||
|
|
||||||
static DEFINE_MUTEX(blkfront_mutex);
|
static DEFINE_MUTEX(blkfront_mutex);
|
||||||
static const struct block_device_operations xlvbd_block_fops;
|
static const struct block_device_operations xlvbd_block_fops;
|
||||||
|
static struct delayed_work blkfront_work;
|
||||||
|
static LIST_HEAD(info_list);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Maximum number of segments in indirect requests, the actual value used by
|
* Maximum number of segments in indirect requests, the actual value used by
|
||||||
@@ -216,6 +219,7 @@ struct blkfront_info
|
|||||||
/* Save uncomplete reqs and bios for migration. */
|
/* Save uncomplete reqs and bios for migration. */
|
||||||
struct list_head requests;
|
struct list_head requests;
|
||||||
struct bio_list bio_list;
|
struct bio_list bio_list;
|
||||||
|
struct list_head info_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int nr_minors;
|
static unsigned int nr_minors;
|
||||||
@@ -1759,6 +1763,12 @@ abort_transaction:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void free_info(struct blkfront_info *info)
|
||||||
|
{
|
||||||
|
list_del(&info->info_list);
|
||||||
|
kfree(info);
|
||||||
|
}
|
||||||
|
|
||||||
/* Common code used when first setting up, and when resuming. */
|
/* Common code used when first setting up, and when resuming. */
|
||||||
static int talk_to_blkback(struct xenbus_device *dev,
|
static int talk_to_blkback(struct xenbus_device *dev,
|
||||||
struct blkfront_info *info)
|
struct blkfront_info *info)
|
||||||
@@ -1880,7 +1890,10 @@ again:
|
|||||||
destroy_blkring:
|
destroy_blkring:
|
||||||
blkif_free(info, 0);
|
blkif_free(info, 0);
|
||||||
|
|
||||||
kfree(info);
|
mutex_lock(&blkfront_mutex);
|
||||||
|
free_info(info);
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
|
|
||||||
dev_set_drvdata(&dev->dev, NULL);
|
dev_set_drvdata(&dev->dev, NULL);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@@ -1991,6 +2004,10 @@ static int blkfront_probe(struct xenbus_device *dev,
|
|||||||
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
|
info->handle = simple_strtoul(strrchr(dev->nodename, '/')+1, NULL, 0);
|
||||||
dev_set_drvdata(&dev->dev, info);
|
dev_set_drvdata(&dev->dev, info);
|
||||||
|
|
||||||
|
mutex_lock(&blkfront_mutex);
|
||||||
|
list_add(&info->info_list, &info_list);
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2301,6 +2318,12 @@ static void blkfront_gather_backend_features(struct blkfront_info *info)
|
|||||||
if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
|
if (indirect_segments <= BLKIF_MAX_SEGMENTS_PER_REQUEST)
|
||||||
indirect_segments = 0;
|
indirect_segments = 0;
|
||||||
info->max_indirect_segments = indirect_segments;
|
info->max_indirect_segments = indirect_segments;
|
||||||
|
|
||||||
|
if (info->feature_persistent) {
|
||||||
|
mutex_lock(&blkfront_mutex);
|
||||||
|
schedule_delayed_work(&blkfront_work, HZ * 10);
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2482,7 +2505,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
|
|||||||
mutex_unlock(&info->mutex);
|
mutex_unlock(&info->mutex);
|
||||||
|
|
||||||
if (!bdev) {
|
if (!bdev) {
|
||||||
kfree(info);
|
mutex_lock(&blkfront_mutex);
|
||||||
|
free_info(info);
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2502,7 +2527,9 @@ static int blkfront_remove(struct xenbus_device *xbdev)
|
|||||||
if (info && !bdev->bd_openers) {
|
if (info && !bdev->bd_openers) {
|
||||||
xlvbd_release_gendisk(info);
|
xlvbd_release_gendisk(info);
|
||||||
disk->private_data = NULL;
|
disk->private_data = NULL;
|
||||||
kfree(info);
|
mutex_lock(&blkfront_mutex);
|
||||||
|
free_info(info);
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&bdev->bd_mutex);
|
mutex_unlock(&bdev->bd_mutex);
|
||||||
@@ -2585,7 +2612,7 @@ static void blkif_release(struct gendisk *disk, fmode_t mode)
|
|||||||
dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
|
dev_info(disk_to_dev(bdev->bd_disk), "releasing disk\n");
|
||||||
xlvbd_release_gendisk(info);
|
xlvbd_release_gendisk(info);
|
||||||
disk->private_data = NULL;
|
disk->private_data = NULL;
|
||||||
kfree(info);
|
free_info(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@@ -2618,6 +2645,61 @@ static struct xenbus_driver blkfront_driver = {
|
|||||||
.is_ready = blkfront_is_ready,
|
.is_ready = blkfront_is_ready,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void purge_persistent_grants(struct blkfront_info *info)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
for (i = 0; i < info->nr_rings; i++) {
|
||||||
|
struct blkfront_ring_info *rinfo = &info->rinfo[i];
|
||||||
|
struct grant *gnt_list_entry, *tmp;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&rinfo->ring_lock, flags);
|
||||||
|
|
||||||
|
if (rinfo->persistent_gnts_c == 0) {
|
||||||
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_for_each_entry_safe(gnt_list_entry, tmp, &rinfo->grants,
|
||||||
|
node) {
|
||||||
|
if (gnt_list_entry->gref == GRANT_INVALID_REF ||
|
||||||
|
gnttab_query_foreign_access(gnt_list_entry->gref))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
list_del(&gnt_list_entry->node);
|
||||||
|
gnttab_end_foreign_access(gnt_list_entry->gref, 0, 0UL);
|
||||||
|
rinfo->persistent_gnts_c--;
|
||||||
|
__free_page(gnt_list_entry->page);
|
||||||
|
kfree(gnt_list_entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&rinfo->ring_lock, flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blkfront_delay_work(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct blkfront_info *info;
|
||||||
|
bool need_schedule_work = false;
|
||||||
|
|
||||||
|
mutex_lock(&blkfront_mutex);
|
||||||
|
|
||||||
|
list_for_each_entry(info, &info_list, info_list) {
|
||||||
|
if (info->feature_persistent) {
|
||||||
|
need_schedule_work = true;
|
||||||
|
mutex_lock(&info->mutex);
|
||||||
|
purge_persistent_grants(info);
|
||||||
|
mutex_unlock(&info->mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (need_schedule_work)
|
||||||
|
schedule_delayed_work(&blkfront_work, HZ * 10);
|
||||||
|
|
||||||
|
mutex_unlock(&blkfront_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
static int __init xlblk_init(void)
|
static int __init xlblk_init(void)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@@ -2626,6 +2708,15 @@ static int __init xlblk_init(void)
|
|||||||
if (!xen_domain())
|
if (!xen_domain())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (!xen_has_pv_disk_devices())
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
|
||||||
|
pr_warn("xen_blk: can't get major %d with name %s\n",
|
||||||
|
XENVBD_MAJOR, DEV_NAME);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
|
if (xen_blkif_max_segments < BLKIF_MAX_SEGMENTS_PER_REQUEST)
|
||||||
xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
|
xen_blkif_max_segments = BLKIF_MAX_SEGMENTS_PER_REQUEST;
|
||||||
|
|
||||||
@@ -2641,14 +2732,7 @@ static int __init xlblk_init(void)
|
|||||||
xen_blkif_max_queues = nr_cpus;
|
xen_blkif_max_queues = nr_cpus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!xen_has_pv_disk_devices())
|
INIT_DELAYED_WORK(&blkfront_work, blkfront_delay_work);
|
||||||
return -ENODEV;
|
|
||||||
|
|
||||||
if (register_blkdev(XENVBD_MAJOR, DEV_NAME)) {
|
|
||||||
printk(KERN_WARNING "xen_blk: can't get major %d with name %s\n",
|
|
||||||
XENVBD_MAJOR, DEV_NAME);
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = xenbus_register_frontend(&blkfront_driver);
|
ret = xenbus_register_frontend(&blkfront_driver);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@@ -2663,6 +2747,8 @@ module_init(xlblk_init);
|
|||||||
|
|
||||||
static void __exit xlblk_exit(void)
|
static void __exit xlblk_exit(void)
|
||||||
{
|
{
|
||||||
|
cancel_delayed_work_sync(&blkfront_work);
|
||||||
|
|
||||||
xenbus_unregister_driver(&blkfront_driver);
|
xenbus_unregister_driver(&blkfront_driver);
|
||||||
unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
|
unregister_blkdev(XENVBD_MAJOR, DEV_NAME);
|
||||||
kfree(minors);
|
kfree(minors);
|
||||||
|
@@ -200,6 +200,7 @@ config BT_HCIUART_RTL
|
|||||||
depends on BT_HCIUART
|
depends on BT_HCIUART
|
||||||
depends on BT_HCIUART_SERDEV
|
depends on BT_HCIUART_SERDEV
|
||||||
depends on GPIOLIB
|
depends on GPIOLIB
|
||||||
|
depends on ACPI
|
||||||
select BT_HCIUART_3WIRE
|
select BT_HCIUART_3WIRE
|
||||||
select BT_RTL
|
select BT_RTL
|
||||||
help
|
help
|
||||||
|
@@ -144,8 +144,10 @@ static int mtk_setup_fw(struct hci_dev *hdev)
|
|||||||
fw_size = fw->size;
|
fw_size = fw->size;
|
||||||
|
|
||||||
/* The size of patch header is 30 bytes, should be skip */
|
/* The size of patch header is 30 bytes, should be skip */
|
||||||
if (fw_size < 30)
|
if (fw_size < 30) {
|
||||||
return -EINVAL;
|
err = -EINVAL;
|
||||||
|
goto free_fw;
|
||||||
|
}
|
||||||
|
|
||||||
fw_size -= 30;
|
fw_size -= 30;
|
||||||
fw_ptr += 30;
|
fw_ptr += 30;
|
||||||
@@ -172,8 +174,8 @@ static int mtk_setup_fw(struct hci_dev *hdev)
|
|||||||
fw_ptr += dlen;
|
fw_ptr += dlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_fw:
|
||||||
release_firmware(fw);
|
release_firmware(fw);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -498,32 +498,29 @@ static int sysc_check_registers(struct sysc *ddata)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* syc_ioremap - ioremap register space for the interconnect target module
|
* syc_ioremap - ioremap register space for the interconnect target module
|
||||||
* @ddata: deviec driver data
|
* @ddata: device driver data
|
||||||
*
|
*
|
||||||
* Note that the interconnect target module registers can be anywhere
|
* Note that the interconnect target module registers can be anywhere
|
||||||
* within the first child device address space. For example, SGX has
|
* within the interconnect target module range. For example, SGX has
|
||||||
* them at offset 0x1fc00 in the 32MB module address space. We just
|
* them at offset 0x1fc00 in the 32MB module address space. And cpsw
|
||||||
* what we need around the interconnect target module registers.
|
* has them at offset 0x1200 in the CPSW_WR child. Usually the
|
||||||
|
* the interconnect target module registers are at the beginning of
|
||||||
|
* the module range though.
|
||||||
*/
|
*/
|
||||||
static int sysc_ioremap(struct sysc *ddata)
|
static int sysc_ioremap(struct sysc *ddata)
|
||||||
{
|
{
|
||||||
u32 size = 0;
|
int size;
|
||||||
|
|
||||||
if (ddata->offsets[SYSC_SYSSTATUS] >= 0)
|
size = max3(ddata->offsets[SYSC_REVISION],
|
||||||
size = ddata->offsets[SYSC_SYSSTATUS];
|
ddata->offsets[SYSC_SYSCONFIG],
|
||||||
else if (ddata->offsets[SYSC_SYSCONFIG] >= 0)
|
ddata->offsets[SYSC_SYSSTATUS]);
|
||||||
size = ddata->offsets[SYSC_SYSCONFIG];
|
|
||||||
else if (ddata->offsets[SYSC_REVISION] >= 0)
|
if (size < 0 || (size + sizeof(u32)) > ddata->module_size)
|
||||||
size = ddata->offsets[SYSC_REVISION];
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
size &= 0xfff00;
|
|
||||||
size += SZ_256;
|
|
||||||
|
|
||||||
ddata->module_va = devm_ioremap(ddata->dev,
|
ddata->module_va = devm_ioremap(ddata->dev,
|
||||||
ddata->module_pa,
|
ddata->module_pa,
|
||||||
size);
|
size + sizeof(u32));
|
||||||
if (!ddata->module_va)
|
if (!ddata->module_va)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
@@ -1224,10 +1221,10 @@ static int sysc_child_suspend_noirq(struct device *dev)
|
|||||||
if (!pm_runtime_status_suspended(dev)) {
|
if (!pm_runtime_status_suspended(dev)) {
|
||||||
error = pm_generic_runtime_suspend(dev);
|
error = pm_generic_runtime_suspend(dev);
|
||||||
if (error) {
|
if (error) {
|
||||||
dev_err(dev, "%s error at %i: %i\n",
|
dev_warn(dev, "%s busy at %i: %i\n",
|
||||||
__func__, __LINE__, error);
|
__func__, __LINE__, error);
|
||||||
|
|
||||||
return error;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = sysc_runtime_suspend(ddata->dev);
|
error = sysc_runtime_suspend(ddata->dev);
|
||||||
|
@@ -2546,7 +2546,7 @@ static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
|
|||||||
if (!CDROM_CAN(CDC_SELECT_DISC) ||
|
if (!CDROM_CAN(CDC_SELECT_DISC) ||
|
||||||
(arg == CDSL_CURRENT || arg == CDSL_NONE))
|
(arg == CDSL_CURRENT || arg == CDSL_NONE))
|
||||||
return cdi->ops->drive_status(cdi, CDSL_CURRENT);
|
return cdi->ops->drive_status(cdi, CDSL_CURRENT);
|
||||||
if (((int)arg >= cdi->capacity))
|
if (arg >= cdi->capacity)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
return cdrom_slot_status(cdi, arg);
|
return cdrom_slot_status(cdi, arg);
|
||||||
}
|
}
|
||||||
|
@@ -558,8 +558,8 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
|
|||||||
if (!clk_base)
|
if (!clk_base)
|
||||||
goto npcm7xx_init_error;
|
goto npcm7xx_init_error;
|
||||||
|
|
||||||
npcm7xx_clk_data = kzalloc(sizeof(*npcm7xx_clk_data->hws) *
|
npcm7xx_clk_data = kzalloc(struct_size(npcm7xx_clk_data, hws,
|
||||||
NPCM7XX_NUM_CLOCKS + sizeof(npcm7xx_clk_data), GFP_KERNEL);
|
NPCM7XX_NUM_CLOCKS), GFP_KERNEL);
|
||||||
if (!npcm7xx_clk_data)
|
if (!npcm7xx_clk_data)
|
||||||
goto npcm7xx_init_np_err;
|
goto npcm7xx_init_np_err;
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ static int st_clk_probe(struct platform_device *pdev)
|
|||||||
clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
|
clk_oscout1_parents, ARRAY_SIZE(clk_oscout1_parents),
|
||||||
0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
|
0, st_data->base + CLKDRVSTR2, OSCOUT1CLK25MHZ, 3, 0, NULL);
|
||||||
|
|
||||||
clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_25M]->clk);
|
clk_set_parent(hws[ST_CLK_MUX]->clk, hws[ST_CLK_48M]->clk);
|
||||||
|
|
||||||
hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
|
hws[ST_CLK_GATE] = clk_hw_register_gate(NULL, "oscout1", "oscout1_mux",
|
||||||
0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
|
0, st_data->base + MISCCLKCNTL1, OSCCLKENB,
|
||||||
|
@@ -379,9 +379,20 @@ static int menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
|
|||||||
if (idx == -1)
|
if (idx == -1)
|
||||||
idx = i; /* first enabled state */
|
idx = i; /* first enabled state */
|
||||||
if (s->target_residency > data->predicted_us) {
|
if (s->target_residency > data->predicted_us) {
|
||||||
if (!tick_nohz_tick_stopped())
|
if (data->predicted_us < TICK_USEC)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if (!tick_nohz_tick_stopped()) {
|
||||||
|
/*
|
||||||
|
* If the state selected so far is shallow,
|
||||||
|
* waking up early won't hurt, so retain the
|
||||||
|
* tick in that case and let the governor run
|
||||||
|
* again in the next iteration of the loop.
|
||||||
|
*/
|
||||||
|
expected_interval = drv->states[idx].target_residency;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the state selected so far is shallow and this
|
* If the state selected so far is shallow and this
|
||||||
* state's target residency matches the time till the
|
* state's target residency matches the time till the
|
||||||
|
@@ -679,10 +679,8 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) {
|
if (keylen != 2 * AES_MIN_KEY_SIZE && keylen != 2 * AES_MAX_KEY_SIZE) {
|
||||||
crypto_ablkcipher_set_flags(ablkcipher,
|
|
||||||
CRYPTO_TFM_RES_BAD_KEY_LEN);
|
|
||||||
dev_err(jrdev, "key size mismatch\n");
|
dev_err(jrdev, "key size mismatch\n");
|
||||||
return -EINVAL;
|
goto badkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->cdata.keylen = keylen;
|
ctx->cdata.keylen = keylen;
|
||||||
@@ -715,7 +713,7 @@ static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
|
|||||||
return ret;
|
return ret;
|
||||||
badkey:
|
badkey:
|
||||||
crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
crypto_ablkcipher_set_flags(ablkcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -71,8 +71,8 @@ static void rsa_priv_f2_unmap(struct device *dev, struct rsa_edesc *edesc,
|
|||||||
dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->d_dma, key->d_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->p_dma, p_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
|
||||||
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
|
static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
|
||||||
@@ -90,8 +90,8 @@ static void rsa_priv_f3_unmap(struct device *dev, struct rsa_edesc *edesc,
|
|||||||
dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->dp_dma, p_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->dq_dma, q_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
|
||||||
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
|
||||||
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp2_dma, q_sz, DMA_BIDIRECTIONAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* RSA Job Completion handler */
|
/* RSA Job Completion handler */
|
||||||
@@ -417,13 +417,13 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
|
|||||||
goto unmap_p;
|
goto unmap_p;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
|
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
|
||||||
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
|
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
|
||||||
dev_err(dev, "Unable to map RSA tmp1 memory\n");
|
dev_err(dev, "Unable to map RSA tmp1 memory\n");
|
||||||
goto unmap_q;
|
goto unmap_q;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
|
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
|
||||||
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
|
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
|
||||||
dev_err(dev, "Unable to map RSA tmp2 memory\n");
|
dev_err(dev, "Unable to map RSA tmp2 memory\n");
|
||||||
goto unmap_tmp1;
|
goto unmap_tmp1;
|
||||||
@@ -451,7 +451,7 @@ static int set_rsa_priv_f2_pdb(struct akcipher_request *req,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unmap_tmp1:
|
unmap_tmp1:
|
||||||
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
|
||||||
unmap_q:
|
unmap_q:
|
||||||
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->q_dma, q_sz, DMA_TO_DEVICE);
|
||||||
unmap_p:
|
unmap_p:
|
||||||
@@ -504,13 +504,13 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
|
|||||||
goto unmap_dq;
|
goto unmap_dq;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_TO_DEVICE);
|
pdb->tmp1_dma = dma_map_single(dev, key->tmp1, p_sz, DMA_BIDIRECTIONAL);
|
||||||
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
|
if (dma_mapping_error(dev, pdb->tmp1_dma)) {
|
||||||
dev_err(dev, "Unable to map RSA tmp1 memory\n");
|
dev_err(dev, "Unable to map RSA tmp1 memory\n");
|
||||||
goto unmap_qinv;
|
goto unmap_qinv;
|
||||||
}
|
}
|
||||||
|
|
||||||
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_TO_DEVICE);
|
pdb->tmp2_dma = dma_map_single(dev, key->tmp2, q_sz, DMA_BIDIRECTIONAL);
|
||||||
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
|
if (dma_mapping_error(dev, pdb->tmp2_dma)) {
|
||||||
dev_err(dev, "Unable to map RSA tmp2 memory\n");
|
dev_err(dev, "Unable to map RSA tmp2 memory\n");
|
||||||
goto unmap_tmp1;
|
goto unmap_tmp1;
|
||||||
@@ -538,7 +538,7 @@ static int set_rsa_priv_f3_pdb(struct akcipher_request *req,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unmap_tmp1:
|
unmap_tmp1:
|
||||||
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->tmp1_dma, p_sz, DMA_BIDIRECTIONAL);
|
||||||
unmap_qinv:
|
unmap_qinv:
|
||||||
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
|
dma_unmap_single(dev, pdb->c_dma, p_sz, DMA_TO_DEVICE);
|
||||||
unmap_dq:
|
unmap_dq:
|
||||||
|
@@ -190,7 +190,8 @@ static void caam_jr_dequeue(unsigned long devarg)
|
|||||||
BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
|
BUG_ON(CIRC_CNT(head, tail + i, JOBR_DEPTH) <= 0);
|
||||||
|
|
||||||
/* Unmap just-run descriptor so we can post-process */
|
/* Unmap just-run descriptor so we can post-process */
|
||||||
dma_unmap_single(dev, jrp->outring[hw_idx].desc,
|
dma_unmap_single(dev,
|
||||||
|
caam_dma_to_cpu(jrp->outring[hw_idx].desc),
|
||||||
jrp->entinfo[sw_idx].desc_size,
|
jrp->entinfo[sw_idx].desc_size,
|
||||||
DMA_TO_DEVICE);
|
DMA_TO_DEVICE);
|
||||||
|
|
||||||
|
@@ -35,6 +35,7 @@ struct nitrox_cmdq {
|
|||||||
/* requests in backlog queues */
|
/* requests in backlog queues */
|
||||||
atomic_t backlog_count;
|
atomic_t backlog_count;
|
||||||
|
|
||||||
|
int write_idx;
|
||||||
/* command size 32B/64B */
|
/* command size 32B/64B */
|
||||||
u8 instr_size;
|
u8 instr_size;
|
||||||
u8 qno;
|
u8 qno;
|
||||||
@@ -87,7 +88,7 @@ struct nitrox_bh {
|
|||||||
struct bh_data *slc;
|
struct bh_data *slc;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* NITROX-5 driver state */
|
/* NITROX-V driver state */
|
||||||
#define NITROX_UCODE_LOADED 0
|
#define NITROX_UCODE_LOADED 0
|
||||||
#define NITROX_READY 1
|
#define NITROX_READY 1
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ static int cmdq_common_init(struct nitrox_cmdq *cmdq)
|
|||||||
cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
|
cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
|
||||||
cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
|
cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
|
||||||
cmdq->qsize = (qsize + PKT_IN_ALIGN);
|
cmdq->qsize = (qsize + PKT_IN_ALIGN);
|
||||||
|
cmdq->write_idx = 0;
|
||||||
|
|
||||||
spin_lock_init(&cmdq->response_lock);
|
spin_lock_init(&cmdq->response_lock);
|
||||||
spin_lock_init(&cmdq->cmdq_lock);
|
spin_lock_init(&cmdq->cmdq_lock);
|
||||||
|
@@ -42,6 +42,16 @@
|
|||||||
* Invalid flag options in AES-CCM IV.
|
* Invalid flag options in AES-CCM IV.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static inline int incr_index(int index, int count, int max)
|
||||||
|
{
|
||||||
|
if ((index + count) >= max)
|
||||||
|
index = index + count - max;
|
||||||
|
else
|
||||||
|
index += count;
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dma_free_sglist - unmap and free the sg lists.
|
* dma_free_sglist - unmap and free the sg lists.
|
||||||
* @ndev: N5 device
|
* @ndev: N5 device
|
||||||
@@ -426,30 +436,29 @@ static void post_se_instr(struct nitrox_softreq *sr,
|
|||||||
struct nitrox_cmdq *cmdq)
|
struct nitrox_cmdq *cmdq)
|
||||||
{
|
{
|
||||||
struct nitrox_device *ndev = sr->ndev;
|
struct nitrox_device *ndev = sr->ndev;
|
||||||
union nps_pkt_in_instr_baoff_dbell pkt_in_baoff_dbell;
|
int idx;
|
||||||
u64 offset;
|
|
||||||
u8 *ent;
|
u8 *ent;
|
||||||
|
|
||||||
spin_lock_bh(&cmdq->cmdq_lock);
|
spin_lock_bh(&cmdq->cmdq_lock);
|
||||||
|
|
||||||
/* get the next write offset */
|
idx = cmdq->write_idx;
|
||||||
offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(cmdq->qno);
|
|
||||||
pkt_in_baoff_dbell.value = nitrox_read_csr(ndev, offset);
|
|
||||||
/* copy the instruction */
|
/* copy the instruction */
|
||||||
ent = cmdq->head + pkt_in_baoff_dbell.s.aoff;
|
ent = cmdq->head + (idx * cmdq->instr_size);
|
||||||
memcpy(ent, &sr->instr, cmdq->instr_size);
|
memcpy(ent, &sr->instr, cmdq->instr_size);
|
||||||
/* flush the command queue updates */
|
|
||||||
dma_wmb();
|
|
||||||
|
|
||||||
sr->tstamp = jiffies;
|
|
||||||
atomic_set(&sr->status, REQ_POSTED);
|
atomic_set(&sr->status, REQ_POSTED);
|
||||||
response_list_add(sr, cmdq);
|
response_list_add(sr, cmdq);
|
||||||
|
sr->tstamp = jiffies;
|
||||||
|
/* flush the command queue updates */
|
||||||
|
dma_wmb();
|
||||||
|
|
||||||
/* Ring doorbell with count 1 */
|
/* Ring doorbell with count 1 */
|
||||||
writeq(1, cmdq->dbell_csr_addr);
|
writeq(1, cmdq->dbell_csr_addr);
|
||||||
/* orders the doorbell rings */
|
/* orders the doorbell rings */
|
||||||
mmiowb();
|
mmiowb();
|
||||||
|
|
||||||
|
cmdq->write_idx = incr_index(idx, 1, ndev->qlen);
|
||||||
|
|
||||||
spin_unlock_bh(&cmdq->cmdq_lock);
|
spin_unlock_bh(&cmdq->cmdq_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -459,6 +468,9 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
|
|||||||
struct nitrox_softreq *sr, *tmp;
|
struct nitrox_softreq *sr, *tmp;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!atomic_read(&cmdq->backlog_count))
|
||||||
|
return 0;
|
||||||
|
|
||||||
spin_lock_bh(&cmdq->backlog_lock);
|
spin_lock_bh(&cmdq->backlog_lock);
|
||||||
|
|
||||||
list_for_each_entry_safe(sr, tmp, &cmdq->backlog_head, backlog) {
|
list_for_each_entry_safe(sr, tmp, &cmdq->backlog_head, backlog) {
|
||||||
@@ -466,7 +478,7 @@ static int post_backlog_cmds(struct nitrox_cmdq *cmdq)
|
|||||||
|
|
||||||
/* submit until space available */
|
/* submit until space available */
|
||||||
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
|
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
|
||||||
ret = -EBUSY;
|
ret = -ENOSPC;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* delete from backlog list */
|
/* delete from backlog list */
|
||||||
@@ -491,23 +503,20 @@ static int nitrox_enqueue_request(struct nitrox_softreq *sr)
|
|||||||
{
|
{
|
||||||
struct nitrox_cmdq *cmdq = sr->cmdq;
|
struct nitrox_cmdq *cmdq = sr->cmdq;
|
||||||
struct nitrox_device *ndev = sr->ndev;
|
struct nitrox_device *ndev = sr->ndev;
|
||||||
int ret = -EBUSY;
|
|
||||||
|
/* try to post backlog requests */
|
||||||
|
post_backlog_cmds(cmdq);
|
||||||
|
|
||||||
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
|
if (unlikely(cmdq_full(cmdq, ndev->qlen))) {
|
||||||
if (!(sr->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
|
if (!(sr->flags & CRYPTO_TFM_REQ_MAY_BACKLOG))
|
||||||
return -EAGAIN;
|
return -ENOSPC;
|
||||||
|
/* add to backlog list */
|
||||||
backlog_list_add(sr, cmdq);
|
backlog_list_add(sr, cmdq);
|
||||||
} else {
|
return -EBUSY;
|
||||||
ret = post_backlog_cmds(cmdq);
|
|
||||||
if (ret) {
|
|
||||||
backlog_list_add(sr, cmdq);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
post_se_instr(sr, cmdq);
|
|
||||||
ret = -EINPROGRESS;
|
|
||||||
}
|
}
|
||||||
return ret;
|
post_se_instr(sr, cmdq);
|
||||||
|
|
||||||
|
return -EINPROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -624,11 +633,9 @@ int nitrox_process_se_request(struct nitrox_device *ndev,
|
|||||||
*/
|
*/
|
||||||
sr->instr.fdata[0] = *((u64 *)&req->gph);
|
sr->instr.fdata[0] = *((u64 *)&req->gph);
|
||||||
sr->instr.fdata[1] = 0;
|
sr->instr.fdata[1] = 0;
|
||||||
/* flush the soft_req changes before posting the cmd */
|
|
||||||
wmb();
|
|
||||||
|
|
||||||
ret = nitrox_enqueue_request(sr);
|
ret = nitrox_enqueue_request(sr);
|
||||||
if (ret == -EAGAIN)
|
if (ret == -ENOSPC)
|
||||||
goto send_fail;
|
goto send_fail;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -96,6 +96,10 @@ enum csk_flags {
|
|||||||
CSK_CONN_INLINE, /* Connection on HW */
|
CSK_CONN_INLINE, /* Connection on HW */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum chtls_cdev_state {
|
||||||
|
CHTLS_CDEV_STATE_UP = 1
|
||||||
|
};
|
||||||
|
|
||||||
struct listen_ctx {
|
struct listen_ctx {
|
||||||
struct sock *lsk;
|
struct sock *lsk;
|
||||||
struct chtls_dev *cdev;
|
struct chtls_dev *cdev;
|
||||||
@@ -146,6 +150,7 @@ struct chtls_dev {
|
|||||||
unsigned int send_page_order;
|
unsigned int send_page_order;
|
||||||
int max_host_sndbuf;
|
int max_host_sndbuf;
|
||||||
struct key_map kmap;
|
struct key_map kmap;
|
||||||
|
unsigned int cdev_state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct chtls_hws {
|
struct chtls_hws {
|
||||||
|
@@ -160,6 +160,7 @@ static void chtls_register_dev(struct chtls_dev *cdev)
|
|||||||
tlsdev->hash = chtls_create_hash;
|
tlsdev->hash = chtls_create_hash;
|
||||||
tlsdev->unhash = chtls_destroy_hash;
|
tlsdev->unhash = chtls_destroy_hash;
|
||||||
tls_register_device(&cdev->tlsdev);
|
tls_register_device(&cdev->tlsdev);
|
||||||
|
cdev->cdev_state = CHTLS_CDEV_STATE_UP;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void chtls_unregister_dev(struct chtls_dev *cdev)
|
static void chtls_unregister_dev(struct chtls_dev *cdev)
|
||||||
@@ -281,8 +282,10 @@ static void chtls_free_all_uld(void)
|
|||||||
struct chtls_dev *cdev, *tmp;
|
struct chtls_dev *cdev, *tmp;
|
||||||
|
|
||||||
mutex_lock(&cdev_mutex);
|
mutex_lock(&cdev_mutex);
|
||||||
list_for_each_entry_safe(cdev, tmp, &cdev_list, list)
|
list_for_each_entry_safe(cdev, tmp, &cdev_list, list) {
|
||||||
chtls_free_uld(cdev);
|
if (cdev->cdev_state == CHTLS_CDEV_STATE_UP)
|
||||||
|
chtls_free_uld(cdev);
|
||||||
|
}
|
||||||
mutex_unlock(&cdev_mutex);
|
mutex_unlock(&cdev_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -107,24 +107,23 @@ static int p8_aes_cbc_encrypt(struct blkcipher_desc *desc,
|
|||||||
ret = crypto_skcipher_encrypt(req);
|
ret = crypto_skcipher_encrypt(req);
|
||||||
skcipher_request_zero(req);
|
skcipher_request_zero(req);
|
||||||
} else {
|
} else {
|
||||||
preempt_disable();
|
|
||||||
pagefault_disable();
|
|
||||||
enable_kernel_vsx();
|
|
||||||
|
|
||||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||||
ret = blkcipher_walk_virt(desc, &walk);
|
ret = blkcipher_walk_virt(desc, &walk);
|
||||||
while ((nbytes = walk.nbytes)) {
|
while ((nbytes = walk.nbytes)) {
|
||||||
|
preempt_disable();
|
||||||
|
pagefault_disable();
|
||||||
|
enable_kernel_vsx();
|
||||||
aes_p8_cbc_encrypt(walk.src.virt.addr,
|
aes_p8_cbc_encrypt(walk.src.virt.addr,
|
||||||
walk.dst.virt.addr,
|
walk.dst.virt.addr,
|
||||||
nbytes & AES_BLOCK_MASK,
|
nbytes & AES_BLOCK_MASK,
|
||||||
&ctx->enc_key, walk.iv, 1);
|
&ctx->enc_key, walk.iv, 1);
|
||||||
|
disable_kernel_vsx();
|
||||||
|
pagefault_enable();
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_kernel_vsx();
|
|
||||||
pagefault_enable();
|
|
||||||
preempt_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -147,24 +146,23 @@ static int p8_aes_cbc_decrypt(struct blkcipher_desc *desc,
|
|||||||
ret = crypto_skcipher_decrypt(req);
|
ret = crypto_skcipher_decrypt(req);
|
||||||
skcipher_request_zero(req);
|
skcipher_request_zero(req);
|
||||||
} else {
|
} else {
|
||||||
preempt_disable();
|
|
||||||
pagefault_disable();
|
|
||||||
enable_kernel_vsx();
|
|
||||||
|
|
||||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||||
ret = blkcipher_walk_virt(desc, &walk);
|
ret = blkcipher_walk_virt(desc, &walk);
|
||||||
while ((nbytes = walk.nbytes)) {
|
while ((nbytes = walk.nbytes)) {
|
||||||
|
preempt_disable();
|
||||||
|
pagefault_disable();
|
||||||
|
enable_kernel_vsx();
|
||||||
aes_p8_cbc_encrypt(walk.src.virt.addr,
|
aes_p8_cbc_encrypt(walk.src.virt.addr,
|
||||||
walk.dst.virt.addr,
|
walk.dst.virt.addr,
|
||||||
nbytes & AES_BLOCK_MASK,
|
nbytes & AES_BLOCK_MASK,
|
||||||
&ctx->dec_key, walk.iv, 0);
|
&ctx->dec_key, walk.iv, 0);
|
||||||
|
disable_kernel_vsx();
|
||||||
|
pagefault_enable();
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_kernel_vsx();
|
|
||||||
pagefault_enable();
|
|
||||||
preempt_enable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@@ -116,32 +116,39 @@ static int p8_aes_xts_crypt(struct blkcipher_desc *desc,
|
|||||||
ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
|
ret = enc? crypto_skcipher_encrypt(req) : crypto_skcipher_decrypt(req);
|
||||||
skcipher_request_zero(req);
|
skcipher_request_zero(req);
|
||||||
} else {
|
} else {
|
||||||
|
blkcipher_walk_init(&walk, dst, src, nbytes);
|
||||||
|
|
||||||
|
ret = blkcipher_walk_virt(desc, &walk);
|
||||||
|
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
pagefault_disable();
|
pagefault_disable();
|
||||||
enable_kernel_vsx();
|
enable_kernel_vsx();
|
||||||
|
|
||||||
blkcipher_walk_init(&walk, dst, src, nbytes);
|
|
||||||
|
|
||||||
ret = blkcipher_walk_virt(desc, &walk);
|
|
||||||
iv = walk.iv;
|
iv = walk.iv;
|
||||||
memset(tweak, 0, AES_BLOCK_SIZE);
|
memset(tweak, 0, AES_BLOCK_SIZE);
|
||||||
aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
|
aes_p8_encrypt(iv, tweak, &ctx->tweak_key);
|
||||||
|
|
||||||
|
disable_kernel_vsx();
|
||||||
|
pagefault_enable();
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
while ((nbytes = walk.nbytes)) {
|
while ((nbytes = walk.nbytes)) {
|
||||||
|
preempt_disable();
|
||||||
|
pagefault_disable();
|
||||||
|
enable_kernel_vsx();
|
||||||
if (enc)
|
if (enc)
|
||||||
aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
|
aes_p8_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
|
||||||
nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
|
nbytes & AES_BLOCK_MASK, &ctx->enc_key, NULL, tweak);
|
||||||
else
|
else
|
||||||
aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
|
aes_p8_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
|
||||||
nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
|
nbytes & AES_BLOCK_MASK, &ctx->dec_key, NULL, tweak);
|
||||||
|
disable_kernel_vsx();
|
||||||
|
pagefault_enable();
|
||||||
|
preempt_enable();
|
||||||
|
|
||||||
nbytes &= AES_BLOCK_SIZE - 1;
|
nbytes &= AES_BLOCK_SIZE - 1;
|
||||||
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
ret = blkcipher_walk_done(desc, &walk, nbytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
disable_kernel_vsx();
|
|
||||||
pagefault_enable();
|
|
||||||
preempt_enable();
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user