Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] drm/sun4i: rgb: Declare RGB encoder and connector as MIPI DPI
From: Chen-Yu Tsai @ 2016-09-19 15:20 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160918191205.GG17518@lukather>

On Mon, Sep 19, 2016 at 3:12 AM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi,
>
> On Thu, Sep 15, 2016 at 11:13:59PM +0800, Chen-Yu Tsai wrote:
>> The 18 or 24 bit parallel RGB LCD panel interface found on Allwinner
>> SoCs matches the description of MIPI DPI. Declare the RGB encoder and
>> connector as MIPI DPI.
>
> Unfortunately, even it that patch might be true (is there a public
> spec for that standard?), this breaks the user-space, so there's no

Not that I know of. I basically googled the term and looked at other
datasheets and asked on #linux-arm-kernel.

> way we change this.

:(

ChenYu

^ permalink raw reply

* [PATCH] ARM: multi_v7_defconfig: enable CONFIG_EFI
From: Arnd Bergmann @ 2016-09-19 15:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473949700-12814-1-git-send-email-ard.biesheuvel@linaro.org>

On Thursday, September 15, 2016 3:28:20 PM CEST Ard Biesheuvel wrote:
> This enables CONFIG_EFI for multi_v7_defconfig, which adds support for
> booting via EFI, and for the EFI framebuffer as builtin options. It
> also enables the EFI rtc, the EFI variable pseudo-filesystem and the
> EFI capsule loader as modules.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> ---
> 
> We have been happily booting multi_v7_defconfig+CONFIG_EFI=y kernels on
> kernelci for months now, so please consider enabling this by default.
> The increase in compressed kernel footprint is ~30 KB, for the uncompressed
> kernel it's ~10 KB, some of which is .init code.
> 

Applied to next/defconfig, thanks!

	Arnd

^ permalink raw reply

* [GIT PULL 1/2] arm64: X-Gene driver updates queued for 4.9
From: Arnd Bergmann @ 2016-09-19 15:16 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CADaLNDnbuQWrV6myasn2k5Mi7=jdg7FAjbdbS3GrbXY34cBfNA@mail.gmail.com>

On Friday, September 16, 2016 12:01:26 AM CEST Duc Dang wrote:
> This is the driver updates for X-Gene platforms targeted for 4.9.
> 
> The change set includes:
> + X-Gene Soc PMU support patch set from Tai Nguyen (v10 reviewed by
> Mark, DT binding document acked by Rob [1] and was suggested to merge
> via am-soc tree by Will [2])
> 
> As we discussed, the X-Gene Soc PMU will go through arm-soc tree this
> time because we don't have a dedicated tree for PMU drivers yet.
> Starting from v4.10, PMU drivers will be collected by Will/Mark before
> sending to arm-soc tree [3].
> 
> 

Pulled into next/drivers, thanks!

	Arnd

^ permalink raw reply

* [PATCH] arm: dts: fix rk3066a based boards vdd_log voltage initialization
From: Doug Anderson @ 2016-09-19 15:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474274696-28090-1-git-send-email-andy.yan@rock-chips.com>

Hi,

On Mon, Sep 19, 2016 at 1:44 AM, Andy Yan <andy.yan@rock-chips.com> wrote:
> The current rk3066a based boards(Rayeager, Bqcurie2, Marsboard) use
> pwm modulate vdd_logic voltage, but the pwm is default disabled and
> the pwm pin acts as a gpio before pwm regulator probed, so the pwm
> regulator driver will get a zero dutycycle at probe time, so change
> the initial dutycycle to zero to match pwm_regulator_init_state check.
>
> Signed-off-by: Andy Yan <andy.yan@rock-chips.com>
>
> ---
>
>  arch/arm/boot/dts/rk3066a-bqcurie2.dts  | 2 +-
>  arch/arm/boot/dts/rk3066a-marsboard.dts | 2 +-
>  arch/arm/boot/dts/rk3066a-rayeager.dts  | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/rk3066a-bqcurie2.dts b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> index bc674ee..618450d 100644
> --- a/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> +++ b/arch/arm/boot/dts/rk3066a-bqcurie2.dts
> @@ -61,7 +61,7 @@
>                 regulator-min-microvolt = <1200000>;
>                 regulator-max-microvolt = <1200000>;
>                 regulator-always-on;
> -               voltage-table = <1000000 100>,
> +               voltage-table = <1000000 0>,

In my opinion this isn't quite the right answer.  I think that you
should add a new property describing the voltage in the case that the
pin is an input and you should fill that property in, like:

  voltage-when-input = <1000000>;

Once you have this property you should ideally be able to read whether
the pin is currently configured as an input or as a special function
at bootup.  Note that I don't actually know if this is possible with
the current pinctrl API, but it does seem like the ideal way to do it
since it means you'll work even if the BIOS changes (AKA: if the BIOS
leaves the pin as an input you can keep the voltage the same and if
the BIOS leaves the pin as PWM you can keep the voltage the same).

It's also possible that you could just add a property that says "init
to a certain value at bootup no matter what the BIOS left it as".  As
long as that voltage is the maximum (and you'll lower it later) this
ought to be safe and you shouldn't risk temporarily undervolting
things.


Note that, if you haven't already done so, you almost certainly want
to make sure your pinctrl species an "init" state in addition to a
"default" state.  See <https://patchwork.kernel.org/patch/7454311/>.

-Doug

^ permalink raw reply

* [PATCH] ASoC: samsung: make audio interface/controller explicitly
From: Krzysztof Kozlowski @ 2016-09-19 15:15 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <30C748BE-359C-4212-96D3-C2A71E1094C3@soulik.info>

On Mon, Sep 19, 2016 at 09:21:54AM +0800, Ayaka wrote:
> 
> 
> ??? iPad ??
> 
> > Krzysztof Kozlowski <krzk@kernel.org> ? 2016?9?19? ??2:09 ???
> > 
> >> On Sun, Sep 18, 2016 at 11:12:34PM +0800, ayaka wrote:
> >> 
> >> 
> >>> On 09/18/2016 10:42 PM, Krzysztof Kozlowski wrote:
> >>>> On Sun, Sep 18, 2016 at 10:09:11PM +0800, Randy Li wrote:
> >>>> It is simple sound card time, we could assign different codec
> >>>> to a interface without making a specific driver for it.
> >>> The description does not convince me and I do not see an example using
> >>> this. Could you provide one?
> >> Sorry, the board TOPEET iTop 4412 for exynos 4412 I posted supported codec
> >> with I2S interface using the simple sound card. Anyway, it is no harm to
> >> make them explicitly right?
> > 
> > kbuild gave you the answer...
> Not sure how comes, even time I sent patches to you, I at lease build and run it once.

Building only one ARM config may be sufficient for trivial changes but
for more complex stuff (especially when dealing with Kconfig) needs more
build coverage. 

On Ubuntu you can easily cross compile for x86, x86_64,
arm, arm64 and powerpc. You can also use this cross-compiler collection:
https://www.kernel.org/pub/tools/crosstool


> > 
> >> Or I have to enabled those codec support for
> >> SMDK, which is not needed for the other board.
> > 
> > If I understand correctly, the i2s/pcm etc are still needed but not
> > built in config choosing only simple-audio-card? I tried now such
> > configuration on Odroid XU and indeed the audio is missing.
> > 
> > The patch looks like needed but:
> > 1. You need to describe the rationale in commit message, why it is
> > needed.
> Sorry about English.
> > 2. You need to fix it... kbuild pointed build issues.
> I would check that.
> > 
> > Other solution would be to add a user-selectable option for generic
> > sound on Samsung using simple audio card. The option would then select
> > appropriate SND_SAMSUNG* options, just like specific drivers do. I see
> > that sh does like this. Personally this approach seems simpler to me -
> > the defconfig could just choose this generic sound instead of many
> > SND_SAMSUNG_* sub-options.
> I would just what  Freescale did. It included those options entries in a sub-menu.
> I don't those options should be bound either, as a board may only use one of interface or controller(like TOPEET iTOP would only use i2s. No place for SPDIF, AC97 nor PCM.)

OK, sounds good for me. Thanks for explanation.


Best regards,
Krzysztof

^ permalink raw reply

* [PATCH v2 4/4] arm64: dts: add Pine64 support
From: Chen-Yu Tsai @ 2016-09-19 15:14 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <c7ad213f-e5d1-d5c5-a83c-af1c38d9c1d6@arm.com>

On Mon, Sep 12, 2016 at 6:11 PM, Andre Przywara <andre.przywara@arm.com> wrote:
> Hi,
>
> On 10/09/16 03:33, Chen-Yu Tsai wrote:
>> Hi,
>>
>> On Sat, Sep 10, 2016 at 4:10 AM, Maxime Ripard
>> <maxime.ripard@free-electrons.com> wrote:
>>> From: Andre Przywara <andre.przywara@arm.com>
>>>
>>> The Pine64 is a cost-efficient development board based on the
>>> Allwinner A64 SoC.
>>> There are three models: the basic version with Fast Ethernet and
>>> 512 MB of DRAM (Pine64) and two Pine64+ versions, which both
>>> feature Gigabit Ethernet and additional connectors for touchscreens
>>> and a camera. Or as my son put it: "Those are smaller and these are
>>> missing." ;-)
>>> The two Pine64+ models just differ in the amount of DRAM
>>> (1GB vs. 2GB). Since U-Boot will figure out the right size for us and
>>> patches the DT accordingly we just need to provide one DT for the
>>> Pine64+.
>>>
>>> Signed-off-by: Andre Przywara <andre.przywara@arm.com>
>>> [Maxime: Removed the common DTSI and include directly the pine64 DTS]
>>> Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
>>> ---
>>>  arch/arm64/boot/dts/Makefile                       |  1 +
>>>  arch/arm64/boot/dts/allwinner/Makefile             |  5 ++
>>>  .../boot/dts/allwinner/sun50i-a64-pine64-plus.dts  | 50 ++++++++++++++++
>>>  .../arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 70 ++++++++++++++++++++++
>>>  4 files changed, 126 insertions(+)
>>>  create mode 100644 arch/arm64/boot/dts/allwinner/Makefile
>>>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
>>>  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
>>>
>>> diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
>>> index 6e199c903676..ddcbf5a2c17e 100644
>>> --- a/arch/arm64/boot/dts/Makefile
>>> +++ b/arch/arm64/boot/dts/Makefile
>>> @@ -1,4 +1,5 @@
>>>  dts-dirs += al
>>> +dts-dirs += allwinner
>>>  dts-dirs += altera
>>>  dts-dirs += amd
>>>  dts-dirs += amlogic
>>> diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile
>>> new file mode 100644
>>> index 000000000000..1e29a5ae8282
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/Makefile
>>> @@ -0,0 +1,5 @@
>>> +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb
>>> +
>>> +always         := $(dtb-y)
>>> +subdir-y       := $(dts-dirs)
>>> +clean-files    := *.dtb
>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
>>> new file mode 100644
>>> index 000000000000..790d14daaa6a
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
>>> @@ -0,0 +1,50 @@
>>> +/*
>>> + * Copyright (c) 2016 ARM Ltd.
>>> + *
>>> + * This file is dual-licensed: you can use it either under the terms
>>> + * of the GPL or the X11 license, at your option. Note that this dual
>>> + * licensing only applies to this file, and not this project as a
>>> + * whole.
>>> + *
>>> + *  a) This library is free software; you can redistribute it and/or
>>> + *     modify it under the terms of the GNU General Public License as
>>> + *     published by the Free Software Foundation; either version 2 of the
>>> + *     License, or (at your option) any later version.
>>> + *
>>> + *     This library is distributed in the hope that it will be useful,
>>> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + *     GNU General Public License for more details.
>>> + *
>>> + * Or, alternatively,
>>> + *
>>> + *  b) Permission is hereby granted, free of charge, to any person
>>> + *     obtaining a copy of this software and associated documentation
>>> + *     files (the "Software"), to deal in the Software without
>>> + *     restriction, including without limitation the rights to use,
>>> + *     copy, modify, merge, publish, distribute, sublicense, and/or
>>> + *     sell copies of the Software, and to permit persons to whom the
>>> + *     Software is furnished to do so, subject to the following
>>> + *     conditions:
>>> + *
>>> + *     The above copyright notice and this permission notice shall be
>>> + *     included in all copies or substantial portions of the Software.
>>> + *
>>> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>>> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>>> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>>> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>>> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>> + *     OTHER DEALINGS IN THE SOFTWARE.
>>> + */
>>> +
>>> +#include "sun50i-a64-pine64.dts"
>>> +
>>> +/ {
>>> +       model = "Pine64+";
>>> +       compatible = "pine64,pine64-plus", "allwinner,sun50i-a64";
>>> +
>>> +       /* TODO: Camera, Ethernet PHY, touchscreen, etc. */
>>> +};
>>> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
>>> new file mode 100644
>>> index 000000000000..da9bca51f5a9
>>> --- /dev/null
>>> +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
>>> @@ -0,0 +1,70 @@
>>> +/*
>>> + * Copyright (c) 2016 ARM Ltd.
>>> + *
>>> + * This file is dual-licensed: you can use it either under the terms
>>> + * of the GPL or the X11 license, at your option. Note that this dual
>>> + * licensing only applies to this file, and not this project as a
>>> + * whole.
>>> + *
>>> + *  a) This library is free software; you can redistribute it and/or
>>> + *     modify it under the terms of the GNU General Public License as
>>> + *     published by the Free Software Foundation; either version 2 of the
>>> + *     License, or (at your option) any later version.
>>> + *
>>> + *     This library is distributed in the hope that it will be useful,
>>> + *     but WITHOUT ANY WARRANTY; without even the implied warranty of
>>> + *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>>> + *     GNU General Public License for more details.
>>> + *
>>> + * Or, alternatively,
>>> + *
>>> + *  b) Permission is hereby granted, free of charge, to any person
>>> + *     obtaining a copy of this software and associated documentation
>>> + *     files (the "Software"), to deal in the Software without
>>> + *     restriction, including without limitation the rights to use,
>>> + *     copy, modify, merge, publish, distribute, sublicense, and/or
>>> + *     sell copies of the Software, and to permit persons to whom the
>>> + *     Software is furnished to do so, subject to the following
>>> + *     conditions:
>>> + *
>>> + *     The above copyright notice and this permission notice shall be
>>> + *     included in all copies or substantial portions of the Software.
>>> + *
>>> + *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
>>> + *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
>>> + *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
>>> + *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
>>> + *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
>>> + *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
>>> + *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
>>> + *     OTHER DEALINGS IN THE SOFTWARE.
>>> + */
>>> +
>>> +/dts-v1/;
>>> +
>>> +#include "sun50i-a64.dtsi"
>>> +
>>> +/ {
>>> +       model = "Pine64";
>>> +       compatible = "pine64,pine64", "allwinner,sun50i-a64";
>>> +
>>> +       aliases {
>>> +               serial0 = &uart0;
>>> +       };
>>> +
>>> +       chosen {
>>> +               stdout-path = "serial0:115200n8";
>>> +       };
>>> +};
>>> +
>>> +&uart0 {
>>> +       pinctrl-names = "default";
>>> +       pinctrl-0 = <&uart0_pins_a>;
>>> +       status = "okay";
>>> +};
>>> +
>>> +&i2c1 {
>>> +       pinctrl-names = "default";
>>> +       pinctrl-0 = <&i2c1_pins>;
>>> +       status = "okay";
>>
>> Schematics say this is missing an external pull-up. Has anyone tried it?
>> Without a pull-up any access on the i2c bus should just block.
>
> I tried it a while ago (with an older kernel), though I had an external
> pull-up on the device side, I think. I can give it a try again with
> Maxime's branch once I find this I2C test device in one of my moving
> boxes ;-)
>
> Do other boards providing a Raspi-compatible header have an on-board
> pull-up here? So will (some) hardware extensions for the Raspi fail on
> the Pine64?

IIRC The Bananapi series have pull-ups on the default I2C pins.

>> Also this is on the RPi-2 compatible header. There's also an UART and SPI
>> that are standard for the RPi-2 header. We should consider enabling them
>> as well.
>
> Interesting topic ;-)
> As both interfaces can be configured for GPIO as well, I think Maxime
> voted to not declare them as special function in the upstream DT.
> UART0 is used for the console, so I guess some people may decide to use
> those UART2 header pins for GPIO. Similarly for SPI: if you don't need
> it, you get four (or five) additional GPIO.
>
> A kind of related issue arises for those BT/Wifi headers. 99.9% of the
> users will plug the Pine64 BT/WiFi module in there, at which point we
> could declare MMC1 as SDIO and UART1 as enabled to cover this.
> But then again nothing prevents people from building a custom module
> which uses those pins for something else. Port G at least does not
> multiplex any other IP to those pins - apart from GPIO, of course.
>
> So what is the exact policy here? In the end I think any pin (including
> UART0's PB8 and PB9) can be configured as GPIO, so do we make some
> assumptions about "sensible" or predominant usage?

My personal position is if the vendor explicitly labeled X pin as Y
peripheral, then we should enable it by default, since that is possibly
what many users would be expecting. We can list, but explicitly disable,
other peripherals that the vendor mentioned as optional or changeable.
Obviously most pins are changeable from the SoC PoV, so my focus here
is what the vendor intended.

Unfortunately I've not completely worked this out with Maxime yet,
and I am somewhat busy on other fronts lately. I'll be at ELCE this
year, so hopefully we'll get this sorted out soon.

> Does "# echo $DEVICE > /sys/devices/platform/$DEVICE/driver/unbind" work
> to get those pins free later in case one wants to configure them as
> GPIOs? In this case we may consider being more generous in declaring
> common use cases in the upstream DT for the sake of the majority of users.

I believe it does, but I've never actually tried it.

Regards
ChenYu

^ permalink raw reply

* [PATCH v5 02/16] dt/bindings: Update binding for PM domain idle states
From: Brendan Jackman @ 2016-09-19 15:09 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7af4c2d7-70a3-1881-2980-8ea49e594e5b@arm.com>


On Fri, Sep 16 2016 at 18:39, Sudeep Holla <sudeep.holla@arm.com> wrote:
> Hi Kevin,
>
> Thanks for looking at this and simplifying various discussions we had so
> far. I was thinking of summarizing something very similar. I couldn't
> due to lack of time.
>
> On 16/09/16 18:13, Kevin Hilman wrote:
>
> [...]
>
>> I think we're having some terminology issues...
>>
>> FWIW, the kernel terminolgy is actually "PM domain", not power domain.
>> This was intentional because the goal of the PM domain was to group
>> devices that some PM features.  To be very specific to the kernel, they
>> us the same set of PM callbacks.  Today, this is most commonly used to
>> model power domains, where a group of devices share a power rail, but it
>> does not need to be limited to that.
>>
>
> Agreed/Understood.
>
>> That being said, I'm having a hard time understanding the root of the
>> disagreement.
>>
>
> Yes. I tried to convey the same earlier, but have failed. The only
> disagreement is about a small part of this DT bindings. We would like to
> make it completely hierarchical up to CPU nodes. More comments on that
> below.
>
>> It seems that you and Sudeep would like to use domain-idle-states to
>> replace/superceed cpu-idle-states with the primary goal (and benefit)
>> being that it simplifies the DT bindings.  Is that correct?
>>
>
> Correct, we want to deprecate cpu-idle-states with the introduction of
> this hierarchical PM bindings. Yes IMO, it simplifies things and avoids
> any ABI break we might trigger if we miss to consider some use-case now.
>
>> The objections have come in because that means that implies that CPUs
>> become their own domains, which may not be the case in hardware in the
>> sense that they share a power rail.
>>
>
> Agreed.
>
>> However, IMO, thinking of a CPU as it's own "PM domain" may make some
>> sense based on the terminology above.
>>
>
> Thanks for that, we do understand that it may not be 100% correct when
> we strictly considers hardware terminologies instead of above ones.
> As along as we see no issues with the above terminologies it should be fine.
>
>> I think the other objection may be that using a genpd to model domain
>> with only a single device in it may be overkill, and I agree with that.
>
> I too agree with that. Just because we represent that in DT in that way
> doesn't mean we need to create a genpd to model domain. We can always
> skip that if not required. That's pure implementation specifics and I
> have tried to convey the same in my previous emails. I must say you have
> summarized it very clearly in this email. Thanks again for that.
>
>> But, I'm not sure if making CPUs use domain-idle-states implies that
>> they necessarily have to use genpd is what you are proposing.  Maybe
>> someone could clarify that?
>>
>
> No, I have not proposing anything around implementation in the whole
> discussion so far. I have constrained myself just to DT bindings so far.
> That's the main reason why I was opposed to mentions of OS vs platform
> co-ordinated modes of CPU suspend in this discussion. IMO that's
> completely out of scope of this DT binding we are defining here.
>
> Hope that helps/clarifies the misunderstanding/disagreement.

Indeed. My intention was that the proposal would result in the exact
same kernel behaviour as Lina's current patchset, i.e. there is one
genpd per cluster, and CPU-level idle states are still handled by
cpuidle.

The only change from the current patchset would be in initialisation
code: some coordination would need to be done to determine which idle
states go into cpuidle and which go into the genpds (whereas with the
current bindings, states from cpu-idle-states go into cpuidle and states
from domain-idle-states go into genpd). So you could say that this would
be a trade-off between binding simplicity and implementation simplicity.

Cheers,
Brendan

^ permalink raw reply

* [PATCH v3 1/8] scpi: Add cmd indirection table to prepare for legacy commands
From: Neil Armstrong @ 2016-09-19 15:03 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <213c023d-bac8-5148-4846-8501501bddf2@arm.com>

On 09/19/2016 04:41 PM, Sudeep Holla wrote:
> Hi Neil,
> 
> On 07/09/16 16:34, Neil Armstrong wrote:
>> Add indirection table to permit multiple command values for legacy support.
>>
> 
> I wrote the most of the patch and you changed the author too ;)

Sorry, forgot this ! v4 will have it !
> 
>> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
>> ---
>>  drivers/firmware/arm_scpi.c | 145 ++++++++++++++++++++++++++++++++++++++------
>>  1 file changed, 127 insertions(+), 18 deletions(-)
>>
>> diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
>> index 4388937..9a87687 100644
>> --- a/drivers/firmware/arm_scpi.c
>> +++ b/drivers/firmware/arm_scpi.c
> 
> [..]
> 
>> @@ -161,6 +194,7 @@ struct scpi_drvinfo {
>>      u32 protocol_version;
>>      u32 firmware_version;
>>      int num_chans;
>> +    int *scpi_cmds;
>>      atomic_t next_chan;
>>      struct scpi_ops *scpi_ops;
>>      struct scpi_chan *channels;
>> @@ -390,6 +424,19 @@ static u32 scpi_get_version(void)
>>      return scpi_info->protocol_version;
>>  }
>>
>> +static inline int check_cmd(unsigned int offset)
>> +{
>> +    if (offset >= CMD_MAX_COUNT ||
> 
> If we call scpi_send_message internally(as it's static) why is this
> check needed ?
> 
> 
>> +        !scpi_info ||
>> +        !scpi_info->scpi_cmds)
> 
> Will be even reach to this point if above is true ?
> 
>> +        return -EINVAL;
>> +
>> +    if (scpi_info->scpi_cmds[offset] < 0)
>> +        return -EOPNOTSUPP;
> 
> IMO just above couple of lines in the beginning of scpi_send_message
> will suffice. You can just add this to my original patch.

Will do.

> 
>>  static int
>>  scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>>  {
>> @@ -397,8 +444,13 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>>      struct clk_get_info clk;
>>      __le16 le_clk_id = cpu_to_le16(clk_id);
>>
>> -    ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
>> -                sizeof(le_clk_id), &clk, sizeof(clk));
>> +    ret = check_cmd(CMD_GET_CLOCK_INFO);
>> +    if (ret)
>> +        return ret;
>> +
> 
> It's totally unnecessary to add check in each and every function calling
> scpi_send_message, why not add it to scpi_send_message instead.
> 

This was my first thought, I should have stayed at this !

Thanks,
Neil

^ permalink raw reply

* [GIT PULL 1/3] ARM: soc: exynos: Drivers for v4.9
From: Arnd Bergmann @ 2016-09-19 15:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474216788-17282-2-git-send-email-krzk@kernel.org>

On Sunday, September 18, 2016 6:39:46 PM CEST Krzysztof Kozlowski wrote:
> Samsung drivers/soc update for v4.9:
> 1. Allow compile testing of exynos-mct clocksource driver on ARM64.
> 2. Document Exynos5433 PMU compatible (already used by clkout driver and more
>    will be coming soon).

Pulled into next/drivers, thanks

Just for my understanding: why do we need the exynos-mct driver on ARM64
but not the delay-timer portion of it?

Is there an advantage in using MCT over the architected timer on these
chips? If so, should we also have a way to use it as the delay timer?

	Arnd

^ permalink raw reply

* [GIT PULL 2/5] i.MX soc updates for 4.9
From: Arnd Bergmann @ 2016-09-19 14:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473670948-4265-2-git-send-email-shawnguo@kernel.org>

On Monday, September 12, 2016 5:02:25 PM CEST Shawn Guo wrote:
> i.MX SoC updates for 4.9:
>  - Set INT_MEM_CLK_LPM bit to get proper WAIT mode support on i.MX6SX.
>    This is a workaround for i.MX6SX WAIT mode hardware issue.
>  - Enable cpuidle support with 3 low-power states (WFI, WAIT, POWER-OFF)
>    for i.MX6UL.
> 
> 

Pulled into next/soc, thanks!

	Arnd

^ permalink raw reply

* [PATCH v4 2/2] KVM: arm/arm64: Route vtimer events to user space
From: Marc Zyngier @ 2016-09-19 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474283695-212421-3-git-send-email-agraf@suse.de>

On 19/09/16 12:14, Alexander Graf wrote:
> We have 2 modes for dealing with interrupts in the ARM world. We can either
> handle them all using hardware acceleration through the vgic or we can emulate
> a gic in user space and only drive CPU IRQ pins from there.
> 
> Unfortunately, when driving IRQs from user space, we never tell user space
> about timer events that may result in interrupt line state changes, so we
> lose out on timer events if we run with user space gic emulation.
> 
> This patch fixes that by routing vtimer expiration events to user space.
> With this patch I can successfully run edk2 and Linux with user space gic
> emulation.
> 
> Signed-off-by: Alexander Graf <agraf@suse.de>
> 
> ---
> 
> v1 -> v2:
> 
>   - Add back curly brace that got lost
> 
> v2 -> v3:
> 
>   - Split into patch set
> 
> v3 -> v4:
> 
>   - Improve documentation
> ---
>  Documentation/virtual/kvm/api.txt |  30 ++++++++-
>  arch/arm/include/asm/kvm_host.h   |   3 +
>  arch/arm/kvm/arm.c                |  22 ++++---
>  arch/arm64/include/asm/kvm_host.h |   3 +
>  include/uapi/linux/kvm.h          |  14 +++++
>  virt/kvm/arm/arch_timer.c         | 125 +++++++++++++++++++++++++++-----------
>  6 files changed, 155 insertions(+), 42 deletions(-)
> 
> diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
> index 23937e0..1c0bd86 100644
> --- a/Documentation/virtual/kvm/api.txt
> +++ b/Documentation/virtual/kvm/api.txt
> @@ -3202,9 +3202,14 @@ struct kvm_run {
>  	/* in */
>  	__u8 request_interrupt_window;
>  
> -Request that KVM_RUN return when it becomes possible to inject external
> +[x86] Request that KVM_RUN return when it becomes possible to inject external
>  interrupts into the guest.  Useful in conjunction with KVM_INTERRUPT.
>  
> +[arm*] Bits set to 1 in here mask IRQ lines that would otherwise potentially
> +trigger forever. These lines are available:
> +
> +    KVM_IRQWINDOW_VTIMER  -  Masks hw virtual timer irq while in guest
> +
>  	__u8 padding1[7];
>  
>  	/* out */
> @@ -3519,6 +3524,18 @@ Hyper-V SynIC state change. Notification is used to remap SynIC
>  event/message pages and to enable/disable SynIC messages/events processing
>  in userspace.
>  
> +		/* KVM_EXIT_ARM_TIMER */
> +		struct {
> +			__u8 timesource;
> +		} arm_timer;
> +
> +Indicates that a timer triggered that user space needs to handle and
> +potentially mask with vcpu->run->request_interrupt_window to allow the
> +guest to proceed. This only happens for timers that got enabled through
> +KVM_CAP_ARM_TIMER. The following time sources are available:
> +
> +    KVM_ARM_TIMER_VTIMER  - virtual cpu timer
> +
>  		/* Fix the size of the union. */
>  		char padding[256];
>  	};
> @@ -3739,6 +3756,17 @@ Once this is done the KVM_REG_MIPS_VEC_* and KVM_REG_MIPS_MSA_* registers can be
>  accessed, and the Config5.MSAEn bit is accessible via the KVM API and also from
>  the guest.
>  
> +6.11 KVM_CAP_ARM_TIMER
> +
> +Architectures: arm, arm64
> +Target: vcpu
> +Parameters: args[0] contains a bitmap of timers to select (see 5.)
> +
> +This capability allows to route per-core timers into user space. When it's
> +enabled and no in-kernel interrupt controller is in use, the timers selected
> +by args[0] trigger KVM_EXIT_ARM_TIMER guest exits when they are pending,
> +unless masked by vcpu->run->request_interrupt_window (see 5.).
> +
>  7. Capabilities that can be enabled on VMs
>  ------------------------------------------
>  
> diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
> index de338d9..77d1f73 100644
> --- a/arch/arm/include/asm/kvm_host.h
> +++ b/arch/arm/include/asm/kvm_host.h
> @@ -180,6 +180,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* User space wants timer notifications */
> +	bool user_space_arm_timers;

Please move this to the timer structure.

>  };
>  
>  struct kvm_vm_stat {
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index c84b6ad..57bdb71 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -187,6 +187,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
>  	case KVM_CAP_ARM_PSCI_0_2:
>  	case KVM_CAP_READONLY_MEM:
>  	case KVM_CAP_MP_STATE:
> +	case KVM_CAP_ARM_TIMER:
>  		r = 1;
>  		break;
>  	case KVM_CAP_COALESCED_MMIO:
> @@ -474,13 +475,7 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu)
>  			return ret;
>  	}
>  
> -	/*
> -	 * Enable the arch timers only if we have an in-kernel VGIC
> -	 * and it has been properly initialized, since we cannot handle
> -	 * interrupts from the virtual timer with a userspace gic.
> -	 */
> -	if (irqchip_in_kernel(kvm) && vgic_initialized(kvm))
> -		ret = kvm_timer_enable(vcpu);
> +	ret = kvm_timer_enable(vcpu);
>  
>  	return ret;
>  }
> @@ -601,6 +596,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
>  			run->exit_reason = KVM_EXIT_INTR;
>  		}
>  
> +		if (kvm_check_request(KVM_REQ_PENDING_TIMER, vcpu)) {

Since this is a very unlikely event (in the grand scheme of things), how
about making this unlikely()?

> +			/* Tell user space about the pending vtimer */
> +			ret = 0;
> +			run->exit_reason = KVM_EXIT_ARM_TIMER;
> +			run->arm_timer.timesource = KVM_ARM_TIMER_VTIMER;
> +		}

More importantly: why does it have to be indirected by a
make_request/check_request, and not be handled as part of the
kvm_timer_sync() call? We do update the state there, and you could
directly find out whether an exit is required.

> +
>  		if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
>  			vcpu->arch.power_off || vcpu->arch.pause) {
>  			local_irq_enable();
> @@ -887,6 +889,12 @@ static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
>  		return -EINVAL;
>  
>  	switch (cap->cap) {
> +	case KVM_CAP_ARM_TIMER:
> +		r = 0;
> +		if (cap->args[0] != KVM_ARM_TIMER_VTIMER)
> +			return -EINVAL;
> +		vcpu->arch.user_space_arm_timers = true;
> +		break;
>  	default:
>  		r = -EINVAL;
>  		break;
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 3eda975..3d01481 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -270,6 +270,9 @@ struct kvm_vcpu_arch {
>  
>  	/* Detect first run of a vcpu */
>  	bool has_run_once;
> +
> +	/* User space wants timer notifications */
> +	bool user_space_arm_timers;
>  };
>  
>  #define vcpu_gp_regs(v)		(&(v)->arch.ctxt.gp_regs)
> diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
> index 300ef25..00f4948 100644
> --- a/include/uapi/linux/kvm.h
> +++ b/include/uapi/linux/kvm.h
> @@ -205,6 +205,7 @@ struct kvm_hyperv_exit {
>  #define KVM_EXIT_S390_STSI        25
>  #define KVM_EXIT_IOAPIC_EOI       26
>  #define KVM_EXIT_HYPERV           27
> +#define KVM_EXIT_ARM_TIMER        28
>  
>  /* For KVM_EXIT_INTERNAL_ERROR */
>  /* Emulate instruction failed. */
> @@ -361,6 +362,10 @@ struct kvm_run {
>  		} eoi;
>  		/* KVM_EXIT_HYPERV */
>  		struct kvm_hyperv_exit hyperv;
> +		/* KVM_EXIT_ARM_TIMER */
> +		struct {
> +			__u8 timesource;
> +		} arm_timer;
>  		/* Fix the size of the union. */
>  		char padding[256];
>  	};
> @@ -870,6 +875,7 @@ struct kvm_ppc_smmu_info {
>  #define KVM_CAP_S390_USER_INSTR0 130
>  #define KVM_CAP_MSI_DEVID 131
>  #define KVM_CAP_PPC_HTM 132
> +#define KVM_CAP_ARM_TIMER 133
>  
>  #ifdef KVM_CAP_IRQ_ROUTING
>  
> @@ -1327,4 +1333,12 @@ struct kvm_assigned_msix_entry {
>  #define KVM_X2APIC_API_USE_32BIT_IDS            (1ULL << 0)
>  #define KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK  (1ULL << 1)
>  
> +/* Available with KVM_CAP_ARM_TIMER */
> +
> +/* Bits for run->request_interrupt_window */
> +#define KVM_IRQWINDOW_VTIMER		(1 << 0)
> +
> +/* Bits for run->arm_timer.timesource */
> +#define KVM_ARM_TIMER_VTIMER		(1 << 0)
> +
>  #endif /* __LINUX_KVM_H */
> diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
> index 4309b60..cbbb50dd 100644
> --- a/virt/kvm/arm/arch_timer.c
> +++ b/virt/kvm/arm/arch_timer.c
> @@ -170,16 +170,45 @@ static void kvm_timer_update_irq(struct kvm_vcpu *vcpu, bool new_level)
>  {
>  	int ret;
>  	struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
> +	struct kvm_run *run = vcpu->run;
>  
> -	BUG_ON(!vgic_initialized(vcpu->kvm));
> +	BUG_ON(irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm));
>  
>  	timer->active_cleared_last = false;
>  	timer->irq.level = new_level;
> -	trace_kvm_timer_update_irq(vcpu->vcpu_id, timer->irq.irq,
> +	trace_kvm_timer_update_irq(vcpu->vcpu_id, host_vtimer_irq,
>  				   timer->irq.level);
> -	ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> -					 timer->irq.irq,
> -					 timer->irq.level);
> +
> +	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {

Given how many times you repeat this idiom in this patch, you should
have a single condition that encapsulate it once and for all.

> +		/* Fire the timer in the VGIC */
> +
> +		ret = kvm_vgic_inject_mapped_irq(vcpu->kvm, vcpu->vcpu_id,
> +						 timer->irq.irq,
> +						 timer->irq.level);
> +	} else if (!vcpu->arch.user_space_arm_timers) {
> +		/* User space has not activated timer use */
> +		ret = 0;
> +	} else {
> +		/*
> +		 * Set PENDING_TIMER so that user space can handle the event if
> +		 *
> +		 *   1) Level is high
> +		 *   2) The vtimer is not suppressed by user space
> +		 *   3) We are not in the timer trigger exit path
> +		 */
> +		if (new_level &&
> +		    !(run->request_interrupt_window & KVM_IRQWINDOW_VTIMER) &&
> +		    (run->exit_reason != KVM_EXIT_ARM_TIMER)) {
> +			/* KVM_REQ_PENDING_TIMER means vtimer triggered */
> +			kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
> +		}
> +
> +		/* Force a new level high check on next entry */
> +		timer->irq.level = 0;

I think this could become a bit more simple if you follow the flow I
mentioned earlier involving kvm_timer_sync(). Also, I only see how you
flag the line as being high, but not how you lower it. Care to explain
that flow?

> +
> +		ret = 0;
> +	}
> +
>  	WARN_ON(ret);
>  }
>  
> @@ -197,7 +226,8 @@ static int kvm_timer_update_state(struct kvm_vcpu *vcpu)
>  	 * because the guest would never see the interrupt.  Instead wait
>  	 * until we call this function from kvm_timer_flush_hwstate.
>  	 */
> -	if (!vgic_initialized(vcpu->kvm) || !timer->enabled)
> +	if ((irqchip_in_kernel(vcpu->kvm) && !vgic_initialized(vcpu->kvm)) ||
> +	    !timer->enabled)
>  		return -ENODEV;
>  
>  	if (kvm_timer_should_fire(vcpu) != timer->irq.level)
> @@ -275,35 +305,57 @@ void kvm_timer_flush_hwstate(struct kvm_vcpu *vcpu)
>  	* to ensure that hardware interrupts from the timer triggers a guest
>  	* exit.
>  	*/
> -	phys_active = timer->irq.level ||
> -			kvm_vgic_map_is_active(vcpu, timer->irq.irq);
> -
> -	/*
> -	 * We want to avoid hitting the (re)distributor as much as
> -	 * possible, as this is a potentially expensive MMIO access
> -	 * (not to mention locks in the irq layer), and a solution for
> -	 * this is to cache the "active" state in memory.
> -	 *
> -	 * Things to consider: we cannot cache an "active set" state,
> -	 * because the HW can change this behind our back (it becomes
> -	 * "clear" in the HW). We must then restrict the caching to
> -	 * the "clear" state.
> -	 *
> -	 * The cache is invalidated on:
> -	 * - vcpu put, indicating that the HW cannot be trusted to be
> -	 *   in a sane state on the next vcpu load,
> -	 * - any change in the interrupt state
> -	 *
> -	 * Usage conditions:
> -	 * - cached value is "active clear"
> -	 * - value to be programmed is "active clear"
> -	 */
> -	if (timer->active_cleared_last && !phys_active)
> -		return;
> +	if (irqchip_in_kernel(vcpu->kvm) && vgic_initialized(vcpu->kvm)) {
> +		phys_active = timer->irq.level ||
> +				kvm_vgic_map_is_active(vcpu, timer->irq.irq);
> +
> +		/*
> +		 * We want to avoid hitting the (re)distributor as much as
> +		 * possible, as this is a potentially expensive MMIO access
> +		 * (not to mention locks in the irq layer), and a solution for
> +		 * this is to cache the "active" state in memory.
> +		 *
> +		 * Things to consider: we cannot cache an "active set" state,
> +		 * because the HW can change this behind our back (it becomes
> +		 * "clear" in the HW). We must then restrict the caching to
> +		 * the "clear" state.
> +		 *
> +		 * The cache is invalidated on:
> +		 * - vcpu put, indicating that the HW cannot be trusted to be
> +		 *   in a sane state on the next vcpu load,
> +		 * - any change in the interrupt state
> +		 *
> +		 * Usage conditions:
> +		 * - cached value is "active clear"
> +		 * - value to be programmed is "active clear"
> +		 */
> +		if (timer->active_cleared_last && !phys_active)
> +			return;
> +
> +		ret = irq_set_irqchip_state(host_vtimer_irq,
> +					    IRQCHIP_STATE_ACTIVE,
> +					    phys_active);
> +	} else {
> +		/* User space tells us whether the timer is in active mode */
> +		phys_active = vcpu->run->request_interrupt_window &
> +			      KVM_IRQWINDOW_VTIMER;

No, this just says "mask the interrupt". It doesn't say anything about
the state of the timer. More importantly: you sample the shared page.
What guarantees that the information there is preserved? Is userspace
writing that bit each time the vcpu thread re-enters the kernel with
this interrupt being in flight?

> +
> +		/* However if the line is high, we exit anyway, so we want
> +		 * to keep the IRQ masked */
> +		phys_active = phys_active || timer->irq.level;

Why would you force the interrupt to be masked as soon as the timer is
firing? If userspace hasn't masked it, I don't think you should paper
over it.

> +
> +		/*
> +		 * So we can just explicitly mask or unmask the IRQ, gaining
> +		 * more compatibility with oddball irq controllers.
> +		 */
> +		if (phys_active)
> +			disable_percpu_irq(host_vtimer_irq);
> +		else
> +			enable_percpu_irq(host_vtimer_irq, 0);

Since you are now targeting random irqchips (as opposed to a GIC
specifically), what guarantees that the timer is a per-cpu IRQ?

> +
> +		ret = 0;
> +	}
>  
> -	ret = irq_set_irqchip_state(host_vtimer_irq,
> -				    IRQCHIP_STATE_ACTIVE,
> -				    phys_active);
>  	WARN_ON(ret);
>  
>  	timer->active_cleared_last = !phys_active;
> @@ -479,6 +531,10 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  	if (timer->enabled)
>  		return 0;
>  
> +	/* No need to route physical IRQs when we don't use the vgic */
> +	if (!irqchip_in_kernel(vcpu->kvm))
> +		goto no_vgic;
> +
>  	/*
>  	 * Find the physical IRQ number corresponding to the host_vtimer_irq
>  	 */
> @@ -502,6 +558,7 @@ int kvm_timer_enable(struct kvm_vcpu *vcpu)
>  	if (ret)
>  		return ret;
>  
> +no_vgic:
>  
>  	/*
>  	 * There is a potential race here between VCPUs starting for the first
> 

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply

* [GIT PULL 1/5] i.MX cleanup for 4.9
From: Arnd Bergmann @ 2016-09-19 14:48 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473670948-4265-1-git-send-email-shawnguo@kernel.org>

On Monday, September 12, 2016 5:02:24 PM CEST Shawn Guo wrote:
> i.MX cleanup for 4.9:
>  - Drop i.MX1 board files and make i.MX1 a DT only platform.
>  - Remove obsolete ENET initialization code for TX28 board, since FEC
>    driver handles those setup well now.
>  - A couple of cleanups on i.MX31 IOMUX headers to drop duplications
>  - A few other random and trivial cleanups
> 

Pulled into next/cleanup, thanks!

	Arnd

^ permalink raw reply

* [GIT PULL] ARM: mediatek: soc updates for v4.9
From: Arnd Bergmann @ 2016-09-19 14:46 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <dd55c369-3684-2a27-6b66-7a98fa485627@gmail.com>

On Monday, September 12, 2016 5:52:30 PM CEST Matthias Brugger wrote:
> - extent the waiting time of the pmic wrapper to 10 ms which
> reduces the failure rate on the data transfer between pmic and
> pmic wrapper.
> 
> ----------------------------------------------------------------
> 

Pulled into next/drivers, thanks!

	Arnd

^ permalink raw reply

* [RFC] Arm64 boot fail with numa enable in BIOS
From: Will Deacon @ 2016-09-19 14:45 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919140709.GA17464@leverpostej>

On Mon, Sep 19, 2016 at 03:07:19PM +0100, Mark Rutland wrote:
> [adding LAKML, arm64 maintainers]

I've also looped in Euler ThunderTown, since (a) he's at Huawei and is
assumedly testing this stuff and (b) he has a fairly big NUMA patch
series doing the rounds (some of which I've queued).

> On Mon, Sep 19, 2016 at 09:05:26PM +0800, Yisheng Xie wrote:
> In future, please make sure to Cc LAKML along with relevant parties when
> sending arm64 patches/queries.
> 
> For everyone newly Cc'd, the original message (with attachments) can be
> found at:
> 
> http://lkml.kernel.org/r/7618d76d-bfa8-d8aa-59aa-06f9d90c1a98 at huawei.com
> 
> > When I enable NUMA in BIOS for arm64, it failed to boot on v4.8-rc4-162-g071e31e.
> 
> That commit ID doesn't seem to be in mainline (I can't find it in my
> local tree). Which tree are you using? Do you have local patches
> applied?

That commit is in mainline:

  http://git.kernel.org/linus/071e31e

It would be nice to know if the problem also exists on the arm64
for-next/core branch.

Will


> I take it that by "enable NUMA in BIOS", you mean exposing SRAT to the
> OS?
> 
> > For the crash log, it seems caused by error number of cpumask.
> > Any ideas about it?
> 
> Much earlier in your log, there was a (non-fatal) warning, as below. Do
> you see this without NUMA/SRAT enabled in your FW? I don't see how the
> SRAT should affect the secondaries we try to bring online.
> 
> Given your MPIDRs have Aff2 bits set, I wonder if we've conflated a
> logical ID with a physical ID somewhere, and it just so happens that the
> NUMA code is more likely to poke something based on that.
> 
> Can you modify the warning in cpumask.h to dump the bad CPU number? That
> would make it fairly clear if that's the case.
> 
> Thanks,
> Mark.
> 
> > [    0.297337] Detected PIPT I-cache on CPU1
> > [    0.297347] GICv3: CPU1: found redistributor 10001 region 1:0x000000004d140000
> > [    0.297356] CPU1: Booted secondary processor [410fd082]
> > [    0.297375] ------------[ cut here ]------------
> > [    0.320390] WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x128/0x17c
> > [    0.329356] Modules linked in:
> > [    0.332434] 
> > [    0.333932] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-rc4-00163-g803ea3a #21
> > [    0.341581] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> > [    0.347735] task: ffff8013e9dd0000 task.stack: ffff8013e9dcc000
> > [    0.353714] PC is at gic_raise_softirq+0x128/0x17c
> > [    0.358550] LR is at gic_raise_softirq+0xa0/0x17c
> > [    0.363298] pc : [<ffff00000838c124>] lr : [<ffff00000838c09c>] pstate: 200001c5
> > [    0.370770] sp : ffff8013e9dcfde0
> > [    0.374112] x29: ffff8013e9dcfde0 x28: 0000000000000000 
> > [    0.379476] x27: 000000000083207c x26: ffff000008ca5d70 
> > [    0.384841] x25: 0000000100000001 x24: ffff000008d63ff3 
> > [    0.390205] x23: 0000000000000000 x22: ffff000008cb0000 
> > [    0.395569] x21: ffff00000884edb0 x20: 0000000000000001 
> > [    0.400933] x19: 0000000100000000 x18: 0000000000000000 
> > [    0.406298] x17: 0000000000000000 x16: 0000000003010066 
> > [    0.411661] x15: ffff000008ca8000 x14: 0000000000000013 
> > [    0.417025] x13: 0000000000000000 x12: 0000000000000013 
> > [    0.422389] x11: 0000000000000013 x10: 0000000002e92aa7 
> > [    0.427754] x9 : 0000000000000000 x8 : ffff8413eb6ca668 
> > [    0.433118] x7 : ffff8413eb6ca690 x6 : 0000000000000000 
> > [    0.438482] x5 : fffffffffffffffe x4 : 0000000000000000 
> > [    0.443845] x3 : 0000000000000040 x2 : 0000000000000041 
> > [    0.449209] x1 : 0000000000000000 x0 : 0000000000000001 
> > [    0.454573] 
> > [    0.456069] ---[ end trace b58e70f3295a8cd7 ]---
> > [    0.460730] Call trace:
> > [    0.463193] Exception stack(0xffff8013e9dcfc10 to 0xffff8013e9dcfd40)
> > [    0.469699] fc00:                                   0000000100000000 0001000000000000
> > [    0.477611] fc20: ffff8013e9dcfde0 ffff00000838c124 ffff000008d72228 ffff8013e9dcff70
> > [    0.485524] fc40: ffff000008d72608 ffff000008ab02a4 0000000000000000 0000000000000000
> > [    0.493436] fc60: 0000000000000000 3464313430303030 0000000000000000 0000000000000000
> > [    0.501348] fc80: ffff8013e9dcfc90 ffff00000836e678 ffff8013e9dcfca0 ffff00000836e910
> > [    0.509259] fca0: ffff8013e9dcfd30 ffff00000836ec10 0000000000000001 0000000000000000
> > [    0.517171] fcc0: 0000000000000041 0000000000000040 0000000000000000 fffffffffffffffe
> > [    0.525083] fce0: 0000000000000000 ffff8413eb6ca690 ffff8413eb6ca668 0000000000000000
> > [    0.532995] fd00: 0000000002e92aa7 0000000000000013 0000000000000013 0000000000000000
> > [    0.540907] fd20: 0000000000000013 ffff000008ca8000 0000000003010066 0000000000000000
> > [    0.548819] [<ffff00000838c124>] gic_raise_softirq+0x128/0x17c
> > [    0.554713] [<ffff00000808e1f4>] smp_send_reschedule+0x34/0x3c
> > [    0.560605] [<ffff0000080ddf18>] resched_curr+0x40/0x5c
> > [    0.565881] [<ffff0000080de650>] check_preempt_curr+0x58/0xa0
> > [    0.571685] [<ffff0000080de6b0>] ttwu_do_wakeup+0x18/0x80
> > [    0.577136] [<ffff0000080de790>] ttwu_do_activate+0x78/0x88
> > [    0.582763] [<ffff0000080df5cc>] try_to_wake_up+0x1f8/0x300
> > [    0.588390] [<ffff0000080df79c>] default_wake_function+0x10/0x18
> > [    0.594458] [<ffff0000080f3210>] __wake_up_common+0x5c/0x9c
> > [    0.600085] [<ffff0000080f3264>] __wake_up_locked+0x14/0x1c
> > [    0.605712] [<ffff0000080f3e10>] complete+0x40/0x5c
> > [    0.610635] [<ffff00000808dba8>] secondary_start_kernel+0x148/0x1a8
> > [    0.616965] [<00000000000831a8>] 0x831a8
> 

^ permalink raw reply

* [PATCH] ASoC: rk3399_gru_sound: fix recording pop at first attempt
From: Mark Rutland @ 2016-09-19 14:44 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1474295379-16936-1-git-send-email-zhengxing@rock-chips.com>

On Mon, Sep 19, 2016 at 10:29:39PM +0800, Xing Zheng wrote:
> From: Wonjoon Lee <woojoo.lee@samsung.com>
> 
> Pop happens when mclk applied but dmic's own boot-time
> Specify dmic delay times in dt to make sure
> clocks are ready earlier than dmic working
> 
> Signed-off-by: Wonjoon Lee <woojoo.lee@samsung.com>
> Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
> ---
> 
>  .../bindings/sound/rockchip,rk3399-gru-sound.txt   |    6 ++++++
>  sound/soc/rockchip/rk3399_gru_sound.c              |   14 ++++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> index f19b6c8..b7dd3ab 100644
> --- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> +++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
> @@ -6,6 +6,12 @@ Required properties:
>    connected to the codecs
>  - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
>  
> +Optional properties:
> +- dmic-delay : specify delay time for DMIC ready.
> +  If this option is specified, which means it's required dmic need
> +  delay for DMIC to ready so that rt5514 can avoid recording before
> +  DMIC send valid data

What units is this in? Per the code it looks like ms, so if we follow
Documentation/devicetree/bindings/property-units.txt, thous should be
named something like dmic-enable-delay-ms.

That said, do we even need a property for this? Does this vary much in
practice?

If it does, can we not derive this delay from other information (e.g.
the rates of input clocks and so on)? What exactly determines the
necessary delay?

Thanks,
Mark.

>  
>  sound {
> diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
> index 164b6da..6ab838b 100644
> --- a/sound/soc/rockchip/rk3399_gru_sound.c
> +++ b/sound/soc/rockchip/rk3399_gru_sound.c
> @@ -37,6 +37,8 @@
>  
>  #define SOUND_FS	256
>  
> +unsigned int rt5514_dmic_delay;
> +
>  static struct snd_soc_jack rockchip_sound_jack;
>  
>  static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
> @@ -122,6 +124,9 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
>  		return ret;
>  	}
>  
> +	/* Wait for DMIC stable */
> +	msleep(rt5514_dmic_delay);
> +
>  	return 0;
>  }
>  
> @@ -334,6 +339,15 @@ static int rockchip_sound_probe(struct platform_device *pdev)
>  		return -ENODEV;
>  	}
>  
> +	/* Set DMIC delay */
> +	ret = device_property_read_u32(&pdev->dev, "dmic-delay",
> +					&rt5514_dmic_delay);
> +	if (ret) {
> +		rt5514_dmic_delay = 0;
> +		dev_dbg(&pdev->dev,
> +			"no optional property 'dmic-delay' found, default: no delay\n");
> +	}
> +
>  	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
>  	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
>  	rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
> -- 
> 1.7.9.5
> 
> 

^ permalink raw reply

* [PATCH v3 1/8] scpi: Add cmd indirection table to prepare for legacy commands
From: Sudeep Holla @ 2016-09-19 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1473262477-18045-2-git-send-email-narmstrong@baylibre.com>

Hi Neil,

On 07/09/16 16:34, Neil Armstrong wrote:
> Add indirection table to permit multiple command values for legacy support.
>

I wrote the most of the patch and you changed the author too ;)

> Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
> ---
>  drivers/firmware/arm_scpi.c | 145 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 127 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c
> index 4388937..9a87687 100644
> --- a/drivers/firmware/arm_scpi.c
> +++ b/drivers/firmware/arm_scpi.c

[..]

> @@ -161,6 +194,7 @@ struct scpi_drvinfo {
>  	u32 protocol_version;
>  	u32 firmware_version;
>  	int num_chans;
> +	int *scpi_cmds;
>  	atomic_t next_chan;
>  	struct scpi_ops *scpi_ops;
>  	struct scpi_chan *channels;
> @@ -390,6 +424,19 @@ static u32 scpi_get_version(void)
>  	return scpi_info->protocol_version;
>  }
>
> +static inline int check_cmd(unsigned int offset)
> +{
> +	if (offset >= CMD_MAX_COUNT ||

If we call scpi_send_message internally(as it's static) why is this
check needed ?


> +	    !scpi_info ||
> +	    !scpi_info->scpi_cmds)

Will be even reach to this point if above is true ?

> +		return -EINVAL;
> +
> +	if (scpi_info->scpi_cmds[offset] < 0)
> +		return -EOPNOTSUPP;

IMO just above couple of lines in the beginning of scpi_send_message
will suffice. You can just add this to my original patch.

>  static int
>  scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>  {
> @@ -397,8 +444,13 @@ scpi_clk_get_range(u16 clk_id, unsigned long *min, unsigned long *max)
>  	struct clk_get_info clk;
>  	__le16 le_clk_id = cpu_to_le16(clk_id);
>
> -	ret = scpi_send_message(SCPI_CMD_GET_CLOCK_INFO, &le_clk_id,
> -				sizeof(le_clk_id), &clk, sizeof(clk));
> +	ret = check_cmd(CMD_GET_CLOCK_INFO);
> +	if (ret)
> +		return ret;
> +

It's totally unnecessary to add check in each and every function calling
scpi_send_message, why not add it to scpi_send_message instead.

-- 
Regards,
Sudeep

^ permalink raw reply

* [PATCH] ARM: mvebu: Select corediv clk for all mvebu v7 SoC
From: Gregory CLEMENT @ 2016-09-19 14:41 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919135230.3ukszs3ybd5fjfx2@pengutronix.de>

Hi Uwe,
 
 On lun., sept. 19 2016, Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de> wrote:

> On Mon, Sep 19, 2016 at 01:52:07PM +0200, Gregory CLEMENT wrote:
>> Since the commit bd3677ff31a3 ("clk: mvebu: Remove corediv clock from
>> Armada XP"), the corediv clk is no more selected for Armada XP, however
>> this clock is used for Armada XP using the compatible
>> armada-370-corediv-clock.
>> 
>> More over even if with the commit 1594d568c6e3 ("clk: mvebu: Move corediv
>> config to mvebu config"), it was selected for Armada 38x and Armada 375,
>> it was still not selected for Armada 39x.
>
> Instead of the above paragraph I'd write:
>
> 	While since commit 1594d568c6e3 ("clk: mvebu: Move corediv
> 	config to mvebu config") Armada 38x and Armada 375 got corediv
> 	support again, not only Armada XP was missed but also Armada
> 	39x.

Thanks for your suggestion I will use it.

>
>> Actually all the SoC selecting MVEBU_V7 config need this clock:
>> git grep "\-corediv-clock" arch/arm/boot/dts
>> arch/arm/boot/dts/armada-370-xp.dtsi: compatible = "marvell,armada-370-corediv-clock";
>> arch/arm/boot/dts/armada-375.dtsi:    compatible = "marvell,armada-375-corediv-clock";
>> arch/arm/boot/dts/armada-38x.dtsi:    compatible = "marvell,armada-380-corediv-clock";
>> arch/arm/boot/dts/armada-39x.dtsi:    compatible = "marvell,armada-390-corediv-clock"
>> 
>> This commit now fixes this behavior.
>
> ... by letting MVEBU_V7 select MVEBU_CLK_COREDIV.


I didn't want describe the content of the patch but I don't mind adding
it.

Thanks,

Gregory

>> Fixes: bd3677ff31a3 ("clk: mvebu: Remove corediv clock from Armada XP")
>> Cc: stable at vger.kernel.org
>> Reported-by: Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>
>> Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
>
> BTW, I considered doing this, too, but failed to see that 39x is
> missing, too, and so thought this to be wrong.
>
> Best regards
> Uwe
>
> -- 
> Pengutronix e.K.                           | Uwe Kleine-K?nig            |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |

-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH] ASoC: rk3399_gru_sound: fix recording pop at first attempt
From: Xing Zheng @ 2016-09-19 14:29 UTC (permalink / raw)
  To: linux-arm-kernel

From: Wonjoon Lee <woojoo.lee@samsung.com>

Pop happens when mclk applied but dmic's own boot-time
Specify dmic delay times in dt to make sure
clocks are ready earlier than dmic working

Signed-off-by: Wonjoon Lee <woojoo.lee@samsung.com>
Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
---

 .../bindings/sound/rockchip,rk3399-gru-sound.txt   |    6 ++++++
 sound/soc/rockchip/rk3399_gru_sound.c              |   14 ++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
index f19b6c8..b7dd3ab 100644
--- a/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
+++ b/Documentation/devicetree/bindings/sound/rockchip,rk3399-gru-sound.txt
@@ -6,6 +6,12 @@ Required properties:
   connected to the codecs
 - rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
 
+Optional properties:
+- dmic-delay : specify delay time for DMIC ready.
+  If this option is specified, which means it's required dmic need
+  delay for DMIC to ready so that rt5514 can avoid recording before
+  DMIC send valid data
+
 Example:
 
 sound {
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c
index 164b6da..6ab838b 100644
--- a/sound/soc/rockchip/rk3399_gru_sound.c
+++ b/sound/soc/rockchip/rk3399_gru_sound.c
@@ -37,6 +37,8 @@
 
 #define SOUND_FS	256
 
+unsigned int rt5514_dmic_delay;
+
 static struct snd_soc_jack rockchip_sound_jack;
 
 static const struct snd_soc_dapm_widget rockchip_dapm_widgets[] = {
@@ -122,6 +124,9 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
+	/* Wait for DMIC stable */
+	msleep(rt5514_dmic_delay);
+
 	return 0;
 }
 
@@ -334,6 +339,15 @@ static int rockchip_sound_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	/* Set DMIC delay */
+	ret = device_property_read_u32(&pdev->dev, "dmic-delay",
+					&rt5514_dmic_delay);
+	if (ret) {
+		rt5514_dmic_delay = 0;
+		dev_dbg(&pdev->dev,
+			"no optional property 'dmic-delay' found, default: no delay\n");
+	}
+
 	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
 	rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
 	rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
-- 
1.7.9.5

^ permalink raw reply related

* [PATCH 3/3] arm: dts: imx7-colibri: Use enable-gpios for BL_ON
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Use pwm-backlight driver 'enable-gpios' property for backlight on/off control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index 2af5e3e..ce5edb5 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -43,7 +43,10 @@
 / {
 	bl: backlight {
 		compatible = "pwm-backlight";
+		pinctrl-names = "default";
+		pinctrl-0 = <&pinctrl_gpio_bl_on>;
 		pwms = <&pwm1 0 5000000 0>;
+		enable-gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
 	};
 
 	reg_module_3v3: regulator-module-3v3 {
@@ -356,7 +359,6 @@
 		fsl,pins = <
 			MX7D_PAD_ECSPI2_SS0__GPIO4_IO23		0x14 /* SODIMM 65 */
 			MX7D_PAD_SD1_CD_B__GPIO5_IO0		0x14 /* SODIMM 69 */
-			MX7D_PAD_SD1_WP__GPIO5_IO1		0x14 /* SODIMM 71 */
 			MX7D_PAD_I2C4_SDA__GPIO4_IO15		0x14 /* SODIMM 75 */
 			MX7D_PAD_ECSPI1_MISO__GPIO4_IO18	0x14 /* SODIMM 79 */
 			MX7D_PAD_I2C3_SCL__GPIO4_IO12		0x14 /* SODIMM 81 */
@@ -388,6 +390,12 @@
 		>;
 	};
 
+		pinctrl_gpio_bl_on: gpio-bl-on {
+			fsl,pins = <
+				MX7D_PAD_SD1_WP__GPIO5_IO1		0x14
+			>;
+		};
+
 	pinctrl_i2c1_int: i2c1-int-grp { /* PMIC / TOUCH */
 		fsl,pins = <
 			MX7D_PAD_GPIO1_IO13__GPIO1_IO13	0x79
-- 
2.9.2

^ permalink raw reply related

* [PATCH 2/3] arm: dts: imx7-colibri: Use pwm polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Configure PWM polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 arch/arm/boot/dts/imx7-colibri.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx7-colibri.dtsi b/arch/arm/boot/dts/imx7-colibri.dtsi
index a9cc657..2af5e3e 100644
--- a/arch/arm/boot/dts/imx7-colibri.dtsi
+++ b/arch/arm/boot/dts/imx7-colibri.dtsi
@@ -43,7 +43,7 @@
 / {
 	bl: backlight {
 		compatible = "pwm-backlight";
-		pwms = <&pwm1 0 5000000>;
+		pwms = <&pwm1 0 5000000 0>;
 	};
 
 	reg_module_3v3: regulator-module-3v3 {
-- 
2.9.2

^ permalink raw reply related

* [PATCH 1/3] arm: dts: imx7: Update #pwm-cells for PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20160919142347.11342-1-bhuvanchandra.dv@toradex.com>

Update #pwm-cells to 3 in order to support PWM signal polarity control.

Signed-off-by: Bhuvanchandra DV <bhuvanchandra.dv@toradex.com>
---
 Documentation/devicetree/bindings/pwm/imx-pwm.txt | 6 +++---
 arch/arm/boot/dts/imx7s.dtsi                      | 8 ++++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/Documentation/devicetree/bindings/pwm/imx-pwm.txt b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
index e00c2e9..c61bdf8 100644
--- a/Documentation/devicetree/bindings/pwm/imx-pwm.txt
+++ b/Documentation/devicetree/bindings/pwm/imx-pwm.txt
@@ -6,8 +6,8 @@ Required properties:
   - "fsl,imx1-pwm" for PWM compatible with the one integrated on i.MX1
   - "fsl,imx27-pwm" for PWM compatible with the one integrated on i.MX27
 - reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
-  the cells format.
+- #pwm-cells: 2 for i.MX1 and 3 for i.MX27 and newer SoCs. See pwm.txt
+  in this directory for a description of the cells format.
 - clocks : Clock specifiers for both ipg and per clocks.
 - clock-names : Clock names should include both "ipg" and "per"
 See the clock consumer binding,
@@ -17,7 +17,7 @@ See the clock consumer binding,
 Example:
 
 pwm1: pwm at 53fb4000 {
-	#pwm-cells = <2>;
+	#pwm-cells = <3>;
 	compatible = "fsl,imx53-pwm", "fsl,imx27-pwm";
 	reg = <0x53fb4000 0x4000>;
 	clocks = <&clks IMX5_CLK_PWM1_IPG_GATE>,
diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
index 0d7d5ac..8d1d471 100644
--- a/arch/arm/boot/dts/imx7s.dtsi
+++ b/arch/arm/boot/dts/imx7s.dtsi
@@ -601,7 +601,7 @@
 				clocks = <&clks IMX7D_PWM1_ROOT_CLK>,
 					 <&clks IMX7D_PWM1_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -612,7 +612,7 @@
 				clocks = <&clks IMX7D_PWM2_ROOT_CLK>,
 					 <&clks IMX7D_PWM2_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -623,7 +623,7 @@
 				clocks = <&clks IMX7D_PWM3_ROOT_CLK>,
 					 <&clks IMX7D_PWM3_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
@@ -634,7 +634,7 @@
 				clocks = <&clks IMX7D_PWM4_ROOT_CLK>,
 					 <&clks IMX7D_PWM4_ROOT_CLK>;
 				clock-names = "ipg", "per";
-				#pwm-cells = <2>;
+				#pwm-cells = <3>;
 				status = "disabled";
 			};
 
-- 
2.9.2

^ permalink raw reply related

* [PATCH 0/3] iMX7 PWM polarity control
From: Bhuvanchandra DV @ 2016-09-19 14:23 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset depends on this patchset[1] and this patch[2] which adds support
for polarity control in imx-pwm driver.

- Use pwm polarity control on iMX7 based modules.
- Enable polarity control on Toradex Colibri iMX7D/S module.
- Add BL_ON GPIO control for Toradex Colibri iMX7D/S module.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2014-October/294027.html
[2] https://www.spinics.net/lists/arm-kernel/msg530818.html

Bhuvanchandra DV (3):
  arm: dts: imx7: Update #pwm-cells for PWM polarity control
  arm: dts: imx7-colibri: Use pwm polarity control
  arm: dts: imx7-colibri: Use enable-gpios for BL_ON

 Documentation/devicetree/bindings/pwm/imx-pwm.txt |  6 +++---
 arch/arm/boot/dts/imx7-colibri.dtsi               | 12 ++++++++++--
 arch/arm/boot/dts/imx7s.dtsi                      |  8 ++++----
 3 files changed, 17 insertions(+), 9 deletions(-)

-- 
2.9.2

^ permalink raw reply

* [PATCH v7 00/22] Generic DT bindings for PCI IOMMUs and ARM SMMU
From: Will Deacon @ 2016-09-19 14:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <99ee0946-c7ff-e6e4-08c1-ff686ea1a8a5@arm.com>

On Mon, Sep 19, 2016 at 01:41:47PM +0100, Robin Murphy wrote:
> On 19/09/16 13:24, Will Deacon wrote:
> > On Mon, Sep 19, 2016 at 02:13:45PM +0200, Auger Eric wrote:
> >> On 16/09/2016 18:18, Robin Murphy wrote:
> >>> What I probably will do, though, since we have the functionality in
> >>> place for the sake of the old binding, and I think there are other folks
> >>> who want PCI iommu-map support but would prefer not to bother with DMA
> >>> ops on the host, is add a command-line option to disable DMA domains
> >>> even for the generic bindings.
> >>
> >> Yes this would be a good thing I think. This series has an important
> >> impact on platforms which do not have smmu v3, where contexts are scarce
> >> HW resources.
> > 
> > Rather than disabling DMA domains entirely, we could specify a number
> > of contexts to reserve for other use (e.g. VFIO). It's a pity that these
> > options are global for the system, as opposed to per SMMU instance,
> > but I can't see a good way around that.
> 
> The problem with that approach is that due to bus traversal order you'd
> typically end up with the even-more-limited number of non-reserved
> contexts getting consumed by bridges that are unlikely to ever actually
> use their DMA ops, so you end up barely any better off than just not
> doing DMA ops at all, which we already have the code for.

For Seattle, perhaps, but that's quite a big generalisation. If we're
going to add an option, I'd much rather add something with some flexibility,
rather than end up supporting both "disable_dma_domains" and
"reserved_s2_contexts" in the long run.

> And yeah, if you had, say, "arm-smmu.reserved_s2_contexts=4", for the
> benefit of your PCI SMMU, what do the SMMUs in front of your other
> platform devices with only 2 contexts (and which only want DMA ops) do?

There's two things in this example:

  (1) If other SMMUs only have 2 contexts, then they reserve both and warn
  (2) If some SMMUs want DMA ops and others don't, then you have an issue
      with *any* sort of cmdline option to control this

Will

^ permalink raw reply

* [RFC] Arm64 boot fail with numa enable in BIOS
From: Mark Rutland @ 2016-09-19 14:07 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <7618d76d-bfa8-d8aa-59aa-06f9d90c1a98@huawei.com>

[adding LAKML, arm64 maintainers]

On Mon, Sep 19, 2016 at 09:05:26PM +0800, Yisheng Xie wrote:
> hi all,

Hi,

In future, please make sure to Cc LAKML along with relevant parties when
sending arm64 patches/queries.

For everyone newly Cc'd, the original message (with attachments) can be
found at:

http://lkml.kernel.org/r/7618d76d-bfa8-d8aa-59aa-06f9d90c1a98 at huawei.com

> When I enable NUMA in BIOS for arm64, it failed to boot on v4.8-rc4-162-g071e31e.

That commit ID doesn't seem to be in mainline (I can't find it in my
local tree). Which tree are you using? Do you have local patches
applied?

I take it that by "enable NUMA in BIOS", you mean exposing SRAT to the
OS?

> For the crash log, it seems caused by error number of cpumask.
> Any ideas about it?

Much earlier in your log, there was a (non-fatal) warning, as below. Do
you see this without NUMA/SRAT enabled in your FW? I don't see how the
SRAT should affect the secondaries we try to bring online.

Given your MPIDRs have Aff2 bits set, I wonder if we've conflated a
logical ID with a physical ID somewhere, and it just so happens that the
NUMA code is more likely to poke something based on that.

Can you modify the warning in cpumask.h to dump the bad CPU number? That
would make it fairly clear if that's the case.

Thanks,
Mark.

> [    0.297337] Detected PIPT I-cache on CPU1
> [    0.297347] GICv3: CPU1: found redistributor 10001 region 1:0x000000004d140000
> [    0.297356] CPU1: Booted secondary processor [410fd082]
> [    0.297375] ------------[ cut here ]------------
> [    0.320390] WARNING: CPU: 1 PID: 0 at ./include/linux/cpumask.h:121 gic_raise_softirq+0x128/0x17c
> [    0.329356] Modules linked in:
> [    0.332434] 
> [    0.333932] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 4.8.0-rc4-00163-g803ea3a #21
> [    0.341581] Hardware name: Hisilicon Hi1616 Evaluation Board (DT)
> [    0.347735] task: ffff8013e9dd0000 task.stack: ffff8013e9dcc000
> [    0.353714] PC is at gic_raise_softirq+0x128/0x17c
> [    0.358550] LR is at gic_raise_softirq+0xa0/0x17c
> [    0.363298] pc : [<ffff00000838c124>] lr : [<ffff00000838c09c>] pstate: 200001c5
> [    0.370770] sp : ffff8013e9dcfde0
> [    0.374112] x29: ffff8013e9dcfde0 x28: 0000000000000000 
> [    0.379476] x27: 000000000083207c x26: ffff000008ca5d70 
> [    0.384841] x25: 0000000100000001 x24: ffff000008d63ff3 
> [    0.390205] x23: 0000000000000000 x22: ffff000008cb0000 
> [    0.395569] x21: ffff00000884edb0 x20: 0000000000000001 
> [    0.400933] x19: 0000000100000000 x18: 0000000000000000 
> [    0.406298] x17: 0000000000000000 x16: 0000000003010066 
> [    0.411661] x15: ffff000008ca8000 x14: 0000000000000013 
> [    0.417025] x13: 0000000000000000 x12: 0000000000000013 
> [    0.422389] x11: 0000000000000013 x10: 0000000002e92aa7 
> [    0.427754] x9 : 0000000000000000 x8 : ffff8413eb6ca668 
> [    0.433118] x7 : ffff8413eb6ca690 x6 : 0000000000000000 
> [    0.438482] x5 : fffffffffffffffe x4 : 0000000000000000 
> [    0.443845] x3 : 0000000000000040 x2 : 0000000000000041 
> [    0.449209] x1 : 0000000000000000 x0 : 0000000000000001 
> [    0.454573] 
> [    0.456069] ---[ end trace b58e70f3295a8cd7 ]---
> [    0.460730] Call trace:
> [    0.463193] Exception stack(0xffff8013e9dcfc10 to 0xffff8013e9dcfd40)
> [    0.469699] fc00:                                   0000000100000000 0001000000000000
> [    0.477611] fc20: ffff8013e9dcfde0 ffff00000838c124 ffff000008d72228 ffff8013e9dcff70
> [    0.485524] fc40: ffff000008d72608 ffff000008ab02a4 0000000000000000 0000000000000000
> [    0.493436] fc60: 0000000000000000 3464313430303030 0000000000000000 0000000000000000
> [    0.501348] fc80: ffff8013e9dcfc90 ffff00000836e678 ffff8013e9dcfca0 ffff00000836e910
> [    0.509259] fca0: ffff8013e9dcfd30 ffff00000836ec10 0000000000000001 0000000000000000
> [    0.517171] fcc0: 0000000000000041 0000000000000040 0000000000000000 fffffffffffffffe
> [    0.525083] fce0: 0000000000000000 ffff8413eb6ca690 ffff8413eb6ca668 0000000000000000
> [    0.532995] fd00: 0000000002e92aa7 0000000000000013 0000000000000013 0000000000000000
> [    0.540907] fd20: 0000000000000013 ffff000008ca8000 0000000003010066 0000000000000000
> [    0.548819] [<ffff00000838c124>] gic_raise_softirq+0x128/0x17c
> [    0.554713] [<ffff00000808e1f4>] smp_send_reschedule+0x34/0x3c
> [    0.560605] [<ffff0000080ddf18>] resched_curr+0x40/0x5c
> [    0.565881] [<ffff0000080de650>] check_preempt_curr+0x58/0xa0
> [    0.571685] [<ffff0000080de6b0>] ttwu_do_wakeup+0x18/0x80
> [    0.577136] [<ffff0000080de790>] ttwu_do_activate+0x78/0x88
> [    0.582763] [<ffff0000080df5cc>] try_to_wake_up+0x1f8/0x300
> [    0.588390] [<ffff0000080df79c>] default_wake_function+0x10/0x18
> [    0.594458] [<ffff0000080f3210>] __wake_up_common+0x5c/0x9c
> [    0.600085] [<ffff0000080f3264>] __wake_up_locked+0x14/0x1c
> [    0.605712] [<ffff0000080f3e10>] complete+0x40/0x5c
> [    0.610635] [<ffff00000808dba8>] secondary_start_kernel+0x148/0x1a8
> [    0.616965] [<00000000000831a8>] 0x831a8

^ permalink raw reply

* [PATCH v2 1/3] ipmi: add an Aspeed BT IPMI BMC driver
From: Corey Minyard @ 2016-09-19 14:01 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <9ce54c4c-e8ae-7ac2-de9c-71402dfa4c39@kaod.org>

On 09/19/2016 03:00 AM, C?dric Le Goater wrote:
> On 09/16/2016 09:41 PM, Corey Minyard wrote:
>> On 09/16/2016 05:39 AM, C?dric Le Goater wrote:
>>> From: Alistair Popple <alistair@popple.id.au>
>>>
>>> This patch adds a simple device driver to expose the iBT interface on
>>> Aspeed SOCs (AST2400 and AST2500) as a character device. Such SOCs are
>>> commonly used as BMCs (BaseBoard Management Controllers) and this
>>> driver implements the BMC side of the BT interface.
>>>
>>> The BT (Block Transfer) interface is used to perform in-band IPMI
>>> communication between a host and its BMC. Entire messages are buffered
>>> before sending a notification to the other end, host or BMC, that
>>> there is data to be read. Usually, the host emits requests and the BMC
>>> responses but the specification provides a mean for the BMC to send
>>> SMS Attention (BMC-to-Host attention or System Management Software
>>> attention) messages.
>>>
>>> For this purpose, the driver introduces a specific ioctl on the
>>> device: 'BT_BMC_IOCTL_SMS_ATN' that can be used by the system running
>>> on the BMC to signal the host of such an event.
>>>
>>> The device name defaults to '/dev/ipmi-bt-host'
>> Others have reviewed this for style and such, and I have looked
>> at it from a protocol point of view.  it looks to be sound for the
>> most part.  I have some higher level concerns:
>>
>> There appears to be no handling for multiple simultaneous users.
>> This interface can only be used by one task at a time, so you should
>> probably only allow one opener.  Well, I guess the BMC could be split
>> into a reader and a writer task, so I'm not really sure about that, but
>> I would think in most situations having more than one opener is a
>> bug.  You do call clr_b_busy() on open, for instance, which might be
>> an issue for multiple openers.  Maybe a module parameter for
>> maximum number of openers? Just want to make sure this was
>> thought about, at least.
> yes but not implemented ... The open_count in the bt_bmc structure
> is unused. In v3, I will replace it with a global atomic_t tracked
> in the open and release operations.
>
>> There is also no mutex protecting reading or writing.  If multiple
>> threads call read or write at the same time, it probably wouldn't
>> work correctly.  I think you need a read and a write mutex on the
>> interface to protect against this.
> yes. I will add a mutex also in v3.
>
>> The spec says:
>>
>>     The BMC must not return a given response once the corresponding
>>     Request-to-Response interval has passed. The BMC can ensure this
>>     by maintaining its own internal list of outstanding requests through
>>     the interface. The BMC could age and expire the entries in the list
>>     by expiring the entries at an interval that is somewhat shorter than
>>     the specified Request-to-Response interval....
> This is clearly not handled in the driver.
>
> For this purpose, we could maintain a request expiry list using the seq
> field of the BT message. Update the list in the read and write operations
> and arm a timer to garbage collect any left overs. As for the errno in
> the write when a response had timeout'ed, may be ETIMEDOUT ?

I think that would work, though I don't think you really need an
error response in this case.

I was thinking more just a timeout in the write function.  Ideally
the timeout would be calculated at receive time and then be
passed in on every write, to preserve the request-to-response
time for slow messages.  I like the simplicity of the driver the
way it is.

The trouble is that there is no easy way to pass in a timeout
in a write operation.  You could pass in a structure where the
first part is a 32-bit timeout, or something like that.  Or
maybe just a fixed timeout and assume every message is
handled in a short enough time that it meets the spec
requirement.  But that doesn't handle slowness on the
host side.  You can send the message via an ioctl,  which
again isn't terribly ideal.

It would be nice if there was a write function which was
able to pass metadata, but AFAIK that's only available on
sockets.

> For configuration of the maximum response time, a sysfs file would do
> I think.
>
> Do you want that in v3 also ? I have some experimental patches for it,
> that I can send as follow ups.

I'm fine either way.

Thanks,

-corey

>
> Thanks,
>
> C.
>
>> On the write side, though, there doesn't seem to be a way to handle a
>> situation where the host side doesn't respond for a while and the
>> pending message would need to be discarded.
>>
>> The spec doesn't mention much about error recovery on this interface,
>> but the way this is written should be fine, I think.
>>
>> I'm copying Rocky Craig, who wrote the host side driver for Linux, in
>> case he wants to comment on this.
>>
>> This is easy to read and understand, so I think v3 should be good.
>>
>> Thanks,
>>
>> -corey
>>
>>> Signed-off-by: Alistair Popple <alistair@popple.id.au>
>>> Signed-off-by: Jeremy Kerr <jk@ozlabs.org>
>>> Signed-off-by: Joel Stanley <joel@jms.id.au>
>>> [clg: - checkpatch fixes
>>>         - added a devicetree binding documentation
>>>         - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>           the BMC side of the IPMI BT interface
>>>         - renamed the device to 'ipmi-bt-host'
>>>         - introduced a temporary buffer to copy_{to,from}_user
>>>         - used platform_get_irq()
>>>         - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>           device
>>>         - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>> ]
>>> Signed-off-by: C?dric Le Goater <clg@kaod.org>
>>> ---
>>>
>>>    Changes since v1:
>>>
>>>    - replace 'bt_host' by 'bt_bmc' to reflect that the driver is
>>>      the BMC side of the IPMI BT interface
>>>    - renamed the device to 'ipmi-bt-host'
>>>    - introduced a temporary buffer to copy_{to,from}_user
>>>    - used platform_get_irq()
>>>    - moved the driver under drivers/char/ipmi/ but kept it as a misc
>>>      device
>>>    - changed the compatible cell to "aspeed,ast2400-bt-bmc"
>>>
>>>    .../bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt   |  23 +
>>>    drivers/Makefile                                   |   2 +-
>>>    drivers/char/ipmi/Kconfig                          |   7 +
>>>    drivers/char/ipmi/Makefile                         |   1 +
>>>    drivers/char/ipmi/bt-bmc.c                         | 486 +++++++++++++++++++++
>>>    include/uapi/linux/Kbuild                          |   1 +
>>>    include/uapi/linux/bt-bmc.h                        |  18 +
>>>    7 files changed, 537 insertions(+), 1 deletion(-)
>>>    create mode 100644 Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>>    create mode 100644 drivers/char/ipmi/bt-bmc.c
>>>    create mode 100644 include/uapi/linux/bt-bmc.h
>>>
>>> diff --git a/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> new file mode 100644
>>> index 000000000000..fbbacd958240
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/char/ipmi/aspeed,ast2400-bt-bmc.txt
>>> @@ -0,0 +1,23 @@
>>> +* Aspeed BT (Block Transfer) IPMI interface
>>> +
>>> +The Aspeed SOCs (AST2400 and AST2500) are commonly used as BMCs
>>> +(BaseBoard Management Controllers) and the BT interface can be used to
>>> +perform in-band IPMI communication with their host.
>>> +
>>> +Required properties:
>>> +
>>> +- compatible : should be "aspeed,ast2400-bt-bmc"
>>> +- reg: physical address and size of the registers
>>> +
>>> +Optional properties:
>>> +
>>> +- interrupts: interrupt generated by the BT interface. without an
>>> +  interrupt, the driver will operate in poll mode.
>>> +
>>> +Example:
>>> +
>>> +    ibt at 1e789140 {
>>> +        compatible = "aspeed,ast2400-bt-bmc";
>>> +        reg = <0x1e789140 0x18>;
>>> +        interrupts = <8>;
>>> +    };
>>> diff --git a/drivers/Makefile b/drivers/Makefile
>>> index 53abb4a5f736..5a9e7b6b7928 100644
>>> --- a/drivers/Makefile
>>> +++ b/drivers/Makefile
>>> @@ -21,7 +21,7 @@ obj-y                += video/
>>>    obj-y                += idle/
>>>      # IPMI must come before ACPI in order to provide IPMI opregion support
>>> -obj-$(CONFIG_IPMI_HANDLER)    += char/ipmi/
>>> +obj-y                += char/ipmi/
>>>      obj-$(CONFIG_ACPI)        += acpi/
>>>    obj-$(CONFIG_SFI)        += sfi/
>>> diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
>>> index 5a9350b1069a..2c234e3e7513 100644
>>> --- a/drivers/char/ipmi/Kconfig
>>> +++ b/drivers/char/ipmi/Kconfig
>>> @@ -76,3 +76,10 @@ config IPMI_POWEROFF
>>>         the IPMI management controller is capable of this.
>>>      endif # IPMI_HANDLER
>>> +
>>> +config ASPEED_BT_IPMI_BMC
>>> +    tristate "BT IPMI bmc driver"
>>> +    help
>>> +      Provides a driver for the BT (Block Transfer) IPMI interface
>>> +      found on Aspeed SOCs (AST2400 and AST2500). The driver
>>> +      implements the BMC side of the BT interface.
>>> diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile
>>> index f3ffde1f5f1f..0d98cd91def1 100644
>>> --- a/drivers/char/ipmi/Makefile
>>> +++ b/drivers/char/ipmi/Makefile
>>> @@ -11,3 +11,4 @@ obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o
>>>    obj-$(CONFIG_IPMI_POWERNV) += ipmi_powernv.o
>>>    obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
>>>    obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o
>>> +obj-$(CONFIG_ASPEED_BT_IPMI_BMC) += bt-bmc.o
>>> diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c
>>> new file mode 100644
>>> index 000000000000..b96cb421e1c2
>>> --- /dev/null
>>> +++ b/drivers/char/ipmi/bt-bmc.c
>>> @@ -0,0 +1,486 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#include <linux/module.h>
>>> +#include <linux/moduleparam.h>
>>> +#include <linux/errno.h>
>>> +#include <linux/poll.h>
>>> +#include <linux/sched.h>
>>> +#include <linux/spinlock.h>
>>> +#include <linux/slab.h>
>>> +#include <linux/init.h>
>>> +#include <linux/device.h>
>>> +#include <linux/of.h>
>>> +#include <linux/of_irq.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/io.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/delay.h>
>>> +#include <linux/miscdevice.h>
>>> +#include <linux/timer.h>
>>> +#include <linux/jiffies.h>
>>> +#include <linux/bt-bmc.h>
>>> +
>>> +/*
>>> + * This is a BMC device used to communicate to the host
>>> + */
>>> +#define DEVICE_NAME    "ipmi-bt-host"
>>> +
>>> +#define BT_IO_BASE    0xe4
>>> +#define BT_IRQ        10
>>> +
>>> +#define BT_CR0        0x0
>>> +#define   BT_CR0_IO_BASE        16
>>> +#define   BT_CR0_IRQ            12
>>> +#define   BT_CR0_EN_CLR_SLV_RDP        0x8
>>> +#define   BT_CR0_EN_CLR_SLV_WRP        0x4
>>> +#define   BT_CR0_ENABLE_IBT        0x1
>>> +#define BT_CR1        0x4
>>> +#define   BT_CR1_IRQ_H2B    0x01
>>> +#define   BT_CR1_IRQ_HBUSY    0x40
>>> +#define BT_CR2        0x8
>>> +#define   BT_CR2_IRQ_H2B    0x01
>>> +#define   BT_CR2_IRQ_HBUSY    0x40
>>> +#define BT_CR3        0xc
>>> +#define BT_CTRL        0x10
>>> +#define   BT_CTRL_B_BUSY        0x80
>>> +#define   BT_CTRL_H_BUSY        0x40
>>> +#define   BT_CTRL_OEM0            0x20
>>> +#define   BT_CTRL_SMS_ATN        0x10
>>> +#define   BT_CTRL_B2H_ATN        0x08
>>> +#define   BT_CTRL_H2B_ATN        0x04
>>> +#define   BT_CTRL_CLR_RD_PTR        0x02
>>> +#define   BT_CTRL_CLR_WR_PTR        0x01
>>> +#define BT_BMC2HOST    0x14
>>> +#define BT_INTMASK    0x18
>>> +#define   BT_INTMASK_B2H_IRQEN        0x01
>>> +#define   BT_INTMASK_B2H_IRQ        0x02
>>> +#define   BT_INTMASK_BMC_HWRST        0x80
>>> +
>>> +struct bt_bmc {
>>> +    struct device        dev;
>>> +    struct miscdevice    miscdev;
>>> +    void __iomem        *base;
>>> +    int            open_count;
>>> +    int            irq;
>>> +    wait_queue_head_t    queue;
>>> +    struct timer_list    poll_timer;
>>> +};
>>> +
>>> +static u8 bt_inb(struct bt_bmc *bt_bmc, int reg)
>>> +{
>>> +    return ioread8(bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg)
>>> +{
>>> +    iowrite8(data, bt_bmc->base + reg);
>>> +}
>>> +
>>> +static void clr_rd_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_RD_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_wr_ptr(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_CLR_WR_PTR, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_h2b_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_H2B_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (!(bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY))
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void clr_b_busy(struct bt_bmc *bt_bmc)
>>> +{
>>> +    if (bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_B_BUSY)
>>> +        bt_outb(bt_bmc, BT_CTRL_B_BUSY, BT_CTRL);
>>> +}
>>> +
>>> +static void set_b2h_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_B2H_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static u8 bt_read(struct bt_bmc *bt_bmc)
>>> +{
>>> +    return bt_inb(bt_bmc, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_readn(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        buf[i] = bt_read(bt_bmc);
>>> +    return n;
>>> +}
>>> +
>>> +static void bt_write(struct bt_bmc *bt_bmc, u8 c)
>>> +{
>>> +    bt_outb(bt_bmc, c, BT_BMC2HOST);
>>> +}
>>> +
>>> +static ssize_t bt_writen(struct bt_bmc *bt_bmc, u8 *buf, size_t n)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < n; i++)
>>> +        bt_write(bt_bmc, buf[i]);
>>> +    return n;
>>> +}
>>> +
>>> +static void set_sms_atn(struct bt_bmc *bt_bmc)
>>> +{
>>> +    bt_outb(bt_bmc, BT_CTRL_SMS_ATN, BT_CTRL);
>>> +}
>>> +
>>> +static struct bt_bmc *file_bt_bmc(struct file *file)
>>> +{
>>> +    return container_of(file->private_data, struct bt_bmc, miscdev);
>>> +}
>>> +
>>> +static int bt_bmc_open(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +#define BT_BMC_BUFFER_SIZE 256
>>> +
>>> +/*
>>> + * The BT (Block Transfer) interface means that entire messages are
>>> + * buffered by the host before a notification is sent to the BMC that
>>> + * there is data to be read. The first byte is the length and the
>>> + * message data follows. The read operation just tries to capture the
>>> + * whole before returning it to userspace.
>>> + */
>>> +static ssize_t bt_bmc_read(struct file *file, char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 len;
>>> +    int len_byte = 1;
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nread;
>>> +
>>> +    if (!access_ok(VERIFY_WRITE, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                bt_inb(bt_bmc, BT_CTRL) & BT_CTRL_H2B_ATN))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    clr_h2b_atn(bt_bmc);
>>> +    clr_rd_ptr(bt_bmc);
>>> +
>>> +    /*
>>> +     * The BT frames start with the message length, which does not
>>> +     * include the length byte.
>>> +     */
>>> +    kbuffer[0] = bt_read(bt_bmc);
>>> +    len = kbuffer[0];
>>> +
>>> +    /* We pass the length back to userspace as well */
>>> +    if (len + 1 > count)
>>> +        len = count - 1;
>>> +
>>> +    while (len) {
>>> +        nread = min_t(ssize_t, len, sizeof(kbuffer) - len_byte);
>>> +
>>> +        bt_readn(bt_bmc, kbuffer + len_byte, nread);
>>> +
>>> +        if (copy_to_user(buf, kbuffer, nread + len_byte)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +        len -= nread;
>>> +        buf += nread + len_byte;
>>> +        ret += nread + len_byte;
>>> +        len_byte = 0;
>>> +    }
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static ssize_t bt_bmc_write(struct file *file, const char __user *buf,
>>> +                size_t count, loff_t *ppos)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    u8 kbuffer[BT_BMC_BUFFER_SIZE];
>>> +    ssize_t ret = 0;
>>> +    ssize_t nwritten;
>>> +
>>> +    if (!access_ok(VERIFY_READ, buf, count))
>>> +        return -EFAULT;
>>> +
>>> +    WARN_ON(*ppos);
>>> +
>>> +    /* There's no interrupt for clearing bmc busy so we have to
>>> +     * poll
>>> +     */
>>> +    if (wait_event_interruptible(bt_bmc->queue,
>>> +                !(bt_inb(bt_bmc, BT_CTRL) &
>>> +                    (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN))))
>>> +        return -ERESTARTSYS;
>>> +
>>> +    clr_wr_ptr(bt_bmc);
>>> +
>>> +    while (count) {
>>> +        nwritten = min_t(ssize_t, count, sizeof(kbuffer));
>>> +        if (copy_from_user(&kbuffer, buf, nwritten)) {
>>> +            ret = -EFAULT;
>>> +            break;
>>> +        }
>>> +
>>> +        bt_writen(bt_bmc, kbuffer, nwritten);
>>> +
>>> +        count -= nwritten;
>>> +        buf += nwritten;
>>> +        ret += nwritten;
>>> +    }
>>> +
>>> +    set_b2h_atn(bt_bmc);
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static long bt_bmc_ioctl(struct file *file, unsigned int cmd,
>>> +        unsigned long param)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    switch (cmd) {
>>> +    case BT_BMC_IOCTL_SMS_ATN:
>>> +        set_sms_atn(bt_bmc);
>>> +        return 0;
>>> +    }
>>> +    return -EINVAL;
>>> +}
>>> +
>>> +static int bt_bmc_release(struct inode *inode, struct file *file)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +
>>> +    set_b_busy(bt_bmc);
>>> +    return 0;
>>> +}
>>> +
>>> +static unsigned int bt_bmc_poll(struct file *file, poll_table *wait)
>>> +{
>>> +    struct bt_bmc *bt_bmc = file_bt_bmc(file);
>>> +    unsigned int mask = 0;
>>> +    uint8_t ctrl;
>>> +
>>> +    poll_wait(file, &bt_bmc->queue, wait);
>>> +
>>> +    ctrl = bt_inb(bt_bmc, BT_CTRL);
>>> +
>>> +    if (ctrl & BT_CTRL_H2B_ATN)
>>> +        mask |= POLLIN;
>>> +
>>> +    if (!(ctrl & (BT_CTRL_H_BUSY | BT_CTRL_B2H_ATN)))
>>> +        mask |= POLLOUT;
>>> +
>>> +    return mask;
>>> +}
>>> +
>>> +static const struct file_operations bt_bmc_fops = {
>>> +    .owner        = THIS_MODULE,
>>> +    .open        = bt_bmc_open,
>>> +    .read        = bt_bmc_read,
>>> +    .write        = bt_bmc_write,
>>> +    .release    = bt_bmc_release,
>>> +    .poll        = bt_bmc_poll,
>>> +    .unlocked_ioctl    = bt_bmc_ioctl,
>>> +};
>>> +
>>> +static void poll_timer(unsigned long data)
>>> +{
>>> +    struct bt_bmc *bt_bmc = (void *)data;
>>> +
>>> +    bt_bmc->poll_timer.expires += msecs_to_jiffies(500);
>>> +    wake_up(&bt_bmc->queue);
>>> +    add_timer(&bt_bmc->poll_timer);
>>> +}
>>> +
>>> +static irqreturn_t bt_bmc_irq(int irq, void *arg)
>>> +{
>>> +    struct bt_bmc *bt_bmc = arg;
>>> +    uint32_t reg;
>>> +
>>> +    reg = ioread32(bt_bmc->base + BT_CR2);
>>> +    reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY;
>>> +    if (!reg)
>>> +        return IRQ_NONE;
>>> +
>>> +    /* ack pending IRQs */
>>> +    iowrite32(reg, bt_bmc->base + BT_CR2);
>>> +
>>> +    wake_up(&bt_bmc->queue);
>>> +    return IRQ_HANDLED;
>>> +}
>>> +
>>> +static int bt_bmc_config_irq(struct bt_bmc *bt_bmc,
>>> +        struct platform_device *pdev)
>>> +{
>>> +    struct device *dev = &pdev->dev;
>>> +    uint32_t reg;
>>> +    int rc;
>>> +
>>> +    bt_bmc->irq = platform_get_irq(pdev, 0);
>>> +    if (!bt_bmc->irq)
>>> +        return -ENODEV;
>>> +
>>> +    rc = devm_request_irq(dev, bt_bmc->irq, bt_bmc_irq, IRQF_SHARED,
>>> +            DEVICE_NAME, bt_bmc);
>>> +    if (rc < 0) {
>>> +        dev_warn(dev, "Unable to request IRQ %d\n", bt_bmc->irq);
>>> +        bt_bmc->irq = 0;
>>> +        return rc;
>>> +    }
>>> +
>>> +    /* Configure IRQs on the bmc clearing the H2B and HBUSY bits;
>>> +     * H2B will be asserted when the bmc has data for us; HBUSY
>>> +     * will be cleared (along with B2H) when we can write the next
>>> +     * message to the BT buffer
>>> +     */
>>> +    reg = ioread32(bt_bmc->base + BT_CR1);
>>> +    reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY;
>>> +    iowrite32(reg, bt_bmc->base + BT_CR1);
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static int bt_bmc_probe(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc;
>>> +    struct device *dev;
>>> +    struct resource *res;
>>> +    int rc;
>>> +
>>> +    if (!pdev || !pdev->dev.of_node)
>>> +        return -ENODEV;
>>> +
>>> +    dev = &pdev->dev;
>>> +    dev_info(dev, "Found bt bmc device\n");
>>> +
>>> +    bt_bmc = devm_kzalloc(dev, sizeof(*bt_bmc), GFP_KERNEL);
>>> +    if (!bt_bmc)
>>> +        return -ENOMEM;
>>> +
>>> +    dev_set_drvdata(&pdev->dev, bt_bmc);
>>> +
>>> +    res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>>> +    if (!res) {
>>> +        dev_err(dev, "Unable to find resources\n");
>>> +        rc = -ENXIO;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    bt_bmc->base = devm_ioremap_resource(&pdev->dev, res);
>>> +    if (!bt_bmc->base) {
>>> +        rc = -ENOMEM;
>>> +        goto out_free;
>>> +    }
>>> +
>>> +    init_waitqueue_head(&bt_bmc->queue);
>>> +
>>> +    bt_bmc->miscdev.minor    = MISC_DYNAMIC_MINOR,
>>> +    bt_bmc->miscdev.name    = DEVICE_NAME,
>>> +    bt_bmc->miscdev.fops    = &bt_bmc_fops,
>>> +    bt_bmc->miscdev.parent = dev;
>>> +    rc = misc_register(&bt_bmc->miscdev);
>>> +    if (rc) {
>>> +        dev_err(dev, "Unable to register device\n");
>>> +        goto out_unmap;
>>> +    }
>>> +
>>> +    bt_bmc_config_irq(bt_bmc, pdev);
>>> +
>>> +    if (bt_bmc->irq) {
>>> +        dev_info(dev, "Using IRQ %d\n", bt_bmc->irq);
>>> +    } else {
>>> +        dev_info(dev, "No IRQ; using timer\n");
>>> +        setup_timer(&bt_bmc->poll_timer, poll_timer,
>>> +                (unsigned long)bt_bmc);
>>> +        bt_bmc->poll_timer.expires = jiffies + msecs_to_jiffies(10);
>>> +        add_timer(&bt_bmc->poll_timer);
>>> +    }
>>> +
>>> +    iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) |
>>> +          (BT_IRQ << BT_CR0_IRQ) |
>>> +          BT_CR0_EN_CLR_SLV_RDP |
>>> +          BT_CR0_EN_CLR_SLV_WRP |
>>> +          BT_CR0_ENABLE_IBT,
>>> +          bt_bmc->base + BT_CR0);
>>> +
>>> +    clr_b_busy(bt_bmc);
>>> +
>>> +    return 0;
>>> +
>>> +out_unmap:
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +
>>> +out_free:
>>> +    devm_kfree(dev, bt_bmc);
>>> +    return rc;
>>> +
>>> +}
>>> +
>>> +static int bt_bmc_remove(struct platform_device *pdev)
>>> +{
>>> +    struct bt_bmc *bt_bmc = dev_get_drvdata(&pdev->dev);
>>> +
>>> +    misc_deregister(&bt_bmc->miscdev);
>>> +    if (!bt_bmc->irq)
>>> +        del_timer_sync(&bt_bmc->poll_timer);
>>> +    devm_iounmap(&pdev->dev, bt_bmc->base);
>>> +    devm_kfree(&pdev->dev, bt_bmc);
>>> +    bt_bmc = NULL;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +static const struct of_device_id bt_bmc_match[] = {
>>> +    { .compatible = "aspeed,ast2400-bt-bmc" },
>>> +    { },
>>> +};
>>> +
>>> +static struct platform_driver bt_bmc_driver = {
>>> +    .driver = {
>>> +        .name        = DEVICE_NAME,
>>> +        .of_match_table = bt_bmc_match,
>>> +    },
>>> +    .probe = bt_bmc_probe,
>>> +    .remove = bt_bmc_remove,
>>> +};
>>> +
>>> +module_platform_driver(bt_bmc_driver);
>>> +
>>> +MODULE_DEVICE_TABLE(of, bt_bmc_match);
>>> +MODULE_LICENSE("GPL");
>>> +MODULE_AUTHOR("Alistair Popple <alistair@popple.id.au>");
>>> +MODULE_DESCRIPTION("Linux device interface to the BT interface");
>>> diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
>>> index 185f8ea2702f..17b12942c67d 100644
>>> --- a/include/uapi/linux/Kbuild
>>> +++ b/include/uapi/linux/Kbuild
>>> @@ -74,6 +74,7 @@ header-y += bpf_common.h
>>>    header-y += bpf.h
>>>    header-y += bpqether.h
>>>    header-y += bsg.h
>>> +header-y += bt-bmc.h
>>>    header-y += btrfs.h
>>>    header-y += can.h
>>>    header-y += capability.h
>>> diff --git a/include/uapi/linux/bt-bmc.h b/include/uapi/linux/bt-bmc.h
>>> new file mode 100644
>>> index 000000000000..d9ec766a63d0
>>> --- /dev/null
>>> +++ b/include/uapi/linux/bt-bmc.h
>>> @@ -0,0 +1,18 @@
>>> +/*
>>> + * Copyright (c) 2015-2016, IBM Corporation.
>>> + *
>>> + * This program is free software; you can redistribute it and/or
>>> + * modify it under the terms of the GNU General Public License
>>> + * as published by the Free Software Foundation; either version
>>> + * 2 of the License, or (at your option) any later version.
>>> + */
>>> +
>>> +#ifndef _UAPI_LINUX_BT_BMC_H
>>> +#define _UAPI_LINUX_BT_BMC_H
>>> +
>>> +#include <linux/ioctl.h>
>>> +
>>> +#define __BT_BMC_IOCTL_MAGIC    0xb1
>>> +#define BT_BMC_IOCTL_SMS_ATN    _IO(__BT_BMC_IOCTL_MAGIC, 0x00)
>>> +
>>> +#endif /* _UAPI_LINUX_BT_BMC_H */
>>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox