* [linux-sunxi] [PATCH v3 09/12] mfd: axp20x: add axp20x-regulator cell for AXP803
From: Chen-Yu Tsai @ 2017-04-18 10:38 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170417115747.7300-10-icenowy@aosc.io>
On Mon, Apr 17, 2017 at 7:57 PM, Icenowy Zheng <icenowy@aosc.io> wrote:
> As axp20x-regulator now supports AXP803, add a cell for it.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> ---
> Changes in v3:
> - Make the new cell one-liner.
>
> drivers/mfd/axp20x.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mfd/axp20x.c b/drivers/mfd/axp20x.c
> index 1dc6235778eb..431b7f118606 100644
> --- a/drivers/mfd/axp20x.c
> +++ b/drivers/mfd/axp20x.c
> @@ -848,7 +848,8 @@ static struct mfd_cell axp803_cells[] = {
> .name = "axp20x-pek",
> .num_resources = ARRAY_SIZE(axp803_pek_resources),
> .resources = axp803_pek_resources,
> - }
> + },
> + { .name = "axp20x-regulator" }
It's best to have a trailing comma, so we don't have to change the line
again when we add more cells, like you just did with the previous line.
Otherwise,
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* [PATCH v3 00/32] PCI: fix config and I/O Address space memory mappings
From: Benjamin Herrenschmidt @ 2017-04-18 10:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418085732.GA23882@red-moon>
On Tue, 2017-04-18 at 09:57 +0100, Lorenzo Pieralisi wrote:
> I can add a defined(pgprot_nonposted) to pci_remap_iospace() if that's
> not too ugly (I suspect Bjorn is thrilled about it :)), that plus
> the Kconfig option for ioremap_nopost() should complete this series.
>
> int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr)
> {
> #if defined(PCI_IOBASE) && defined(CONFIG_MMU) && defined(pgprot_nonposted)
> ????????unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start;
>
> ????????if (!(res->flags & IORESOURCE_IO))
> ????????????????return -EINVAL;
>
> ????????if (res->end > IO_SPACE_LIMIT)
> ????????????????return -EINVAL
> ????????return ioremap_page_range(vaddr, vaddr + resource_size(res), phys_addr,
> ????????????????????????????????? pgprot_nonposted(PAGE_KERNEL));
> #else
> ????????/* this architecture does not have memory mapped I/O space,
> ?????????? so this function should never be called */
> ????????WARN_ONCE(1, "This architecture does not support memory mapped I/O\n");
> ????????return -ENODEV;
> #endif
The above would effectively disable mmap'ing of IO space for any
architecture that doesn't have pgprot_nonposted... so everybody except
ARM. Thus breaking a number of systems that have been working fine for
years.
I fail to see the point....
I think you are giving the whole non-posted stuff way more importance
than it deserves. It's originally a kludge Intel did to PCI because it
well with their synchronous IO space, which was itself a remnant of
pre-history that should have long died.
In the specific case of PCI (again I'm not talking about the general
case of pgprot/ioremap_nonposted), we have routinely been "violating"
that rule, at least on the CPU -> PCI Bridge path (the PCI bridge
itself tends to respect it though I've seen exceptions) for decades
without any adverse effect.
I don't think there's much code (if any) out there which actually
relies on the non-posted characteristics of IO space.
I don't care *that* much mind you, we dropped IO space on PCI with
POWER8, but it would break stuff on existing older machines such as
PowerMacs for no good reason.
I'd rather we document that mmap'ing IO space via sysfs doesn't fully
respect the "non-posted" semantics of IO and be done with it.
Is there any other practical use of non-posted mappings ? Config space
I suppose, though here mostly PCI host bridges handle it by doing a
read back in the config ops...
Cheers,
Ben.
^ permalink raw reply
* [linux-sunxi] [PATCH v3 07/12] dt-bindings: add AXP803's regulator info
From: Chen-Yu Tsai @ 2017-04-18 10:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170417115747.7300-8-icenowy@aosc.io>
On Mon, Apr 17, 2017 at 7:57 PM, Icenowy Zheng <icenowy@aosc.io> wrote:
> AXP803 have the most regulators in currently supported AXP PMICs.
>
> Add info for the regulators in the dt-bindings document.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
> Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* [linux-sunxi] [PATCH v3 03/12] dt-bindings: make AXP20X compatible strings one per line
From: Chen-Yu Tsai @ 2017-04-18 10:35 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170417115747.7300-4-icenowy@aosc.io>
On Mon, Apr 17, 2017 at 7:57 PM, Icenowy Zheng <icenowy@aosc.io> wrote:
> In the binding documentation of AXP20X mfd, the compatible strings used
> to be listed for three per line, which leads to some mess when trying to
> add AXP803 compatible string (as we have already AXP806 and AXP809
> compatibles, which is after AXP803 in ascending order).
>
> Make the compatible strings one per line, so that inserting a new
> compatible string will be directly a new line.
>
> Signed-off-by: Icenowy Zheng <icenowy@aosc.io>
Acked-by: Chen-Yu Tsai <wens@csie.org>
^ permalink raw reply
* kvm/arm64: use-after-free in kvm_unmap_hva_handler/unmap_stage2_pmds
From: Suzuki K Poulose @ 2017-04-18 10:30 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418090845.GC17866@leverpostej>
On 18/04/17 10:08, Mark Rutland wrote:
> On Tue, Apr 18, 2017 at 09:32:31AM +0100, Mark Rutland wrote:
>> Hi Suzuki,
>>
>> On Thu, Apr 13, 2017 at 04:50:46PM +0100, Suzuki K. Poulose wrote:
>>> kvm: Hold reference to the user address space
>>>
>>> The core KVM code, uses mmgrab/mmdrop to pin the mm struct of the user
>>> application. mmgrab only guarantees that the mm struct is available,
>>> while the "real address space" (see Documentation/vm/active_mm.txt) may
>>> be destroyed. Since the KVM depends on the user space page tables for
>>> the Guest pages, we should instead do an mmget/mmput. Even though
>>> mmget/mmput is not encouraged for uses with unbounded time, the KVM
>>> is fine to do so, as we are doing it from the context of the same process.
>>>
>>> This also prevents the race condition where mmu_notifier_release() could
>>> be called in parallel and one instance could end up using a free'd kvm
>>> instance.
>>>
>>> Cc: Mark Rutland <mark.rutland@arm.com>
>>> Cc: Paolo Bonzin <pbonzini@redhat.com>
>>> Cc: Radim Kr?m?? <rkrcmar@redhat.com>
>>> Cc: Marc Zyngier <marc.zyngier@arm.com>
>>> Cc: Christoffer Dall <christoffer.dall@linaro.org>
>>> Cc: andreyknvl at google.com
>>> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
>>> ---
>>> virt/kvm/kvm_main.c | 6 +++---
>>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
>>> index 88257b3..555712e 100644
>>> --- a/virt/kvm/kvm_main.c
>>> +++ b/virt/kvm/kvm_main.c
>>> @@ -613,7 +613,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
>>> return ERR_PTR(-ENOMEM);
>>>
>>> spin_lock_init(&kvm->mmu_lock);
>>> - mmgrab(current->mm);
>>> + mmget(current->mm);
>>> kvm->mm = current->mm;
>>> kvm_eventfd_init(kvm);
>>> mutex_init(&kvm->lock);
>>> @@ -685,7 +685,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
>>> for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
>>> kvm_free_memslots(kvm, kvm->memslots[i]);
>>> kvm_arch_free_vm(kvm);
>>> - mmdrop(current->mm);
>>> + mmput(current->mm);
>>> return ERR_PTR(r);
>>> }
>>>
>>> @@ -747,7 +747,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
>>> kvm_arch_free_vm(kvm);
>>> preempt_notifier_dec();
>>> hardware_disable_all();
>>> - mmdrop(mm);
>>> + mmput(mm);
>>> }
>>
>>
>> As a heads-up, I'm seeing what looks to be a KVM memory leak with this
>> patch applied atop of next-20170411.
>>
>> I don't yet know if this is a problem with next-20170411 or this patch
>> in particular -- I will try to track that down. In the mean time, info
>> dump below.
This is indeed a side effect of the new patch. The VCPU doesn't get released
completely, due to an mmap count held on the VCPU fd, even when we close the
VCPU fd. This keeps the refcount on the KVM instance which in turn holds the
mmap count (with the new patch). So the mmap count on VCPU will never get
released due to the circular dependency here. :-(
Suzuki
^ permalink raw reply
* [PATCH] i2c: designware: do not show SDA hold time warning when not needed
From: Jarkko Nikula @ 2017-04-18 10:23 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418095939.68788787@free-electrons.com>
On 04/18/2017 10:59 AM, Thomas Petazzoni wrote:
> Hello,
>
> On Tue, 18 Apr 2017 10:54:47 +0300, Andy Shevchenko wrote:
>> On Fri, 2017-04-14 at 22:53 +0200, Thomas Petazzoni wrote:
>>> When the I2C controller IP block has a revision too old to be able to
>>> configure the SDA hold time, the driver currently displays a
>>> warning. However, it does so unconditionally, even if no SDA hold time
>>> has been configured through the Device Tree. This causes useless
>>> warnings when running the system, so only show the warning if a SDA
>>> hold time was specified.
>>
>> As far as I understand the warning it would be better to keep it in
>> either way, though you may shift it to debug level.
>>
>> Wolfram, Jarkko, thoughts?
>
> Why show a message when the user has not requested a custom SDA hold
> time? Getting a warning about something you haven't requested seems
> really odd.
>
> I think it makes a lot more sense to keep it at the warning level
> (because it's important to get this message if you configure a custom
> SDA hold time), but only show it when appropriate.
>
I guess warning over debug level could have slightly better chance to
prevent someone not adding needless "i2c-sda-hold-time-ns" property in a
hardware that doesn't support SDA hold time. But needless spamming have
negative value so this is worth to fix. (I would do this as a single
liner by else if ()).
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
^ permalink raw reply
* et8ek8 camera on Nokia N900: trying to understand what is going on with modes
From: Sakari Ailus @ 2017-04-18 10:19 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170412211159.GA2313@amd>
Hi Pavel,
On Wed, Apr 12, 2017 at 11:11:59PM +0200, Pavel Machek wrote:
> Hi!
>
> 5Mpix mode does not work on N900, which is something I'd like to
> understand. et8ek8_mode contains huge tables of register settings and
> parameter values, but it seems that they are not really independend.
>
> To test that theory, I started with checking values against each
> other.
>
> This is the work so far, it is neither complete nor completely working
> at the moment. Perhaps someone wants to play...
You might seek to try lowering the pixel clock on the sensor to see whether
it makes any difference. I don't think there's been any changes to how the
sensor is programmed since the original software was shipped with the
device. That doesn't apply to the SoC and the clock tree in the SoC however.
I wonder if there could be changes in clock frequencies and how the ISP is
clocked. The omap3isp driver has changed heavily as well.
Just my 5 Euro cents (they have no smaller coins around here).
--
Kind regards,
Sakari Ailus
e-mail: sakari.ailus at iki.fi XMPP: sailus at retiisi.org.uk
^ permalink raw reply
* [PATCH v2 1/3] ARM: dts: rockchip: Add support for phyCORE-RK3288 SoM
From: Jacob Chen @ 2017-04-18 10:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1491483866-18368-1-git-send-email-w.egorov@phytec.de>
Hi wadim,
2017-04-06 21:04 GMT+08:00 Wadim Egorov <w.egorov@phytec.de>:
> The phyCORE-RK3288 is a SoM (System on Module) containing a RK3288 SoC.
> The module can be connected to different carrier boards.
> It can be also equipped with different RAM, SPI flash and eMMC variants.
> The Rapid Development Kit option is using the following setup:
>
> - 1 GB DDR3 RAM (2 Banks)
> - 1x 4 KB EEPROM
> - DP83867 Gigabit Ethernet PHY
> - 16 MB SPI Flash
> - 4 GB eMMC Flash
>
> Signed-off-by: Wadim Egorov <w.egorov@phytec.de>
> ---
> Changes in v2:
> - Added a dual license which is used for all rk3288 based boards.
>
> Include minor changes from Heiko St?bner:
> - moved phy-handle property up a bit
> - switches compatible and #address+#size-cells in mdio0
> - dropped rockchip,grf from &io_domains (grf is a simple-mfd and can
> get the grf syscon on its own via its parent)
> - vdd_cpu: regulator at 60 (from fan53555 at 60)
> - serial_flash: flash at 0 (from m25p80 at 0)
> Nodes should be named after their "category" not the actual device
>
> ---
> arch/arm/boot/dts/rk3288-phycore-som.dtsi | 497 ++++++++++++++++++++++++++++++
> 1 file changed, 497 insertions(+)
> create mode 100644 arch/arm/boot/dts/rk3288-phycore-som.dtsi
>
> diff --git a/arch/arm/boot/dts/rk3288-phycore-som.dtsi b/arch/arm/boot/dts/rk3288-phycore-som.dtsi
> new file mode 100644
> index 0000000..26cd3ad
> --- /dev/null
> +++ b/arch/arm/boot/dts/rk3288-phycore-som.dtsi
> @@ -0,0 +1,497 @@
> +/*
> + * Device tree file for Phytec phyCORE-RK3288 SoM
> + * Copyright (C) 2017 PHYTEC Messtechnik GmbH
> + * Author: Wadim Egorov <w.egorov@phytec.de>
> + *
> + * 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 file 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 file 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 <dt-bindings/net/ti-dp83867.h>
> +#include "rk3288.dtsi"
> +
> +/ {
> + model = "Phytec RK3288 phyCORE";
> + compatible = "phytec,rk3288-phycore-som", "rockchip,rk3288";
> +
> + /*
> + * Set the minimum memory size here and
> + * let the bootloader set the real size.
> + */
> + memory {
> + device_type = "memory";
> + reg = <0 0x8000000>;
> + };
> +
> + aliases {
> + rtc0 = &i2c_rtc;
> + rtc1 = &rk818;
> + };
> +
> + ext_gmac: external-gmac-clock {
> + compatible = "fixed-clock";
> + #clock-cells = <0>;
> + clock-frequency = <125000000>;
> + clock-output-names = "ext_gmac";
> + };
> +
> + leds: user-leds {
> + compatible = "gpio-leds";
> + pinctrl-names = "default";
> + pinctrl-0 = <&user_led>;
> +
> + user {
> + label = "green_led";
> + gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>;
> + linux,default-trigger = "heartbeat";
> + default-state = "keep";
> + };
> + };
> +
> + vdd_emmc_io: vdd-emmc-io {
> + compatible = "regulator-fixed";
> + regulator-name = "vdd_emmc_io";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + vin-supply = <&vdd_3v3_io>;
> + };
> +
> + vdd_in_otg_out: vdd-in-otg-out {
> + compatible = "regulator-fixed";
> + regulator-name = "vdd_in_otg_out";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + };
> +
> + vdd_misc_1v8: vdd-misc-1v8 {
> + compatible = "regulator-fixed";
> + regulator-name = "vdd_misc_1v8";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +};
> +
> +&cpu0 {
> + cpu0-supply = <&vdd_cpu>;
> + operating-points = <
> + /* KHz uV */
> + 1800000 1400000
> + 1608000 1350000
> + 1512000 1300000
> + 1416000 1200000
> + 1200000 1100000
> + 1008000 1050000
> + 816000 1000000
> + 696000 950000
> + 600000 900000
> + 408000 900000
> + 312000 900000
> + 216000 900000
> + 126000 900000
> + >;
> +};
> +
> +&emmc {
> + status = "okay";
> + bus-width = <8>;
> + cap-mmc-highspeed;
> + disable-wp;
> + non-removable;
> + num-slots = <1>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_pwr &emmc_bus8>;
> + vmmc-supply = <&vdd_3v3_io>;
> + vqmmc-supply = <&vdd_emmc_io>;
> +};
> +
> +&gmac {
> + assigned-clocks = <&cru SCLK_MAC>;
> + assigned-clock-parents = <&ext_gmac>;
> + clock_in_out = "input";
> + pinctrl-names = "default";
> + pinctrl-0 = <&rgmii_pins &phy_rst &phy_int>;
> + phy-handle = <&phy0>;
> + phy-supply = <&vdd_eth_2v5>;
> + phy-mode = "rgmii-id";
> + snps,reset-active-low;
> + snps,reset-delays-us = <0 10000 1000000>;
> + snps,reset-gpio = <&gpio4 8 GPIO_ACTIVE_HIGH>;
> + tx_delay = <0x0>;
> + rx_delay = <0x0>;
> +
> + mdio0 {
> + compatible = "snps,dwmac-mdio";
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + phy0: ethernet-phy at 0 {
> + compatible = "ethernet-phy-ieee802.3-c22";
> + reg = <0>;
> + interrupt-parent = <&gpio4>;
> + interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
> + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>;
> + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>;
> + enet-phy-lane-no-swap;
> + };
> + };
> +};
> +
> +&hdmi {
> + ddc-i2c-bus = <&i2c5>;
> +};
> +
> +&io_domains {
> + status = "okay";
> + sdcard-supply = <&vdd_io_sd>;
> + flash0-supply = <&vdd_emmc_io>;
> + flash1-supply = <&vdd_misc_1v8>;
> + gpio1830-supply = <&vdd_3v3_io>;
> + gpio30-supply = <&vdd_3v3_io>;
> + bb-supply = <&vdd_3v3_io>;
> + dvp-supply = <&vdd_3v3_io>;
> + lcdc-supply = <&vdd_3v3_io>;
> + wifi-supply = <&vdd_3v3_io>;
> + audio-supply = <&vdd_3v3_io>;
> +};
> +
> +&i2c0 {
> + status = "okay";
> + clock-frequency = <400000>;
> +
> + rk818: pmic at 1c {
> + compatible = "rockchip,rk818";
> + reg = <0x1c>;
> + interrupt-parent = <&gpio0>;
> + interrupts = <4 IRQ_TYPE_LEVEL_LOW>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&pmic_int>;
> + rockchip,system-power-controller;
> + wakeup-source;
> + #clock-cells = <1>;
> +
I think you miss "clock-output-names = "xin32k" here.
> + vcc1-supply = <&vdd_sys>;
> + vcc2-supply = <&vdd_sys>;
> + vcc3-supply = <&vdd_sys>;
> + vcc4-supply = <&vdd_sys>;
> + boost-supply = <&vdd_in_otg_out>;
> + vcc6-supply = <&vdd_sys>;
> + vcc7-supply = <&vdd_misc_1v8>;
> + vcc8-supply = <&vdd_misc_1v8>;
> + vcc9-supply = <&vdd_3v3_io>;
> + vddio-supply = <&vdd_3v3_io>;
> +
> + regulators {
> + vdd_log: DCDC_REG1 {
> + regulator-name = "vdd_log";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1100000>;
> + regulator-max-microvolt = <1100000>;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + vdd_gpu: DCDC_REG2 {
> + regulator-name = "vdd_gpu";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1250000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <1000000>;
> + };
> + };
> +
> + vcc_ddr: DCDC_REG3 {
> + regulator-name = "vcc_ddr";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + };
> + };
> +
> + vdd_3v3_io: DCDC_REG4 {
> + regulator-name = "vdd_3v3_io";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <3300000>;
> + };
> + };
> +
> + vdd_sys: DCDC_BOOST {
> + regulator-name = "vdd_sys";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <5000000>;
> + regulator-max-microvolt = <5000000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <5000000>;
> + };
> + };
> +
> + /* vcc9 */
> + vdd_sd: SWITCH_REG {
> + regulator-name = "vdd_sd";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + /* vcc6 */
> + vdd_eth_2v5: LDO_REG2 {
> + regulator-name = "vdd_eth_2v5";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <2500000>;
> + regulator-max-microvolt = <2500000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <2500000>;
> + };
> + };
> +
> + /* vcc7 */
> + vdd_1v0: LDO_REG3 {
> + regulator-name = "vdd_1v0";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <1000000>;
> + };
> + };
> +
> + /* vcc8 */
> + vdd_1v8_lcd_ldo: LDO_REG4 {
> + regulator-name = "vdd_1v8_lcd_ldo";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <1800000>;
> + };
> + };
> +
> + /* vcc8 */
> + vdd_1v0_lcd: LDO_REG6 {
> + regulator-name = "vdd_1v0_lcd";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <1000000>;
> + };
> + };
> +
> + /* vcc7 */
> + vdd_1v8_ldo: LDO_REG7 {
> + regulator-name = "vdd_1v8_ldo";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + regulator-suspend-microvolt = <1800000>;
> + };
> + };
> +
> + /* vcc9 */
> + vdd_io_sd: LDO_REG9 {
> + regulator-name = "vdd_io_sd";
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-state-mem {
> + regulator-on-in-suspend;
> + regulator-suspend-microvolt = <3300000>;
> + };
> + };
> + };
> + };
> +
> + /* M24C32-D */
> + i2c_eeprom: eeprom at 50 {
> + compatible = "atmel,24c32";
> + reg = <0x50>;
> + pagesize = <32>;
> + };
> +
> + vdd_cpu: regulator at 60 {
> + compatible = "fcs,fan53555";
> + reg = <0x60>;
> + fcs,suspend-voltage-selector = <1>;
> + regulator-always-on;
> + regulator-boot-on;
> + regulator-enable-ramp-delay = <300>;
> + regulator-name = "vdd_cpu";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1430000>;
> + regulator-ramp-delay = <8000>;
> + vin-supply = <&vdd_sys>;
> + };
> +};
> +
> +&pinctrl {
> + pcfg_output_high: pcfg-output-high {
> + output-high;
> + };
> +
> + emmc {
> + /*
> + * We run eMMC at max speed; bump up drive strength.
> + * We also have external pulls, so disable the internal ones.
> + */
> + emmc_clk: emmc-clk {
> + rockchip,pins = <3 18 RK_FUNC_2 &pcfg_pull_none_12ma>;
> + };
> +
> + emmc_cmd: emmc-cmd {
> + rockchip,pins = <3 16 RK_FUNC_2 &pcfg_pull_none_12ma>;
> + };
> +
> + emmc_bus8: emmc-bus8 {
> + rockchip,pins = <3 0 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 1 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 2 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 3 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 4 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 5 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 6 RK_FUNC_2 &pcfg_pull_none_12ma>,
> + <3 7 RK_FUNC_2 &pcfg_pull_none_12ma>;
> + };
> + };
> +
> + gmac {
> + phy_int: phy-int {
> + rockchip,pins = <4 2 RK_FUNC_GPIO &pcfg_pull_up>;
> + };
> +
> + phy_rst: phy-rst {
> + rockchip,pins = <4 8 RK_FUNC_GPIO &pcfg_output_high>;
> + };
> + };
> +
> + leds {
> + user_led: user-led {
> + rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_output_high>;
> + };
> + };
> +
> + pmic {
> + pmic_int: pmic-int {
> + rockchip,pins = <RK_GPIO0 4 RK_FUNC_GPIO &pcfg_pull_up>;
> + };
> +
> + /* Pin for switching state between sleep and non-sleep state */
> + pmic_sleep: pmic-sleep {
> + rockchip,pins = <RK_GPIO0 0 RK_FUNC_GPIO &pcfg_pull_up>;
> + };
> + };
> +};
> +
> +&pwm1 {
> + status = "okay";
> +};
> +
> +&saradc {
> + status = "okay";
> + vref-supply = <&vdd_1v8_ldo>;
> +};
> +
> +&spi2 {
> + status = "okay";
> +
> + serial_flash: flash at 0 {
> + compatible = "micron,n25q128a13", "jedec,spi-nor";
> + reg = <0x0>;
> + spi-max-frequency = <50000000>;
> + m25p,fast-read;
> + #address-cells = <1>;
> + #size-cells = <1>;
> + status = "okay";
> + };
> +};
> +
> +&tsadc {
> + status = "okay";
> + rockchip,hw-tshut-mode = <0>;
> + rockchip,hw-tshut-polarity = <0>;
> +};
> +
> +&vopb {
> + status = "okay";
> +};
> +
> +&vopb_mmu {
> + status = "okay";
> +};
> +
> +&vopl {
> + status = "okay";
> +};
> +
> +&vopl_mmu {
> + status = "okay";
> +};
> +
> +&wdt {
> + status = "okay";
> +};
> --
> 1.9.1
>
^ permalink raw reply
* [PATCH v2 3/3] mmc: sdio: mediatek: Support SDIO feature
From: Yong Mao @ 2017-04-18 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492510391-704-1-git-send-email-yong.mao@mediatek.com>
From: yong mao <yong.mao@mediatek.com>
1. Add irqlock to protect accessing the shared register
2. Implement enable_sdio_irq interface
3. Add msdc_recheck_sdio_irq mechanism to make sure all interrupts
can be processed immediately
Signed-off-by: Yong Mao <yong.mao@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
drivers/mmc/host/mtk-sd.c | 182 +++++++++++++++++++++++++++++++++++----------
1 file changed, 143 insertions(+), 39 deletions(-)
diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c
index 07f3236..fdae197 100644
--- a/drivers/mmc/host/mtk-sd.c
+++ b/drivers/mmc/host/mtk-sd.c
@@ -118,6 +118,7 @@
#define MSDC_PS_CDSTS (0x1 << 1) /* R */
#define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */
#define MSDC_PS_DAT (0xff << 16) /* R */
+#define MSDC_PS_DATA1 (0x1 << 17) /* R */
#define MSDC_PS_CMD (0x1 << 24) /* R */
#define MSDC_PS_WP (0x1 << 31) /* R */
@@ -312,6 +313,7 @@ struct msdc_host {
int cmd_rsp;
spinlock_t lock;
+ spinlock_t irqlock; /* irq lock */
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
@@ -330,12 +332,14 @@ struct msdc_host {
struct pinctrl_state *pins_uhs;
struct delayed_work req_timeout;
int irq; /* host interrupt */
+ bool irq_thread_alive;
struct clk *src_clk; /* msdc source clock */
struct clk *h_clk; /* msdc h_clk */
u32 mclk; /* mmc subsystem clock frequency */
u32 src_clk_freq; /* source clock frequency */
u32 sclk; /* SD/MS bus clock frequency */
+ bool clock_on;
unsigned char timing;
bool vqmmc_enabled;
u32 hs400_ds_delay;
@@ -343,6 +347,7 @@ struct msdc_host {
u32 hs400_cmd_int_delay; /* cmd internal delay for HS400 */
bool hs400_cmd_resp_sel_rising;
/* cmd response sample selection for HS400 */
+ u32 clk_pad_delay;
bool hs400_mode; /* current eMMC will run@hs400 mode */
struct msdc_save_para save_para; /* used when gate HCLK */
struct msdc_tune_para def_tune_para; /* default tune setting */
@@ -399,6 +404,7 @@ static void msdc_reset_hw(struct msdc_host *host)
static void msdc_cmd_next(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd);
+static void msdc_recheck_sdio_irq(struct msdc_host *host);
static const u32 cmd_ints_mask = MSDC_INTEN_CMDRDY | MSDC_INTEN_RSPCRCERR |
MSDC_INTEN_CMDTMO | MSDC_INTEN_ACMDRDY |
@@ -525,6 +531,7 @@ static void msdc_gate_clock(struct msdc_host *host)
{
clk_disable_unprepare(host->src_clk);
clk_disable_unprepare(host->h_clk);
+ host->clock_on = false;
}
static void msdc_ungate_clock(struct msdc_host *host)
@@ -533,6 +540,7 @@ static void msdc_ungate_clock(struct msdc_host *host)
clk_prepare_enable(host->src_clk);
while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB))
cpu_relax();
+ host->clock_on = true;
}
static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
@@ -541,6 +549,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
u32 flags;
u32 div;
u32 sclk;
+ unsigned long irq_flags;
if (!hz) {
dev_dbg(host->dev, "set mclk to 0\n");
@@ -549,8 +558,11 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
return;
}
+ spin_lock_irqsave(&host->irqlock, irq_flags);
flags = readl(host->base + MSDC_INTEN);
sdr_clr_bits(host->base + MSDC_INTEN, flags);
+ spin_unlock_irqrestore(&host->irqlock, irq_flags);
+
sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_HS400_CK_MODE);
if (timing == MMC_TIMING_UHS_DDR50 ||
timing == MMC_TIMING_MMC_DDR52 ||
@@ -600,7 +612,10 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz)
host->timing = timing;
/* need because clk changed. */
msdc_set_timeout(host, host->timeout_ns, host->timeout_clks);
+
+ spin_lock_irqsave(&host->irqlock, irq_flags);
sdr_set_bits(host->base + MSDC_INTEN, flags);
+ spin_unlock_irqrestore(&host->irqlock, irq_flags);
/*
* mmc_select_hs400() will drop to 50Mhz and High speed mode,
@@ -708,6 +723,7 @@ static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host,
static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
struct mmc_command *cmd, struct mmc_data *data)
{
+ unsigned long flags;
bool read;
WARN_ON(host->data);
@@ -716,8 +732,12 @@ static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq,
mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
msdc_dma_setup(host, &host->dma, data);
+
+ spin_lock_irqsave(&host->irqlock, flags);
sdr_set_bits(host->base + MSDC_INTEN, data_ints_mask);
sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1);
+ spin_unlock_irqrestore(&host->irqlock, flags);
+
dev_dbg(host->dev, "DMA start\n");
dev_dbg(host->dev, "%s: cmd=%d DMA data: %d blocks; read=%d\n",
__func__, cmd->opcode, data->blocks, read);
@@ -774,6 +794,8 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq)
if (mrq->data)
msdc_unprepare_data(host, mrq);
mmc_request_done(host->mmc, mrq);
+
+ msdc_recheck_sdio_irq(host);
}
/* returns true if command is fully handled; returns false otherwise */
@@ -797,15 +819,17 @@ static bool msdc_cmd_done(struct msdc_host *host, int events,
| MSDC_INT_CMDTMO)))
return done;
- spin_lock_irqsave(&host->lock, flags);
done = !host->cmd;
+ spin_lock_irqsave(&host->lock, flags);
host->cmd = NULL;
spin_unlock_irqrestore(&host->lock, flags);
if (done)
return true;
+ spin_lock_irqsave(&host->irqlock, flags);
sdr_clr_bits(host->base + MSDC_INTEN, cmd_ints_mask);
+ spin_unlock_irqrestore(&host->irqlock, flags);
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136) {
@@ -883,6 +907,7 @@ static inline bool msdc_cmd_is_ready(struct msdc_host *host,
static void msdc_start_command(struct msdc_host *host,
struct mmc_request *mrq, struct mmc_command *cmd)
{
+ unsigned long flags;
u32 rawcmd;
WARN_ON(host->cmd);
@@ -901,7 +926,10 @@ static void msdc_start_command(struct msdc_host *host,
rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd);
mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT);
+ spin_lock_irqsave(&host->irqlock, flags);
sdr_set_bits(host->base + MSDC_INTEN, cmd_ints_mask);
+ spin_unlock_irqrestore(&host->irqlock, flags);
+
writel(cmd->arg, host->base + SDC_ARG);
writel(rawcmd, host->base + SDC_CMD);
}
@@ -993,8 +1021,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
| MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR
| MSDC_INT_DMA_PROTECT);
- spin_lock_irqsave(&host->lock, flags);
done = !host->data;
+ spin_lock_irqsave(&host->lock, flags);
if (check_data)
host->data = NULL;
spin_unlock_irqrestore(&host->lock, flags);
@@ -1009,7 +1037,11 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events,
1);
while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS)
cpu_relax();
+
+ spin_lock_irqsave(&host->irqlock, flags);
sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask);
+ spin_unlock_irqrestore(&host->irqlock, flags);
+
dev_dbg(host->dev, "DMA stop\n");
if ((events & MSDC_INT_XFER_COMPL) && (!stop || !stop->error)) {
@@ -1123,44 +1155,47 @@ static void msdc_request_timeout(struct work_struct *work)
static irqreturn_t msdc_irq(int irq, void *dev_id)
{
+ unsigned long flags;
struct msdc_host *host = (struct msdc_host *) dev_id;
+ struct mmc_request *mrq;
+ struct mmc_command *cmd;
+ struct mmc_data *data;
+ u32 events, event_mask;
+
+ spin_lock_irqsave(&host->irqlock, flags);
+ events = readl(host->base + MSDC_INT);
+ event_mask = readl(host->base + MSDC_INTEN);
+ /* clear interrupts */
+ writel(events & event_mask, host->base + MSDC_INT);
+
+ mrq = host->mrq;
+ cmd = host->cmd;
+ data = host->data;
+ spin_unlock_irqrestore(&host->irqlock, flags);
+
+ if ((events & event_mask) & MSDC_INT_SDIOIRQ) {
+ mmc_signal_sdio_irq(host->mmc);
+ if (!mrq)
+ return IRQ_HANDLED;
+ }
- while (true) {
- unsigned long flags;
- struct mmc_request *mrq;
- struct mmc_command *cmd;
- struct mmc_data *data;
- u32 events, event_mask;
-
- spin_lock_irqsave(&host->lock, flags);
- events = readl(host->base + MSDC_INT);
- event_mask = readl(host->base + MSDC_INTEN);
- /* clear interrupts */
- writel(events & event_mask, host->base + MSDC_INT);
-
- mrq = host->mrq;
- cmd = host->cmd;
- data = host->data;
- spin_unlock_irqrestore(&host->lock, flags);
-
- if (!(events & event_mask))
- break;
+ if (!(events & (event_mask & ~MSDC_INT_SDIOIRQ)))
+ return IRQ_HANDLED;
- if (!mrq) {
- dev_err(host->dev,
- "%s: MRQ=NULL; events=%08X; event_mask=%08X\n",
- __func__, events, event_mask);
- WARN_ON(1);
- break;
- }
+ if (!mrq) {
+ dev_err(host->dev,
+ "%s: MRQ=NULL; events=%08X; event_mask=%08X\n",
+ __func__, events, event_mask);
+ WARN_ON(1);
+ return IRQ_HANDLED;
+ }
- dev_dbg(host->dev, "%s: events=%08X\n", __func__, events);
+ dev_dbg(host->dev, "%s: events=%08X\n", __func__, events);
- if (cmd)
- msdc_cmd_done(host, events, mrq, cmd);
- else if (data)
- msdc_data_xfer_done(host, events, mrq, data);
- }
+ if (cmd)
+ msdc_cmd_done(host, events, mrq, cmd);
+ else if (data)
+ msdc_data_xfer_done(host, events, mrq, data);
return IRQ_HANDLED;
}
@@ -1168,6 +1203,7 @@ static irqreturn_t msdc_irq(int irq, void *dev_id)
static void msdc_init_hw(struct msdc_host *host)
{
u32 val;
+ unsigned long flags;
/* Configure to MMC/SD mode, clock free running */
sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN);
@@ -1179,11 +1215,14 @@ static void msdc_init_hw(struct msdc_host *host)
sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN);
/* Disable and clear all interrupts */
+ spin_lock_irqsave(&host->irqlock, flags);
writel(0, host->base + MSDC_INTEN);
val = readl(host->base + MSDC_INT);
writel(val, host->base + MSDC_INT);
+ spin_unlock_irqrestore(&host->irqlock, flags);
- writel(0, host->base + MSDC_PAD_TUNE);
+ sdr_set_field(host->base + MSDC_PAD_TUNE,
+ MSDC_PAD_TUNE_CLKTDLY, host->clk_pad_delay);
writel(0, host->base + MSDC_IOCON);
sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 0);
writel(0x403c0046, host->base + MSDC_PATCH_BIT);
@@ -1196,9 +1235,11 @@ static void msdc_init_hw(struct msdc_host *host)
*/
sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO);
- /* disable detect SDIO device interrupt function */
- sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
-
+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+ sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+ else
+ /* disable detect SDIO device interrupt function */
+ sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
/* Configure to default data timeout */
sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3);
@@ -1210,11 +1251,15 @@ static void msdc_init_hw(struct msdc_host *host)
static void msdc_deinit_hw(struct msdc_host *host)
{
u32 val;
+ unsigned long flags;
+
/* Disable and clear all interrupts */
+ spin_lock_irqsave(&host->irqlock, flags);
writel(0, host->base + MSDC_INTEN);
val = readl(host->base + MSDC_INT);
writel(val, host->base + MSDC_INT);
+ spin_unlock_irqrestore(&host->irqlock, flags);
}
/* init gpd and bd list in msdc_drv_probe */
@@ -1582,6 +1627,48 @@ static void msdc_hw_reset(struct mmc_host *mmc)
sdr_clr_bits(host->base + EMMC_IOCON, 1);
}
+/**
+ * msdc_recheck_sdio_irq - recheck whether the SDIO IRQ is lost
+ * @host: The host to check.
+ *
+ * Host controller may lost interrupt in some special case.
+ * Add sdio IRQ recheck mechanism to make sure all interrupts
+ * can be processed immediately
+ */
+static void msdc_recheck_sdio_irq(struct msdc_host *host)
+{
+ u32 reg_int, reg_ps;
+
+ if (host->clock_on && (host->mmc->caps & MMC_CAP_SDIO_IRQ) &&
+ host->irq_thread_alive) {
+ reg_int = readl(host->base + MSDC_INT);
+ reg_ps = readl(host->base + MSDC_PS);
+ if (!((reg_int & MSDC_INT_SDIOIRQ) ||
+ (reg_ps & MSDC_PS_DATA1)))
+ mmc_signal_sdio_irq(host->mmc);
+ }
+}
+
+static void msdc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ unsigned long flags;
+ struct msdc_host *host = mmc_priv(mmc);
+
+ host->irq_thread_alive = true;
+ if (enable) {
+ msdc_recheck_sdio_irq(host);
+
+ spin_lock_irqsave(&host->irqlock, flags);
+ sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE);
+ sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+ spin_unlock_irqrestore(&host->irqlock, flags);
+ } else {
+ spin_lock_irqsave(&host->irqlock, flags);
+ sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_SDIOIRQ);
+ spin_unlock_irqrestore(&host->irqlock, flags);
+ }
+}
+
static struct mmc_host_ops mt_msdc_ops = {
.post_req = msdc_post_req,
.pre_req = msdc_pre_req,
@@ -1593,6 +1680,7 @@ static void msdc_hw_reset(struct mmc_host *mmc)
.execute_tuning = msdc_execute_tuning,
.prepare_hs400_tuning = msdc_prepare_hs400_tuning,
.hw_reset = msdc_hw_reset,
+ .enable_sdio_irq = msdc_enable_sdio_irq,
};
static void msdc_of_property_parse(struct platform_device *pdev,
@@ -1612,6 +1700,9 @@ static void msdc_of_property_parse(struct platform_device *pdev,
host->hs400_cmd_resp_sel_rising = true;
else
host->hs400_cmd_resp_sel_rising = false;
+
+ of_property_read_u32(pdev->dev.of_node, "mediatek,clk-pad-delay",
+ &host->clk_pad_delay);
}
static int msdc_drv_probe(struct platform_device *pdev)
@@ -1705,6 +1796,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
mmc_dev(mmc)->dma_mask = &host->dma_mask;
host->timeout_clks = 3 * 1048576;
+ host->irq_thread_alive = false;
host->dma.gpd = dma_alloc_coherent(&pdev->dev,
2 * sizeof(struct mt_gpdma_desc),
&host->dma.gpd_addr, GFP_KERNEL);
@@ -1718,6 +1810,7 @@ static int msdc_drv_probe(struct platform_device *pdev)
msdc_init_gpd_bd(host, &host->dma);
INIT_DELAYED_WORK(&host->req_timeout, msdc_request_timeout);
spin_lock_init(&host->lock);
+ spin_lock_init(&host->irqlock);
platform_set_drvdata(pdev, mmc);
msdc_ungate_clock(host);
@@ -1732,6 +1825,10 @@ static int msdc_drv_probe(struct platform_device *pdev)
pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY);
pm_runtime_use_autosuspend(host->dev);
pm_runtime_enable(host->dev);
+
+ /* In SDIO irq mode, DATA1 slways need to be detected */
+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+ pm_runtime_get_sync(host->dev);
ret = mmc_add_host(mmc);
if (ret)
@@ -1821,6 +1918,10 @@ static int msdc_runtime_suspend(struct device *dev)
msdc_save_reg(host);
msdc_gate_clock(host);
+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ) {
+ pm_runtime_mark_last_busy(dev);
+ pm_runtime_put_autosuspend(dev);
+ }
return 0;
}
@@ -1829,6 +1930,9 @@ static int msdc_runtime_resume(struct device *dev)
struct mmc_host *mmc = dev_get_drvdata(dev);
struct msdc_host *host = mmc_priv(mmc);
+ /* In SDIO irq mode, DATA1 slways need to be detected */
+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ)
+ pm_runtime_get_sync(host->dev);
msdc_ungate_clock(host);
msdc_restore_reg(host);
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 2/3] ARM64: dts: mediatek: Enable mmc3 for supporting sdio feature
From: Yong Mao @ 2017-04-18 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492510391-704-1-git-send-email-yong.mao@mediatek.com>
From: yong mao <yong.mao@mediatek.com>
Add description of mmc3 for supporting sdio feature
Signed-off-by: Yong Mao <yong.mao@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 77 +++++++++++++++++++++++++++
1 file changed, 77 insertions(+)
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
index 1c3634f..fb8fa5c 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
+++ b/arch/arm64/boot/dts/mediatek/mt8173-evb.dts
@@ -68,6 +68,14 @@
gpio = <&pio 9 GPIO_ACTIVE_HIGH>;
enable-active-high;
};
+
+ sdio_fixed_3v3: regulator at 2 {
+ compatible = "regulator-fixed";
+ regulator-name = "3V3";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ gpio = <&pio 85 GPIO_ACTIVE_HIGH>;
+ };
};
&cec {
@@ -156,6 +164,25 @@
vqmmc-supply = <&mt6397_vmc_reg>;
};
+&mmc3 {
+ status = "okay";
+ pinctrl-names = "default", "state_uhs";
+ pinctrl-0 = <&mmc3_pins_default>;
+ pinctrl-1 = <&mmc3_pins_uhs>;
+ bus-width = <4>;
+ max-frequency = <200000000>;
+ cap-sd-highspeed;
+ sd-uhs-sdr50;
+ sd-uhs-sdr104;
+ mediatek,clk-pad-delay = <5>;
+ keep-power-in-suspend;
+ enable-sdio-wakeup;
+ cap-sdio-irq;
+ vmmc-supply = <&sdio_fixed_3v3>;
+ vqmmc-supply = <&mt6397_vgp3_reg>;
+ non-removable;
+};
+
&pio {
disp_pwm0_pins: disp_pwm0_pins {
pins1 {
@@ -261,6 +288,56 @@
};
};
+ mmc3_pins_default: mmc3default {
+ pins_dat {
+ pinmux = <MT8173_PIN_22_MSDC3_DAT0__FUNC_MSDC3_DAT0>,
+ <MT8173_PIN_23_MSDC3_DAT1__FUNC_MSDC3_DAT1>,
+ <MT8173_PIN_24_MSDC3_DAT2__FUNC_MSDC3_DAT2>,
+ <MT8173_PIN_25_MSDC3_DAT3__FUNC_MSDC3_DAT3>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins_cmd {
+ pinmux = <MT8173_PIN_27_MSDC3_CMD__FUNC_MSDC3_CMD>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins_clk {
+ pinmux = <MT8173_PIN_26_MSDC3_CLK__FUNC_MSDC3_CLK>;
+ bias-pull-down;
+ drive-strength = <MTK_DRIVE_8mA>;
+ };
+ };
+
+ mmc3_pins_uhs: mmc3 {
+ pins_dat {
+ pinmux = <MT8173_PIN_22_MSDC3_DAT0__FUNC_MSDC3_DAT0>,
+ <MT8173_PIN_23_MSDC3_DAT1__FUNC_MSDC3_DAT1>,
+ <MT8173_PIN_24_MSDC3_DAT2__FUNC_MSDC3_DAT2>,
+ <MT8173_PIN_25_MSDC3_DAT3__FUNC_MSDC3_DAT3>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins_cmd {
+ pinmux = <MT8173_PIN_27_MSDC3_CMD__FUNC_MSDC3_CMD>;
+ input-enable;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-up = <MTK_PUPD_SET_R1R0_10>;
+ };
+
+ pins_clk {
+ pinmux = <MT8173_PIN_26_MSDC3_CLK__FUNC_MSDC3_CLK>;
+ drive-strength = <MTK_DRIVE_8mA>;
+ bias-pull-down = <MTK_PUPD_SET_R1R0_10>;
+ };
+ };
+
usb_id_pins_float: usb_iddig_pull_up {
pins_iddig {
pinmux = <MT8173_PIN_16_IDDIG__FUNC_IDDIG>;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2 1/3] mmc: dt-bindings: update Mediatek MMC bindings
From: Yong Mao @ 2017-04-18 10:13 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492510391-704-1-git-send-email-yong.mao@mediatek.com>
From: yong mao <yong.mao@mediatek.com>
Add description for mediatek,clk-pad-delay
Signed-off-by: Yong Mao <yong.mao@mediatek.com>
Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com>
---
Documentation/devicetree/bindings/mmc/mtk-sd.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
index 4182ea3..fbb3fd6 100644
--- a/Documentation/devicetree/bindings/mmc/mtk-sd.txt
+++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt
@@ -30,6 +30,7 @@ Optional properties:
- mediatek,hs400-cmd-resp-sel-rising: HS400 command response sample selection
If present,HS400 command responses are sampled on rising edges.
If not present,HS400 command responses are sampled on falling edges.
+- mediatek,clk-pad-delay: clock pad delay setting
Examples:
mmc0: mmc at 11230000 {
@@ -50,4 +51,5 @@ mmc0: mmc at 11230000 {
mediatek,hs200-cmd-int-delay = <26>;
mediatek,hs400-cmd-int-delay = <14>;
mediatek,hs400-cmd-resp-sel-rising;
+ mediatek,clk-pad-delay = <5>;
};
--
1.7.9.5
^ permalink raw reply related
* [RESEND v2] mmc: mediatek: Support SDIO feature
From: Yong Mao @ 2017-04-18 10:13 UTC (permalink / raw)
To: linux-arm-kernel
Documentation/devicetree/bindings/mmc/mtk-sd.txt | 2 +
arch/arm64/boot/dts/mediatek/mt8173-evb.dts | 77 ++++++++++
drivers/mmc/host/mtk-sd.c | 182 ++++++++++++++++++-----
3 files changed, 222 insertions(+), 39 deletions(-)
--
1.8.1.1.dirty
^ permalink raw reply
* [PATCH 09/11] drm/sun4i: Support two display pipelines
From: Chen-Yu Tsai @ 2017-04-18 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418095741.dfay2drvyiwpmlyl@lukather>
On Tue, Apr 18, 2017 at 5:57 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> Hi Chen-Yu,
>
> On Sat, Apr 08, 2017 at 01:30:55AM +0800, Chen-Yu Tsai wrote:
>> Hi,
>>
>> On Thu, Mar 9, 2017 at 10:40 PM, Maxime Ripard
>> <maxime.ripard@free-electrons.com> wrote:
>> > On Thu, Mar 09, 2017 at 07:20:30PM +0800, Chen-Yu Tsai wrote:
>> >> On Thu, Mar 9, 2017 at 6:36 PM, Maxime Ripard
>> >> <maxime.ripard@free-electrons.com> wrote:
>> >> > Hi,
>> >> >
>> >> > On Thu, Mar 09, 2017 at 06:05:32PM +0800, Chen-Yu Tsai wrote:
>> >> >> Some Allwinner SoCs have two display pipelines (frontend -> backend ->
>> >> >> tcon).
>> >> >>
>> >> >> Previously we only supported one pipeline. This patch extends the
>> >> >> current driver to support two. It extends the tcon and backend pointers
>> >> >> in sun4i_drv into arrays, and makes the related bind functions store
>> >> >> the pointer into said arrays based on the id fetched from the device
>> >> >> tree. In the case of the tcons, it falls back to a first come order
>> >> >> if no encoders that can be used for differentiating the tcons are
>> >> >> defined. The driver's depth-first traversal of the of graph, coupled
>> >> >> with the increasing address ordering of the of graph endpoints, and
>> >> >> the fact that tcon0 should always be enabled for the tcon/encoder
>> >> >> mux to be accessible, means that tcon1 would always come after tcon0.
>> >> >>
>> >> >> Assignment of the device structure into sun4i_drv is moved to the end
>> >> >> of the bind function, when all possible error checks have passed.
>> >> >>
>> >> >> This patch also drops a trailing 0 in one of the backend probe messages.
>> >> >>
>> >> >> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> >> >> ---
>> >> >> drivers/gpu/drm/sun4i/sun4i_backend.c | 9 +++++++--
>> >> >> drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +-
>> >> >> drivers/gpu/drm/sun4i/sun4i_drv.h | 6 ++++--
>> >> >> drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 +++++++++++++++++--------
>> >> >> 4 files changed, 29 insertions(+), 13 deletions(-)
>> >> >>
>> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
>> >> >> index f3c92d54c8e4..8d22efd5a9cc 100644
>> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
>> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
>> >> >> @@ -350,12 +350,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
>> >> >> if (!backend)
>> >> >> return -ENOMEM;
>> >> >> dev_set_drvdata(dev, backend);
>> >> >> - drv->backend = backend;
>> >> >>
>> >> >> backend->id = sun4i_backend_of_get_id(dev->of_node);
>> >> >> if (backend->id < 0)
>> >> >> return backend->id;
>> >> >>
>> >> >> + /* We only support SUN4I_DRM_MAX_PIPELINES number of backends */
>> >> >> + if (backend->id >= SUN4I_DRM_MAX_PIPELINES)
>> >> >> + return -EINVAL;
>> >> >> +
>> >> >> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
>> >> >> regs = devm_ioremap_resource(dev, res);
>> >> >> if (IS_ERR(regs))
>> >> >> @@ -364,7 +367,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
>> >> >> backend->regs = devm_regmap_init_mmio(dev, regs,
>> >> >> &sun4i_backend_regmap_config);
>> >> >> if (IS_ERR(backend->regs)) {
>> >> >> - dev_err(dev, "Couldn't create the backend0 regmap\n");
>> >> >> + dev_err(dev, "Couldn't create the backend regmap\n");
>> >> >> return PTR_ERR(backend->regs);
>> >> >> }
>> >> >>
>> >> >> @@ -413,6 +416,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
>> >> >> }
>> >> >> }
>> >> >>
>> >> >> + drv->backend[backend->id] = backend;
>> >> >> +
>> >> >> /* Reset the registers */
>> >> >> for (i = 0x800; i < 0x1000; i += 4)
>> >> >> regmap_write(backend->regs, i, 0);
>> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
>> >> >> index 767bbadcc85d..c15ecb8343d7 100644
>> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
>> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
>> >> >> @@ -271,7 +271,7 @@ static int sun4i_drv_probe(struct platform_device *pdev)
>> >> >> struct device_node *np = pdev->dev.of_node;
>> >> >> int i, count = 0;
>> >> >>
>> >> >> - for (i = 0;; i++) {
>> >> >> + for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++) {
>> >> >> struct device_node *pipeline = of_parse_phandle(np,
>> >> >> "allwinner,pipelines",
>> >> >> i);
>> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.h b/drivers/gpu/drm/sun4i/sun4i_drv.h
>> >> >> index 5df50126ff52..ec1c08af47e1 100644
>> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_drv.h
>> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.h
>> >> >> @@ -16,9 +16,11 @@
>> >> >> #include <linux/clk.h>
>> >> >> #include <linux/regmap.h>
>> >> >>
>> >> >> +#define SUN4I_DRM_MAX_PIPELINES 2
>> >> >> +
>> >> >> struct sun4i_drv {
>> >> >> - struct sun4i_backend *backend;
>> >> >> - struct sun4i_tcon *tcon;
>> >> >> + struct sun4i_backend *backend[SUN4I_DRM_MAX_PIPELINES];
>> >> >> + struct sun4i_tcon *tcon[SUN4I_DRM_MAX_PIPELINES];
>> >> >>
>> >> >> struct drm_fbdev_cma *fbdev;
>> >> >> };
>> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> index b774c9a50c55..7749c3133f38 100644
>> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
>> >> >> @@ -532,7 +532,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>> >> >> if (!tcon)
>> >> >> return -ENOMEM;
>> >> >> dev_set_drvdata(dev, tcon);
>> >> >> - drv->tcon = tcon;
>> >> >> tcon->drm = drm;
>> >> >> tcon->dev = dev;
>> >> >> tcon->quirks = of_device_get_match_data(dev);
>> >> >> @@ -540,14 +539,22 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>> >> >> /* This can fail if the DT does not have any downstream encoders. */
>> >> >> tcon->id = sun4i_tcon_of_get_id(dev->of_node);
>> >> >> if (tcon->id < 0) {
>> >> >> - /*
>> >> >> - * TODO We currently support only 1 TCON, so we can
>> >> >> - * safely set this to 0. This should be revisited
>> >> >> - * when we add support for multiple pipelines.
>> >> >> - */
>> >> >> - tcon->id = 0;
>> >> >> + int i;
>> >> >> +
>> >> >> + /* find the first empty tcon in sun4i_drv */
>> >> >> + for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++)
>> >> >> + if (!drv->tcon[i])
>> >> >> + tcon->id = i;
>> >> >> +
>> >> >> + /* bail out if that failed */
>> >> >> + if (tcon->id < 0)
>> >> >> + return tcon->id;
>> >> >> }
>> >> >>
>> >> >> + /* We only support SUN4I_DRM_MAX_PIPELINES number of tcons */
>> >> >> + if (tcon->id >= SUN4I_DRM_MAX_PIPELINES)
>> >> >> + return -EINVAL;
>> >> >> +
>> >> >> tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
>> >> >> if (IS_ERR(tcon->lcd_rst)) {
>> >> >> dev_err(dev, "Couldn't get our reset line\n");
>> >> >> @@ -588,7 +595,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
>> >> >> goto err_free_dotclock;
>> >> >> }
>> >> >>
>> >> >> - tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon);
>> >> >> + tcon->crtc = sun4i_crtc_init(drm, drv->backend[tcon->id], tcon);
>> >> >
>> >> > I'm not a big fan of those IDs. The heuristic seems to be a bit
>> >> > fragile since we really never enforced any order in our bindings.
>> >>
>> >> Yes. I seem to have forgotten that bit which I had intended to add.
>> >> The endpoint IDs would ideally match the actual mux values used.
>> >
>> > That works for me, but the binding documentation would need to be
>> > amended.
>> >
>> >> On the TCON side that's not doable, so we might have to just require
>> >> them being in an increasing order.
>> >
>> > What are you planning to use those IDs on for the TCON?
>>
>> This reply sat in my draft box for way too long.
>>
>> As mentioned, the IDs on the TCON side are for the IDing the TV encoders.
>> I think having the IDs for the same type of encoder be increasing, such
>> that the endpoint for TV encoder 1 has a higher ID than the one for TV
>> encoder 0 should be enough. There aren't any other instances where we
>> have 2 or more of the same type. Or we could just add some kind of index
>> property to the TV encoder node. This is for the A20 by the way.
>
> Sorry if I'm missing a bit of context here, but I still don't get
> *why* you would need to ID them. So far, your explanation seems to
> have been "so that we can ID them", which is pretty circular to me :)
The mux controls for the TCON output path to the TV/HDMI/MIPI encoders,
and the TV encoder outputs, reside in the address space of the first TCON
and TV encoder, respectively. That's why we need to ID them, to access
the mux controls in the right block to setup the display pipeline.
>> >> > You seem to use it for two things:
>> >> > - to match a TCON to its backend in our code
>> >> > - to not step on each others' toes when registering the backends/tcons
>> >> >
>> >> > I think the second could be easily addressed using a linked list, and
>> >> > the first one by storing the of_node. Then we just need to follow the
>> >> > OF graph to our input of_node, and then iterate through our registered
>> >> > backend list to find the one with the same of_node.
>> >>
>> >> Yes that would work for the above purposes.
>> >>
>> >> For getting the first TCON to access the mux registers, it kind of falls
>> >> short. We also need something like this for the TV encoders on A10/A20.
>> >> They too have a mux, which seems to be in the first TV encoder. This
>> >> controls how the 8 DACs are mapped to the 4 external pins.
>> >
>> > How are those pins muxed between the two? Can't we just create a
>> > connector that would be usable for both encoders?
>>
>> They are freely muxable. However if you want VGA output, you need 3 pins
>> for RGB from the same TV encoder, plus H/V sync from it's upstream TCON.
>
> (you don't really need hsync and vsync on VGA, those are optional signals)
Really? I think you are confusing VGA with the broader "component RGB video".
AFAIK most monitors need separate sync signals.
See https://en.wikipedia.org/wiki/Component_video#RGB_analog_component_video
>> And you have one pin left that you can use for composite, which would
>> likely be fed from the other TCON, as you need interlaced YUV data,
>> which is like the opposite of VGA.
>
> I'm not sure how these muxers should be implemented in DRM. One
> trivial way would be to have a small pinctrl driver in the TCON driver
> to deal with that, and switch states in both TV encoders at runtime
> (if needed, statically otherwise).
>
> Or maybe we can do something simpler, I don't know.
Pinctrl or pinctrl like seems to be a good solution. The lines are routed
on the board so it doesn't make sense to have something runtime configurable.
We just need to know which pins are in the same group, and what kind of
signals they each expect.
ChenYu
^ permalink raw reply
* [PATCH 09/11] drm/sun4i: Support two display pipelines
From: Maxime Ripard @ 2017-04-18 9:57 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <CAGb2v64fmMj-YX+A-Gm_T7U=dr9J6ekwX4thqD7zegoqGMdSFQ@mail.gmail.com>
Hi Chen-Yu,
On Sat, Apr 08, 2017 at 01:30:55AM +0800, Chen-Yu Tsai wrote:
> Hi,
>
> On Thu, Mar 9, 2017 at 10:40 PM, Maxime Ripard
> <maxime.ripard@free-electrons.com> wrote:
> > On Thu, Mar 09, 2017 at 07:20:30PM +0800, Chen-Yu Tsai wrote:
> >> On Thu, Mar 9, 2017 at 6:36 PM, Maxime Ripard
> >> <maxime.ripard@free-electrons.com> wrote:
> >> > Hi,
> >> >
> >> > On Thu, Mar 09, 2017 at 06:05:32PM +0800, Chen-Yu Tsai wrote:
> >> >> Some Allwinner SoCs have two display pipelines (frontend -> backend ->
> >> >> tcon).
> >> >>
> >> >> Previously we only supported one pipeline. This patch extends the
> >> >> current driver to support two. It extends the tcon and backend pointers
> >> >> in sun4i_drv into arrays, and makes the related bind functions store
> >> >> the pointer into said arrays based on the id fetched from the device
> >> >> tree. In the case of the tcons, it falls back to a first come order
> >> >> if no encoders that can be used for differentiating the tcons are
> >> >> defined. The driver's depth-first traversal of the of graph, coupled
> >> >> with the increasing address ordering of the of graph endpoints, and
> >> >> the fact that tcon0 should always be enabled for the tcon/encoder
> >> >> mux to be accessible, means that tcon1 would always come after tcon0.
> >> >>
> >> >> Assignment of the device structure into sun4i_drv is moved to the end
> >> >> of the bind function, when all possible error checks have passed.
> >> >>
> >> >> This patch also drops a trailing 0 in one of the backend probe messages.
> >> >>
> >> >> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> >> >> ---
> >> >> drivers/gpu/drm/sun4i/sun4i_backend.c | 9 +++++++--
> >> >> drivers/gpu/drm/sun4i/sun4i_drv.c | 2 +-
> >> >> drivers/gpu/drm/sun4i/sun4i_drv.h | 6 ++++--
> >> >> drivers/gpu/drm/sun4i/sun4i_tcon.c | 25 +++++++++++++++++--------
> >> >> 4 files changed, 29 insertions(+), 13 deletions(-)
> >> >>
> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_backend.c b/drivers/gpu/drm/sun4i/sun4i_backend.c
> >> >> index f3c92d54c8e4..8d22efd5a9cc 100644
> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_backend.c
> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_backend.c
> >> >> @@ -350,12 +350,15 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
> >> >> if (!backend)
> >> >> return -ENOMEM;
> >> >> dev_set_drvdata(dev, backend);
> >> >> - drv->backend = backend;
> >> >>
> >> >> backend->id = sun4i_backend_of_get_id(dev->of_node);
> >> >> if (backend->id < 0)
> >> >> return backend->id;
> >> >>
> >> >> + /* We only support SUN4I_DRM_MAX_PIPELINES number of backends */
> >> >> + if (backend->id >= SUN4I_DRM_MAX_PIPELINES)
> >> >> + return -EINVAL;
> >> >> +
> >> >> res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> >> >> regs = devm_ioremap_resource(dev, res);
> >> >> if (IS_ERR(regs))
> >> >> @@ -364,7 +367,7 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
> >> >> backend->regs = devm_regmap_init_mmio(dev, regs,
> >> >> &sun4i_backend_regmap_config);
> >> >> if (IS_ERR(backend->regs)) {
> >> >> - dev_err(dev, "Couldn't create the backend0 regmap\n");
> >> >> + dev_err(dev, "Couldn't create the backend regmap\n");
> >> >> return PTR_ERR(backend->regs);
> >> >> }
> >> >>
> >> >> @@ -413,6 +416,8 @@ static int sun4i_backend_bind(struct device *dev, struct device *master,
> >> >> }
> >> >> }
> >> >>
> >> >> + drv->backend[backend->id] = backend;
> >> >> +
> >> >> /* Reset the registers */
> >> >> for (i = 0x800; i < 0x1000; i += 4)
> >> >> regmap_write(backend->regs, i, 0);
> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> >> >> index 767bbadcc85d..c15ecb8343d7 100644
> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> >> >> @@ -271,7 +271,7 @@ static int sun4i_drv_probe(struct platform_device *pdev)
> >> >> struct device_node *np = pdev->dev.of_node;
> >> >> int i, count = 0;
> >> >>
> >> >> - for (i = 0;; i++) {
> >> >> + for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++) {
> >> >> struct device_node *pipeline = of_parse_phandle(np,
> >> >> "allwinner,pipelines",
> >> >> i);
> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.h b/drivers/gpu/drm/sun4i/sun4i_drv.h
> >> >> index 5df50126ff52..ec1c08af47e1 100644
> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_drv.h
> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.h
> >> >> @@ -16,9 +16,11 @@
> >> >> #include <linux/clk.h>
> >> >> #include <linux/regmap.h>
> >> >>
> >> >> +#define SUN4I_DRM_MAX_PIPELINES 2
> >> >> +
> >> >> struct sun4i_drv {
> >> >> - struct sun4i_backend *backend;
> >> >> - struct sun4i_tcon *tcon;
> >> >> + struct sun4i_backend *backend[SUN4I_DRM_MAX_PIPELINES];
> >> >> + struct sun4i_tcon *tcon[SUN4I_DRM_MAX_PIPELINES];
> >> >>
> >> >> struct drm_fbdev_cma *fbdev;
> >> >> };
> >> >> diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> >> index b774c9a50c55..7749c3133f38 100644
> >> >> --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> >> +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c
> >> >> @@ -532,7 +532,6 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> >> >> if (!tcon)
> >> >> return -ENOMEM;
> >> >> dev_set_drvdata(dev, tcon);
> >> >> - drv->tcon = tcon;
> >> >> tcon->drm = drm;
> >> >> tcon->dev = dev;
> >> >> tcon->quirks = of_device_get_match_data(dev);
> >> >> @@ -540,14 +539,22 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> >> >> /* This can fail if the DT does not have any downstream encoders. */
> >> >> tcon->id = sun4i_tcon_of_get_id(dev->of_node);
> >> >> if (tcon->id < 0) {
> >> >> - /*
> >> >> - * TODO We currently support only 1 TCON, so we can
> >> >> - * safely set this to 0. This should be revisited
> >> >> - * when we add support for multiple pipelines.
> >> >> - */
> >> >> - tcon->id = 0;
> >> >> + int i;
> >> >> +
> >> >> + /* find the first empty tcon in sun4i_drv */
> >> >> + for (i = 0; i < SUN4I_DRM_MAX_PIPELINES; i++)
> >> >> + if (!drv->tcon[i])
> >> >> + tcon->id = i;
> >> >> +
> >> >> + /* bail out if that failed */
> >> >> + if (tcon->id < 0)
> >> >> + return tcon->id;
> >> >> }
> >> >>
> >> >> + /* We only support SUN4I_DRM_MAX_PIPELINES number of tcons */
> >> >> + if (tcon->id >= SUN4I_DRM_MAX_PIPELINES)
> >> >> + return -EINVAL;
> >> >> +
> >> >> tcon->lcd_rst = devm_reset_control_get(dev, "lcd");
> >> >> if (IS_ERR(tcon->lcd_rst)) {
> >> >> dev_err(dev, "Couldn't get our reset line\n");
> >> >> @@ -588,7 +595,7 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master,
> >> >> goto err_free_dotclock;
> >> >> }
> >> >>
> >> >> - tcon->crtc = sun4i_crtc_init(drm, drv->backend, tcon);
> >> >> + tcon->crtc = sun4i_crtc_init(drm, drv->backend[tcon->id], tcon);
> >> >
> >> > I'm not a big fan of those IDs. The heuristic seems to be a bit
> >> > fragile since we really never enforced any order in our bindings.
> >>
> >> Yes. I seem to have forgotten that bit which I had intended to add.
> >> The endpoint IDs would ideally match the actual mux values used.
> >
> > That works for me, but the binding documentation would need to be
> > amended.
> >
> >> On the TCON side that's not doable, so we might have to just require
> >> them being in an increasing order.
> >
> > What are you planning to use those IDs on for the TCON?
>
> This reply sat in my draft box for way too long.
>
> As mentioned, the IDs on the TCON side are for the IDing the TV encoders.
> I think having the IDs for the same type of encoder be increasing, such
> that the endpoint for TV encoder 1 has a higher ID than the one for TV
> encoder 0 should be enough. There aren't any other instances where we
> have 2 or more of the same type. Or we could just add some kind of index
> property to the TV encoder node. This is for the A20 by the way.
Sorry if I'm missing a bit of context here, but I still don't get
*why* you would need to ID them. So far, your explanation seems to
have been "so that we can ID them", which is pretty circular to me :)
> >> > You seem to use it for two things:
> >> > - to match a TCON to its backend in our code
> >> > - to not step on each others' toes when registering the backends/tcons
> >> >
> >> > I think the second could be easily addressed using a linked list, and
> >> > the first one by storing the of_node. Then we just need to follow the
> >> > OF graph to our input of_node, and then iterate through our registered
> >> > backend list to find the one with the same of_node.
> >>
> >> Yes that would work for the above purposes.
> >>
> >> For getting the first TCON to access the mux registers, it kind of falls
> >> short. We also need something like this for the TV encoders on A10/A20.
> >> They too have a mux, which seems to be in the first TV encoder. This
> >> controls how the 8 DACs are mapped to the 4 external pins.
> >
> > How are those pins muxed between the two? Can't we just create a
> > connector that would be usable for both encoders?
>
> They are freely muxable. However if you want VGA output, you need 3 pins
> for RGB from the same TV encoder, plus H/V sync from it's upstream TCON.
(you don't really need hsync and vsync on VGA, those are optional signals)
> And you have one pin left that you can use for composite, which would
> likely be fed from the other TCON, as you need interlaced YUV data,
> which is like the opposite of VGA.
I'm not sure how these muxers should be implemented in DRM. One
trivial way would be to have a small pinctrl driver in the TCON driver
to deal with that, and switch states in both TV encoders at runtime
(if needed, statically otherwise).
Or maybe we can do something simpler, I don't know.
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170418/e772c93c/attachment-0001.sig>
^ permalink raw reply
* [PATCH] arm: bitops: Align prototypes to generic API
From: Mason @ 2017-04-18 9:36 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <b6610c43-75fe-64ee-8b22-867f970e3fe7@free.fr>
On 05/04/2017 14:21, Mason wrote:
> include/asm-generic/bitops/find.h declares:
>
> extern unsigned long
> find_first_zero_bit(const unsigned long *addr, unsigned long size);
>
> while arch/arm/include/asm/bitops.h declares:
>
> #define find_first_zero_bit(p,sz) _find_first_zero_bit_le(p,sz)
> extern int _find_first_zero_bit_le(const void * p, unsigned size);
>
> Align the arm prototypes to the generic API, to have gcc report
> inadequate arguments, such as pointer to u32.
>
> Signed-off-by: Mason <slash.tmp@free.fr>
> ---
> arch/arm/include/asm/bitops.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
> index e943e6cee254..f308c8c40cb9 100644
> --- a/arch/arm/include/asm/bitops.h
> +++ b/arch/arm/include/asm/bitops.h
> @@ -159,16 +159,16 @@ extern int _test_and_change_bit(int nr, volatile unsigned long * p);
> /*
> * Little endian assembly bitops. nr = 0 -> byte 0 bit 0.
> */
> -extern int _find_first_zero_bit_le(const void * p, unsigned size);
> -extern int _find_next_zero_bit_le(const void * p, int size, int offset);
> +extern int _find_first_zero_bit_le(const unsigned long *p, unsigned size);
> +extern int _find_next_zero_bit_le(const unsigned long *p, int size, int offset);
> extern int _find_first_bit_le(const unsigned long *p, unsigned size);
> extern int _find_next_bit_le(const unsigned long *p, int size, int offset);
>
> /*
> * Big endian assembly bitops. nr = 0 -> byte 3 bit 0.
> */
> -extern int _find_first_zero_bit_be(const void * p, unsigned size);
> -extern int _find_next_zero_bit_be(const void * p, int size, int offset);
> +extern int _find_first_zero_bit_be(const unsigned long *p, unsigned size);
> +extern int _find_next_zero_bit_be(const unsigned long *p, int size, int offset);
> extern int _find_first_bit_be(const unsigned long *p, unsigned size);
> extern int _find_next_bit_be(const unsigned long *p, int size, int offset);
Marc, it was you who pointed out that it is not valid to pass
the address of a u32 to find_first_zero_bit()
What are your thoughts on this trivial patch?
Russell, same question.
If no one thinks this patch is useful, I'll drop it and move on.
Regards.
^ permalink raw reply
* [PATCH v2] serial: 8250_early: Add earlycon support for Palmchip UART
From: Marc Gonzalez @ 2017-04-18 9:27 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <7a016ff6-08fc-2811-92e0-7c4603fa8586@sigmadesigns.com>
[ Trimming CC list to minimize noise ]
On 10/04/2017 11:47, Marc Gonzalez wrote:
> Define an OF early console for Palmchip UART, which can be enabled
> by passing "earlycon" on the boot command line.
>
> Signed-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>
> ---
> drivers/tty/serial/8250/8250_early.c | 24 ++++++++++++++++++++++++
> drivers/tty/serial/8250/8250_port.c | 4 ++--
> 2 files changed, 26 insertions(+), 2 deletions(-)
Hello Greg,
I'd really like to have earlycon support for this UART in v4.12
Do you see anything wrong with this patch, preventing it from landing?
Do you want me to move the function declarations to a header?
(If so, which one?)
Regards.
^ permalink raw reply
* [PATCH] arm64: dts: m3ulcb: Fix EthernetAVB PHY timing
From: Sergei Shtylyov @ 2017-04-18 9:26 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492477578-10228-1-git-send-email-horms+renesas@verge.net.au>
Hello.
On 4/18/2017 4:06 AM, Simon Horman wrote:
> Set PHY rxc-skew-ps to 1500 and all other values to their default values.
>
> This is intended to to address failures in the case of 1Gbps communication
> using the by salvator-x board with the KSZ9031RNX phy. This has been
The by? :-)
> reported to occur with both the r8a7795 (H3) and r8a7796 (M3-W) SoCs.
>
> Based in a similar patch for the r8a7796 salvator-x by Kazuya Mizuguchi.
>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
[...]
MBR, Sergei
^ permalink raw reply
* [PATCH 2/3] ARM: sun8i: a83t: Drop leading zeroes from device node addresses
From: Chen-Yu Tsai @ 2017-04-18 9:22 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418090329.odixwybrkqvp2o7z@lukather>
On Tue, Apr 18, 2017 at 5:03 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Tue, Apr 18, 2017 at 12:22:04PM +0800, Chen-Yu Tsai wrote:
>> Kbuild now complains about leading zeroes in the address portion of
>> device node names.
>>
>> Get rid of them.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>> ---
>> arch/arm/boot/dts/sun8i-a83t.dtsi | 10 +++++-----
>> 1 file changed, 5 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
>> index 913aacafe8d5..82cb87f21b96 100644
>> --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
>> +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
>> @@ -162,7 +162,7 @@
>> #size-cells = <1>;
>> ranges;
>>
>> - pio: pinctrl at 01c20800 {
>> + pio: pinctrl at 1c20800 {
>
> As far as I know this breaks Uboot's auto-addition of stdout-path
You're right. It breaks as Uboot has the path to the uarts hard-coded.
That sucks. And from what I can tell, it's not easily solvable by just
switching to serial alias based references. CONS_INDEX won't line up
on the A23/A33 Q8 tablets.
Maybe we can just keep the uart device node the same for now, but fix
all the other ones. We can come back and fix the uart later once we
figure out how to fix Uboot.
Regards
ChenYu
^ permalink raw reply
* [PATCH/RFT] sata: rcar_sata: Reset SATA PHY on resume
From: Sergei Shtylyov @ 2017-04-18 9:20 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492498973-2969-1-git-send-email-horms+renesas@verge.net.au>
Hello.
On 4/18/2017 10:02 AM, Simon Horman wrote:
> In the case where power is cut on suspend the SATA PHY state needs to be
> suspended on resume.
>
> This is the case on the Salvator-X board with the r8a7795 or r8a7796 SoC.
> In that environment it has been observed that SATA partitions cannot not be
> accessed on resume.
>
> Based on work by Khiem Nguyen.
>
> Cc: Khiem Nguyen <khiem.nguyen.xt@rvc.renesas.com>
> Signed-off-by: Simon Horman <horms+renesas@verge.net.au>
> ---
> * Compile and boot tested only
> ---
> drivers/ata/sata_rcar.c | 9 +--------
> 1 file changed, 1 insertion(+), 8 deletions(-)
Why the scope prefix in the subject is not just "sata_rcar: "? :-)
[...]
MBR, Sergei
^ permalink raw reply
* [PATCH 3/3] ARM: sun8i: a83t: Rename pinmux setting names
From: Chen-Yu Tsai @ 2017-04-18 9:16 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418090447.dcxinewczubf26b7@lukather>
On Tue, Apr 18, 2017 at 5:04 PM, Maxime Ripard
<maxime.ripard@free-electrons.com> wrote:
> On Tue, Apr 18, 2017 at 12:22:05PM +0800, Chen-Yu Tsai wrote:
>> The pinmux setting nodes all have an address element in their node
>> names, however the pinctrl node does not have #address-cells.
>>
>> Rename the existing pinmux setting nodes and labels in sun8i-a83t.dtsi,
>> dropping identifiers for functions that only have one possible setting,
>> and using the pingroup name if the function is identically available on
>> different pingroups.
>>
>> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
>
> Applied, and I really like the new names.
>
> Would you make the same patch for everyone?
I can. No guarantees on the schedule though.
ChenYu
^ permalink raw reply
* [PATCH v2 1/5] dt-bindings: gpu: add bindings for the ARM Mali Midgard GPU
From: Guillaume Tucker @ 2017-04-18 9:15 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170404020056.d7osj7rmog22xbjd@rob-hp-laptop>
Hi Rob,
On 04/04/17 03:00, Rob Herring wrote:
> On Sun, Apr 02, 2017 at 08:59:44AM +0100, Guillaume Tucker wrote:
>> The ARM Mali Midgard GPU family is present in a number of SoCs
>> from many different vendors such as Samsung Exynos and Rockchip.
>>
>> Import the device tree bindings documentation from the r16p0
>> release of the Mali Midgard GPU kernel driver:
>>
>> https://developer.arm.com/-/media/Files/downloads/mali-drivers/kernel/mali-midgard-gpu/TX011-SW-99002-r16p0-00rel0.tgz
>>
>> The following optional bindings have been omitted in this initial
>> version as they are only used in very specific cases:
>>
>> * snoop_enable_smc
>> * snoop_disable_smc
>> * jm_config
>> * power_model
>> * system-coherency
>> * ipa-model
>>
>> The example has been simplified accordingly.
>>
>> The compatible string definition has been limited to
>> "arm,mali-midgard" to avoid checkpatch.pl warnings and to match
>> what the driver actually expects (as of r16p0 out-of-tree).
>>
>> CC: John Reitan <john.reitan@arm.com>
>> Signed-off-by: Guillaume Tucker <guillaume.tucker@collabora.com>
>> ---
>> .../devicetree/bindings/gpu/arm,mali-midgard.txt | 53 ++++++++++++++++++++++
>> 1 file changed, 53 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>>
>> diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>> new file mode 100644
>> index 000000000000..da8fc6d21bbf
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt
>> @@ -0,0 +1,53 @@
>> +#
>> +# (C) COPYRIGHT 2013-2016 ARM Limited.
>> +# Copyright (C) 2017 Collabora Ltd
>> +#
>> +# This program is free software and is provided to you under the terms of the
>> +# GNU General Public License version 2 as published by the Free Software
>> +# Foundation, and any use by you of this program is subject to the terms
>> +# of such GNU licence.
>> +#
>> +
>> +
>> +ARM Mali Midgard GPU
>> +====================
>> +
>> +Required properties:
>> +
>> +- compatible : Should be "arm,mali-midgard".
>
> As Neil said...
Sure; as discussed in my previous emails.
>> +- reg : Physical base address of the device and length of the register area.
>> +- interrupts : Contains the three IRQ lines required by Mali Midgard devices.
>> +- interrupt-names : Contains the names of IRQ resources in the order they were
>> + provided in the interrupts property. Must contain: "JOB, "MMU", "GPU".
>> +
>> +Optional:
>> +
>> +- clocks : Phandle to clock for the Mali Midgard device.
>> +- clock-names : Shall be "clk_mali".
>
> "clk_" is redundant. Actually, if there is only 1 clock, then just drop
> names. But there's not at least a core and bus clock?
Only one clock needs to be provided with the Midgard GPU
architecture. It shares the same bus and system memory as the
CPU. So I'll remove clock-names in patch v3.
>> +- mali-supply : Phandle to regulator for the Mali device. Refer to
>> + Documentation/devicetree/bindings/regulator/regulator.txt for details.
>> +- operating-points : Refer to Documentation/devicetree/bindings/power/opp.txt
>> + for details.
>
> Is this going to be sufficient vs. operating-points-v2? Or should it be
> a power domain with OPPs?
In principle, switching to operating-points-v2 should be very
straightforward. I have smoke-tested the driver with an
operating-points-v2 table and a phandle to it inside the gpu node
in place of operating-points and it seems to be working fine. At
least it parsed the OPPs and got initialised correctly.
My understanding is that operating-points (v1) are not deprecated
so we could keep the bindings as-is, but please let me know
otherwise and I can try to address that in my next patch version.
In the documentation, it should only be the case of replacing
operating-points with operating-points-v2.
>> +
>> +Example for a Mali-T602:
>> +
>> +gpu at 0xfc010000 {
>
> Drop the '0x'.
OK, I'm also updating the example with lower-case IRQ names, no
clock-names etc...
Thanks,
Guillaume
^ permalink raw reply
* kvm/arm64: use-after-free in kvm_unmap_hva_handler/unmap_stage2_pmds
From: Mark Rutland @ 2017-04-18 9:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418083230.GA17866@leverpostej>
On Tue, Apr 18, 2017 at 09:32:31AM +0100, Mark Rutland wrote:
> Hi Suzuki,
>
> On Thu, Apr 13, 2017 at 04:50:46PM +0100, Suzuki K. Poulose wrote:
> > kvm: Hold reference to the user address space
> >
> > The core KVM code, uses mmgrab/mmdrop to pin the mm struct of the user
> > application. mmgrab only guarantees that the mm struct is available,
> > while the "real address space" (see Documentation/vm/active_mm.txt) may
> > be destroyed. Since the KVM depends on the user space page tables for
> > the Guest pages, we should instead do an mmget/mmput. Even though
> > mmget/mmput is not encouraged for uses with unbounded time, the KVM
> > is fine to do so, as we are doing it from the context of the same process.
> >
> > This also prevents the race condition where mmu_notifier_release() could
> > be called in parallel and one instance could end up using a free'd kvm
> > instance.
> >
> > Cc: Mark Rutland <mark.rutland@arm.com>
> > Cc: Paolo Bonzin <pbonzini@redhat.com>
> > Cc: Radim Kr?m?? <rkrcmar@redhat.com>
> > Cc: Marc Zyngier <marc.zyngier@arm.com>
> > Cc: Christoffer Dall <christoffer.dall@linaro.org>
> > Cc: andreyknvl at google.com
> > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
> > ---
> > virt/kvm/kvm_main.c | 6 +++---
> > 1 file changed, 3 insertions(+), 3 deletions(-)
> >
> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 88257b3..555712e 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -613,7 +613,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
> > return ERR_PTR(-ENOMEM);
> >
> > spin_lock_init(&kvm->mmu_lock);
> > - mmgrab(current->mm);
> > + mmget(current->mm);
> > kvm->mm = current->mm;
> > kvm_eventfd_init(kvm);
> > mutex_init(&kvm->lock);
> > @@ -685,7 +685,7 @@ static struct kvm *kvm_create_vm(unsigned long type)
> > for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++)
> > kvm_free_memslots(kvm, kvm->memslots[i]);
> > kvm_arch_free_vm(kvm);
> > - mmdrop(current->mm);
> > + mmput(current->mm);
> > return ERR_PTR(r);
> > }
> >
> > @@ -747,7 +747,7 @@ static void kvm_destroy_vm(struct kvm *kvm)
> > kvm_arch_free_vm(kvm);
> > preempt_notifier_dec();
> > hardware_disable_all();
> > - mmdrop(mm);
> > + mmput(mm);
> > }
>
>
> As a heads-up, I'm seeing what looks to be a KVM memory leak with this
> patch applied atop of next-20170411.
>
> I don't yet know if this is a problem with next-20170411 or this patch
> in particular -- I will try to track that down. In the mean time, info
> dump below.
>
> I left syzkaller running over the weekend using this kernel on the host,
> and OOM kicked in after it had been running for a short while. Almost
> all of my memory is in use, but judging by top, almost none of this is
> associated with processes.
FWIW, it seems easy enough to trigger this leak with kvmtool. Start a
guest that'll allocate a tonne of memory:
$ lkvm run --console virtio -m 4096 --kernel Image \
-p "memtest=1 console=hvc0,38400 earlycon=uart,mmio,0x3f8"
... then kill this with a SIGKILL from your favourite process management
tool.
Also, if the guest exits normally, everything appears to be cleaned up
correctly. So it looks like this is in some way related to our fatal
signal handling.
Thanks,
Mark.
^ permalink raw reply
* [PATCH v6 17/39] platform: add video-multiplexer subdevice driver
From: Pavel Machek @ 2017-04-18 9:05 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1492502989.2432.23.camel@pengutronix.de>
Hi!
> That self-referencing mux-controls property looks a bit superfluous:
>
> mux: video-multiplexer {
> mux-controls = <&mux>;
> };
>
> Other than that, I'm completely fine with splitting the compatible into
> something like video-mux-gpio and video-mux-mmio and reusing the
> mux-gpios property for video-mux-gpio.
Agreed, I overseen that.
> > You should be able to use code in drivers/mux as a library...
>
> This is a good idea in principle, but this requires some rework of the
> mux subsystem, and that subsystem hasn't even landed yet. For now I'd
> like to focus on getting the DT bindings right.
>
> I'd honestly prefer to not add this rework as a requirement for the i.MX
> media drivers to get into staging.
Hmm. staging/ normally accepts code with bigger design problems than
that.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170418/1c115102/attachment.sig>
^ permalink raw reply
* [PATCH 3/3] ARM: sun8i: a83t: Rename pinmux setting names
From: Maxime Ripard @ 2017-04-18 9:04 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418042205.27894-4-wens@csie.org>
On Tue, Apr 18, 2017 at 12:22:05PM +0800, Chen-Yu Tsai wrote:
> The pinmux setting nodes all have an address element in their node
> names, however the pinctrl node does not have #address-cells.
>
> Rename the existing pinmux setting nodes and labels in sun8i-a83t.dtsi,
> dropping identifiers for functions that only have one possible setting,
> and using the pingroup name if the function is identically available on
> different pingroups.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Applied, and I really like the new names.
Would you make the same patch for everyone?
Maxime
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170418/4f2ee0ac/attachment.sig>
^ permalink raw reply
* [PATCH 2/3] ARM: sun8i: a83t: Drop leading zeroes from device node addresses
From: Maxime Ripard @ 2017-04-18 9:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20170418042205.27894-3-wens@csie.org>
On Tue, Apr 18, 2017 at 12:22:04PM +0800, Chen-Yu Tsai wrote:
> Kbuild now complains about leading zeroes in the address portion of
> device node names.
>
> Get rid of them.
>
> Signed-off-by: Chen-Yu Tsai <wens@csie.org>
> ---
> arch/arm/boot/dts/sun8i-a83t.dtsi | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi b/arch/arm/boot/dts/sun8i-a83t.dtsi
> index 913aacafe8d5..82cb87f21b96 100644
> --- a/arch/arm/boot/dts/sun8i-a83t.dtsi
> +++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
> @@ -162,7 +162,7 @@
> #size-cells = <1>;
> ranges;
>
> - pio: pinctrl at 01c20800 {
> + pio: pinctrl at 1c20800 {
As far as I know this breaks Uboot's auto-addition of stdout-path
Maxime
>
--
Maxime Ripard, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170418/8e60df3b/attachment.sig>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox