* [PATCH v6 1/8] MFD: add bindings for STM32 Timers driver
From: Benjamin Gaignard @ 2016-12-09 14:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481292919-26587-1-git-send-email-benjamin.gaignard@st.com>
Add bindings information for STM32 Timers
version 6:
- rename stm32-gtimer to stm32-timers
- change compatible
- add description about the IPs
version 2:
- rename stm32-mfd-timer to stm32-gptimer
- only keep one compatible string
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
---
.../devicetree/bindings/mfd/stm32-timers.txt | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
new file mode 100644
index 0000000..b30868e
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
@@ -0,0 +1,46 @@
+STM32 Timers driver bindings
+
+This IP provides 3 types of timer along with PWM functionality:
+- advanced-control timers consist of a 16-bit auto-reload counter driven by a programmable
+ prescaler, break input feature, PWM outputs and complementary PWM ouputs channels.
+- general-purpose timers consist of a 16-bit or 32-bit auto-reload counter driven by a
+ programmable prescaler and PWM outputs.
+- basic timers consist of a 16-bit auto-reload counter driven by a programmable prescaler.
+
+Required parameters:
+- compatible: must be "st,stm32-timers"
+
+- reg: Physical base address and length of the controller's
+ registers.
+- clock-names: Set to "clk_int".
+- clocks: Phandle to the clock used by the timer module.
+ For Clk properties, please refer to ../clock/clock-bindings.txt
+
+Optional parameters:
+- resets: Phandle to the parent reset controller.
+ See ../reset/st,stm32-rcc.txt
+
+Optional subnodes:
+- pwm: See ../pwm/pwm-stm32.txt
+- timer: See ../iio/timer/stm32-timer-trigger.txt
+
+Example:
+ timers at 40010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40010000 0x400>;
+ clocks = <&rcc 0 160>;
+ clock-names = "clk_int";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ pinctrl-0 = <&pwm1_pins>;
+ pinctrl-names = "default";
+ };
+
+ timer {
+ compatible = "st,stm32-timer-trigger";
+ reg = <0>;
+ };
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v6 0/8] Add PWM and IIO timer drivers for STM32
From: Benjamin Gaignard @ 2016-12-09 14:15 UTC (permalink / raw)
To: linux-arm-kernel
version 6:
- rename stm32-gptimer in stm32-timers.
- change "st,stm32-gptimer" compatible to "st,stm32-timers".
- modify "st,breakinput" parameter in pwm part.
- split DT patch in 2
version 5:
- fix comments done on version 4
- rebased on kernel 4.9-rc8
- change nodes names and re-order then by addresses
version 4:
- fix comments done on version 3
- don't use interrupts anymore in IIO timer
- detect hardware capabilities at probe time to simplify binding
version 3:
- no change on mfd and pwm divers patches
- add cross reference between bindings
- change compatible to "st,stm32-timer-trigger"
- fix attributes access rights
- use string instead of int for master_mode and slave_mode
- document device attributes in sysfs-bus-iio-timer-stm32
- update DT with the new compatible
version 2:
- keep only one compatible per driver
- use DT parameters to describe hardware block configuration:
- pwm channels, complementary output, counter size, break input
- triggers accepted and create by IIO timers
- change DT to limite use of reference to the node
- interrupt is now in IIO timer driver
- rename stm32-mfd-timer to stm32-timers (for general purpose timer)
The following patches enable PWM and IIO Timer features for STM32 platforms.
Those two features are mixed into the registers of the same hardware block
(named general purpose timer) which lead to introduce a multifunctions driver
on the top of them to be able to share the registers.
In STM32f4 14 instances of timer hardware block exist, even if they all have
the same register mapping they could have a different number of pwm channels
and/or different triggers capabilities. We use various parameters in DT to
describe the differences between hardware blocks
The MFD (stm32-timers.c) takes care of clock and register mapping
by using regmap. stm32_timers structure is provided to its sub-node to
share those information.
PWM driver is implemented into pwm-stm32.c. Depending of the instance we may
have up to 4 channels, sometime with complementary outputs or 32 bits counter
instead of 16 bits. Some hardware blocks may also have a break input function
which allows to stop pwm depending of a level, defined in devicetree, on an
external pin.
IIO timer driver (stm32-timer-trigger.c and stm32-timer-trigger.h) define a list
of hardware triggers usable by hardware blocks like ADC, DAC or other timers.
The matrix of possible connections between blocks is quite complex so we use
trigger names and is_stm32_iio_timer_trigger() function to be sure that
triggers are valid and configure the IPs.
At run time IIO timer hardware blocks can configure (through "master_mode"
IIO device attribute) which internal signal (counter enable, reset,
comparison block, etc...) is used to generate the trigger.
By using "slave_mode" IIO device attribute timer can also configure on which
event (level, rising edge) of the block is enabled.
Since we can use trigger from one hardware to control an other block, we can
use a pwm to control an other one. The following example shows how to configure
pwm1 and pwm3 to make pwm3 generate pulse only when pwm1 pulse level is high.
/sys/bus/iio/devices # ls
iio:device0 iio:device1 trigger0 trigger1
configure timer1 to use pwm1 channel 0 as output trigger
/sys/bus/iio/devices # echo 'OC1REF' > iio\:device0/master_mode
configure timer3 to enable only when input is high
/sys/bus/iio/devices # echo 'gated' > iio\:device1/slave_mode
/sys/bus/iio/devices # cat trigger0/name
tim1_trgo
configure timer2 to use timer1 trigger is input
/sys/bus/iio/devices # echo "tim1_trgo" > iio\:device1/trigger/current_trigger
configure pwm3 channel 0 to generate a signal with a period of 100ms and a
duty cycle of 50%
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 0 > export
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 100000000 > pwm0/period
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 50000000 > pwm0/duty_cycle
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 1 > pwm0/enable
here pwm3 channel 0, as expected, doesn't start because has to be triggered by
pwm1 channel 0
configure pwm1 channel 0 to generate a signal with a period of 1s and a
duty cycle of 50%
/sys/devices/platform/soc/40010000.timers/40010000.timers:pwm/pwm/pwmchip0 # echo 0 > export
/sys/devices/platform/soc/40010000.timers/40010000.timers:pwm/pwm/pwmchip0 # echo 1000000000 > pwm0/period
/sys/devices/platform/soc/40010000.timers/40010000.timers:pwm/pwm/pwmchip0 # echo 500000000 > pwm0/duty_cycle
/sys/devices/platform/soc/40010000.timers/40010000.timers:pwm/pwm/pwmchip0 # echo 1 > pwm0/enable
finally pwm1 starts and pwm3 only generates pulse when pwm1 signal is high
An other example to use a timer as source of clock for another device.
Here timer1 is used a source clock for pwm3:
/sys/bus/iio/devices # echo 100000 > trigger0/sampling_frequency
/sys/bus/iio/devices # echo "tim1_trgo" > iio\:device1/trigger/current_trigger
/sys/bus/iio/devices # echo 'external_clock' > iio\:device1/slave_mode
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 0 > export
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 1000000 > pwm0/period
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 500000 > pwm0/duty_cycle
/sys/devices/platform/soc/40000400.timers/40000400.timers:pwm/pwm/pwmchip4 # echo 1 > pwm0/enable
Benjamin Gaignard (8):
MFD: add bindings for STM32 Timers driver
MFD: add STM32 Timers driver
PWM: add pwm-stm32 DT bindings
PWM: add PWM driver for STM32 plaftorm
IIO: add bindings for STM32 timer trigger driver
IIO: add STM32 timer trigger driver
ARM: dts: stm32: add Timers driver for stm32f429 MCU
ARM: dts: stm32: Enable pw1 and pwm3 for stm32f469-disco
.../ABI/testing/sysfs-bus-iio-timer-stm32 | 55 +++
.../bindings/iio/timer/stm32-timer-trigger.txt | 23 +
.../devicetree/bindings/mfd/stm32-timers.txt | 46 ++
.../devicetree/bindings/pwm/pwm-stm32.txt | 33 ++
arch/arm/boot/dts/stm32f429.dtsi | 275 ++++++++++++
arch/arm/boot/dts/stm32f469-disco.dts | 28 ++
drivers/iio/Kconfig | 2 +-
drivers/iio/Makefile | 1 +
drivers/iio/timer/Kconfig | 13 +
drivers/iio/timer/Makefile | 1 +
drivers/iio/timer/stm32-timer-trigger.c | 466 +++++++++++++++++++++
drivers/iio/trigger/Kconfig | 1 -
drivers/mfd/Kconfig | 11 +
drivers/mfd/Makefile | 2 +
drivers/mfd/stm32-timers.c | 80 ++++
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-stm32.c | 434 +++++++++++++++++++
include/linux/iio/timer/stm32-timer-trigger.h | 62 +++
include/linux/mfd/stm32-timers.h | 71 ++++
20 files changed, 1612 insertions(+), 2 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
create mode 100644 drivers/iio/timer/Kconfig
create mode 100644 drivers/iio/timer/Makefile
create mode 100644 drivers/iio/timer/stm32-timer-trigger.c
create mode 100644 drivers/mfd/stm32-timers.c
create mode 100644 drivers/pwm/pwm-stm32.c
create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
create mode 100644 include/linux/mfd/stm32-timers.h
--
1.9.1
^ permalink raw reply
* [PATCH] crypto: arm/aes-neonbs - process 8 blocks in parallel if we can
From: Ard Biesheuvel @ 2016-12-09 13:47 UTC (permalink / raw)
To: linux-arm-kernel
The bit-sliced NEON implementation of AES only performs optimally if
it can process 8 blocks of input in parallel. This is due to the nature
of bit slicing, where the n-th bit of each byte of AES state of each input
block is collected into NEON register 'n', for registers q0 - q7.
This implies that the amount of work for the transform is fixed,
regardless of whether we are handling just one block or 8 in parallel.
So let's try a bit harder to iterate over the input in suitably sized
chunks, by increasing the chunksize to 8 * AES_BLOCK_SIZE, and tweaking
the loops to only process multiples of the chunk size, unless we are
handling the last chunk in the input stream.
Note that the skcipher walk API guarantees that a step in the walk never
returns less that 'chunksize' bytes if there are at least that many bytes
of input still available. However, it does *not* guarantee that those steps
produce an exact multiple of the chunk size.
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
---
arch/arm/crypto/aesbs-glue.c | 68 +++++++++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 30 deletions(-)
diff --git a/arch/arm/crypto/aesbs-glue.c b/arch/arm/crypto/aesbs-glue.c
index d8e06de72ef3..938d1e1bf9a3 100644
--- a/arch/arm/crypto/aesbs-glue.c
+++ b/arch/arm/crypto/aesbs-glue.c
@@ -121,39 +121,26 @@ static int aesbs_cbc_encrypt(struct skcipher_request *req)
return crypto_cbc_encrypt_walk(req, aesbs_encrypt_one);
}
-static inline void aesbs_decrypt_one(struct crypto_skcipher *tfm,
- const u8 *src, u8 *dst)
-{
- struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
-
- AES_decrypt(src, dst, &ctx->dec.rk);
-}
-
static int aesbs_cbc_decrypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct aesbs_cbc_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk walk;
- unsigned int nbytes;
int err;
- for (err = skcipher_walk_virt(&walk, req, false);
- (nbytes = walk.nbytes); err = skcipher_walk_done(&walk, nbytes)) {
- u32 blocks = nbytes / AES_BLOCK_SIZE;
- u8 *dst = walk.dst.virt.addr;
- u8 *src = walk.src.virt.addr;
- u8 *iv = walk.iv;
-
- if (blocks >= 8) {
- kernel_neon_begin();
- bsaes_cbc_encrypt(src, dst, nbytes, &ctx->dec, iv);
- kernel_neon_end();
- nbytes %= AES_BLOCK_SIZE;
- continue;
- }
+ err = skcipher_walk_virt(&walk, req, false);
+
+ while (walk.nbytes) {
+ unsigned int nbytes = walk.nbytes;
+
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, walk.chunksize);
- nbytes = crypto_cbc_decrypt_blocks(&walk, tfm,
- aesbs_decrypt_one);
+ kernel_neon_begin();
+ bsaes_cbc_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
+ nbytes, &ctx->dec, walk.iv);
+ kernel_neon_end();
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
return err;
}
@@ -186,6 +173,12 @@ static int aesbs_ctr_encrypt(struct skcipher_request *req)
__be32 *ctr = (__be32 *)walk.iv;
u32 headroom = UINT_MAX - be32_to_cpu(ctr[3]);
+ if (walk.nbytes < walk.total) {
+ blocks = round_down(blocks,
+ walk.chunksize / AES_BLOCK_SIZE);
+ tail = walk.nbytes - blocks * AES_BLOCK_SIZE;
+ }
+
/* avoid 32 bit counter overflow in the NEON code */
if (unlikely(headroom < blocks)) {
blocks = headroom + 1;
@@ -198,6 +191,9 @@ static int aesbs_ctr_encrypt(struct skcipher_request *req)
kernel_neon_end();
inc_be128_ctr(ctr, blocks);
+ if (tail > 0 && tail < AES_BLOCK_SIZE)
+ break;
+
err = skcipher_walk_done(&walk, tail);
}
if (walk.nbytes) {
@@ -227,11 +223,16 @@ static int aesbs_xts_encrypt(struct skcipher_request *req)
AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
while (walk.nbytes) {
+ unsigned int nbytes = walk.nbytes;
+
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, walk.chunksize);
+
kernel_neon_begin();
bsaes_xts_encrypt(walk.src.virt.addr, walk.dst.virt.addr,
- walk.nbytes, &ctx->enc, walk.iv);
+ nbytes, &ctx->enc, walk.iv);
kernel_neon_end();
- err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
return err;
}
@@ -249,11 +250,16 @@ static int aesbs_xts_decrypt(struct skcipher_request *req)
AES_encrypt(walk.iv, walk.iv, &ctx->twkey);
while (walk.nbytes) {
+ unsigned int nbytes = walk.nbytes;
+
+ if (nbytes < walk.total)
+ nbytes = round_down(nbytes, walk.chunksize);
+
kernel_neon_begin();
bsaes_xts_decrypt(walk.src.virt.addr, walk.dst.virt.addr,
- walk.nbytes, &ctx->dec, walk.iv);
+ nbytes, &ctx->dec, walk.iv);
kernel_neon_end();
- err = skcipher_walk_done(&walk, walk.nbytes % AES_BLOCK_SIZE);
+ err = skcipher_walk_done(&walk, walk.nbytes - nbytes);
}
return err;
}
@@ -272,6 +278,7 @@ static struct skcipher_alg aesbs_algs[] = { {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
+ .chunksize = 8 * AES_BLOCK_SIZE,
.setkey = aesbs_cbc_set_key,
.encrypt = aesbs_cbc_encrypt,
.decrypt = aesbs_cbc_decrypt,
@@ -289,7 +296,7 @@ static struct skcipher_alg aesbs_algs[] = { {
.min_keysize = AES_MIN_KEY_SIZE,
.max_keysize = AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
- .chunksize = AES_BLOCK_SIZE,
+ .chunksize = 8 * AES_BLOCK_SIZE,
.setkey = aesbs_ctr_set_key,
.encrypt = aesbs_ctr_encrypt,
.decrypt = aesbs_ctr_encrypt,
@@ -307,6 +314,7 @@ static struct skcipher_alg aesbs_algs[] = { {
.min_keysize = 2 * AES_MIN_KEY_SIZE,
.max_keysize = 2 * AES_MAX_KEY_SIZE,
.ivsize = AES_BLOCK_SIZE,
+ .chunksize = 8 * AES_BLOCK_SIZE,
.setkey = aesbs_xts_set_key,
.encrypt = aesbs_xts_encrypt,
.decrypt = aesbs_xts_decrypt,
--
2.7.4
^ permalink raw reply related
* [PATCH v8 02/16] arm: use new phandle allocation functions
From: Marc Zyngier @ 2016-12-09 13:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161104173203.21168-3-andre.przywara@arm.com>
On 04/11/16 17:31, Andre Przywara wrote:
> To refer to the GIC FDT node, we used to pass the GIC phandle to most
> of the functions dealing with FDT nodes.
> Since we now have a global phandle reference, use that to refer to the
> GIC handle in various places and get rid of the now unneeded parameter
> passing.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Despite the comments on the previous patch, this one is a good cleanup.
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v2] arm64: mm: Fix memmap to be initialized for the entire section
From: Yisheng Xie @ 2016-12-09 13:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <584AA257.3080608@linaro.org>
On 2016/12/9 20:23, Hanjun Guo wrote:
> On 12/09/2016 08:19 PM, Ard Biesheuvel wrote:
>> On 9 December 2016 at 12:14, Yisheng Xie <xieyisheng1@huawei.com> wrote:
>>> Hi Robert,
>>> We have merged your patch to 4.9.0-rc8, however we still meet the similar problem
>>> on our D05 board:
>>>
>>
>> To be clear: does this issue also occur on D05 *without* the patch?
>
> It boots ok on D05 without this patch.
>
> But I think the problem Robert described in the commit message is
> still there, just not triggered in the boot. we met this problem
> when having LTP stress memory test and hit the same BUG_ON.
>
That's right. for D05's case, when trigger the BUG_ON on:
1863 VM_BUG_ON(page_zone(start_page) != page_zone(end_page));
the end_page is not nomap, but BIOS reserved. here is the log I got:
[ 0.000000] efi: 0x00003fc00000-0x00003fffffff [Reserved | | | | | | | | | | | | ]
[...]
[ 5.081443] move_freepages: phys(start_page: 0x20000000,end_page:0x3fff0000)
For invalid pages, their zone and node information is not initialized, and it
do have risk to trigger the BUG_ON, so I have a silly question,
why not just change the BUG_ON:
-----------
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 6de9440..af199b8 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1860,12 +1860,13 @@ int move_freepages(struct zone *zone,
* Remove at a later date when no bug reports exist related to
* grouping pages by mobility
*/
- VM_BUG_ON(page_zone(start_page) != page_zone(end_page));
+ VM_BUG_ON(early_pfn_valid(start_page) && early_pfn_valid(end_page) &&
+ page_zone(start_page) != page_zone(end_page));
#endif
for (page = start_page; page <= end_page;) {
/* Make sure we are not inadvertently changing nodes */
- VM_BUG_ON_PAGE(page_to_nid(page) != zone_to_nid(zone), page);
+ VM_BUG_ON_PAGE(early_pfn_valid(page) && (page_to_nid(page) != zone_to_nid(zone)), page);
if (!pfn_valid_within(page_to_pfn(page))) {
page++;
Thanks,
Yisheng Xie
> Thanks
> Hanjun
>
> .
>
^ permalink raw reply related
* [PATCH v2 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2016-12-09 13:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481289284-19919-1-git-send-email-sergio.prado@e-labworks.com>
Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
tree.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
drivers/mmc/host/s3cmci.c | 155 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 131 insertions(+), 24 deletions(-)
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 932a4b1fed33..bfeb90e8ffee 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -23,6 +23,9 @@
#include <linux/gpio.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/dma.h>
@@ -127,6 +130,22 @@ enum dbg_channels {
dbg_conf = (1 << 8),
};
+struct s3cmci_drv_data {
+ int is2440;
+};
+
+static const struct s3cmci_drv_data s3c2410_s3cmci_drv_data = {
+ .is2440 = 0,
+};
+
+static const struct s3cmci_drv_data s3c2412_s3cmci_drv_data = {
+ .is2440 = 1,
+};
+
+static const struct s3cmci_drv_data s3c2440_s3cmci_drv_data = {
+ .is2440 = 1,
+};
+
static const int dbgmap_err = dbg_fail;
static const int dbgmap_info = dbg_info | dbg_conf;
static const int dbgmap_debug = dbg_err | dbg_debug;
@@ -1241,8 +1260,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_ON:
case MMC_POWER_UP:
/* Configure GPE5...GPE10 pins in SD mode */
- s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
- S3C_GPIO_PULL_NONE);
+ if (!host->pdev->dev.of_node)
+ s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_NONE);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1254,7 +1274,8 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
default:
- gpio_direction_output(S3C2410_GPE(5), 0);
+ if (!host->pdev->dev.of_node)
+ gpio_direction_output(S3C2410_GPE(5), 0);
if (host->is2440)
mci_con |= S3C2440_SDICON_SDRESET;
@@ -1544,21 +1565,12 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
#endif /* CONFIG_DEBUG_FS */
-static int s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe_pdata(struct s3cmci_host *host)
{
- struct s3cmci_host *host;
- struct mmc_host *mmc;
- int ret;
- int is2440;
- int i;
+ struct platform_device *pdev = host->pdev;
+ int i, ret;
- is2440 = platform_get_device_id(pdev)->driver_data;
-
- mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- goto probe_out;
- }
+ host->is2440 = platform_get_device_id(pdev)->driver_data;
for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
ret = gpio_request(i, dev_name(&pdev->dev));
@@ -1568,14 +1580,90 @@ static int s3cmci_probe(struct platform_device *pdev)
for (i--; i >= S3C2410_GPE(5); i--)
gpio_free(i);
- goto probe_free_host;
+ return ret;
}
}
+ return 0;
+}
+
+static int s3cmci_probe_dt(struct s3cmci_host *host)
+{
+ struct platform_device *pdev = host->pdev;
+ struct s3c24xx_mci_pdata *pdata;
+ const struct s3cmci_drv_data *drvdata;
+ struct mmc_host *mmc = host->mmc;
+ int gpio, ret;
+
+ drvdata = of_device_get_match_data(&pdev->dev);
+ if (!drvdata)
+ return -ENODEV;
+
+ host->is2440 = drvdata->is2440;
+
+ ret = mmc_of_parse(mmc);
+ if (ret)
+ return ret;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdata->ocr_avail = mmc->ocr_avail;
+
+ if (mmc->caps2 & MMC_CAP2_NO_WRITE_PROTECT)
+ pdata->no_wprotect = 1;
+
+ if (mmc->caps & MMC_CAP_NEEDS_POLL)
+ pdata->no_detect = 1;
+
+ if (mmc->caps2 & MMC_CAP2_RO_ACTIVE_HIGH)
+ pdata->wprotect_invert = 1;
+
+ if (mmc->caps2 & MMC_CAP2_CD_ACTIVE_HIGH)
+ pdata->detect_invert = 1;
+
+ gpio = of_get_named_gpio(pdev->dev.of_node, "cd-gpios", 0);
+ if (gpio_is_valid(gpio)) {
+ pdata->gpio_detect = gpio;
+ gpio_free(gpio);
+ }
+
+ gpio = of_get_named_gpio(pdev->dev.of_node, "wp-gpios", 0);
+ if (gpio_is_valid(gpio)) {
+ pdata->gpio_wprotect = gpio;
+ gpio_free(gpio);
+ }
+
+ pdev->dev.platform_data = pdata;
+
+ return 0;
+}
+
+static int s3cmci_probe(struct platform_device *pdev)
+{
+ struct s3cmci_host *host;
+ struct mmc_host *mmc;
+ int ret;
+ int i;
+
+ mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto probe_out;
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
- host->is2440 = is2440;
+
+ if (pdev->dev.of_node)
+ ret = s3cmci_probe_dt(host);
+ else
+ ret = s3cmci_probe_pdata(host);
+
+ if (ret)
+ goto probe_free_host;
host->pdata = pdev->dev.platform_data;
if (!host->pdata) {
@@ -1586,7 +1674,7 @@ static int s3cmci_probe(struct platform_device *pdev)
spin_lock_init(&host->complete_lock);
tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
- if (is2440) {
+ if (host->is2440) {
host->sdiimsk = S3C2440_SDIIMSK;
host->sdidata = S3C2440_SDIDATA;
host->clk_div = 1;
@@ -1789,8 +1877,9 @@ static int s3cmci_probe(struct platform_device *pdev)
release_mem_region(host->mem->start, resource_size(host->mem));
probe_free_gpio:
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
@@ -1837,9 +1926,9 @@ static int s3cmci_remove(struct platform_device *pdev)
if (!pd->no_detect)
gpio_free(pd->gpio_detect);
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
-
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
iounmap(host->base);
release_mem_region(host->mem->start, resource_size(host->mem));
@@ -1848,6 +1937,23 @@ static int s3cmci_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id s3cmci_dt_match[] = {
+ {
+ .compatible = "samsung,s3c2410-sdi",
+ .data = &s3c2410_s3cmci_drv_data,
+ },
+ {
+ .compatible = "samsung,s3c2412-sdi",
+ .data = &s3c2412_s3cmci_drv_data,
+ },
+ {
+ .compatible = "samsung,s3c2440-sdi",
+ .data = &s3c2440_s3cmci_drv_data,
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, sdhci_s3c_dt_match);
+
static const struct platform_device_id s3cmci_driver_ids[] = {
{
.name = "s3c2410-sdi",
@@ -1867,6 +1973,7 @@ static int s3cmci_remove(struct platform_device *pdev)
static struct platform_driver s3cmci_driver = {
.driver = {
.name = "s3c-sdi",
+ .of_match_table = s3cmci_dt_match,
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
--
1.9.1
^ permalink raw reply related
* [PATCH v2 1/2] dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
From: Sergio Prado @ 2016-12-09 13:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481289284-19919-1-git-send-email-sergio.prado@e-labworks.com>
Adds the device tree bindings description for Samsung S3C24XX
MMC/SD/SDIO controller, used as a connectivity interface with external
MMC, SD and SDIO storage mediums.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 ++++++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
diff --git a/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
new file mode 100644
index 000000000000..d09dbf4b3824
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
@@ -0,0 +1,34 @@
+* Samsung's S3C24XX MMC/SD/SDIO controller device tree bindings
+
+Samsung's S3C24XX MMC/SD/SDIO controller is used as a connectivity interface
+with external MMC, SD and SDIO storage mediums.
+
+This file documents differences between the core mmc properties described by
+mmc.txt and the properties used by the Samsung S3C24XX MMC/SD/SDIO controller
+implementation.
+
+Required SoC Specific Properties:
+- compatible: should be one of the following
+ - "samsung,s3c2410-sdi": for controllers compatible with s3c2410
+ - "samsung,s3c2412-sdi": for controllers compatible with s3c2412
+ - "samsung,s3c2440-sdi": for controllers compatible with s3c2440
+- clocks: Should reference the controller clock
+- clock-names: Should contain "sdi"
+
+Example:
+ mmc0: mmc at 5a000000 {
+ compatible = "samsung,s3c2440-sdi";
+ pinctrl-names = "default";
+ pinctrl-0 = <&sdi_pins>;
+ reg = <0x5a000000 0x100000>;
+ interrupts = <0 0 21 3>;
+ clocks = <&clocks PCLK_SDI>;
+ clock-names = "sdi";
+ bus-width = <4>;
+ cd-gpios = <&gpg 8 GPIO_ACTIVE_LOW>;
+ wp-gpios = <&gph 8 GPIO_ACTIVE_LOW>;
+ };
+
+ Note: This example shows both SoC specific and board specific properties
+ in a single device node. The properties can be actually be separated
+ into SoC specific node and board specific node.
--
1.9.1
^ permalink raw reply related
* [PATCH v2 0/2] mmc: host: s3cmci: add device tree support
From: Sergio Prado @ 2016-12-09 13:14 UTC (permalink / raw)
To: linux-arm-kernel
This series adds support for configuring Samsung's S3C24XX MMC/SD/SDIO
controller via device tree.
Tested on FriendlyARM mini2440, based on s3c2440 SoC.
Changes since v1:
- pinctrl description removed from DT binding
- unit and label on DT binding renamed to mmc
Sergio Prado (2):
dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
mmc: host: s3cmci: allow probing from device tree
.../devicetree/bindings/mmc/samsung,s3cmci.txt | 34 +++++
drivers/mmc/host/s3cmci.c | 155 +++++++++++++++++----
2 files changed, 165 insertions(+), 24 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
--
1.9.1
^ permalink raw reply
* [PATCH v5 1/7] MFD: add bindings for STM32 General Purpose Timer driver
From: Benjamin Gaignard @ 2016-12-09 12:40 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161209085331.GB3625@dell.home>
2016-12-09 9:53 GMT+01:00 Lee Jones <lee.jones@linaro.org>:
> Sorry to do this Ben. Not much to do now though!
>
>> Add bindings information for STM32 General Purpose Timer
>>
>> version 2:
>> - rename stm32-mfd-timer to stm32-gptimer
>> - only keep one compatible string
>>
>> Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
>> ---
>> .../bindings/mfd/stm32-general-purpose-timer.txt | 39 ++++++++++++++++++++++
>> 1 file changed, 39 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt b/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
>> new file mode 100644
>> index 0000000..ce67755
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/stm32-general-purpose-timer.txt
>> @@ -0,0 +1,39 @@
>> +STM32 General Purpose Timer driver bindings
>
> This is a great place to describe what we're *actually* trying to
> achieve with this driver, and the worst place to use the term "general
> purpose", since this IP is so much more than that.
>
>
> "STM32 Timers
>
> This IP provides 3 types of timer along with PWM functionality.
>
> [...]"
>
> ... then go on to explain what the 3 types are and how they can be
> used.
>
>> +Required parameters:
>> +- compatible: must be "st,stm32-gptimer"
>
> I vehemently disagree that this entire IP is a GP Timer. It contains
> GP timers, sure, but it also contains Advanced and Basic timers.
>
> IMHO this compatible should be "st,stm32-timers".
>
> And the file name of both this and the *.c file should reflect that
> too.
I will do those name changes in v6.
>
> Remainder looks nice.
>
>> +- reg: Physical base address and length of the controller's
>> + registers.
>> +- clock-names: Set to "clk_int".
>> +- clocks: Phandle to the clock used by the timer module.
>> + For Clk properties, please refer to ../clock/clock-bindings.txt
>> +
>> +Optional parameters:
>> +- resets: Phandle to the parent reset controller.
>> + See ../reset/st,stm32-rcc.txt
>> +
>> +Optional subnodes:
>> +- pwm: See ../pwm/pwm-stm32.txt
>> +- timer: See ../iio/timer/stm32-timer-trigger.txt
>> +
>> +Example:
>> + timers at 40010000 {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + compatible = "st,stm32-gptimer";
>> + reg = <0x40010000 0x400>;
>> + clocks = <&rcc 0 160>;
>> + clock-names = "clk_int";
>> +
>> + pwm at 0 {
>
> Out of interest, do you use the "@0", "@1" for anything now?
No I don't use them so I will remove them in v6
>
>> + compatible = "st,stm32-pwm";
>> + pinctrl-0 = <&pwm1_pins>;
>> + pinctrl-names = "default";
>> + };
>> +
>> + timer at 0 {
>> + compatible = "st,stm32-timer-trigger";
>> + reg = <0>;
>> + };
>> + };
>
> --
> Lee Jones
> Linaro STMicroelectronics Landing Team Lead
> Linaro.org ? Open source software for ARM SoCs
> Follow Linaro: Facebook | Twitter | Blog
--
Benjamin Gaignard
Graphic Study Group
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v3] arm64: fpsimd: improve stacking logic in non-interruptible context
From: Dave Martin @ 2016-12-09 12:33 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu-P6ReNVVyyuwF8mE3S7U+X3uK6A=qKmmzU7vQy_SgXWQ@mail.gmail.com>
On Fri, Dec 09, 2016 at 12:24:03PM +0000, Ard Biesheuvel wrote:
> On 9 December 2016 at 12:20, Dave Martin <Dave.Martin@arm.com> wrote:
> > On Thu, Dec 08, 2016 at 04:49:39PM +0000, Ard Biesheuvel wrote:
> >> Currently, we allow kernel mode NEON in softirq or hardirq context by
> >> stacking and unstacking a slice of the NEON register file for each call
> >> to kernel_neon_begin() and kernel_neon_end(), respectively.
> >>
> >> Given that
> >> a) a CPU typically spends most of its time in userland, during which time
> >> no kernel mode NEON in process context is in progress,
> >> b) a CPU spends most of its time in the kernel doing other things than
> >> kernel mode NEON when it gets interrupted to perform kernel mode NEON
> >> in softirq context
> >>
> >> the stacking and subsequent unstacking is only necessary if we are
> >> interrupting a thread while it is performing kernel mode NEON in process
> >> context, which means that in all other cases, we can simply preserve the
> >> userland FPSIMD state once, and only restore it upon return to userland,
> >> even if we are being invoked from softirq or hardirq context.
> >>
> >> So instead of checking whether we are running in interrupt context, keep
> >> track of the level of nested kernel mode NEON calls in progress, and only
> >> perform the eager stack/unstack if the level exceeds 1.
> >>
> >> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> >> ---
> >> v3:
> >> - avoid corruption by concurrent invocations of kernel_neon_begin()/_end()
> >>
> >> v2:
> >> - BUG() on unexpected values of the nesting level
> >> - relax the BUG() on num_regs>32 to a WARN, given that nothing actually
> >> breaks in that case
> >>
> >> arch/arm64/kernel/fpsimd.c | 47 ++++++++++++++------
> >> 1 file changed, 33 insertions(+), 14 deletions(-)
> >>
> >> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> >> index 394c61db5566..536ddab9316d 100644
> >> --- a/arch/arm64/kernel/fpsimd.c
> >> +++ b/arch/arm64/kernel/fpsimd.c
> >> @@ -220,20 +220,35 @@ void fpsimd_flush_task_state(struct task_struct *t)
[...]
> >> + * state structure, we need two additional levels of storage.
> >> + */
> >> +static DEFINE_PER_CPU(struct fpsimd_partial_state, nested_fpsimdstate[2]);
> >> +static DEFINE_PER_CPU(atomic_t, kernel_neon_nesting_level);
> >
> > Come to think of it, should we use this_cpu_{read,add}() etc?
> >
>
> I wasn't aware those existed ...
Actually, nor was I ... I asked Will about local atomics and he
suggested to use those ... then he remembered about the this_cpu_
variants.
The local atomic might still have some barrier semantics, apparently.
For arm64, they're just implemented using the non-local atomics anyway.
>
> > I'm not sure why we need the barrier semantics of atomic_t ops here.
> >
>
> I don't think we do. We only need the atomic increment/decrement, afaict
That's what I was thinking.
Otherwise, the patch looked reasonable to me, but I'll take another look
if you wanted to twiddle the atomics.
Cheers
---Dave
^ permalink raw reply
* [PATCH v3] arm64: fpsimd: improve stacking logic in non-interruptible context
From: Ard Biesheuvel @ 2016-12-09 12:24 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161209122021.GA1574@e103592.cambridge.arm.com>
On 9 December 2016 at 12:20, Dave Martin <Dave.Martin@arm.com> wrote:
> On Thu, Dec 08, 2016 at 04:49:39PM +0000, Ard Biesheuvel wrote:
>> Currently, we allow kernel mode NEON in softirq or hardirq context by
>> stacking and unstacking a slice of the NEON register file for each call
>> to kernel_neon_begin() and kernel_neon_end(), respectively.
>>
>> Given that
>> a) a CPU typically spends most of its time in userland, during which time
>> no kernel mode NEON in process context is in progress,
>> b) a CPU spends most of its time in the kernel doing other things than
>> kernel mode NEON when it gets interrupted to perform kernel mode NEON
>> in softirq context
>>
>> the stacking and subsequent unstacking is only necessary if we are
>> interrupting a thread while it is performing kernel mode NEON in process
>> context, which means that in all other cases, we can simply preserve the
>> userland FPSIMD state once, and only restore it upon return to userland,
>> even if we are being invoked from softirq or hardirq context.
>>
>> So instead of checking whether we are running in interrupt context, keep
>> track of the level of nested kernel mode NEON calls in progress, and only
>> perform the eager stack/unstack if the level exceeds 1.
>>
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> ---
>> v3:
>> - avoid corruption by concurrent invocations of kernel_neon_begin()/_end()
>>
>> v2:
>> - BUG() on unexpected values of the nesting level
>> - relax the BUG() on num_regs>32 to a WARN, given that nothing actually
>> breaks in that case
>>
>> arch/arm64/kernel/fpsimd.c | 47 ++++++++++++++------
>> 1 file changed, 33 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
>> index 394c61db5566..536ddab9316d 100644
>> --- a/arch/arm64/kernel/fpsimd.c
>> +++ b/arch/arm64/kernel/fpsimd.c
>> @@ -220,20 +220,35 @@ void fpsimd_flush_task_state(struct task_struct *t)
>>
>> #ifdef CONFIG_KERNEL_MODE_NEON
>>
>> -static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate);
>> -static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate);
>> +/*
>> + * Although unlikely, it is possible for three kernel mode NEON contexts to
>> + * be live at the same time: process context, softirq context and hardirq
>> + * context. So while the userland context is stashed in the thread's fpsimd
>> + * state structure, we need two additional levels of storage.
>> + */
>> +static DEFINE_PER_CPU(struct fpsimd_partial_state, nested_fpsimdstate[2]);
>> +static DEFINE_PER_CPU(atomic_t, kernel_neon_nesting_level);
>
> Come to think of it, should we use this_cpu_{read,add}() etc?
>
I wasn't aware those existed ...
> I'm not sure why we need the barrier semantics of atomic_t ops here.
>
I don't think we do. We only need the atomic increment/decrement, afaict
^ permalink raw reply
* [PATCH v2] arm64: mm: Fix memmap to be initialized for the entire section
From: Hanjun Guo @ 2016-12-09 12:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAKv+Gu_XsKU6godiQC7wVDmCUC9bZL=kv0RarTOTATuQ5EZp2Q@mail.gmail.com>
On 12/09/2016 08:19 PM, Ard Biesheuvel wrote:
> On 9 December 2016 at 12:14, Yisheng Xie <xieyisheng1@huawei.com> wrote:
>> Hi Robert,
>> We have merged your patch to 4.9.0-rc8, however we still meet the similar problem
>> on our D05 board:
>>
>
> To be clear: does this issue also occur on D05 *without* the patch?
It boots ok on D05 without this patch.
But I think the problem Robert described in the commit message is
still there, just not triggered in the boot. we met this problem
when having LTP stress memory test and hit the same BUG_ON.
Thanks
Hanjun
^ permalink raw reply
* [PATCH v3] arm64: fpsimd: improve stacking logic in non-interruptible context
From: Dave Martin @ 2016-12-09 12:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481215779-23432-1-git-send-email-ard.biesheuvel@linaro.org>
On Thu, Dec 08, 2016 at 04:49:39PM +0000, Ard Biesheuvel wrote:
> Currently, we allow kernel mode NEON in softirq or hardirq context by
> stacking and unstacking a slice of the NEON register file for each call
> to kernel_neon_begin() and kernel_neon_end(), respectively.
>
> Given that
> a) a CPU typically spends most of its time in userland, during which time
> no kernel mode NEON in process context is in progress,
> b) a CPU spends most of its time in the kernel doing other things than
> kernel mode NEON when it gets interrupted to perform kernel mode NEON
> in softirq context
>
> the stacking and subsequent unstacking is only necessary if we are
> interrupting a thread while it is performing kernel mode NEON in process
> context, which means that in all other cases, we can simply preserve the
> userland FPSIMD state once, and only restore it upon return to userland,
> even if we are being invoked from softirq or hardirq context.
>
> So instead of checking whether we are running in interrupt context, keep
> track of the level of nested kernel mode NEON calls in progress, and only
> perform the eager stack/unstack if the level exceeds 1.
>
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> v3:
> - avoid corruption by concurrent invocations of kernel_neon_begin()/_end()
>
> v2:
> - BUG() on unexpected values of the nesting level
> - relax the BUG() on num_regs>32 to a WARN, given that nothing actually
> breaks in that case
>
> arch/arm64/kernel/fpsimd.c | 47 ++++++++++++++------
> 1 file changed, 33 insertions(+), 14 deletions(-)
>
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index 394c61db5566..536ddab9316d 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -220,20 +220,35 @@ void fpsimd_flush_task_state(struct task_struct *t)
>
> #ifdef CONFIG_KERNEL_MODE_NEON
>
> -static DEFINE_PER_CPU(struct fpsimd_partial_state, hardirq_fpsimdstate);
> -static DEFINE_PER_CPU(struct fpsimd_partial_state, softirq_fpsimdstate);
> +/*
> + * Although unlikely, it is possible for three kernel mode NEON contexts to
> + * be live at the same time: process context, softirq context and hardirq
> + * context. So while the userland context is stashed in the thread's fpsimd
> + * state structure, we need two additional levels of storage.
> + */
> +static DEFINE_PER_CPU(struct fpsimd_partial_state, nested_fpsimdstate[2]);
> +static DEFINE_PER_CPU(atomic_t, kernel_neon_nesting_level);
Come to think of it, should we use this_cpu_{read,add}() etc?
I'm not sure why we need the barrier semantics of atomic_t ops here.
[...]
Cheers
---Dave
^ permalink raw reply
* [PATCH v2] arm64: mm: Fix memmap to be initialized for the entire section
From: Ard Biesheuvel @ 2016-12-09 12:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <bc099ca6-d927-3eb6-438c-291a66ecf5f9@huawei.com>
On 9 December 2016 at 12:14, Yisheng Xie <xieyisheng1@huawei.com> wrote:
> Hi Robert,
> We have merged your patch to 4.9.0-rc8, however we still meet the similar problem
> on our D05 board:
>
To be clear: does this issue also occur on D05 *without* the patch?
> -----------------
> [ 5.081971] ------------[ cut here ]------------
> [ 5.086668] kernel BUG at mm/page_alloc.c:1863!
> [ 5.091281] Internal error: Oops - BUG: 0 [#1] SMP
> [ 5.096159] Modules linked in:
> [ 5.099265] CPU: 61 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc8+ #58
> [ 5.105822] Hardware name: Huawei Taishan 2280 /D05, BIOS Hisilicon D05 UEFI 16.08 RC1 12/08/2016
> [ 5.114860] task: fffffe13f23d7400 task.stack: fffffe13f66f8000
> [ 5.120903] PC is at move_freepages+0x170/0x180
> [ 5.125514] LR is at move_freepages_block+0xa8/0xb8
> [ 5.130479] pc : [<fffffc00081e9588>] lr : [<fffffc00081e9640>] pstate: 200000c5
> [ 5.138008] sp : fffffe13f66fb910
> [ 5.141375] x29: fffffe13f66fb910 x28: 00000000ffffff80
> [ 5.146784] x27: fffffdff800b0000 x26: fffffe13fbf62b90
> [ 5.152193] x25: 000000000000000a x24: fffffdff800b0020
> [ 5.157598] x23: 0000000000000000 x22: fffffdff800b0000
> [ 5.163006] x21: fffffdff800fffc0 x20: fffffe13fbf62680
> [ 5.168412] x19: fffffdff80080000 x18: 000000004c4d6d26
> [ 5.173820] x17: 0000000000000000 x16: 0000000000000000
> [ 5.179226] x15: 000000005c589429 x14: 0000000000000000
> [ 5.184634] x13: 0000000000000000 x12: 00000000fe2ce6e0
> [ 5.190039] x11: 00000000bb5b525b x10: 00000000bb48417b
> [ 5.195446] x9 : 0000000000000068 x8 : 0000000000000000
> [ 5.200854] x7 : fffffe13fbff2680 x6 : 0000000000000001
> [ 5.206260] x5 : fffffc0008e12328 x4 : 0000000000000000
> [ 5.211667] x3 : fffffe13fbf62680 x2 : 0000000000000000
> [ 5.217073] x1 : fffffe13fbff2680 x0 : fffffe13fbf62680
> [...]
> [ 5.768991] [<fffffc00081e9588>] move_freepages+0x170/0x180
> [ 5.774664] [<fffffc00081e9640>] move_freepages_block+0xa8/0xb8
> [ 5.780691] [<fffffc00081e9bbc>] __rmqueue+0x494/0x5f0
> [ 5.785921] [<fffffc00081eb10c>] get_page_from_freelist+0x5ec/0xb58
> [ 5.792302] [<fffffc00081ebc4c>] __alloc_pages_nodemask+0x144/0xd08
> [ 5.798687] [<fffffc0008240514>] alloc_page_interleave+0x64/0xc0
> [ 5.804801] [<fffffc0008240b20>] alloc_pages_current+0x108/0x168
> [ 5.810920] [<fffffc0008c75410>] atomic_pool_init+0x78/0x1cc
> [ 5.816680] [<fffffc0008c755a0>] arm64_dma_init+0x3c/0x44
> [ 5.822180] [<fffffc0008082d94>] do_one_initcall+0x44/0x138
> [ 5.827853] [<fffffc0008c70d54>] kernel_init_freeable+0x1ec/0x28c
> [ 5.834060] [<fffffc00088a79f0>] kernel_init+0x18/0x110
> [ 5.839378] [<fffffc0008082b30>] ret_from_fork+0x10/0x20
> [ 5.844785] Code: 9108a021 9400afc5 d4210000 d503201f (d4210000)
> [ 5.851024] ---[ end trace 3382df1ae82057db ]---
>
>
> On 2016/12/1 2:21, Robert Richter wrote:
>> On ThunderX systems with certain memory configurations we see the
>> following BUG_ON():
>>
>> kernel BUG at mm/page_alloc.c:1848!
>>
>> This happens for some configs with 64k page size enabled. The BUG_ON()
>> checks if start and end page of a memmap range belongs to the same
>> zone.
>>
>> The BUG_ON() check fails if a memory zone contains NOMAP regions. In
>> this case the node information of those pages is not initialized. This
>> causes an inconsistency of the page links with wrong zone and node
>> information for that pages. NOMAP pages from node 1 still point to the
>> mem zone from node 0 and have the wrong nid assigned.
>>
>> The reason for the mis-configuration is a change in pfn_valid() which
>> reports pages marked NOMAP as invalid:
>>
>> 68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping
>>
>> This causes pages marked as nomap being no long reassigned to the new
>> zone in memmap_init_zone() by calling __init_single_pfn().
>>
>> Fixing this by restoring the old behavior of pfn_valid() to use
>> memblock_is_memory(). Also changing users of pfn_valid() in arm64 code
>> to use memblock_is_map_memory() where necessary. This only affects
>> code in ioremap.c. The code in mmu.c still can use the new version of
>> pfn_valid().
>>
>> As a consequence, pfn_valid() can not be used to check if a physical
>> page is RAM. It just checks if there is an underlying memmap with a
>> valid struct page. Moreover, for performance reasons the whole memmap
>> (with pageblock_nr_pages number of pages) has valid pfns (SPARSEMEM
>> config). The memory range is extended to fit the alignment of the
>> memmap. Thus, pfn_valid() may return true for pfns that do not map to
>> physical memory. Those pages are simply not reported to the mm, they
>> are not marked reserved nor added to the list of free pages. Other
>> functions such a page_is_ram() or memblock_is_map_ memory() must be
>> used to check for memory and if the page can be mapped with the linear
>> mapping.
>>
>> Since NOMAP mem ranges may need to be mapped with different mem
>> attributes (e.g. read-only or non-caching) we can not use linear
>> mapping here. The use of memblock_is_memory() in pfn_valid() may not
>> break this behaviour. Since commit:
>>
>> e7cd190385d1 arm64: mark reserved memblock regions explicitly in iomem
>>
>> NOMAP mem resources are no longer marked as system RAM (IORESOURCE_
>> SYSTEM_RAM). Now page_is_ram() and region_intersects() (see
>> memremap()) do not detect NOMAP mem as system ram and NOMAP mem is not
>> added to the linear mapping as system RAM is.
>>
>> v2:
>>
>> * Added Ack
>> * updated description to reflect the discussion
>>
>> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Signed-off-by: Robert Richter <rrichter@cavium.com>
>> ---
>> arch/arm64/mm/init.c | 2 +-
>> arch/arm64/mm/ioremap.c | 5 +++--
>> 2 files changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
>> index 212c4d1e2f26..166911f4a2e6 100644
>> --- a/arch/arm64/mm/init.c
>> +++ b/arch/arm64/mm/init.c
>> @@ -147,7 +147,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
>> #ifdef CONFIG_HAVE_ARCH_PFN_VALID
>> int pfn_valid(unsigned long pfn)
>> {
>> - return memblock_is_map_memory(pfn << PAGE_SHIFT);
>> + return memblock_is_memory(pfn << PAGE_SHIFT);
>> }
>> EXPORT_SYMBOL(pfn_valid);
>> #endif
>> diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
>> index 01e88c8bcab0..c17c220b0c48 100644
>> --- a/arch/arm64/mm/ioremap.c
>> +++ b/arch/arm64/mm/ioremap.c
>> @@ -21,6 +21,7 @@
>> */
>>
>> #include <linux/export.h>
>> +#include <linux/memblock.h>
>> #include <linux/mm.h>
>> #include <linux/vmalloc.h>
>> #include <linux/io.h>
>> @@ -55,7 +56,7 @@ static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
>> /*
>> * Don't allow RAM to be mapped.
>> */
>> - if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
>> + if (WARN_ON(memblock_is_map_memory(phys_addr)))
>> return NULL;
>>
>> area = get_vm_area_caller(size, VM_IOREMAP, caller);
>> @@ -96,7 +97,7 @@ EXPORT_SYMBOL(__iounmap);
>> void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
>> {
>> /* For normal memory we already have a cacheable mapping. */
>> - if (pfn_valid(__phys_to_pfn(phys_addr)))
>> + if (memblock_is_map_memory(phys_addr))
>> return (void __iomem *)__phys_to_virt(phys_addr);
>>
>> return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL),
>>
>
^ permalink raw reply
* [PATCH v2] arm64: mm: Fix memmap to be initialized for the entire section
From: Yisheng Xie @ 2016-12-09 12:14 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1480530091-1092-1-git-send-email-rrichter@cavium.com>
Hi Robert,
We have merged your patch to 4.9.0-rc8, however we still meet the similar problem
on our D05 board:
Thanks,
Yisheng Xie
-----------------
[ 5.081971] ------------[ cut here ]------------
[ 5.086668] kernel BUG at mm/page_alloc.c:1863!
[ 5.091281] Internal error: Oops - BUG: 0 [#1] SMP
[ 5.096159] Modules linked in:
[ 5.099265] CPU: 61 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc8+ #58
[ 5.105822] Hardware name: Huawei Taishan 2280 /D05, BIOS Hisilicon D05 UEFI 16.08 RC1 12/08/2016
[ 5.114860] task: fffffe13f23d7400 task.stack: fffffe13f66f8000
[ 5.120903] PC is at move_freepages+0x170/0x180
[ 5.125514] LR is at move_freepages_block+0xa8/0xb8
[ 5.130479] pc : [<fffffc00081e9588>] lr : [<fffffc00081e9640>] pstate: 200000c5
[ 5.138008] sp : fffffe13f66fb910
[ 5.141375] x29: fffffe13f66fb910 x28: 00000000ffffff80
[ 5.146784] x27: fffffdff800b0000 x26: fffffe13fbf62b90
[ 5.152193] x25: 000000000000000a x24: fffffdff800b0020
[ 5.157598] x23: 0000000000000000 x22: fffffdff800b0000
[ 5.163006] x21: fffffdff800fffc0 x20: fffffe13fbf62680
[ 5.168412] x19: fffffdff80080000 x18: 000000004c4d6d26
[ 5.173820] x17: 0000000000000000 x16: 0000000000000000
[ 5.179226] x15: 000000005c589429 x14: 0000000000000000
[ 5.184634] x13: 0000000000000000 x12: 00000000fe2ce6e0
[ 5.190039] x11: 00000000bb5b525b x10: 00000000bb48417b
[ 5.195446] x9 : 0000000000000068 x8 : 0000000000000000
[ 5.200854] x7 : fffffe13fbff2680 x6 : 0000000000000001
[ 5.206260] x5 : fffffc0008e12328 x4 : 0000000000000000
[ 5.211667] x3 : fffffe13fbf62680 x2 : 0000000000000000
[ 5.217073] x1 : fffffe13fbff2680 x0 : fffffe13fbf62680
[...]
[ 5.768991] [<fffffc00081e9588>] move_freepages+0x170/0x180
[ 5.774664] [<fffffc00081e9640>] move_freepages_block+0xa8/0xb8
[ 5.780691] [<fffffc00081e9bbc>] __rmqueue+0x494/0x5f0
[ 5.785921] [<fffffc00081eb10c>] get_page_from_freelist+0x5ec/0xb58
[ 5.792302] [<fffffc00081ebc4c>] __alloc_pages_nodemask+0x144/0xd08
[ 5.798687] [<fffffc0008240514>] alloc_page_interleave+0x64/0xc0
[ 5.804801] [<fffffc0008240b20>] alloc_pages_current+0x108/0x168
[ 5.810920] [<fffffc0008c75410>] atomic_pool_init+0x78/0x1cc
[ 5.816680] [<fffffc0008c755a0>] arm64_dma_init+0x3c/0x44
[ 5.822180] [<fffffc0008082d94>] do_one_initcall+0x44/0x138
[ 5.827853] [<fffffc0008c70d54>] kernel_init_freeable+0x1ec/0x28c
[ 5.834060] [<fffffc00088a79f0>] kernel_init+0x18/0x110
[ 5.839378] [<fffffc0008082b30>] ret_from_fork+0x10/0x20
[ 5.844785] Code: 9108a021 9400afc5 d4210000 d503201f (d4210000)
[ 5.851024] ---[ end trace 3382df1ae82057db ]---
On 2016/12/1 2:21, Robert Richter wrote:
> On ThunderX systems with certain memory configurations we see the
> following BUG_ON():
>
> kernel BUG at mm/page_alloc.c:1848!
>
> This happens for some configs with 64k page size enabled. The BUG_ON()
> checks if start and end page of a memmap range belongs to the same
> zone.
>
> The BUG_ON() check fails if a memory zone contains NOMAP regions. In
> this case the node information of those pages is not initialized. This
> causes an inconsistency of the page links with wrong zone and node
> information for that pages. NOMAP pages from node 1 still point to the
> mem zone from node 0 and have the wrong nid assigned.
>
> The reason for the mis-configuration is a change in pfn_valid() which
> reports pages marked NOMAP as invalid:
>
> 68709f45385a arm64: only consider memblocks with NOMAP cleared for linear mapping
>
> This causes pages marked as nomap being no long reassigned to the new
> zone in memmap_init_zone() by calling __init_single_pfn().
>
> Fixing this by restoring the old behavior of pfn_valid() to use
> memblock_is_memory(). Also changing users of pfn_valid() in arm64 code
> to use memblock_is_map_memory() where necessary. This only affects
> code in ioremap.c. The code in mmu.c still can use the new version of
> pfn_valid().
>
> As a consequence, pfn_valid() can not be used to check if a physical
> page is RAM. It just checks if there is an underlying memmap with a
> valid struct page. Moreover, for performance reasons the whole memmap
> (with pageblock_nr_pages number of pages) has valid pfns (SPARSEMEM
> config). The memory range is extended to fit the alignment of the
> memmap. Thus, pfn_valid() may return true for pfns that do not map to
> physical memory. Those pages are simply not reported to the mm, they
> are not marked reserved nor added to the list of free pages. Other
> functions such a page_is_ram() or memblock_is_map_ memory() must be
> used to check for memory and if the page can be mapped with the linear
> mapping.
>
> Since NOMAP mem ranges may need to be mapped with different mem
> attributes (e.g. read-only or non-caching) we can not use linear
> mapping here. The use of memblock_is_memory() in pfn_valid() may not
> break this behaviour. Since commit:
>
> e7cd190385d1 arm64: mark reserved memblock regions explicitly in iomem
>
> NOMAP mem resources are no longer marked as system RAM (IORESOURCE_
> SYSTEM_RAM). Now page_is_ram() and region_intersects() (see
> memremap()) do not detect NOMAP mem as system ram and NOMAP mem is not
> added to the linear mapping as system RAM is.
>
> v2:
>
> * Added Ack
> * updated description to reflect the discussion
>
> Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Signed-off-by: Robert Richter <rrichter@cavium.com>
> ---
> arch/arm64/mm/init.c | 2 +-
> arch/arm64/mm/ioremap.c | 5 +++--
> 2 files changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
> index 212c4d1e2f26..166911f4a2e6 100644
> --- a/arch/arm64/mm/init.c
> +++ b/arch/arm64/mm/init.c
> @@ -147,7 +147,7 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
> #ifdef CONFIG_HAVE_ARCH_PFN_VALID
> int pfn_valid(unsigned long pfn)
> {
> - return memblock_is_map_memory(pfn << PAGE_SHIFT);
> + return memblock_is_memory(pfn << PAGE_SHIFT);
> }
> EXPORT_SYMBOL(pfn_valid);
> #endif
> diff --git a/arch/arm64/mm/ioremap.c b/arch/arm64/mm/ioremap.c
> index 01e88c8bcab0..c17c220b0c48 100644
> --- a/arch/arm64/mm/ioremap.c
> +++ b/arch/arm64/mm/ioremap.c
> @@ -21,6 +21,7 @@
> */
>
> #include <linux/export.h>
> +#include <linux/memblock.h>
> #include <linux/mm.h>
> #include <linux/vmalloc.h>
> #include <linux/io.h>
> @@ -55,7 +56,7 @@ static void __iomem *__ioremap_caller(phys_addr_t phys_addr, size_t size,
> /*
> * Don't allow RAM to be mapped.
> */
> - if (WARN_ON(pfn_valid(__phys_to_pfn(phys_addr))))
> + if (WARN_ON(memblock_is_map_memory(phys_addr)))
> return NULL;
>
> area = get_vm_area_caller(size, VM_IOREMAP, caller);
> @@ -96,7 +97,7 @@ EXPORT_SYMBOL(__iounmap);
> void __iomem *ioremap_cache(phys_addr_t phys_addr, size_t size)
> {
> /* For normal memory we already have a cacheable mapping. */
> - if (pfn_valid(__phys_to_pfn(phys_addr)))
> + if (memblock_is_map_memory(phys_addr))
> return (void __iomem *)__phys_to_virt(phys_addr);
>
> return __ioremap_caller(phys_addr, size, __pgprot(PROT_NORMAL),
>
^ permalink raw reply
* [PATCH v8 01/16] FDT: introduce global phandle allocation
From: Marc Zyngier @ 2016-12-09 12:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161104173203.21168-2-andre.przywara@arm.com>
On 04/11/16 17:31, Andre Przywara wrote:
> Allocating an FDT phandle (a unique identifier) using a static
> variable in a static inline function defined in a header file works
> only if all users are in the same source file. So trying to allocate
> a handle from two different compilation units fails.
> Introduce global phandle allocation and reference code to properly
> allocate unique phandles.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> Makefile | 1 +
> arm/fdt.c | 2 +-
> arm/gic.c | 2 +-
> include/kvm/fdt.h | 10 +++++-----
> kvm-fdt.c | 26 ++++++++++++++++++++++++++
> 5 files changed, 34 insertions(+), 7 deletions(-)
> create mode 100644 kvm-fdt.c
>
> diff --git a/Makefile b/Makefile
> index 1f0196f..e4a4002 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -98,6 +98,7 @@ OBJS += kvm-ipc.o
> OBJS += builtin-sandbox.o
> OBJS += virtio/mmio.o
> OBJS += hw/i8042.o
> +OBJS += kvm-fdt.o
>
> # Translate uname -m into ARCH string
> ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
> diff --git a/arm/fdt.c b/arm/fdt.c
> index 381d48f..8bcfffb 100644
> --- a/arm/fdt.c
> +++ b/arm/fdt.c
> @@ -114,7 +114,7 @@ static int setup_fdt(struct kvm *kvm)
> {
> struct device_header *dev_hdr;
> u8 staging_fdt[FDT_MAX_SIZE];
> - u32 gic_phandle = fdt__alloc_phandle();
> + u32 gic_phandle = fdt__get_phandle(PHANDLE_GIC);
> u64 mem_reg_prop[] = {
> cpu_to_fdt64(kvm->arch.memory_guest_start),
> cpu_to_fdt64(kvm->ram_size),
> diff --git a/arm/gic.c b/arm/gic.c
> index d6d6dd0..b60437e 100644
> --- a/arm/gic.c
> +++ b/arm/gic.c
> @@ -222,7 +222,7 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
> _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
> _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
> _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
> - _FDT(fdt_property_cell(fdt, "phandle", phandle));
> + _FDT(fdt_property_cell(fdt, "phandle", fdt__get_phandle(PHANDLE_GIC)));
> _FDT(fdt_end_node(fdt));
> }
>
> diff --git a/include/kvm/fdt.h b/include/kvm/fdt.h
> index 53d85a4..cd2bb72 100644
> --- a/include/kvm/fdt.h
> +++ b/include/kvm/fdt.h
> @@ -8,6 +8,10 @@
> #include <linux/types.h>
>
> #define FDT_MAX_SIZE 0x10000
> +#define FDT_INVALID_PHANDLE 0
> +#define FDT_IS_VALID_PHANDLE(phandle) ((phandle) != FDT_INVALID_PHANDLE)
> +
> +enum phandles {PHANDLE_GIC, PHANDLES_MAX};
Another nit here: PHANDLE_GIC is pretty much ARM-specific, while FDT is
supposed to be generic. Can't we move the enum to be architecture
specific and not put this in an architecture agnostic one?
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH v8 01/16] FDT: introduce global phandle allocation
From: Marc Zyngier @ 2016-12-09 11:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161104173203.21168-2-andre.przywara@arm.com>
Hi Andre,
On 04/11/16 17:31, Andre Przywara wrote:
> Allocating an FDT phandle (a unique identifier) using a static
> variable in a static inline function defined in a header file works
> only if all users are in the same source file. So trying to allocate
> a handle from two different compilation units fails.
> Introduce global phandle allocation and reference code to properly
> allocate unique phandles.
>
> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
> ---
> Makefile | 1 +
> arm/fdt.c | 2 +-
> arm/gic.c | 2 +-
> include/kvm/fdt.h | 10 +++++-----
> kvm-fdt.c | 26 ++++++++++++++++++++++++++
> 5 files changed, 34 insertions(+), 7 deletions(-)
> create mode 100644 kvm-fdt.c
>
> diff --git a/Makefile b/Makefile
> index 1f0196f..e4a4002 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -98,6 +98,7 @@ OBJS += kvm-ipc.o
> OBJS += builtin-sandbox.o
> OBJS += virtio/mmio.o
> OBJS += hw/i8042.o
> +OBJS += kvm-fdt.o
>
> # Translate uname -m into ARCH string
> ARCH ?= $(shell uname -m | sed -e s/i.86/i386/ -e s/ppc.*/powerpc/ \
> diff --git a/arm/fdt.c b/arm/fdt.c
> index 381d48f..8bcfffb 100644
> --- a/arm/fdt.c
> +++ b/arm/fdt.c
> @@ -114,7 +114,7 @@ static int setup_fdt(struct kvm *kvm)
> {
> struct device_header *dev_hdr;
> u8 staging_fdt[FDT_MAX_SIZE];
> - u32 gic_phandle = fdt__alloc_phandle();
> + u32 gic_phandle = fdt__get_phandle(PHANDLE_GIC);
> u64 mem_reg_prop[] = {
> cpu_to_fdt64(kvm->arch.memory_guest_start),
> cpu_to_fdt64(kvm->ram_size),
> diff --git a/arm/gic.c b/arm/gic.c
> index d6d6dd0..b60437e 100644
> --- a/arm/gic.c
> +++ b/arm/gic.c
> @@ -222,7 +222,7 @@ void gic__generate_fdt_nodes(void *fdt, u32 phandle, enum irqchip_type type)
> _FDT(fdt_property_cell(fdt, "#interrupt-cells", GIC_FDT_IRQ_NUM_CELLS));
> _FDT(fdt_property(fdt, "interrupt-controller", NULL, 0));
> _FDT(fdt_property(fdt, "reg", reg_prop, sizeof(reg_prop)));
> - _FDT(fdt_property_cell(fdt, "phandle", phandle));
> + _FDT(fdt_property_cell(fdt, "phandle", fdt__get_phandle(PHANDLE_GIC)));
> _FDT(fdt_end_node(fdt));
> }
>
> diff --git a/include/kvm/fdt.h b/include/kvm/fdt.h
> index 53d85a4..cd2bb72 100644
> --- a/include/kvm/fdt.h
> +++ b/include/kvm/fdt.h
> @@ -8,6 +8,10 @@
> #include <linux/types.h>
>
> #define FDT_MAX_SIZE 0x10000
> +#define FDT_INVALID_PHANDLE 0
> +#define FDT_IS_VALID_PHANDLE(phandle) ((phandle) != FDT_INVALID_PHANDLE)
> +
> +enum phandles {PHANDLE_GIC, PHANDLES_MAX};
>
> /* Those definitions are generic FDT values for specifying IRQ
> * types and are used in the Linux kernel internally as well as in
> @@ -33,10 +37,6 @@ enum irq_type {
> } \
> } while (0)
>
> -static inline u32 fdt__alloc_phandle(void)
> -{
> - static u32 phandle = 0;
> - return ++phandle;
> -}
> +u32 fdt__get_phandle(enum phandles phandle);
>
> #endif /* KVM__FDT_H */
> diff --git a/kvm-fdt.c b/kvm-fdt.c
> new file mode 100644
> index 0000000..d05f3fe
> --- /dev/null
> +++ b/kvm-fdt.c
> @@ -0,0 +1,26 @@
> +/*
> + * Commonly used FDT functions.
> + */
> +
> +#include <stdio.h>
> +#include "kvm/fdt.h"
> +#include "kvm/util.h"
> +
> +u32 phandles[PHANDLES_MAX] = {};
It is a bit weird that you're initializing this to zero...
> +u32 next_phandle = 1;
> +
> +u32 fdt__get_phandle(enum phandles phandle)
> +{
> + u32 ret;
> +
> + if (phandle >= PHANDLES_MAX)
> + return FDT_INVALID_PHANDLE;
> +
> + ret = phandles[phandle];
> + if (ret == FDT_INVALID_PHANDLE) {
and yet test against a #define that isn't the initializer.
Also, given that fdt__get_phandle() can now fail by returning
FDT_INVALID_HANDLE, maybe we should abort instead of returning something
that is definitely wrong and use it blindly (which is going to be fun to
debug...).
> + ret = next_phandle++;
> + phandles[phandle] = ret;
> + }
> +
> + return ret;
> +}
>
Thanks,
M.
--
Jazz is not dead. It just smells funny...
^ permalink raw reply
* [PATCH 02/12] ARM: dts: imx6qdl: rename ipu client nodes
From: Philipp Zabel @ 2016-12-09 11:39 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1481158673-15937-3-git-send-email-steve_longerbeam@mentor.com>
Hi Steve,
Am Mittwoch, den 07.12.2016, 16:57 -0800 schrieb Steve Longerbeam:
> To allow for IPU client devices that are composed of more than one
> port for input and output (SMFC and IC), change the nodes from being
> a single port node to nodes that can contain multiple ports. Rename
> the nodes to use the following format: "ipu<id>_<subunit>".
Don't do this. These are not IPU client device nodes, they are input and
output port nodes according to the of graph bindings, as described in
Documentation/devicetree/bindings/display/imx/fsl-imx-drm.txt.
They happen to match to the CSI0/1 and DI0/1 modules, but really what is
described here are the external connections of the IPU. The IPU
internals are not described in the device tree at all.
regards
Philipp
> The IPUv3 driver will then need to lookup the client nodes by name
> rather than by port id.
>
> Signed-off-by: Steve Longerbeam <steve_longerbeam@mentor.com>
> ---
> arch/arm/boot/dts/imx6q.dtsi | 12 ++++++------
> arch/arm/boot/dts/imx6qdl.dtsi | 12 ++++++------
> 2 files changed, 12 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
> index e9a5d0b..2b261ba 100644
> --- a/arch/arm/boot/dts/imx6q.dtsi
> +++ b/arch/arm/boot/dts/imx6q.dtsi
> @@ -141,18 +141,18 @@
> clock-names = "bus", "di0", "di1";
> resets = <&src 4>;
>
> - ipu2_csi0: port at 0 {
> + ipu2_csi0: ipu2_csi at 0 {
> reg = <0>;
> };
>
> - ipu2_csi1: port at 1 {
> + ipu2_csi1: ipu2_csi at 1 {
> reg = <1>;
> };
>
> - ipu2_di0: port at 2 {
> + ipu2_di0: ipu2_di at 0 {
> #address-cells = <1>;
> #size-cells = <0>;
> - reg = <2>;
> + reg = <0>;
>
> ipu2_di0_disp0: disp0-endpoint {
> };
> @@ -174,10 +174,10 @@
> };
> };
>
> - ipu2_di1: port at 3 {
> + ipu2_di1: ipu2_di at 1 {
> #address-cells = <1>;
> #size-cells = <0>;
> - reg = <3>;
> + reg = <1>;
>
> ipu2_di1_hdmi: hdmi-endpoint {
> remote-endpoint = <&hdmi_mux_3>;
> diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
> index e01e5d5..2465187 100644
> --- a/arch/arm/boot/dts/imx6qdl.dtsi
> +++ b/arch/arm/boot/dts/imx6qdl.dtsi
> @@ -1226,18 +1226,18 @@
> clock-names = "bus", "di0", "di1";
> resets = <&src 2>;
>
> - ipu1_csi0: port at 0 {
> + ipu1_csi0: ipu1_csi at 0 {
> reg = <0>;
> };
>
> - ipu1_csi1: port at 1 {
> + ipu1_csi1: ipu1_csi at 1 {
> reg = <1>;
> };
>
> - ipu1_di0: port at 2 {
> + ipu1_di0: ipu1_di at 0 {
> #address-cells = <1>;
> #size-cells = <0>;
> - reg = <2>;
> + reg = <0>;
>
> ipu1_di0_disp0: disp0-endpoint {
> };
> @@ -1259,10 +1259,10 @@
> };
> };
>
> - ipu1_di1: port at 3 {
> + ipu1_di1: ipu1_di at 1 {
> #address-cells = <1>;
> #size-cells = <0>;
> - reg = <3>;
> + reg = <1>;
>
> ipu1_di1_disp1: disp1-endpoint {
> };
^ permalink raw reply
* Tearing down DMA transfer setup after DMA client has finished
From: 1Måns Rullgård @ 2016-12-09 11:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6ce1ea97-1d68-2203-c7b4-73315e801655@laposte.net>
Sebastian Frias <sf84@laposte.net> writes:
> On 09/12/16 07:59, Vinod Koul wrote:
>> On Thu, Dec 08, 2016 at 04:48:18PM +0000, M?ns Rullg?rd wrote:
>>> Vinod Koul <vinod.koul@intel.com> writes:
>>>
>>>> To make it efficient, disregarding your Sbox HW issue, the solution is
>>>> virtual channels. You can delink physical channels and virtual channels. If
>>>> one has SW controlled MUX then a channel can service any client. For few
>>>> controllers request lines are hard wired so they cant use any channel. But
>>>> if you dont have this restriction then driver can queue up many transactions
>>>> from different controllers.
>>>
>>> Have you been paying attention at all? This exactly what the driver
>>> ALREADY DOES.
>>
>> And have you read what the question was?
I wrote the driver. I think I know what Mason and I are asking.
> I think many people appreciate the quick turn around time and
> responsiveness of knowledgeable people making constructive remarks in
> this thread, but it looks we are slowly drifting away from the main
> problem.
>
> If we had to sum up the discussion, the current DMA API/framework in
> Linux seems to lack a way to properly handle this HW (or if it has a
> way, the information got lost somewhere).
>
> What concrete solution do you propose?
>
> Alternatively, one can think of the current issue (i.e.: the fact that
> the IRQ arrives "too soon") in a different way. Instead of thinking
> the IRQ indicates "transfer complete", it is indicating "ready to
> accept another command", which in practice (and with proper API
> support) can translate into efficient queuing of DMA operations.
For multiple back to back transfers to the same peripheral, it is indeed
a slight optimisation. What's apparently lacking is some way of doing a
full flush at the end of a series of transfers, before switching the
channel to another device.
--
M?ns Rullg?rd
^ permalink raw reply
* Tearing down DMA transfer setup after DMA client has finished
From: Måns Rullgård @ 2016-12-09 11:34 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <6ce1ea97-1d68-2203-c7b4-73315e801655@laposte.net>
Sebastian Frias <sf84@laposte.net> writes:
> On 09/12/16 07:59, Vinod Koul wrote:
>> On Thu, Dec 08, 2016 at 04:48:18PM +0000, M?ns Rullg?rd wrote:
>>> Vinod Koul <vinod.koul@intel.com> writes:
>>>
>>>> To make it efficient, disregarding your Sbox HW issue, the solution is
>>>> virtual channels. You can delink physical channels and virtual channels. If
>>>> one has SW controlled MUX then a channel can service any client. For few
>>>> controllers request lines are hard wired so they cant use any channel. But
>>>> if you dont have this restriction then driver can queue up many transactions
>>>> from different controllers.
>>>
>>> Have you been paying attention at all? This exactly what the driver
>>> ALREADY DOES.
>>
>> And have you read what the question was?
I wrote the driver. I think I know what Mason and I are asking.
> I think many people appreciate the quick turn around time and
> responsiveness of knowledgeable people making constructive remarks in
> this thread, but it looks we are slowly drifting away from the main
> problem.
>
> If we had to sum up the discussion, the current DMA API/framework in
> Linux seems to lack a way to properly handle this HW (or if it has a
> way, the information got lost somewhere).
>
> What concrete solution do you propose?
>
> Alternatively, one can think of the current issue (i.e.: the fact that
> the IRQ arrives "too soon") in a different way. Instead of thinking
> the IRQ indicates "transfer complete", it is indicating "ready to
> accept another command", which in practice (and with proper API
> support) can translate into efficient queuing of DMA operations.
For multiple back to back transfers to the same peripheral, it is indeed
a slight optimisation. What's apparently lacking is some way of doing a
full flush
--
M?ns Rullg?rd
^ permalink raw reply
* [PATCH v2 1/8] mfd: sun6i-prcm: Add codec analog controls sub-device for Allwinner A23
From: Lee Jones @ 2016-12-09 11:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161125123442.28410-2-wens@csie.org>
On Fri, 25 Nov 2016, Chen-Yu Tsai wrote:
> The PRCM block on the A23 contains a message box like interface to
> the registers for the analog path controls of the internal codec.
>
> Add a sub-device for it.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> drivers/mfd/sun6i-prcm.c | 13 +++++++++++++
> 1 file changed, 13 insertions(+)
Applied for v4.11, thanks.
> diff --git a/drivers/mfd/sun6i-prcm.c b/drivers/mfd/sun6i-prcm.c
> index 011fcc555945..2b658bed47db 100644
> --- a/drivers/mfd/sun6i-prcm.c
> +++ b/drivers/mfd/sun6i-prcm.c
> @@ -12,6 +12,9 @@
> #include <linux/init.h>
> #include <linux/of.h>
>
> +#define SUN8I_CODEC_ANALOG_BASE 0x1c0
> +#define SUN8I_CODEC_ANALOG_SIZE 0x4
> +
> struct prcm_data {
> int nsubdevs;
> const struct mfd_cell *subdevs;
> @@ -57,6 +60,10 @@ static const struct resource sun6i_a31_apb0_rstc_res[] = {
> },
> };
>
> +static const struct resource sun8i_codec_analog_res[] = {
> + DEFINE_RES_MEM(SUN8I_CODEC_ANALOG_BASE, SUN8I_CODEC_ANALOG_SIZE),
> +};
> +
> static const struct mfd_cell sun6i_a31_prcm_subdevs[] = {
> {
> .name = "sun6i-a31-ar100-clk",
> @@ -109,6 +116,12 @@ static const struct mfd_cell sun8i_a23_prcm_subdevs[] = {
> .num_resources = ARRAY_SIZE(sun6i_a31_apb0_rstc_res),
> .resources = sun6i_a31_apb0_rstc_res,
> },
> + {
> + .name = "sun8i-codec-analog",
> + .of_compatible = "allwinner,sun8i-a23-codec-analog",
> + .num_resources = ARRAY_SIZE(sun8i_codec_analog_res),
> + .resources = sun8i_codec_analog_res,
> + },
> };
>
> static const struct prcm_data sun6i_a31_prcm_data = {
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v2 2/2] mfd: axp20x: Fix AXP806 access errors on cold boot
From: Lee Jones @ 2016-12-09 11:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123031616.10114-3-wens@csie.org>
Mark,
Is the following valid/necessary?
On Wed, 23 Nov 2016, Chen-Yu Tsai wrote:
> The AXP806 supports either master/standalone or slave mode.
> Slave mode allows sharing the serial bus, even with multiple
> AXP806 which all have the same hardware address.
>
> This is done with extra "serial interface address extension",
> or AXP806_BUS_ADDR_EXT, and "register address extension", or
> AXP806_REG_ADDR_EXT, registers. The former is read-only, with
> 1 bit customizable at the factory, and 1 bit depending on the
> state of an external pin. The latter is writable. Only when
> the these device addressing bits (in the upper 4 bits of the
> registers) match, will the device respond to operations on
> its other registers.
>
> The AXP806_REG_ADDR_EXT was previously configured by Allwinner's
> bootloader. Work on U-boot SPL support now allows us to switch
> to mainline U-boot, which doesn't do this for us. There might
> be other bare minimum bootloaders out there which don't to this
> either. It's best to handle this in the kernel.
>
> This patch sets AXP806_REG_ADDR_EXT to 0x10, which is what we
> know to be the proper value for a standard AXP806 in slave mode.
> Afterwards it will reinitialize the regmap cache, to purge any
> invalid stale values.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> drivers/mfd/axp20x.c | 38 ++++++++++++++++++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index cdaeb34a9a38..a0166c667656 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -31,6 +31,8 @@
>
> #define AXP20X_OFF 0x80
>
> +#define AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE BIT(4)
> +
> static const char * const axp20x_model_names[] = {
> "AXP152",
> "AXP202",
> @@ -829,6 +831,42 @@ int axp20x_device_probe(struct axp20x_dev *axp20x)
> {
> int ret;
>
> + /*
> + * The AXP806 supports either master/standalone or slave mode.
> + * Slave mode allows sharing the serial bus, even with multiple
> + * AXP806 which all have the same hardware address.
> + *
> + * This is done with extra "serial interface address extension",
> + * or AXP806_BUS_ADDR_EXT, and "register address extension", or
> + * AXP806_REG_ADDR_EXT, registers. The former is read-only, with
> + * 1 bit customizable at the factory, and 1 bit depending on the
> + * state of an external pin. The latter is writable. Only when
> + * the these device addressing bits (in the upper 4 bits of the
> + * registers) match, will the device respond to operations on its
> + * other registers.
> + *
> + * Since we only support an AXP806 chained to an AXP809 in slave
> + * mode, and there isn't any existing hardware which uses AXP806
> + * in master mode, or has 2 AXP806s in the same system, we can
> + * just program the register address extension to the slave mode
> + * address.
> + */
> + if (axp20x->variant == AXP806_ID) {
> + /* Write to the register address extension register */
> + regmap_write(axp20x->regmap, AXP806_REG_ADDR_EXT,
> + AXP806_REG_ADDR_EXT_ADDR_SLAVE_MODE);
> +
> + /* Make sure the write hits the device */
> + regcache_sync_region(axp20x->regmap, AXP806_REG_ADDR_EXT,
> + AXP806_REG_ADDR_EXT);
> +
> + /*
> + * Reinitialize the regmap cache in case the device didn't
> + * properly respond to our reads before.
> + */
> + regmap_reinit_cache(axp20x->regmap, axp20x->regmap_cfg);
> + }
> +
> ret = regmap_add_irq_chip(axp20x->regmap, axp20x->irq,
> IRQF_ONESHOT | IRQF_SHARED, -1,
> axp20x->regmap_irq_chip,
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v2 1/2] mfd: axp20x: Add address extension registers for AXP806 regmap
From: Lee Jones @ 2016-12-09 11:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161123031616.10114-2-wens@csie.org>
On Wed, 23 Nov 2016, Chen-Yu Tsai wrote:
> The AXP806 supports either master/standalone or slave mode.
> Slave mode allows sharing the serial bus, even with multiple
> AXP806 which all have the same hardware address.
>
> This is done with extra "serial interface address extension",
> or AXP806_BUS_ADDR_EXT, and "register address extension", or
> AXP806_REG_ADDR_EXT, registers. The former is read-only, with
> 1 bit customizable at the factory, and 1 bit depending on the
> state of an external pin. The latter is writable. Only when
> the these device addressing bits (in the upper 4 bits of the
> registers) match, will the device respond to operations on
> its other registers.
>
> Add these 2 registers to the regmap so we can access them.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> drivers/mfd/axp20x.c | 3 ++-
> include/linux/mfd/axp20x.h | 2 ++
> 2 files changed, 4 insertions(+), 1 deletion(-)
Applied for v4.11, thanks.
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index ba130be32e61..cdaeb34a9a38 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -135,6 +135,7 @@ static const struct regmap_range axp806_writeable_ranges[] = {
> regmap_reg_range(AXP806_PWR_OUT_CTRL1, AXP806_CLDO3_V_CTRL),
> regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IRQ2_EN),
> regmap_reg_range(AXP20X_IRQ1_STATE, AXP20X_IRQ2_STATE),
> + regmap_reg_range(AXP806_REG_ADDR_EXT, AXP806_REG_ADDR_EXT),
> };
>
> static const struct regmap_range axp806_volatile_ranges[] = {
> @@ -305,7 +306,7 @@ static const struct regmap_config axp806_regmap_config = {
> .val_bits = 8,
> .wr_table = &axp806_writeable_table,
> .volatile_table = &axp806_volatile_table,
> - .max_register = AXP806_VREF_TEMP_WARN_L,
> + .max_register = AXP806_REG_ADDR_EXT,
> .cache_type = REGCACHE_RBTREE,
> };
>
> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
> index fec597fb34cb..7e85ececcedf 100644
> --- a/include/linux/mfd/axp20x.h
> +++ b/include/linux/mfd/axp20x.h
> @@ -115,6 +115,8 @@ enum {
> #define AXP806_CLDO2_V_CTRL 0x25
> #define AXP806_CLDO3_V_CTRL 0x26
> #define AXP806_VREF_TEMP_WARN_L 0xf3
> +#define AXP806_BUS_ADDR_EXT 0xfe
> +#define AXP806_REG_ADDR_EXT 0xff
>
> /* Interrupt */
> #define AXP152_IRQ1_EN 0x40
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v2 11/11] ARM: dtsi: sun8i-reference-design-tablet: use AXP223 DTSI
From: Quentin Schulz @ 2016-12-09 11:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161209110419.28981-1-quentin.schulz@free-electrons.com>
Previously, the sun8i tablets used everything declared in AXP221 DTSI
while they have an AXP223 PMIC.
This corrects that so the sun8i tablets can get some features the AXP223
has (at the moment, ability to have 100mA as maximal current on VBUS
power supply).
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
index 08cd001..ea79c33 100644
--- a/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
+++ b/arch/arm/boot/dts/sun8i-reference-design-tablet.dtsi
@@ -136,7 +136,7 @@
};
};
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
®_aldo1 {
regulator-always-on;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 10/11] ARM: dts: sun8i-r16-parrot: use AXP223 DTSI
From: Quentin Schulz @ 2016-12-09 11:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20161209110419.28981-1-quentin.schulz@free-electrons.com>
Previously, the Allwinner Parrot R16 used everything declared in AXP221
DTSI while it has an AXP223 PMIC.
This corrects that so the Allwinner Parrot R16 can get some features the
AXP223 has (at the moment, ability to have 100mA as maximal current on
VBUS power supply).
Signed-off-by: Quentin Schulz <quentin.schulz@free-electrons.com>
Acked-by: Chen-Yu Tsai <wens@csie.org>
---
arch/arm/boot/dts/sun8i-r16-parrot.dts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/sun8i-r16-parrot.dts b/arch/arm/boot/dts/sun8i-r16-parrot.dts
index 47553e5..6afdba3 100644
--- a/arch/arm/boot/dts/sun8i-r16-parrot.dts
+++ b/arch/arm/boot/dts/sun8i-r16-parrot.dts
@@ -209,7 +209,7 @@
};
};
-#include "axp22x.dtsi"
+#include "axp223.dtsi"
®_aldo1 {
regulator-always-on;
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox