* [PATCH 0/1] remove the "cpu_clk" from the GXBB/GXL/GXM driver
From: Martin Blumenstingl @ 2017-04-01 12:55 UTC (permalink / raw)
To: linux-amlogic, jbrunet, narmstrong, linux-clk
Cc: devicetree, khilman, carlo, sboyd, mturquette, linux-arm-kernel,
Martin Blumenstingl
This is the updated version of my RFC patch from [0].
The quick summary for this patch is that the "cpu_clk" seems to have
been copied from the Meson8b clock driver when the GXBB clock driver
was initially added. However, on GXBB (and the other GX SoCs) the
actual CPU clock is provided by a SCPI DVFS clock.
More details can be found in the patch description itself.
This was tested on a Khadas VIM board (GXL S905X).
Changes since the RFC version:
- rebased to the "clk-meson" branch (e65ae3fb97b4 "dt-bindings: clock:
gxbb-clkc: Add GXL compatible variant") and Jerome's audio clock
patches (in version 2: [1])
- remove the now unused cpu_div_table (which was left over in the RFC
version)
- slightly updated the comment for the now unused clock ID 1 in
drivers/clk/meson/gxbb.h
[0] https://patchwork.kernel.org/patch/9644993/
[1] http://lists.infradead.org/pipermail/linux-amlogic/2017-March/003200.html
Martin Blumenstingl (1):
clk: meson: gxbb: remove the "cpu_clk" from the GXBB and GXL driver
drivers/clk/meson/gxbb.c | 64 ++---------------------------------
drivers/clk/meson/gxbb.h | 2 +-
include/dt-bindings/clock/gxbb-clkc.h | 1 -
3 files changed, 4 insertions(+), 63 deletions(-)
--
2.12.1
^ permalink raw reply
* Re: [PATCH v5 1/2] Documentation: dt-bindings: Document bindings for Aspeed ADC
From: Jonathan Cameron @ 2017-04-01 10:51 UTC (permalink / raw)
To: Joel Stanley, Rick Altherr
Cc: OpenBMC Maillist, Linux Kernel Mailing List,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-iio-u79uwXL29TY76Z2rM5mHXA, Hartmut Knaack, Rob Herring,
Lars-Peter Clausen, Mark Rutland, Peter Meerwald-Stadler
In-Reply-To: <CACPK8Xcf2A8RMy7cthJrdi2CA0L_Hfi+2Hy3JBCzLTsofjhEuA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On 29/03/17 03:33, Joel Stanley wrote:
> On Wed, Mar 29, 2017 at 8:22 AM, Rick Altherr <raltherr-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> wrote:
>> Signed-off-by: Rick Altherr <raltherr-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
>> ---
>
> Acked-by: Joel Stanley <joel-U3u1mxZcP9KHXe+LvDLADg@public.gmane.org>
I can't see why Rob would mind any of the changes made since he
Acked this (and having acked it I doubt he is looking at newer versions!)
so I'm going to take the view his Ack still applies.
Applied to the togreg branch of iio.git which will get pushed out first
as testing for the autobuilders to have a chance to play with it.
Thanks,
Jonathan
>
>>
>> Changes in v5: None
>> Changes in v4: None
>> Changes in v3:
>> - Consistently write hex contstants with lowercase letters
>> - Drop model numbers from description as same IP is used in every generation
>>
>> Changes in v2:
>> - Rewritten as an IIO ADC device
>>
>> .../devicetree/bindings/iio/adc/aspeed_adc.txt | 20 ++++++++++++++++++++
>> 1 file changed, 20 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
>> new file mode 100644
>> index 000000000000..674e133b7cd7
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/iio/adc/aspeed_adc.txt
>> @@ -0,0 +1,20 @@
>> +Aspeed ADC
>> +
>> +This device is a 10-bit converter for 16 voltage channels. All inputs are
>> +single ended.
>> +
>> +Required properties:
>> +- compatible: Should be "aspeed,ast2400-adc" or "aspeed,ast2500-adc"
>> +- reg: memory window mapping address and length
>> +- clocks: Input clock used to derive the sample clock. Expected to be the
>> + SoC's APB clock.
>> +- #io-channel-cells: Must be set to <1> to indicate channels are selected
>> + by index.
>> +
>> +Example:
>> + adc@1e6e9000 {
>> + compatible = "aspeed,ast2400-adc";
>> + reg = <0x1e6e9000 0xb0>;
>> + clocks = <&clk_apb>;
>> + #io-channel-cells = <1>;
>> + };
>> --
>> 2.12.2.564.g063fe858b8-goog
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-iio" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply
* Re: [PATCH V8 5/6] ACPI: Support the probing on the devices which apply indirect-IO
From: Rafael J. Wysocki @ 2017-04-01 9:52 UTC (permalink / raw)
To: zhichang.yuan
Cc: Rafael J. Wysocki, zhichang.yuan, Rafael J. Wysocki,
Catalin Marinas, Will Deacon, Rob Herring, Frank Rowand,
Bjorn Helgaas, Arnd Bergmann,
linux-arm-kernel@lists.infradead.org, Mark Rutland, Brian Starkey,
Olof Johansson, Lorenzo Pieralisi, Benjamin Herrenschmidt,
Linux Kernel Mailing List, ACPI Devel Maling List, linuxar
In-Reply-To: <bfdf2de0-c309-0139-4075-dfcd678b6d51@gmail.com>
On Sat, Apr 1, 2017 at 4:16 AM, zhichang.yuan <zhichang.yuan02@gmail.com> wrote:
>
>
> On 04/01/2017 07:02 AM, Rafael J. Wysocki wrote:
>> On Fri, Mar 31, 2017 at 8:52 AM, zhichang.yuan
>> <yuanzhichang@hisilicon.com> wrote:
>>> Hi, Rafael,
>>>
>>> Thanks for reviewing this!
>>>
>>> On 2017/3/31 4:31, Rafael J. Wysocki wrote:
>>>> On Thursday, March 30, 2017 11:26:58 PM zhichang.yuan wrote:
>>>>> On some platforms(such as Hip06/Hip07), the legacy ISA/LPC devices access I/O
>>>>> with some special host-local I/O ports known on x86. To access the I/O
>>>>> peripherals, an indirect-IO mechanism is introduced to mapped the host-local
>>>>> I/O to system logical/fake PIO similar the PCI MMIO on architectures where no
>>>>> separate I/O space exists. Just as PCI MMIO, the host I/O range should be
>>>>> registered before probing the downstream devices and set up the I/O mapping.
>>>>> But current ACPI bus probing doesn't support these indirect-IO hosts/devices.
>>>>>
>>>>> This patch introdueces a new ACPI handler for this device category. Through the
>>>>> handler attach callback, the indirect-IO hosts I/O registration is done and
>>>>> all peripherals' I/O resources are translated into logic/fake PIO before
>>>>> starting the enumeration.
>>>>
>>>> Can you explain to me briefly what exactly this code is expected to be doing?
>>>
>>> As you know currently for ARM architecture IO space is memory mapped and
>>> is only used by pci devices. The port number is dynamically allocated
>>> converting the device IO address into a PIO token: i.e.
>>> http://lxr.free-electrons.com/source/drivers/acpi/pci_root.c#L745
>>> This patch is meant to support a new class of IO host controller
>>> that are not PCI based and that still require to have the IO addresses
>>> be translated in the same PIO token space as the PCI controller
>>
>> IOW, this is ARM-specific, right?
>
> Yes. The current host added in this patch with _HID "HISI0191" is on ARM64.
But the underlying mechanism is ARM-specific as well AFAICS.
> But, I think the handler driver is architecture dependent.
I guess you mean "independent"? That doesn't matter.
If ARM64 is the only architecture to use it in foreseeable future
(which is the case for all I can say), it should go into acpi/arm64/
and please ask the maintainers thereof to review it.
Thanks,
Rafael
^ permalink raw reply
* Re: [PATCH v2 2/2] phy: meson: add USB2 PHY support for Meson GXL and GXM
From: Martin Blumenstingl @ 2017-04-01 9:37 UTC (permalink / raw)
To: Kishon Vijay Abraham I
Cc: linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
mark.rutland-5wv7dgnIgG8, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
hendrik-MJglGmTD+GWCT0AhDRffsw, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
carlo-KA+7E9HrN00dnm+yROfE0A, khilman-rdvid1DuHRBWk0Htik3J/w
In-Reply-To: <82edc36e-80ae-3aa2-cd45-664b26a21e4a-l0cyMroinI0@public.gmane.org>
Hi Kishon,
On Wed, Mar 29, 2017 at 12:56 PM, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
> Hi,
>
> On Wednesday 29 March 2017 03:03 AM, Martin Blumenstingl wrote:
>> Hi Kishon,
>>
>> On Sat, Mar 18, 2017 at 2:00 PM, Martin Blumenstingl
>> <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org> wrote:
>>> This adds a new driver for the USB2 PHYs found on Meson GXL and GXM SoCs
>>> (both SoCs are using the same USB PHY register layout).
>>>
>>> The USB2 PHY is a simple PHY which only has a few registers to configure
>>> the mode (host/device) and a reset register (to enable/disable the PHY).
>>>
>>> Unfortunately there are no datasheets available for this PHY. The driver
>>> was written by reading the code from Amlogic's GPL kernel sources and
>>> by analyzing the registers on an actual GXL and GXM device running the
>>> kernel that was shipped on the boards I have.
>> gentle ping - did you have time to review this patch in v2 yet?
>
> Have a few comments, see below..
thanks for taking the time to review this!
>>
>>> Signed-off-by: Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>>> ---
>>> drivers/phy/Kconfig | 14 ++
>>> drivers/phy/Makefile | 1 +
>>> drivers/phy/phy-meson-gxl-usb2.c | 273 +++++++++++++++++++++++++++++++++++++++
>>> 3 files changed, 288 insertions(+)
>>> create mode 100644 drivers/phy/phy-meson-gxl-usb2.c
>>>
>>> diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
>>> index dc5277ad1b5a..2573e139fd17 100644
>>> --- a/drivers/phy/Kconfig
>>> +++ b/drivers/phy/Kconfig
>>> @@ -510,6 +510,19 @@ config PHY_MESON8B_USB2
>>> and GXBB SoCs.
>>> If unsure, say N.
>>>
>>> +config PHY_MESON_GXL_USB
>>> + tristate "Meson GXL and GXM USB2 PHY drivers"
>>> + default ARCH_MESON
>>> + depends on OF && (ARCH_MESON || COMPILE_TEST)
>>> + depends on USB_SUPPORT
>>> + select USB_COMMON
>>> + select GENERIC_PHY
>>> + select REGMAP_MMIO
>>> + help
>>> + Enable this to support the Meson USB2 PHYs found in Meson
>>> + GXL and GXM SoCs.
>>> + If unsure, say N.
>>> +
>>> config PHY_NSP_USB3
>>> tristate "Broadcom NorthStar plus USB3 PHY driver"
>>> depends on OF && (ARCH_BCM_NSP || COMPILE_TEST)
>>> @@ -518,4 +531,5 @@ config PHY_NSP_USB3
>>> help
>>> Enable this to support the Broadcom Northstar plus USB3 PHY.
>>> If unsure, say N.
>>> +
>
> spurious space..
you're right, this shouldn't be here. I'll fix this in the next version
>>> endmenu
>>> diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
>>> index e7b0feb1e125..e680b856e38e 100644
>>> --- a/drivers/phy/Makefile
>>> +++ b/drivers/phy/Makefile
>>> @@ -62,4 +62,5 @@ obj-$(CONFIG_PHY_CYGNUS_PCIE) += phy-bcm-cygnus-pcie.o
>>> obj-$(CONFIG_ARCH_TEGRA) += tegra/
>>> obj-$(CONFIG_PHY_NS2_PCIE) += phy-bcm-ns2-pcie.o
>>> obj-$(CONFIG_PHY_MESON8B_USB2) += phy-meson8b-usb2.o
>>> +obj-$(CONFIG_PHY_MESON_GXL_USB) += phy-meson-gxl-usb2.o
>>> obj-$(CONFIG_PHY_NSP_USB3) += phy-bcm-nsp-usb3.o
>>> diff --git a/drivers/phy/phy-meson-gxl-usb2.c b/drivers/phy/phy-meson-gxl-usb2.c
>>> new file mode 100644
>>> index 000000000000..4bf646a52c45
>>> --- /dev/null
>>> +++ b/drivers/phy/phy-meson-gxl-usb2.c
>>> @@ -0,0 +1,273 @@
>>> +/*
>>> + * Meson GXL and GXM USB2 PHY driver
>>> + *
>>> + * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl-gM/Ye1E23mwN+BqQ9rBEUg@public.gmane.org>
>>> + *
>>> + * This program is free software; you can redistribute it and/or modify
>>> + * it under the terms of the GNU General Public License version 2 as
>>> + * published by the Free Software Foundation.
>>> + *
>>> + * You should have received a copy of the GNU General Public License
>>> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
>>> + */
>>> +
>>> +#include <linux/delay.h>
>>> +#include <linux/io.h>
>>> +#include <linux/module.h>
>>> +#include <linux/of_device.h>
>>> +#include <linux/regmap.h>
>>> +#include <linux/phy/phy.h>
>>> +#include <linux/platform_device.h>
>>> +#include <linux/usb/of.h>
>>> +
>>> +/* bits [31:27] are read-only */
>>> +#define U2P_R0 0x0
>>> + #define U2P_R0_BYPASS_SEL BIT(0)
>>> + #define U2P_R0_BYPASS_DM_EN BIT(1)
>>> + #define U2P_R0_BYPASS_DP_EN BIT(2)
>>> + #define U2P_R0_TXBITSTUFF_ENH BIT(3)
>>> + #define U2P_R0_TXBITSTUFF_EN BIT(4)
>>> + #define U2P_R0_DM_PULLDOWN BIT(5)
>>> + #define U2P_R0_DP_PULLDOWN BIT(6)
>>> + #define U2P_R0_DP_VBUS_VLD_EXT_SEL BIT(7)
>>> + #define U2P_R0_DP_VBUS_VLD_EXT BIT(8)
>>> + #define U2P_R0_ADP_PRB_EN BIT(9)
>>> + #define U2P_R0_ADP_DISCHARGE BIT(10)
>>> + #define U2P_R0_ADP_CHARGE BIT(11)
>>> + #define U2P_R0_DRV_VBUS BIT(12)
>>> + #define U2P_R0_ID_PULLUP BIT(13)
>>> + #define U2P_R0_LOOPBACK_EN_B BIT(14)
>>> + #define U2P_R0_OTG_DISABLE BIT(15)
>>> + #define U2P_R0_COMMON_ONN BIT(16)
>>> + #define U2P_R0_FSEL_MASK GENMASK(19, 17)
>>> + #define U2P_R0_REF_CLK_SEL_MASK GENMASK(21, 20)
>>> + #define U2P_R0_POWER_ON_RESET BIT(22)
>>> + #define U2P_R0_V_ATE_TEST_EN_B_MASK GENMASK(24, 23)
>>> + #define U2P_R0_ID_SET_ID_DQ BIT(25)
>>> + #define U2P_R0_ATE_RESET BIT(26)
>>> + #define U2P_R0_FSV_MINUS BIT(27)
>>> + #define U2P_R0_FSV_PLUS BIT(28)
>>> + #define U2P_R0_BYPASS_DM_DATA BIT(29)
>>> + #define U2P_R0_BYPASS_DP_DATA BIT(30)
>>> +
>>> +#define U2P_R1 0x4
>>> + #define U2P_R1_BURN_IN_TEST BIT(0)
>>> + #define U2P_R1_ACA_ENABLE BIT(1)
>>> + #define U2P_R1_DCD_ENABLE BIT(2)
>>> + #define U2P_R1_VDAT_SRC_EN_B BIT(3)
>>> + #define U2P_R1_VDAT_DET_EN_B BIT(4)
>>> + #define U2P_R1_CHARGES_SEL BIT(5)
>>> + #define U2P_R1_TX_PREEMP_PULSE_TUNE BIT(6)
>>> + #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK GENMASK(8, 7)
>>> + #define U2P_R1_TX_RES_TUNE_MASK GENMASK(10, 9)
>>> + #define U2P_R1_TX_RISE_TUNE_MASK GENMASK(12, 11)
>>> + #define U2P_R1_TX_VREF_TUNE_MASK GENMASK(16, 13)
>>> + #define U2P_R1_TX_FSLS_TUNE_MASK GENMASK(20, 17)
>>> + #define U2P_R1_TX_HSXV_TUNE_MASK GENMASK(22, 21)
>>> + #define U2P_R1_OTG_TUNE_MASK GENMASK(25, 23)
>>> + #define U2P_R1_SQRX_TUNE_MASK GENMASK(28, 26)
>>> + #define U2P_R1_COMP_DIS_TUNE_MASK GENMASK(31, 29)
>>> +
>>> +/* bits [31:14] are read-only */
>>> +#define U2P_R2 0x8
>>> + #define U2P_R2_DATA_IN_MASK GENMASK(3, 0)
>>> + #define U2P_R2_DATA_IN_EN_MASK GENMASK(7, 4)
>>> + #define U2P_R2_ADDR_MASK GENMASK(11, 8)
>>> + #define U2P_R2_DATA_OUT_SEL BIT(12)
>>> + #define U2P_R2_CLK BIT(13)
>>> + #define U2P_R2_DATA_OUT_MASK GENMASK(17, 14)
>>> + #define U2P_R2_ACA_PIN_RANGE_C BIT(18)
>>> + #define U2P_R2_ACA_PIN_RANGE_B BIT(19)
>>> + #define U2P_R2_ACA_PIN_RANGE_A BIT(20)
>>> + #define U2P_R2_ACA_PIN_GND BIT(21)
>>> + #define U2P_R2_ACA_PIN_FLOAT BIT(22)
>>> + #define U2P_R2_CHARGE_DETECT BIT(23)
>>> + #define U2P_R2_DEVICE_SESSION_VALID BIT(24)
>>> + #define U2P_R2_ADP_PROBE BIT(25)
>>> + #define U2P_R2_ADP_SENSE BIT(26)
>>> + #define U2P_R2_SESSION_END BIT(27)
>>> + #define U2P_R2_VBUS_VALID BIT(28)
>>> + #define U2P_R2_B_VALID BIT(29)
>>> + #define U2P_R2_A_VALID BIT(30)
>>> + #define U2P_R2_ID_DIG BIT(31)
>>> +
>>> +#define U2P_R3 0xc
>>> +
>>> +#define RESET_COMPLETE_TIME 500
>>> +
>>> +struct phy_meson_gxl_usb2_priv {
>>> + struct regmap *regmap;
>>> + enum phy_mode mode;
>>> + int is_enabled;
>>> +};
>>> +
>>> +static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
>>> + .reg_bits = 8,
>>> + .val_bits = 32,
>>> + .reg_stride = 4,
>>> + .max_register = U2P_R3,
>>> +};
>>> +
>>> +static int phy_meson_gxl_usb2_reset(struct phy *phy)
>>> +{
>>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>>> +
>>> + if (priv->is_enabled) {
>>> + /* reset the PHY and wait until settings are stabilized */
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>>> + U2P_R0_POWER_ON_RESET);
>>> + udelay(RESET_COMPLETE_TIME);
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>>> + 0);
>>> + udelay(RESET_COMPLETE_TIME);
>>> + }
>
> Instead of having big if condition blocks, it could be
> if (!priv->is_enabled)
> return 0
>
> the configuration when priv->is_enabled is true should go here.
makes sense (and the code easier to read) in this case - I'll fix it
in the next version
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int phy_meson_gxl_usb2_set_mode(struct phy *phy, enum phy_mode mode)
>>> +{
>>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>>> +
>>> + switch (mode) {
>>> + case PHY_MODE_USB_HOST:
>>> + case PHY_MODE_USB_OTG:
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>>> + U2P_R0_DM_PULLDOWN);
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>>> + U2P_R0_DP_PULLDOWN);
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP, 0);
>>> + break;
>>> +
>>> + case PHY_MODE_USB_DEVICE:
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
>>> + 0);
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
>>> + 0);
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
>>> + U2P_R0_ID_PULLUP);
>>> + break;
>>> +
>>> + default:
>>> + return -EINVAL;
>>> + }
>>> +
>>> + phy_meson_gxl_usb2_reset(phy);
>>> +
>>> + priv->mode = mode;
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int phy_meson_gxl_usb2_power_off(struct phy *phy)
>>> +{
>>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>>> +
>>> + priv->is_enabled = 0;
>>> +
>>> + /* power off the PHY by putting it into reset mode */
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
>>> + U2P_R0_POWER_ON_RESET);
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static int phy_meson_gxl_usb2_power_on(struct phy *phy)
>>> +{
>>> + struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
>>> + int ret;
>>> +
>>> + priv->is_enabled = 1;
>>> +
>>> + /* power on the PHY by taking it out of reset mode */
>>> + regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
>>> +
>>> + ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode);
>
> Since this is already part of phy_ops, the consumer of this phy will take care
> of setting the mode right?
many USB PHYs are configured through of_usb_get_dr_mode_by_phy()
(which fetches the USB controller DT node and looks up the dr_mode
property). this means that the driver will even work for controller
which did not call phy_set_mode() (currently dwc2 and dwc3 are an
example where phy_set_mode() is not called, and this driver is
probably going to be used by both). are you fine with keeping this or
should we instead investigate why dwc2 and dwc3 are not calling
phy_set_mode yet?
>>> + if (ret) {
>>> + phy_meson_gxl_usb2_power_off(phy);
>
> This would mess up the reference count in phy_core, since this function is also
> part of the phy_ops. The consumer should be responsible for powering off the phy.
actually it shouldn't. it would cause issues if I used
phy_power_off(phy) here, but I'm using the driver-internal callback
here.
if phy_meson_gxl_usb2_power_on() fails then phy_power_on() (from
phy-core) prints a warnings and does not increment the internal
ref-counter (++phy->power_count).
so in my opinion there shouldn't be a problem
could you please have a look at my replies for issue #3 and #4 (both
affecting phy_meson_gxl_usb2_power_on) and let me know what you think?
Regards,
Martin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v3 12/37] mtd: nand: denali: support 1024 byte ECC step size
From: Masahiro Yamada @ 2017-04-01 8:43 UTC (permalink / raw)
To: linux-mtd-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: Enrico Jorns, Artem Bityutskiy, Dinh Nguyen, Boris Brezillon,
Marek Vasut, Graham Moore, David Woodhouse, Masami Hiramatsu,
Chuanxiao Dong, Jassi Brar, Masahiro Yamada,
devicetree-u79uwXL29TY76Z2rM5mHXA, Linux Kernel Mailing List,
Brian Norris, Richard Weinberger, Cyrille Pitchen, Rob Herring,
Mark Rutland
In-Reply-To: <1490856383-31560-13-git-send-email-yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
2017-03-30 15:45 GMT+09:00 Masahiro Yamada <yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>:
> This driver was originally written for the Intel MRST platform with
> several platform specific parameters hard-coded. Another thing we
> need to fix is the hard-coded ECC step size. Currently, it is
> defined as follows:
>
> #define ECC_SECTOR_SIZE 512
>
> (somehow, it is defined in both denali.c and denali.h)
>
> This must be avoided because the Denali IP supports 1024B ECC size
> as well. The Denali User's Guide also says supporting both 512B and
> 1024B ECC sectors is possible, though it would require instantiation
> of two different ECC circuits. So, possible cases are:
>
> [1] only 512B ECC size is supported
> [2] only 1024B ECC size is supported
> [3] both 512B and 1024B ECC sizes are supported
>
> Newer versions of this IP need ecc.size and ecc.steps explicitly
> set up via the following registers:
> CFG_DATA_BLOCK_SIZE (0x6b0)
> CFG_LAST_DATA_BLOCK_SIZE (0x6c0)
> CFG_NUM_DATA_BLOCKS (0x6d0)
>
> Older versions do not have such registers (they were reserved), so
> write accesses are safely ignored.
>
> This commit adds new flags DENALI_CAP_ECC_SIZE_{512,1024}.
>
> The DT property "nand-ecc-step-size" is still optional; a reasonable
> default will be chosen for [1] and [2]. For case [3], users can
> force ECC size via DT in case firmware hard-codes ECC settings.
> If not specified, the driver will use chip's ECC requirement as a
> hint to decide the ECC size.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
> Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> ---
>
> Changes in v3:
> - Move DENALI_CAP_ define out of struct denali_nand_info
> - Use chip->ecc_step_ds as a hint to choose chip->ecc.size
> where possible
>
Please hold back this patch
until we decide how to handle 14.
--
Best Regards
Masahiro Yamada
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ARM: dts: armada-38x: label USB and SATA nodes
From: Ralph Sennhauser @ 2017-04-01 8:09 UTC (permalink / raw)
To: Andrew Lunn
Cc: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Jason Cooper,
Gregory Clement, Sebastian Hesselbarth, Rob Herring, Mark Rutland,
Russell King, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170331182111.GJ22609-g2DYL2Zd6BY@public.gmane.org>
On Fri, 31 Mar 2017 20:21:11 +0200
Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
> On Fri, Mar 31, 2017 at 07:39:20PM +0200, Ralph Sennhauser wrote:
> > On Fri, 31 Mar 2017 18:50:15 +0200
> > Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org> wrote:
> >
> > > > - sata@a8000 {
> > > > + satac0: sata@a8000 {
> > >
> > > Hi Ralph
> > >
> > > Why the c in satac0?
> >
> > For controller and to not conflict with a use case of sata0 for a
> > port, similarly to pciec and pcie1. See
> > armada-385-synology-ds116.dts.
>
> :~/linux/arch/arm/boot/dts$ ls *ds116*
> ls: cannot access '*ds116*': No such file or directory
Ah, not in mainline yet, from linux-next
commit a58d73340b0ec93fc29a826e45fbbfbc3f81b7eb
Author: Willy Tarreau <w@1wt.eu>
Date: Sun Feb 12 10:30:35 2017 +0100
The arch/arm/boot/dts/armada-388-gp.dts from below was
meant as the example for the conflict I mentioned.
>
> But anyway, a few boards seem to solve this by calling the controller
> node ahci0: and the port sata0:
That's another option I missed.
$ git grep -n ahci.:
arch/arm/boot/dts/spear1310.dtsi:59: ahci0: ahci@b1000000 {
arch/arm/boot/dts/spear1310.dtsi:68: ahci1: ahci@b1800000 {
arch/arm/boot/dts/spear1310.dtsi:77: ahci2: ahci@b4000000 {
arch/arm/boot/dts/spear1340.dtsi:42: ahci0: ahci@b1000000 {
Not a big list which I have here and the nodes themselves are named
ahci@xxxxxxxx.
>
> > > > - usb3@f0000 {
> > > > + usb3_0: usb3@f0000 {
> > > > compatible =
> > > > "marvell,armada-380-xhci"; reg = <0xf0000 0x4000>,<0xf4000
> > > > 0x4000>; interrupts = <GIC_SPI 16
> > > > IRQ_TYPE_LEVEL_HIGH>; @@ -598,7 +598,7 @@
> > > > status = "disabled";
> > > > };
> > > >
> > > > - usb3@f8000 {
> > > > + usb3_1: usb3@f8000 {
> > > > compatible =
> > > > "marvell,armada-380-xhci"; reg = <0xf8000 0x4000>,<0xfc000
> > > > 0x4000>; interrupts = <GIC_SPI 17
> > > > IRQ_TYPE_LEVEL_HIGH>;
> > >
> > > I can understand what you are saying. But does anybody else care?
> > > Are there other .dtsi files differentiating between USB 1.1, 2
> > > and 3?
> >
> > It's handled differently where ever I looked, some do some don't. A
> > case for distinguishing USB 2.0 and USB 3.0 like this is
> > armada-388-gp.dts.
>
> Humm...
>
> /* CON4 */
> usb@58000 {
> vcc-supply = <®_usb2_0_vbus>;
> status = "okay";
> };
>
>
> /* CON5 */
> usb3@f0000 {
> usb-phy = <&usb2_1_phy>;
> status = "okay";
> };
>
> /* CON7 */
> usb3@f8000 {
> usb-phy = <&usb3_phy>;
> status = "okay";
> };
>
> Is this clear? Is CON5 a USB 3 host, but has a USB 2 PHY connected to
> it? CON7 is the only true USB 3 port? I think some comments written in
> schwiizerdütsch would be clearre.:-)
Did you just find a bug? :)
*ufm sprung gxi* (about to head out), sorry for the mix-up. The synology
dts would actually have worked for both usb and sata labels :)
$git grep -hn -A8 usb3_0_phy: arch/arm/boot/dts/armada-385-synology-ds116.dts
191: usb3_0_phy: usb3_0_phy {
192- compatible = "usb-nop-xceiv";
193- vcc-supply = <®_usb3_0_vbus>;
194- };
195-
196- usb3_1_phy: usb3_1_phy {
197- compatible = "usb-nop-xceiv";
198- vcc-supply = <®_usb3_1_vbus>;
199- };
---
Let's add another argument for and against usb3_x type labels:
$ git grep -hn usb arch/arm/boot/dts/armada-38x.dtsi
455: usb0: usb@58000 {
593: usb3_0: usb3@f0000 {
601: usb3_1: usb3@f8000 {
They might actually be considered different types. usb vs. usb3, though
that feels quite arbitrary.
$ git grep -hn usb3_0 Documentation/devicetree/bindings/usb/qcom,dwc3.txt
45: usb3_0: usb30@0 {
usb3_0 could be mistaken for the protocol version. A bit of a stretch as well ...
First thought was using usb0,usb1,usb2. For the individual linksys
boards this meant a potential pit-fall, namely using "usb2:" for the
only USB 3.0 port while "usb0:" for the only USB 2.0 port appears in the
armada-385-linksys.dtsi only, hence the quest for alternatives.
In the end it boils down to I couldn't make out a definitive standard and
made a pick that felt about right.
If there was an obvious choice there wouldn't have been a reason to omit
the labels this patch handles when handling the bulk. Make the bulk a none
discussion item and handle the corner cases later. Guess that's what
happened here.
Thanks
Ralph
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC PATCH 2/5] soc/fsl/qbman: Use shared-dma-pool for QMan private memory allocations
From: Scott Wood @ 2017-04-01 7:25 UTC (permalink / raw)
To: Robin Murphy, Michael Ellerman, roy.pledge-3arQi8VN3Tc,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Mark Rutland, madalin.bucur-3arQi8VN3Tc
In-Reply-To: <dfaa1a28-66d8-15fb-7d2d-75e206161770-5wv7dgnIgG8@public.gmane.org>
On Fri, 2017-03-31 at 18:55 +0100, Robin Murphy wrote:
> On 31/03/17 04:27, Michael Ellerman wrote:
> >
> > Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> writes:
> >
> > >
> > > Hi Roy,
> > >
> > > On 29/03/17 22:13, Roy Pledge wrote:
> > > >
> > > > Use the shared-memory-pool mechanism for frame queue descriptor and
> > > > packed frame descriptor record area allocations.
> > > Thanks for persevering with this - in my opinion it's now looking like
> > > it was worth the effort :)
> > >
> > > AFAICS the ioremap_wc() that this leads to does appear to give back
> > > something non-cacheable on PPC (assuming "pgprot_noncached_wc" isn't
> > > horrendously misnamed), and "no-map" should rule out any cacheable
> > > linear map alias existing, so it would seem that this approach should
> > > avert Scott's concerns about attribute mismatches.
> > How does 'no-map' translate into something being excluded from the
> > linear mapping?
> Reserved regions marked with "no-map" get memblock_remove()d by
> early_init_dt_alloc_reserved_memory_arch(). As I understand things, the
> linear map should only cover memblock areas, and it would be explicitly
> violating the semantics of "no-map" to still cover such a region.
Discontiguous memory isn't supported on these PPC chips. Everything up to
memblock_end_of_DRAM() gets mapped -- and if that were to change, the
fragmentation would waste TLB1 entries.
This also breaks compatibility with existing device trees. I suggest putting
an ifdef in the qbman driver to add the new scheme for non-PPC arches only.
-Scott
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v3 7/7] ARM: ux500: Add vendor prefix to tps61052 node
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel
Cc: devicetree, Rob Herring, Lee Jones, Javier Martinez Canillas,
Mark Rutland, Russell King, linux-arm-kernel
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
The tps61052 device node doesn't have a vendor prefix
in its compatible string, fix it by adding one.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/ste-hrefprev60.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/ste-hrefprev60.dtsi b/arch/arm/boot/dts/ste-hrefprev60.dtsi
index 5882a2606ac3..3f14b4df69b4 100644
--- a/arch/arm/boot/dts/ste-hrefprev60.dtsi
+++ b/arch/arm/boot/dts/ste-hrefprev60.dtsi
@@ -30,7 +30,7 @@
i2c@80004000 {
tps61052@33 {
- compatible = "tps61052";
+ compatible = "ti,tps61052";
reg = <0x33>;
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 6/7] mfd: tps6105x: Add OF device ID table
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel; +Cc: devicetree, Rob Herring, Lee Jones, Javier Martinez Canillas
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
The driver doesn't have a struct of_device_id table but supported devices
are registered via Device Trees. This is working on the assumption that a
I2C device registered via OF will always match a legacy I2C device ID and
that the MODALIAS reported will always be of the form i2c:<device>.
But this could change in the future so the correct approach is to have a
OF device ID table if the devices are registered via OF.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3:
- Add a vendor prefix to the compatible string (Rob Herring).
Changes in v2:
- Don't use of_match_ptr() to avoid build warning when CONFIG_OF is disabled.
drivers/mfd/tps6105x.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/mfd/tps6105x.c b/drivers/mfd/tps6105x.c
index baa12ea666fb..187848c93779 100644
--- a/drivers/mfd/tps6105x.c
+++ b/drivers/mfd/tps6105x.c
@@ -173,9 +173,17 @@ static const struct i2c_device_id tps6105x_id[] = {
};
MODULE_DEVICE_TABLE(i2c, tps6105x_id);
+static const struct of_device_id tps6105x_of_match[] = {
+ { .compatible = "ti,tps61050" },
+ { .compatible = "ti,tps61052" },
+ { },
+};
+MODULE_DEVICE_TABLE(of, tps6105x_of_match);
+
static struct i2c_driver tps6105x_driver = {
.driver = {
.name = "tps6105x",
+ .of_match_table = tps6105x_of_match,
},
.probe = tps6105x_probe,
.remove = tps6105x_remove,
--
2.9.3
^ permalink raw reply related
* [PATCH v3 5/7] mfd: Add Device Tree bindings document for TI tps6105x chip
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Lee Jones,
Javier Martinez Canillas, Mark Rutland
In-Reply-To: <20170401071854.23198-1-javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
There are Device Tree source files defining a device node for the
tps61050/61052 I2C chip but there isn't a binding document for it.
Signed-off-by: Javier Martinez Canillas <javier-JPH+aEBZ4P+UEJcrhfAQsw@public.gmane.org>
---
Changes in v3: None
Changes in v2: None
Documentation/devicetree/bindings/mfd/tps6105x.txt | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/tps6105x.txt
diff --git a/Documentation/devicetree/bindings/mfd/tps6105x.txt b/Documentation/devicetree/bindings/mfd/tps6105x.txt
new file mode 100644
index 000000000000..c076f28575fc
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/tps6105x.txt
@@ -0,0 +1,17 @@
+* Device tree bindings for TI TPS61050/61052 Boost Converters
+
+The TP61050/TPS61052 is a high-power "white LED driver". This boost converter
+is also used for other things than white LEDs, and also contains a GPIO pin.
+
+Required properties:
+- compatible: "ti,tps61050" or "ti,tps61052"
+- reg: Specifies the I2C slave address
+
+Example:
+
+i2c0 {
+ tps61052@33 {
+ compatible = "ti,tps61052";
+ reg = <0x33>;
+ };
+};
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 4/7] ARM: dts: n8x0: Add vendor prefix to retu node
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel
Cc: Mark Rutland, devicetree, Tony Lindgren, Russell King,
Javier Martinez Canillas, Rob Herring, Benoît Cousson,
linux-omap, Lee Jones, linux-arm-kernel
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
The retu-mfd device node doesn't have a vendor prefix
in its compatible string, fix it by adding one.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
index 7e5ffc583c90..a633a55820bb 100644
--- a/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
+++ b/arch/arm/boot/dts/omap2420-n8x0-common.dtsi
@@ -16,7 +16,7 @@
#address-cells = <1>;
#size-cells = <0>;
retu_mfd: retu@1 {
- compatible = "retu-mfd";
+ compatible = "nokia,retu-mfd";
interrupt-parent = <&gpio4>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
reg = <0x1>;
--
2.9.3
^ permalink raw reply related
* [PATCH v3 3/7] i2c: i2c-cbus-gpio: Add vendor prefix to retu node in example
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel
Cc: devicetree, Rob Herring, Lee Jones, Javier Martinez Canillas,
Wolfram Sang, linux-i2c, Mark Rutland
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
The example contains a device node for a retu-mfd device,
but its compatible string doesn't have a vendor prefix.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt
index 8ce9cd2855b5..32bcb1943f00 100644
--- a/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt
+++ b/Documentation/devicetree/bindings/i2c/i2c-cbus-gpio.txt
@@ -21,7 +21,7 @@ i2c@0 {
#size-cells = <0>;
retu-mfd: retu@1 {
- compatible = "retu-mfd";
+ compatible = "nokia,retu-mfd";
reg = <0x1>;
};
};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 2/7] mfd: retu: Add OF device ID table
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel; +Cc: devicetree, Rob Herring, Lee Jones, Javier Martinez Canillas
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
The driver doesn't have a struct of_device_id table but supported devices
are registered via Device Trees. This is working on the assumption that a
I2C device registered via OF will always match a legacy I2C device ID and
that the MODALIAS reported will always be of the form i2c:<device>.
But this could change in the future so the correct approach is to have a
OF device ID table if the devices are registered via OF.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3:
- Add a vendor prefix to the compatible string (Rob Herring).
Changes in v2:
- Don't use of_match_ptr() to avoid build warning when CONFIG_OF is disabled.
drivers/mfd/retu-mfd.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/mfd/retu-mfd.c b/drivers/mfd/retu-mfd.c
index d4c114abeb75..937a1c21eec4 100644
--- a/drivers/mfd/retu-mfd.c
+++ b/drivers/mfd/retu-mfd.c
@@ -308,9 +308,17 @@ static const struct i2c_device_id retu_id[] = {
};
MODULE_DEVICE_TABLE(i2c, retu_id);
+static const struct of_device_id retu_of_match[] = {
+ { .compatible = "nokia,retu-mfd" },
+ { .compatible = "nokia,tahvo-mfd" },
+ { }
+};
+MODULE_DEVICE_TABLE(of, retu_of_match);
+
static struct i2c_driver retu_driver = {
.driver = {
.name = "retu-mfd",
+ .of_match_table = retu_of_match,
},
.probe = retu_probe,
.remove = retu_remove,
--
2.9.3
^ permalink raw reply related
* [PATCH v3 1/7] mfd: Add Device Tree bindings document for retu/tahvo ASIC chips
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel
Cc: devicetree, Rob Herring, Lee Jones, Javier Martinez Canillas,
Mark Rutland
In-Reply-To: <20170401071854.23198-1-javier@osg.samsung.com>
There are Device Tree source files defining a device node for the
retu/tahvo I2C chip, but there isn't a DT binding document for it.
Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>
---
Changes in v3: None
Changes in v2: None
Documentation/devicetree/bindings/mfd/retu.txt | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/retu.txt
diff --git a/Documentation/devicetree/bindings/mfd/retu.txt b/Documentation/devicetree/bindings/mfd/retu.txt
new file mode 100644
index 000000000000..2309e599a731
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/retu.txt
@@ -0,0 +1,19 @@
+* Device tree bindings for Nokia Retu and Tahvo multi-function device
+
+Retu and Tahvo are a multi-function devices found on Nokia Internet
+Tablets (770, N800 and N810).
+
+Required properties:
+- compatible: "nokia,retu-mfd" or "nokia,tahvo-mfd"
+- reg: Specifies the I2C slave address of the ASIC chip
+
+Example:
+
+i2c0 {
+ retu_mfd: retu@1 {
+ compatible = "nokia,retu-mfd";
+ interrupt-parent = <&gpio4>;
+ interrupts = <12 IRQ_TYPE_EDGE_RISING>;
+ reg = <0x1>;
+ };
+};
--
2.9.3
^ permalink raw reply related
* [PATCH v3 0/7] mfd: Add OF device table to I2C drivers that are missing it
From: Javier Martinez Canillas @ 2017-04-01 7:18 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA, Rob Herring, Lee Jones,
Javier Martinez Canillas, Benoît Cousson, Wolfram Sang,
linux-i2c-u79uwXL29TY76Z2rM5mHXA, Mark Rutland,
linux-omap-u79uwXL29TY76Z2rM5mHXA, Russell King,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r, Tony Lindgren
Hello,
This series add OF device ID tables to mfd I2C drivers whose devices are
either used in Device Tree source files or are listed in binding docs as
a compatible string.
That's done because the plan is to change the I2C core to report proper OF
modaliases instead of always reporting a MODALIAS=i2c:<foo> regardless if
a device was registered via DT or using the legacy platform data mechanism.
So these patches will make sure that mfd I2C drivers modules will continue
to be autoloaded once the I2C core is changed to report proper OF modalias.
Users didn't have a vendor prefix in the used compatible strings, but since
there wasn't a DT binding document for these drivers, it can be said that
were working for mere luck and so this series fixes the users and add a DT
binding doc for the drivers.
It's safe to apply the patches independently.
Best regards,
Javier
Changes in v3:
- Add a vendor prefix to the compatible string (Rob Herring).
- Add a vendor prefix to the compatible string (Rob Herring).
Changes in v2:
- Don't use of_match_ptr() to avoid build warning when CONFIG_OF is disabled.
- Don't use of_match_ptr() to avoid build warning when CONFIG_OF is disabled.
Javier Martinez Canillas (7):
mfd: Add Device Tree bindings document for retu/tahvo ASIC chips
mfd: retu: Add OF device ID table
i2c: i2c-cbus-gpio: Add vendor prefix to retu node in example
ARM: dts: n8x0: Add vendor prefix to retu node
mfd: Add Device Tree bindings document for TI tps6105x chip
mfd: tps6105x: Add OF device ID table
ARM: ux500: Add vendor prefix to tps61052 node
.../devicetree/bindings/i2c/i2c-cbus-gpio.txt | 2 +-
Documentation/devicetree/bindings/mfd/retu.txt | 19 +++++++++++++++++++
Documentation/devicetree/bindings/mfd/tps6105x.txt | 17 +++++++++++++++++
arch/arm/boot/dts/omap2420-n8x0-common.dtsi | 2 +-
arch/arm/boot/dts/ste-hrefprev60.dtsi | 2 +-
drivers/mfd/retu-mfd.c | 8 ++++++++
drivers/mfd/tps6105x.c | 8 ++++++++
7 files changed, 55 insertions(+), 3 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mfd/retu.txt
create mode 100644 Documentation/devicetree/bindings/mfd/tps6105x.txt
--
2.9.3
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method
From: kbuild test robot @ 2017-04-01 6:31 UTC (permalink / raw)
Cc: kbuild-all, catalin.marinas, will.deacon, robh+dt, frowand.list,
bhelgaas, rafael, arnd, linux-arm-kernel, mark.rutland,
brian.starkey, olof, lorenzo.pieralisi, benh, linux-kernel,
linux-acpi, linuxarm, devicetree, linux-pci, minyard, zourongrong,
john.garry, gabriele.paoloni, zhichang.yuan02, kantyzc, xuwei5,
zhichang.yuan
In-Reply-To: <1490887619-61732-2-git-send-email-yuanzhichang@hisilicon.com>
[-- Attachment #1: Type: text/plain, Size: 29623 bytes --]
Hi zhichang.yuan,
[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc4 next-20170331]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
config: m68k-m5475evb_defconfig (attached as .config)
compiler: m68k-linux-gcc (GCC) 4.9.0
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=m68k
All error/warnings (new ones prefixed by >>):
lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
^
lib/logic_pio.c:52:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
[PIO_CPU_MMIO] = {
^
lib/logic_pio.c:52:2: error: array index in initializer not of integer type
[PIO_CPU_MMIO] = {
^
lib/logic_pio.c:52:2: error: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:53:3: error: field name not in record or union initializer
.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
^
lib/logic_pio.c:53:3: error: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:54:3: error: field name not in record or union initializer
.sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
^
lib/logic_pio.c:54:3: error: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:54:3: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
lib/logic_pio.c:55:3: error: field name not in record or union initializer
.sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
^
lib/logic_pio.c:55:3: error: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:55:3: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
In file included from include/linux/list.h:8:0,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/kernel.h:852:48: warning: initialization from incompatible pointer type
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
include/linux/kernel.h:853:3: note: in definition of macro 'container_of'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
In file included from include/linux/compiler.h:62:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/of.h:18,
from lib/logic_pio.c:18:
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
include/linux/compiler-gcc.h:161:21: note: in definition of macro '__compiler_offsetof'
__builtin_offsetof(a, b)
^
include/linux/kernel.h:853:29: note: in expansion of macro 'offsetof'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
In file included from include/linux/pid.h:4:0,
from include/linux/sched.h:13,
from arch/m68k/include/asm/pgtable_mm.h:10,
from arch/m68k/include/asm/pgtable.h:4,
from include/linux/mm.h:68,
from lib/logic_pio.c:20:
include/linux/rculist.h:352:7: error: dereferencing pointer to incomplete type
&pos->member != (head); \
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
In file included from include/linux/list.h:8:0,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
include/linux/rculist.h:353:49: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:27: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
include/linux/rculist.h:353:49: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/kernel.h:853:3: note: in definition of macro 'container_of'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
In file included from include/linux/compiler.h:62:0,
from include/uapi/linux/stddef.h:1,
from include/linux/stddef.h:4,
from include/uapi/linux/posix_types.h:4,
from include/uapi/linux/types.h:13,
from include/linux/types.h:5,
from include/linux/of.h:18,
from lib/logic_pio.c:18:
include/linux/rculist.h:353:49: error: dereferencing pointer to incomplete type
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
include/linux/compiler-gcc.h:161:21: note: in definition of macro '__compiler_offsetof'
__builtin_offsetof(a, b)
^
include/linux/kernel.h:853:29: note: in expansion of macro 'offsetof'
(type *)( (char *)__mptr - offsetof(type,member) );})
^
include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^
lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^
>> lib/logic_pio.c:78:13: error: dereferencing pointer to incomplete type
if (!range->pio_peer) {
^
In file included from include/linux/kernel.h:13:0,
from include/linux/list.h:8,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
lib/logic_pio.c:80:11: error: dereferencing pointer to incomplete type
&range->hw_start);
^
include/linux/printk.h:303:37: note: in definition of macro 'pr_warning'
printk(KERN_WARNING pr_fmt(fmt), ##__VA_ARGS__)
^
>> lib/logic_pio.c:79:4: note: in expansion of macro 'pr_warn'
pr_warn("Invalid cpu addr node(%pa) in list!\n",
^
lib/logic_pio.c:83:12: error: dereferencing pointer to incomplete type
if (range->fwnode != fwnode)
^
lib/logic_pio.c:86:21: error: dereferencing pointer to incomplete type
if (start >= range->hw_start + range->size ||
^
lib/logic_pio.c:86:39: error: dereferencing pointer to incomplete type
if (start >= range->hw_start + range->size ||
^
lib/logic_pio.c:87:15: error: dereferencing pointer to incomplete type
end < range->hw_start)
^
lib/logic_pio.c:90:20: error: dereferencing pointer to incomplete type
if (start < range->hw_start ||
^
lib/logic_pio.c:91:16: error: dereferencing pointer to incomplete type
end >= range->hw_start + range->size)
^
lib/logic_pio.c:91:34: error: dereferencing pointer to incomplete type
end >= range->hw_start + range->size)
^
lib/logic_pio.c: In function 'logic_pio_alloc_range':
lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type
idle_start = root->sec_min;
^
lib/logic_pio.c:110:15: error: dereferencing pointer to incomplete type
*prev = &root->sec_head;
^
In file included from include/linux/list.h:8:0,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(entry, &root->sec_head, list) {
^
lib/logic_pio.c:111:38: error: dereferencing pointer to incomplete type
list_for_each_entry_rcu(entry, &root->sec_head, list) {
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/linux/rculist.h:277:15: note: in expansion of macro 'lockless_dereference'
container_of(lockless_dereference(ptr), type, member)
^
include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^
lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(entry, &root->sec_head, list) {
^
lib/logic_pio.c:111:38: error: dereferencing pointer to incomplete type
list_for_each_entry_rcu(entry, &root->sec_head, list) {
^
include/linux/kernel.h:852:49: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
include/linux/compiler.h:323:22: note: in expansion of macro '__READ_ONCE'
#define READ_ONCE(x) __READ_ONCE(x, 1)
^
>> include/linux/compiler.h:574:26: note: in expansion of macro 'READ_ONCE'
typeof(p) _________p1 = READ_ONCE(p); \
^
vim +351 include/linux/rculist.h
3943f42c Andrey Utkin 2014-11-14 271 * @member: the name of the list_head within the struct.
72c6a987 Jiri Pirko 2009-04-14 272 *
72c6a987 Jiri Pirko 2009-04-14 273 * This primitive may safely run concurrently with the _rcu list-mutation
72c6a987 Jiri Pirko 2009-04-14 274 * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
72c6a987 Jiri Pirko 2009-04-14 275 */
72c6a987 Jiri Pirko 2009-04-14 276 #define list_entry_rcu(ptr, type, member) \
8db70b13 Patrick Marlier 2015-09-11 @277 container_of(lockless_dereference(ptr), type, member)
72c6a987 Jiri Pirko 2009-04-14 278
72c6a987 Jiri Pirko 2009-04-14 279 /**
f88022a4 Michel Machado 2012-04-10 280 * Where are list_empty_rcu() and list_first_entry_rcu()?
f88022a4 Michel Machado 2012-04-10 281 *
f88022a4 Michel Machado 2012-04-10 282 * Implementing those functions following their counterparts list_empty() and
f88022a4 Michel Machado 2012-04-10 283 * list_first_entry() is not advisable because they lead to subtle race
f88022a4 Michel Machado 2012-04-10 284 * conditions as the following snippet shows:
f88022a4 Michel Machado 2012-04-10 285 *
f88022a4 Michel Machado 2012-04-10 286 * if (!list_empty_rcu(mylist)) {
f88022a4 Michel Machado 2012-04-10 287 * struct foo *bar = list_first_entry_rcu(mylist, struct foo, list_member);
f88022a4 Michel Machado 2012-04-10 288 * do_something(bar);
f88022a4 Michel Machado 2012-04-10 289 * }
f88022a4 Michel Machado 2012-04-10 290 *
f88022a4 Michel Machado 2012-04-10 291 * The list may not be empty when list_empty_rcu checks it, but it may be when
f88022a4 Michel Machado 2012-04-10 292 * list_first_entry_rcu rereads the ->next pointer.
f88022a4 Michel Machado 2012-04-10 293 *
f88022a4 Michel Machado 2012-04-10 294 * Rereading the ->next pointer is not a problem for list_empty() and
f88022a4 Michel Machado 2012-04-10 295 * list_first_entry() because they would be protected by a lock that blocks
f88022a4 Michel Machado 2012-04-10 296 * writers.
f88022a4 Michel Machado 2012-04-10 297 *
f88022a4 Michel Machado 2012-04-10 298 * See list_first_or_null_rcu for an alternative.
f88022a4 Michel Machado 2012-04-10 299 */
f88022a4 Michel Machado 2012-04-10 300
f88022a4 Michel Machado 2012-04-10 301 /**
f88022a4 Michel Machado 2012-04-10 302 * list_first_or_null_rcu - get the first element from a list
72c6a987 Jiri Pirko 2009-04-14 303 * @ptr: the list head to take the element from.
72c6a987 Jiri Pirko 2009-04-14 304 * @type: the type of the struct this is embedded in.
3943f42c Andrey Utkin 2014-11-14 305 * @member: the name of the list_head within the struct.
72c6a987 Jiri Pirko 2009-04-14 306 *
f88022a4 Michel Machado 2012-04-10 307 * Note that if the list is empty, it returns NULL.
72c6a987 Jiri Pirko 2009-04-14 308 *
72c6a987 Jiri Pirko 2009-04-14 309 * This primitive may safely run concurrently with the _rcu list-mutation
72c6a987 Jiri Pirko 2009-04-14 310 * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
72c6a987 Jiri Pirko 2009-04-14 311 */
f88022a4 Michel Machado 2012-04-10 312 #define list_first_or_null_rcu(ptr, type, member) \
0adab9b9 Joe Perches 2013-12-05 313 ({ \
0adab9b9 Joe Perches 2013-12-05 314 struct list_head *__ptr = (ptr); \
7d0ae808 Paul E. McKenney 2015-03-03 315 struct list_head *__next = READ_ONCE(__ptr->next); \
0adab9b9 Joe Perches 2013-12-05 316 likely(__ptr != __next) ? list_entry_rcu(__next, type, member) : NULL; \
f88022a4 Michel Machado 2012-04-10 317 })
72c6a987 Jiri Pirko 2009-04-14 318
82524746 Franck Bui-Huu 2008-05-12 319 /**
ff3c44e6 Tom Herbert 2016-03-07 320 * list_next_or_null_rcu - get the first element from a list
ff3c44e6 Tom Herbert 2016-03-07 321 * @head: the head for the list.
ff3c44e6 Tom Herbert 2016-03-07 322 * @ptr: the list head to take the next element from.
ff3c44e6 Tom Herbert 2016-03-07 323 * @type: the type of the struct this is embedded in.
ff3c44e6 Tom Herbert 2016-03-07 324 * @member: the name of the list_head within the struct.
ff3c44e6 Tom Herbert 2016-03-07 325 *
ff3c44e6 Tom Herbert 2016-03-07 326 * Note that if the ptr is at the end of the list, NULL is returned.
ff3c44e6 Tom Herbert 2016-03-07 327 *
ff3c44e6 Tom Herbert 2016-03-07 328 * This primitive may safely run concurrently with the _rcu list-mutation
ff3c44e6 Tom Herbert 2016-03-07 329 * primitives such as list_add_rcu() as long as it's guarded by rcu_read_lock().
ff3c44e6 Tom Herbert 2016-03-07 330 */
ff3c44e6 Tom Herbert 2016-03-07 331 #define list_next_or_null_rcu(head, ptr, type, member) \
ff3c44e6 Tom Herbert 2016-03-07 332 ({ \
ff3c44e6 Tom Herbert 2016-03-07 333 struct list_head *__head = (head); \
ff3c44e6 Tom Herbert 2016-03-07 334 struct list_head *__ptr = (ptr); \
ff3c44e6 Tom Herbert 2016-03-07 335 struct list_head *__next = READ_ONCE(__ptr->next); \
ff3c44e6 Tom Herbert 2016-03-07 336 likely(__next != __head) ? list_entry_rcu(__next, type, \
ff3c44e6 Tom Herbert 2016-03-07 337 member) : NULL; \
ff3c44e6 Tom Herbert 2016-03-07 338 })
ff3c44e6 Tom Herbert 2016-03-07 339
ff3c44e6 Tom Herbert 2016-03-07 340 /**
82524746 Franck Bui-Huu 2008-05-12 341 * list_for_each_entry_rcu - iterate over rcu list of given type
82524746 Franck Bui-Huu 2008-05-12 342 * @pos: the type * to use as a loop cursor.
82524746 Franck Bui-Huu 2008-05-12 343 * @head: the head for your list.
3943f42c Andrey Utkin 2014-11-14 344 * @member: the name of the list_head within the struct.
82524746 Franck Bui-Huu 2008-05-12 345 *
82524746 Franck Bui-Huu 2008-05-12 346 * This list-traversal primitive may safely run concurrently with
82524746 Franck Bui-Huu 2008-05-12 347 * the _rcu list-mutation primitives such as list_add_rcu()
82524746 Franck Bui-Huu 2008-05-12 348 * as long as the traversal is guarded by rcu_read_lock().
82524746 Franck Bui-Huu 2008-05-12 349 */
82524746 Franck Bui-Huu 2008-05-12 350 #define list_for_each_entry_rcu(pos, head, member) \
72c6a987 Jiri Pirko 2009-04-14 @351 for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
e66eed65 Linus Torvalds 2011-05-19 352 &pos->member != (head); \
72c6a987 Jiri Pirko 2009-04-14 @353 pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
82524746 Franck Bui-Huu 2008-05-12 354
82524746 Franck Bui-Huu 2008-05-12 355 /**
69b90729 Alexey Kardashevskiy 2015-12-05 356 * list_entry_lockless - get the struct for this entry
:::::: The code at line 351 was first introduced by commit
:::::: 72c6a9870f901045f2464c3dc6ee8914bfdc07aa rculist.h: introduce list_entry_rcu() and list_first_entry_rcu()
:::::: TO: Jiri Pirko <jpirko@redhat.com>
:::::: CC: Ingo Molnar <mingo@elte.hu>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 6383 bytes --]
^ permalink raw reply
* Re: [PATCH V8 1/6] LIBIO: Introduce a generic PIO mapping method
From: kbuild test robot @ 2017-04-01 5:58 UTC (permalink / raw)
Cc: kbuild-all, catalin.marinas, will.deacon, robh+dt, frowand.list,
bhelgaas, rafael, arnd, linux-arm-kernel, mark.rutland,
brian.starkey, olof, lorenzo.pieralisi, benh, linux-kernel,
linux-acpi, linuxarm, devicetree, linux-pci, minyard, zourongrong,
john.garry, gabriele.paoloni, zhichang.yuan02, kantyzc, xuwei5,
zhichang.yuan
In-Reply-To: <1490887619-61732-2-git-send-email-yuanzhichang@hisilicon.com>
[-- Attachment #1: Type: text/plain, Size: 14599 bytes --]
Hi zhichang.yuan,
[auto build test ERROR on linus/master]
[also build test ERROR on v4.11-rc4 next-20170331]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/zhichang-yuan/LIBIO-Introduce-a-generic-PIO-mapping-method/20170401-104801
config: alpha-allyesconfig (attached as .config)
compiler: alpha-linux-gnu-gcc (Debian 6.1.1-9) 6.1.1 20160705
reproduce:
wget https://raw.githubusercontent.com/01org/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=alpha
All error/warnings (new ones prefixed by >>):
>> lib/logic_pio.c:32:50: error: 'PIO_MAX_SECT' undeclared here (not in a function)
static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
^~~~~~~~~~~~
>> lib/logic_pio.c:39:3: error: 'PIO_CPU_MMIO' undeclared here (not in a function)
[PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
^~~~~~~~~~~~
>> lib/logic_pio.c:39:20: error: 'PIO_INDIRECT' undeclared here (not in a function)
[PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
^~~~~~~~~~~~
>> lib/logic_pio.c:39:3: error: array index in initializer not of integer type
[PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
^~~~~~~~~~~~
lib/logic_pio.c:39:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:40:3: error: field name not in record or union initializer
.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
^
lib/logic_pio.c:40:3: note: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:41:3: error: field name not in record or union initializer
.sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
^
lib/logic_pio.c:41:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:41:14: error: implicit declaration of function 'PIO_SECT_MIN' [-Werror=implicit-function-declaration]
.sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
^~~~~~~~~~~~
lib/logic_pio.c:42:3: error: field name not in record or union initializer
.sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
^
lib/logic_pio.c:42:3: note: (near initialization for 'logic_pio_root_list')
>> lib/logic_pio.c:42:14: error: implicit declaration of function 'PIO_SECT_MAX' [-Werror=implicit-function-declaration]
.sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
^~~~~~~~~~~~
lib/logic_pio.c:46:3: error: array index in initializer not of integer type
[PIO_INDIRECT] = {
^~~~~~~~~~~~
lib/logic_pio.c:46:3: note: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:47:3: error: field name not in record or union initializer
.sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
^
lib/logic_pio.c:47:3: note: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:48:3: error: field name not in record or union initializer
.sec_min = PIO_SECT_MIN(PIO_INDIRECT),
^
lib/logic_pio.c:48:3: note: (near initialization for 'logic_pio_root_list')
lib/logic_pio.c:49:3: error: field name not in record or union initializer
.sec_max = PIO_SECT_MAX(PIO_INDIRECT),
^
lib/logic_pio.c:49:3: note: (near initialization for 'logic_pio_root_list')
In file included from include/linux/list.h:8:0,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
lib/logic_pio.c: In function 'logic_pio_find_range_byaddr':
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_hwaddr'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^~~~~~~~~~~~~~~~~~~~~~~
include/linux/kernel.h:852:48: error: initialization from incompatible pointer type [-Werror=incompatible-pointer-types]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^~~~~~~~~~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
>> include/linux/rculist.h:277:2: note: in expansion of macro 'container_of'
container_of(lockless_dereference(ptr), type, member)
^~~~~~~~~~~~
include/linux/rculist.h:353:9: note: in expansion of macro 'list_entry_rcu'
pos = list_entry_rcu(pos->member.next, typeof(*pos), member))
^~~~~~~~~~~~~~
>> lib/logic_pio.c:77:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(range, &io_range_list, list) {
^~~~~~~~~~~~~~~~~~~~~~~
lib/logic_pio.c: In function 'logic_pio_alloc_range':
>> lib/logic_pio.c:109:19: error: dereferencing pointer to incomplete type 'struct logic_pio_root'
idle_start = root->sec_min;
^~
In file included from include/linux/list.h:8:0,
from include/linux/kobject.h:20,
from include/linux/of.h:21,
from lib/logic_pio.c:18:
>> include/linux/rculist.h:351:49: error: dereferencing pointer to incomplete type 'struct logic_pio_sect'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
include/linux/kernel.h:852:18: note: in definition of macro 'container_of'
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^~~~
>> include/linux/rculist.h:351:13: note: in expansion of macro 'list_entry_rcu'
for (pos = list_entry_rcu((head)->next, typeof(*pos), member); \
^~~~~~~~~~~~~~
lib/logic_pio.c:111:2: note: in expansion of macro 'list_for_each_entry_rcu'
list_for_each_entry_rcu(entry, &root->sec_head, list) {
^~~~~~~~~~~~~~~~~~~~~~~
>> include/linux/kernel.h:852:48: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
^
vim +/PIO_MAX_SECT +32 lib/logic_pio.c
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
> 18 #include <linux/of.h>
19 #include <linux/io.h>
20 #include <linux/mm.h>
21 #include <linux/rculist.h>
22 #include <linux/sizes.h>
23 #include <linux/slab.h>
24
25 /* The unique hardware address list. */
26 static LIST_HEAD(io_range_list);
27 static DEFINE_MUTEX(io_range_mutex);
28
29 /*
30 * These are the lists for PIO. The highest PIO_SECT_BITS of PIO is the index.
31 */
> 32 static struct logic_pio_root logic_pio_root_list[PIO_MAX_SECT] = {
33 #ifdef CONFIG_INDIRECT_PIO
34 /*
35 * At this moment, assign all the other logic PIO space to MMIO.
36 * If more elements added, please adjust the ending index and .sec_max;
37 * Please keep MMIO element started from index ZERO.
38 */
> 39 [PIO_CPU_MMIO ... PIO_INDIRECT - 1] = {
> 40 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
> 41 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
> 42 .sec_max = PIO_SECT_MAX(PIO_INDIRECT - 1),
43 },
44
45 /* The last element */
46 [PIO_INDIRECT] = {
47 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_INDIRECT].sec_head),
48 .sec_min = PIO_SECT_MIN(PIO_INDIRECT),
49 .sec_max = PIO_SECT_MAX(PIO_INDIRECT),
50 },
51 #else
52 [PIO_CPU_MMIO] = {
53 .sec_head = LIST_HEAD_INIT(logic_pio_root_list[PIO_CPU_MMIO].sec_head),
54 .sec_min = PIO_SECT_MIN(PIO_CPU_MMIO),
55 .sec_max = PIO_SECT_MAX(PIO_CPU_MMIO),
56 },
57
58 #endif
59 };
60
61 /*
62 * Search a io_range registered which match the fwnode and addr.
63 *
64 * @fwnode: the host fwnode which must be valid;
65 * @start: the start hardware address of this search;
66 * @end: the end hardware address of this search. can be equal to @start;
67 *
68 * return NULL when there is no matched node; IS_ERR() means ERROR;
69 * valid virtual address represent a matched node was found.
70 */
71 static struct logic_pio_hwaddr *
72 logic_pio_find_range_byaddr(struct fwnode_handle *fwnode,
73 resource_size_t start, resource_size_t end)
74 {
75 struct logic_pio_hwaddr *range;
76
> 77 list_for_each_entry_rcu(range, &io_range_list, list) {
78 if (!range->pio_peer) {
79 pr_warn("Invalid cpu addr node(%pa) in list!\n",
80 &range->hw_start);
81 continue;
82 }
83 if (range->fwnode != fwnode)
84 continue;
85 /* without any overlap with current range */
86 if (start >= range->hw_start + range->size ||
87 end < range->hw_start)
88 continue;
89 /* overlap is not supported now. */
90 if (start < range->hw_start ||
91 end >= range->hw_start + range->size)
92 return ERR_PTR(-EBUSY);
93 /* had been registered. */
94 return range;
95 }
96
97 return NULL;
98 }
99
100
101 static int logic_pio_alloc_range(struct logic_pio_root *root,
102 resource_size_t size, unsigned long align,
103 struct list_head **prev, resource_size_t *pio_alloc)
104 {
105 struct logic_pio_sect *entry;
106 resource_size_t tmp_start;
107 resource_size_t idle_start, idle_end;
108
> 109 idle_start = root->sec_min;
110 *prev = &root->sec_head;
111 list_for_each_entry_rcu(entry, &root->sec_head, list) {
112 if (!entry->hwpeer ||
113 idle_start > entry->io_start) {
114 WARN(1, "skip an invalid io range during traversal!\n");
115 goto nextentry;
116 }
117 /* set the end edge. */
118 if (idle_start == entry->io_start) {
119 struct logic_pio_sect *next;
120
121 idle_start = entry->io_start + entry->hwpeer->size;
> 122 next = list_next_or_null_rcu(&root->sec_head,
> 123 &entry->list, struct logic_pio_sect, list);
124 if (next) {
125 entry = next;
126 } else {
127 *prev = &entry->list;
128 break;
129 }
130 }
131 idle_end = entry->io_start - 1;
132
133 /* contiguous range... */
134 if (idle_start > idle_end)
135 goto nextentry;
136
137 tmp_start = idle_start;
138 idle_start = ALIGN(idle_start, align);
139 if (idle_start >= tmp_start &&
140 idle_start + size <= idle_end) {
141 *prev = &entry->list;
142 *pio_alloc = idle_start;
143 return 0;
144 }
145
146 nextentry:
147 idle_start = entry->io_start + entry->hwpeer->size;
148 *prev = &entry->list;
149 }
150 /* check the last free gap... */
151 idle_end = root->sec_max;
152
153 tmp_start = idle_start;
154 idle_start = ALIGN(idle_start, align);
155 if (idle_start >= tmp_start &&
156 idle_start + size <= idle_end) {
157 *pio_alloc = idle_start;
158 return 0;
159 }
160
161 return -EBUSY;
162 }
163
164 /*
165 * register a io range node in the io range list.
166 *
167 * @newrange: pointer to the io range to be registered.
168 *
169 * return 'newrange' when success, ERR_VALUE() is for failures.
170 * specially, return a valid pointer which is not equal to 'newrange' when
171 * the io range had been registered before.
172 */
173 struct logic_pio_hwaddr
174 *logic_pio_register_range(struct logic_pio_hwaddr *newrange,
175 unsigned long align)
176 {
177 struct logic_pio_hwaddr *range;
178 struct logic_pio_sect *newsect;
179 resource_size_t pio_alloc;
180 struct list_head *prev, *hwprev;
181 unsigned long sect_id;
182 int err;
183
184 if (!newrange || !newrange->fwnode || !newrange->size)
185 return ERR_PTR(-EINVAL);
186
187 sect_id = newrange->flags;
188 if (sect_id >= PIO_MAX_SECT)
189 return ERR_PTR(-EINVAL);
190
191 mutex_lock(&io_range_mutex);
192 range = logic_pio_find_range_byaddr(newrange->fwnode,
193 newrange->hw_start,
194 newrange->hw_start + newrange->size - 1);
195 if (range) {
196 if (!IS_ERR(range))
197 pr_info("the request IO range had been registered!\n");
198 else
199 pr_err("registering IO[%pa - sz%pa) got failed!\n",
200 &newrange->hw_start, &newrange->size);
201 mutex_unlock(&io_range_mutex);
202 return range;
203 }
204
205 err = logic_pio_alloc_range(&logic_pio_root_list[sect_id],
206 newrange->size, align, &prev, &pio_alloc);
207 if (err) {
208 pr_err("can't find free %pa logical IO range!\n",
209 &newrange->size);
210 goto exitproc;
211 }
212
213 if (prev == &logic_pio_root_list[sect_id].sec_head) {
214 hwprev = &io_range_list;
215 } else {
> 216 newsect = to_pio_sect(prev);
> 217 hwprev = &newsect->hwpeer->list;
218 }
219
220 newsect = kzalloc(sizeof(*newsect), GFP_KERNEL);
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 49584 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: imx7: add USDHC NAND clock to SDHC instances
From: Stefan Agner @ 2017-04-01 4:15 UTC (permalink / raw)
To: Dong Aisheng
Cc: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ, aisheng.dong-3arQi8VN3Tc,
fabio.estevam-3arQi8VN3Tc, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170401030312.GB24882@b29396-OptiPlex-7040>
On 2017-03-31 20:03, Dong Aisheng wrote:
> On Wed, Mar 29, 2017 at 05:50:29PM -0700, Stefan Agner wrote:
>> The USDHC instances need the USDHC NAND clock in order to operate.
>> Add the clock as ahb bus clock.
>>
>> Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
>> ---
>> arch/arm/boot/dts/imx7s.dtsi | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
>> index 5d3a43b8de20..5794febb19a4 100644
>> --- a/arch/arm/boot/dts/imx7s.dtsi
>> +++ b/arch/arm/boot/dts/imx7s.dtsi
>> @@ -936,7 +936,7 @@
>> reg = <0x30b40000 0x10000>;
>> interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
>> clocks = <&clks IMX7D_CLK_DUMMY>,
>
> Would you please change the left ipg dummy to IMX7D_IPG_ROOT_CLK as well?
IMX7D_IPG_ROOT_CLK is currently not a valid clock in upstream... So we
would have to add it to the clock driver first.
I guess we could/should add it anyway at one point? But probably also as
init on, just to make sure Linux does not disable it since it is
currently used by several IPs implicitly.
--
Stefan
>
> Otherwise,
>
> Acked-by: Dong Aisheng <aisheng.dong-3arQi8VN3Tc@public.gmane.org>
>
> Regards
> Dong Aisheng
>
>> - <&clks IMX7D_CLK_DUMMY>,
>> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>> <&clks IMX7D_USDHC1_ROOT_CLK>;
>> clock-names = "ipg", "ahb", "per";
>> bus-width = <4>;
>> @@ -948,7 +948,7 @@
>> reg = <0x30b50000 0x10000>;
>> interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
>> clocks = <&clks IMX7D_CLK_DUMMY>,
>> - <&clks IMX7D_CLK_DUMMY>,
>> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>> <&clks IMX7D_USDHC2_ROOT_CLK>;
>> clock-names = "ipg", "ahb", "per";
>> bus-width = <4>;
>> @@ -960,7 +960,7 @@
>> reg = <0x30b60000 0x10000>;
>> interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
>> clocks = <&clks IMX7D_CLK_DUMMY>,
>> - <&clks IMX7D_CLK_DUMMY>,
>> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
>> <&clks IMX7D_USDHC3_ROOT_CLK>;
>> clock-names = "ipg", "ahb", "per";
>> bus-width = <4>;
>> --
>> 2.12.1
>>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/2] ARM: dts: imx7: add USDHC NAND clock to SDHC instances
From: Dong Aisheng @ 2017-04-01 3:03 UTC (permalink / raw)
To: Stefan Agner
Cc: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ, aisheng.dong-3arQi8VN3Tc,
fabio.estevam-3arQi8VN3Tc, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170330005029.6472-2-stefan-XLVq0VzYD2Y@public.gmane.org>
On Wed, Mar 29, 2017 at 05:50:29PM -0700, Stefan Agner wrote:
> The USDHC instances need the USDHC NAND clock in order to operate.
> Add the clock as ahb bus clock.
>
> Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
> ---
> arch/arm/boot/dts/imx7s.dtsi | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
> index 5d3a43b8de20..5794febb19a4 100644
> --- a/arch/arm/boot/dts/imx7s.dtsi
> +++ b/arch/arm/boot/dts/imx7s.dtsi
> @@ -936,7 +936,7 @@
> reg = <0x30b40000 0x10000>;
> interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clks IMX7D_CLK_DUMMY>,
Would you please change the left ipg dummy to IMX7D_IPG_ROOT_CLK as well?
Otherwise,
Acked-by: Dong Aisheng <aisheng.dong-3arQi8VN3Tc@public.gmane.org>
Regards
Dong Aisheng
> - <&clks IMX7D_CLK_DUMMY>,
> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
> <&clks IMX7D_USDHC1_ROOT_CLK>;
> clock-names = "ipg", "ahb", "per";
> bus-width = <4>;
> @@ -948,7 +948,7 @@
> reg = <0x30b50000 0x10000>;
> interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clks IMX7D_CLK_DUMMY>,
> - <&clks IMX7D_CLK_DUMMY>,
> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
> <&clks IMX7D_USDHC2_ROOT_CLK>;
> clock-names = "ipg", "ahb", "per";
> bus-width = <4>;
> @@ -960,7 +960,7 @@
> reg = <0x30b60000 0x10000>;
> interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
> clocks = <&clks IMX7D_CLK_DUMMY>,
> - <&clks IMX7D_CLK_DUMMY>,
> + <&clks IMX7D_NAND_USDHC_BUS_ROOT_CLK>,
> <&clks IMX7D_USDHC3_ROOT_CLK>;
> clock-names = "ipg", "ahb", "per";
> bus-width = <4>;
> --
> 2.12.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] clk: imx7d: fix USDHC NAND clock
From: Dong Aisheng @ 2017-04-01 3:00 UTC (permalink / raw)
To: Stefan Agner
Cc: shawnguo-DgEjT+Ai2ygdnm+yROfE0A, kernel-bIcnvbaLZ9MEGnE8C9+IrQ,
sboyd-sgV2jX0FEOL9JmXXK+q4OQ, aisheng.dong-3arQi8VN3Tc,
fabio.estevam-3arQi8VN3Tc, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170330005029.6472-1-stefan-XLVq0VzYD2Y@public.gmane.org>
On Wed, Mar 29, 2017 at 05:50:28PM -0700, Stefan Agner wrote:
> The USDHC NAND root clock is not gated by any CCM clock gate. Remove
> the bogus gate definition.
>
> Signed-off-by: Stefan Agner <stefan-XLVq0VzYD2Y@public.gmane.org>
> ---
> The IMX7D_NAND_USDHC_BUS_ROOT_CLK clock is also in clks_init_on.
> In a quick test I removed IMX7D_NAND_USDHC_BUS_ROOT_CLK from
> clks_init_on, and the system including SD-cards seemed to work
> fine... So I guess we could remove the clock from clks_init_on
> after the two both changes got applied, any thoughts?
>
Yes, it can be removed after apply.
> The gate 0x4130 was actually the DRAM gate, hence disabling that
> clock lead to disabling this gate, and hence a crash before this
> fixes... Maybe that was the reason it landed in clks_init_on...?
>
Probably a history reason or mistake. :-)
Acked-by: Dong Aisheng <aisheng.dong-3arQi8VN3Tc@public.gmane.org>
Regards
Dong Aisheng
> --
> Stefan
>
> drivers/clk/imx/clk-imx7d.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/clk/imx/clk-imx7d.c b/drivers/clk/imx/clk-imx7d.c
> index ae1d31be906e..4466acaacb71 100644
> --- a/drivers/clk/imx/clk-imx7d.c
> +++ b/drivers/clk/imx/clk-imx7d.c
> @@ -724,7 +724,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
> clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
> clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
> clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
> - clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider2("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
> + clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_divider2("nand_usdhc_root_clk", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
> clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
> clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
> clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
> @@ -797,7 +797,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
> clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
> clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "axi_post_div", base + 0x4110, 0);
> clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
> - clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate4("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
> clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate4("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
> clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
> clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
> --
> 2.12.1
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V3 0/5] iommu/arm-smmu: Add runtime pm/sleep support
From: Rob Clark @ 2017-04-01 2:58 UTC (permalink / raw)
To: Will Deacon
Cc: Mark Rutland, devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Mathieu Poirier, linux-arm-msm, Stephen Boyd,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
Rob Herring, linux-clk-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
In-Reply-To: <20170331175457.GD4897-5wv7dgnIgG8@public.gmane.org>
On Fri, Mar 31, 2017 at 1:54 PM, Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org> wrote:
> On Thu, Mar 09, 2017 at 09:05:43PM +0530, Sricharan R wrote:
>> This series provides the support for turning on the arm-smmu's
>> clocks/power domains using runtime pm. This is done using the
>> recently introduced device links patches, which lets the symmu's
>> runtime to follow the master's runtime pm, so the smmu remains
>> powered only when the masters use it.
>
> Do you have any numbers for the power savings you achieve with this?
> How often do we actually manage to stop the SMMU clocks on an SoC with
> a handful of masters?
>
> In other words, is this too coarse-grained to be useful, or is it common
> that all the devices upstream of the SMMU are suspended?
well, if you think about a phone/tablet with a command mode panel,
pretty much all devices will be suspended most of the time ;-)
maybe it's a different case with servers.. unfortunately we have to
share the same driver across both..
BR,
-R
> Thanks,
>
> Will
>
>>
>> Took some reference from the exynos runtime patches [2].
>> Tested this with MDP, GPU, VENUS devices on apq8096-db820c board.
>>
>> Previous version of the patchset [1].
>>
>> [V3]
>> * Reworked the patches to keep the clocks init/enabling function
>> seperately for each compatible.
>>
>> * Added clocks bindings for MMU40x/500.
>>
>> * Added a new compatible for qcom,smmu-v2 implementation and
>> the clock bindings for the same.
>>
>> * Rebased on top of 4.11-rc1
>>
>> [V2]
>> * Split the patches little differently.
>>
>> * Addressed comments.
>>
>> * Removed the patch #4 [3] from previous post
>> for arm-smmu context save restore. Planning to
>> post this separately after reworking/addressing Robin's
>> feedback.
>>
>> * Reversed the sequence to disable clocks than enabling.
>> This was required for those cases where the
>> clocks are populated in a dependent order from DT.
>>
>> [1] https://www.spinics.net/lists/linux-arm-msm/msg23870.html
>> [2] https://lkml.org/lkml/2016/10/20/70
>> [3] https://patchwork.kernel.org/patch/9389717/
>>
>> Sricharan R (5):
>> iommu/arm-smmu: Add pm_runtime/sleep ops
>> iommu/arm-smmu: Add support for MMU40x/500 clocks
>> drivers: arm-smmu: Add clock support for QCOM_SMMUV2
>> iommu/arm-smmu: Invoke pm_runtime during probe, add/remove device
>> iommu/arm-smmu: Add the device_link between masters and smmu
>>
>> .../devicetree/bindings/iommu/arm,smmu.txt | 35 +++
>> drivers/iommu/arm-smmu.c | 349 ++++++++++++++++++++-
>> 2 files changed, 373 insertions(+), 11 deletions(-)
>>
>> --
>> QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
>>
> _______________________________________________
> iommu mailing list
> iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
> https://lists.linuxfoundation.org/mailman/listinfo/iommu
^ permalink raw reply
* Re: [PATCH V8 5/6] ACPI: Support the probing on the devices which apply indirect-IO
From: zhichang.yuan @ 2017-04-01 2:16 UTC (permalink / raw)
To: Rafael J. Wysocki, zhichang.yuan
Cc: Rafael J. Wysocki, Catalin Marinas, Will Deacon, Rob Herring,
Frank Rowand, Bjorn Helgaas, Arnd Bergmann,
linux-arm-kernel@lists.infradead.org, Mark Rutland, Brian Starkey,
Olof Johansson, Lorenzo Pieralisi, Benjamin Herrenschmidt,
Linux Kernel Mailing List, ACPI Devel Maling List, linuxarm,
devicetree@vger.kernel.org
In-Reply-To: <CAJZ5v0gZdghH7jjd-zMmqXNkuvVVVSPDHfBrJXx5OXR2NE0KgA@mail.gmail.com>
On 04/01/2017 07:02 AM, Rafael J. Wysocki wrote:
> On Fri, Mar 31, 2017 at 8:52 AM, zhichang.yuan
> <yuanzhichang@hisilicon.com> wrote:
>> Hi, Rafael,
>>
>> Thanks for reviewing this!
>>
>> On 2017/3/31 4:31, Rafael J. Wysocki wrote:
>>> On Thursday, March 30, 2017 11:26:58 PM zhichang.yuan wrote:
>>>> On some platforms(such as Hip06/Hip07), the legacy ISA/LPC devices access I/O
>>>> with some special host-local I/O ports known on x86. To access the I/O
>>>> peripherals, an indirect-IO mechanism is introduced to mapped the host-local
>>>> I/O to system logical/fake PIO similar the PCI MMIO on architectures where no
>>>> separate I/O space exists. Just as PCI MMIO, the host I/O range should be
>>>> registered before probing the downstream devices and set up the I/O mapping.
>>>> But current ACPI bus probing doesn't support these indirect-IO hosts/devices.
>>>>
>>>> This patch introdueces a new ACPI handler for this device category. Through the
>>>> handler attach callback, the indirect-IO hosts I/O registration is done and
>>>> all peripherals' I/O resources are translated into logic/fake PIO before
>>>> starting the enumeration.
>>>
>>> Can you explain to me briefly what exactly this code is expected to be doing?
>>
>> As you know currently for ARM architecture IO space is memory mapped and
>> is only used by pci devices. The port number is dynamically allocated
>> converting the device IO address into a PIO token: i.e.
>> http://lxr.free-electrons.com/source/drivers/acpi/pci_root.c#L745
>> This patch is meant to support a new class of IO host controller
>> that are not PCI based and that still require to have the IO addresses
>> be translated in the same PIO token space as the PCI controller
>
> IOW, this is ARM-specific, right?
Yes. The current host added in this patch with _HID "HISI0191" is on ARM64.
But, I think the handler driver is architecture dependent.
Thanks,
Zhichang
>
> Thanks,
> Rafael
>
^ permalink raw reply
* Re: [PATCH v5 3/6] irqdomain: Add irq_domain_{push,pop}_irq() functions.
From: David Daney @ 2017-04-01 0:21 UTC (permalink / raw)
To: Marc Zyngier, David Daney, Linus Walleij, Alexandre Courbot,
Rob Herring, Mark Rutland, Thomas Gleixner, linux-gpio,
devicetree
Cc: linux-kernel
In-Reply-To: <4486da82-bc22-4334-3d48-70f4304da591@arm.com>
On 03/14/2017 09:11 AM, Marc Zyngier wrote:
> Hi David,
>
> On 01/03/17 01:48, David Daney wrote:
>> For an already existing irqdomain hierarchy, as might be obtained via
>> a call to pci_enable_msix(), a PCI driver wishing to add an additional
>> irqdomain to the hierarchy needs to be able to insert the irqdomain to
>> that already initialized hierarchy. Calling
>> irq_domain_create_hierarchy() allows the new irqdomain to be created,
>> but no existing code allows for initializing the associated irq_data.
>
> I must say that I like this idea a lot. Pretty elegant. Now, there is a
> couple of things that do worry me. And instead of worrying, maybe I
> should just ask the questions.
>
>> Add a couple of helper functions (irq_domain_push_irq()
>> irq_domain_pop_irq()) to initialize the irq_data for the new
>> irqdomain.
>>
>> Signed-off-by: David Daney <david.daney@cavium.com>
>> ---
>> include/linux/irqdomain.h | 3 +
>> kernel/irq/irqdomain.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 140 insertions(+)
>>
>> diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
>> index 188eced..a7a16b7 100644
>> --- a/include/linux/irqdomain.h
>> +++ b/include/linux/irqdomain.h
>> @@ -425,6 +425,9 @@ extern void irq_domain_free_irqs_common(struct irq_domain *domain,
>> extern void irq_domain_free_irqs_top(struct irq_domain *domain,
>> unsigned int virq, unsigned int nr_irqs);
>>
>> +extern int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg);
>> +extern int irq_domain_pop_irq(struct irq_domain *domain, int virq);
>> +
>> extern int irq_domain_alloc_irqs_parent(struct irq_domain *domain,
>> unsigned int irq_base,
>> unsigned int nr_irqs, void *arg);
>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>> index 31805f2..d5d1c01 100644
>> --- a/kernel/irq/irqdomain.c
>> +++ b/kernel/irq/irqdomain.c
>> @@ -1304,6 +1304,143 @@ int __irq_domain_alloc_irqs(struct irq_domain *domain, int irq_base,
>> return ret;
>> }
>>
>> +/* The irq_data was moved, fix the revmap to refer to the new location */
>> +static void irq_domain_fix_revmap(struct irq_data *d)
>> +{
>> + void **slot;
>> +
>> + if (d->hwirq < d->domain->revmap_size)
>> + return; /* Not using radix tree. */
>> +
>> + /* Fix up the revmap. */
>> + mutex_lock(&revmap_trees_mutex);
>> + slot = radix_tree_lookup_slot(&d->domain->revmap_tree, d->hwirq);
>> + if (slot)
>> + radix_tree_replace_slot(&d->domain->revmap_tree, slot, d);
>> + mutex_unlock(&revmap_trees_mutex);
>> +}
>> +
>> +/**
>> + * irq_domain_push_irq() - Push a domain in to the top of a hierarchy.
>> + * @domain: Domain to push.
>> + * @virq: Irq to push the domain in to.
>> + * @arg: Passed to the irq_domain_ops alloc() function.
>> + *
>> + * For an already existing irqdomain hierarchy, as might be obtained
>> + * via a call to pci_enable_msix(), add an additional domain to the
>> + * head of the processing chain.
>> + */
>> +int irq_domain_push_irq(struct irq_domain *domain, int virq, void *arg)
>> +{
>> + struct irq_data *child_irq_data;
>> + struct irq_data *root_irq_data = irq_get_irq_data(virq);
>> +
>> + if (domain == NULL)
>> + return -EINVAL;
>> +
>> + if (WARN_ON(!domain->ops->alloc))
>> + return -EINVAL;
>> +
>> + if (!root_irq_data)
>> + return -EINVAL;
>> +
>> + child_irq_data = kzalloc_node(sizeof(*child_irq_data), GFP_KERNEL,
>> + irq_data_get_node(root_irq_data));
>> + if (!child_irq_data)
>> + return -ENOMEM;
>> +
>> + mutex_lock(&irq_domain_mutex);
>> +
>> + /* Copy the original irq_data. */
>> + *child_irq_data = *root_irq_data;
>> +
>> + irq_domain_fix_revmap(child_irq_data);
>> +
>> + /*
>> + * Overwrite the root_irq_data, which is embedded in struct
>> + * irq_desc, with values for this domain.
>> + */
>> + root_irq_data->parent_data = child_irq_data;
>> + root_irq_data->domain = domain;
>> + root_irq_data->mask = 0;
>> + root_irq_data->hwirq = 0;
>> + root_irq_data->chip = NULL;
>> + root_irq_data->chip_data = NULL;
>
> What guarantees do we have that nobody is using this irqdesc at this
> point? Is it a "don't do that because it will hurt" kind of thing?
Yes.
> I'd be more confident if we had some locking here, just to make sure that we
> don't start processing an interrupt with all these NULL pointers.
>
The only time it makes sense to push/pop is when no request_irq() are
active. Perhaps checking (with proper locking) that there are no
actions registered is the proper thing to do.
> Also, maybe moving the whole stuff to a helper in irqdesc.c if that
> makes it easier/nicer? Your call.
>
>> + domain->ops->alloc(domain, virq, 1, arg);
>
> Check return value? You may have to revert your previous fixup if it fails.
OK.
>
>> +
>> + if (root_irq_data->hwirq < domain->revmap_size) {
>> + domain->linear_revmap[root_irq_data->hwirq] = virq;
>> + } else {
>> + mutex_lock(&revmap_trees_mutex);
>> + radix_tree_insert(&domain->revmap_tree,
>> + root_irq_data->hwirq, root_irq_data);
>> + mutex_unlock(&revmap_trees_mutex);
>> + }
>> +
>> + mutex_unlock(&irq_domain_mutex);
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(irq_domain_push_irq);
>> +
>> +/**
>> + * irq_domain_pop_irq() - Remove a domain from the top of a hierarchy.
>> + * @domain: Domain to remove.
>> + * @virq: Irq to remove the domain from.
>> + *
>> + * Undo the effects of a call to irq_domain_push_irq().
>> + */
>> +int irq_domain_pop_irq(struct irq_domain *domain, int virq)
>> +{
>> + struct irq_data *root_irq_data = irq_get_irq_data(virq);
>> + struct irq_data *child_irq_data;
>> + struct irq_data *tmp_irq_data;
>> +
>> + if (domain == NULL)
>> + return -EINVAL;
>> +
>> + if (!root_irq_data)
>> + return -EINVAL;
>> +
>> + tmp_irq_data = irq_domain_get_irq_data(domain, virq);
>> +
>> + /* We can only "pop" if this domain is at the top of the list */
>> + if (WARN_ON(root_irq_data != tmp_irq_data))
>> + return -EINVAL;
>> +
>> + if (WARN_ON(root_irq_data->domain != domain))
>> + return -EINVAL;
>> +
>> + child_irq_data = root_irq_data->parent_data;
>> + if (WARN_ON(!child_irq_data))
>> + return -EINVAL;
>> +
>> + mutex_lock(&irq_domain_mutex);
>> +
>> + root_irq_data->parent_data = NULL;
>> +
>> + if (root_irq_data->hwirq >= domain->revmap_size) {
>> + mutex_lock(&revmap_trees_mutex);
>> + radix_tree_delete(&domain->revmap_tree, root_irq_data->hwirq);
>> + mutex_unlock(&revmap_trees_mutex);
>> + }
>> +
>> + if (domain->ops->free)
>> + domain->ops->free(domain, virq, 1);
>> +
>> + /* Restore the original irq_data. */
>> + *root_irq_data = *child_irq_data;
>
> Similar concerns about locking here.
>
>> +
>> + irq_domain_fix_revmap(root_irq_data);
>> +
>> + mutex_unlock(&irq_domain_mutex);
>> +
>> + kfree(child_irq_data);
>> +
>> + return 0;
>> +}
>> +EXPORT_SYMBOL_GPL(irq_domain_pop_irq);
>> +
>> /**
>> * irq_domain_free_irqs - Free IRQ number and associated data structures
>> * @virq: base IRQ number
>>
>
> Thanks,
>
> M.
>
^ permalink raw reply
* Re: [PATCH v5 2/6] genirq: Add handle_fasteoi_{level,edge}_irq flow handlers.
From: David Daney @ 2017-03-31 23:57 UTC (permalink / raw)
To: Marc Zyngier, David Daney, Linus Walleij, Alexandre Courbot,
Rob Herring, Mark Rutland, Thomas Gleixner,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <254c0505-6890-2e9f-cf04-3c8efbcfeb2d-5wv7dgnIgG8@public.gmane.org>
I am finally getting back to this, sorry for the delay ...
On 03/14/2017 09:54 AM, Marc Zyngier wrote:
> On 01/03/17 01:48, David Daney wrote:
>> Follow-on patch for gpio-thunderx uses a irqdomain hierarchy which
>> requires slightly different flow handlers, add them to chip.c which
>> contains most of the other flow handlers.
>>
>> Signed-off-by: David Daney <david.daney-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org>
>> ---
>> include/linux/irq.h | 2 ++
>> kernel/irq/chip.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 2 files changed, 104 insertions(+)
>>
>> diff --git a/include/linux/irq.h b/include/linux/irq.h
>> index f887351..3db0eb8 100644
>> --- a/include/linux/irq.h
>> +++ b/include/linux/irq.h
>> @@ -518,6 +518,8 @@ static inline int irq_set_parent(int irq, int parent_irq)
>> extern int irq_chip_pm_get(struct irq_data *data);
>> extern int irq_chip_pm_put(struct irq_data *data);
>> #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
>> +extern void handle_fasteoi_edge_irq(struct irq_desc *desc);
>> +extern void handle_fasteoi_level_irq(struct irq_desc *desc);
>> extern void irq_chip_enable_parent(struct irq_data *data);
>> extern void irq_chip_disable_parent(struct irq_data *data);
>> extern void irq_chip_ack_parent(struct irq_data *data);
>> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
>> index 73ea90b..213105d 100644
>> --- a/kernel/irq/chip.c
>> +++ b/kernel/irq/chip.c
>> @@ -981,6 +981,108 @@ void irq_cpu_offline(void)
>>
>> #ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
>> /**
>> + * handle_fasteoi_edge_irq - irq handler for edge hierarchy
>> + * stacked on transparent controllers
>> + *
>> + * @desc: the interrupt description structure for this irq
>> + *
>> + * Like handle_fasteoi_irq(), but for use with hierarchy where
>> + * the irq_chip also needs to have its ->irq_ack() function
>> + * called.
>> + */
>> +void handle_fasteoi_edge_irq(struct irq_desc *desc)
>> +{
>> + struct irq_chip *chip = desc->irq_data.chip;
>> +
>> + raw_spin_lock(&desc->lock);
>> +
>> + if (!irq_may_run(desc))
>> + goto out;
>> +
>> + desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
>> +
>> + /*
>> + * If its disabled or no action available
>> + * then mask it and get out of here:
>> + */
>> + if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
>> + desc->istate |= IRQS_PENDING;
>> + mask_irq(desc);
>> + goto out;
>> + }
>> +
>> + kstat_incr_irqs_this_cpu(desc);
>> + if (desc->istate & IRQS_ONESHOT)
>> + mask_irq(desc);
>> +
>> + /* Start handling the irq */
>> + desc->irq_data.chip->irq_ack(&desc->irq_data);
>> +
>> + preflow_handler(desc);
>> + handle_irq_event(desc);
>> +
>> + cond_unmask_eoi_irq(desc, chip);
>> +
>> + raw_spin_unlock(&desc->lock);
>> + return;
>> +out:
>> + if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
>> + chip->irq_eoi(&desc->irq_data);
>> + raw_spin_unlock(&desc->lock);
>> +}
>> +EXPORT_SYMBOL_GPL(handle_fasteoi_edge_irq);
>
> So this is handle_fasteoi_irq with an irq_ack() added in the middle. In
> the spirit of making this a bit more maintainable, how about making the
> handle_fasteoi_irq code reusable (if necessary by forcing the compiler
> to inline stuff)?
You, yourself, said in response to an earlier version of the patch set:
So you want to generalize CONFIG_IRQ_PREFLOW_FASTEOI so that it is
on each level of a domain stack? Humm. I personally think that
this is a massive bloat that is going to impact all the hot paths
for no gain whatsoever, but I'll let tglx speak his mind on that.
Your current suggestion is, from the point of view of the "impact",
almost identical to what I was proposing back then.
>
> But the one thing that makes me uncomfortable here is that we're seem to
> have this irq_ack() propagated all along the irqdata chain, which is not
> what's happening. Only the EOI gets propagated.
That is intentional. The parent domain is handle_fasteoi_irq(), so we
know that it has no irq_ack().
>
> Why can't you just put the irq_ack call in your top level irq_eoi
> callback? That'd make it similar to what is happening on the mbigen side
> (not exactly surprising, since they are doing very similar things).
irq_ack() must be called before handle_irq_event(), otherwise there is a
race condition where edge interrupts could be lost.
>
> Same remark about handle_fasteoi_level_irq.
>
> Thoughts?
Several:
1) Adding the additional mask_ack_irq()/irq_ack() to
handle_fasteoi_irq() is probably the cleanest solution, however ...
2) There is a risk of breaking systems that inadvertently supply the new
chip methods, but the methods don't currently get called by
handle_fasteoi_irq().
3) Checking for the presence of mask_ack_irq()/irq_ack() methods may
introduce additional branch mispredictions and cache misses on all
non-ThunderGPIO systems.
David Daney
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v6 2/2] mmc: host: s3cmci: allow probing from device tree
From: Sergio Prado @ 2017-03-31 23:50 UTC (permalink / raw)
To: ulf.hansson, robh+dt, mark.rutland, linux-mmc, devicetree,
linux-kernel, ben-linux, linux-arm-kernel
Cc: Sergio Prado
In-Reply-To: <1491004256-13969-1-git-send-email-sergio.prado@e-labworks.com>
Allows configuring Samsung S3C24XX MMC/SD/SDIO controller using a device
tree.
Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
---
drivers/mmc/host/s3cmci.c | 257 +++++++++++++++++++++++-----------------------
1 file changed, 126 insertions(+), 131 deletions(-)
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 7a173f8c455b..c101f7e178f7 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -24,6 +24,10 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
+#include <linux/mmc/slot-gpio.h>
#include <plat/gpio-cfg.h>
#include <mach/dma.h>
@@ -807,21 +811,6 @@ static irqreturn_t s3cmci_irq(int irq, void *dev_id)
}
-/*
- * ISR for the CardDetect Pin
-*/
-
-static irqreturn_t s3cmci_irq_cd(int irq, void *dev_id)
-{
- struct s3cmci_host *host = (struct s3cmci_host *)dev_id;
-
- dbg(host, dbg_irq, "card detect\n");
-
- mmc_detect_change(host->mmc, msecs_to_jiffies(500));
-
- return IRQ_HANDLED;
-}
-
static void s3cmci_dma_done_callback(void *arg)
{
struct s3cmci_host *host = arg;
@@ -1177,19 +1166,6 @@ static void s3cmci_send_request(struct mmc_host *mmc)
s3cmci_enable_irq(host, true);
}
-static int s3cmci_card_present(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_detect)
- return -ENOSYS;
-
- ret = gpio_get_value(pdata->gpio_detect) ? 0 : 1;
- return ret ^ pdata->detect_invert;
-}
-
static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1198,7 +1174,7 @@ static void s3cmci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->cmd_is_stop = 0;
host->mrq = mrq;
- if (s3cmci_card_present(mmc) == 0) {
+ if (mmc_gpio_get_cd(mmc) == 0) {
dbg(host, dbg_err, "%s: no medium present\n", __func__);
host->mrq->cmd->error = -ENOMEDIUM;
mmc_request_done(mmc, mrq);
@@ -1242,8 +1218,9 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_ON:
case MMC_POWER_UP:
/* Configure GPE5...GPE10 pins in SD mode */
- s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
- S3C_GPIO_PULL_NONE);
+ if (!host->pdev->dev.of_node)
+ s3c_gpio_cfgall_range(S3C2410_GPE(5), 6, S3C_GPIO_SFN(2),
+ S3C_GPIO_PULL_NONE);
if (host->pdata->set_power)
host->pdata->set_power(ios->power_mode, ios->vdd);
@@ -1255,7 +1232,8 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
case MMC_POWER_OFF:
default:
- gpio_direction_output(S3C2410_GPE(5), 0);
+ if (!host->pdev->dev.of_node)
+ gpio_direction_output(S3C2410_GPE(5), 0);
if (host->is2440)
mci_con |= S3C2440_SDICON_SDRESET;
@@ -1295,21 +1273,6 @@ static void s3cmci_reset(struct s3cmci_host *host)
writel(con, host->base + S3C2410_SDICON);
}
-static int s3cmci_get_ro(struct mmc_host *mmc)
-{
- struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pdata = host->pdata;
- int ret;
-
- if (pdata->no_wprotect)
- return 0;
-
- ret = gpio_get_value(pdata->gpio_wprotect) ? 1 : 0;
- ret ^= pdata->wprotect_invert;
-
- return ret;
-}
-
static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct s3cmci_host *host = mmc_priv(mmc);
@@ -1353,8 +1316,8 @@ static void s3cmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
static struct mmc_host_ops s3cmci_ops = {
.request = s3cmci_request,
.set_ios = s3cmci_set_ios,
- .get_ro = s3cmci_get_ro,
- .get_cd = s3cmci_card_present,
+ .get_ro = mmc_gpio_get_ro,
+ .get_cd = mmc_gpio_get_cd,
.enable_sdio_irq = s3cmci_enable_sdio_irq,
};
@@ -1545,21 +1508,14 @@ static inline void s3cmci_debugfs_remove(struct s3cmci_host *host) { }
#endif /* CONFIG_DEBUG_FS */
-static int s3cmci_probe(struct platform_device *pdev)
+static int s3cmci_probe_pdata(struct s3cmci_host *host)
{
- struct s3cmci_host *host;
- struct mmc_host *mmc;
- int ret;
- int is2440;
- int i;
+ struct platform_device *pdev = host->pdev;
+ struct mmc_host *mmc = host->mmc;
+ struct s3c24xx_mci_pdata *pdata;
+ int i, ret;
- is2440 = platform_get_device_id(pdev)->driver_data;
-
- mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
- if (!mmc) {
- ret = -ENOMEM;
- goto probe_out;
- }
+ host->is2440 = platform_get_device_id(pdev)->driver_data;
for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++) {
ret = gpio_request(i, dev_name(&pdev->dev));
@@ -1569,25 +1525,101 @@ static int s3cmci_probe(struct platform_device *pdev)
for (i--; i >= S3C2410_GPE(5); i--)
gpio_free(i);
- goto probe_free_host;
+ return ret;
+ }
+ }
+
+ if (!pdev->dev.platform_data)
+ pdev->dev.platform_data = &s3cmci_def_pdata;
+
+ pdata = pdev->dev.platform_data;
+
+ if (pdata->no_wprotect)
+ mmc->caps2 |= MMC_CAP2_NO_WRITE_PROTECT;
+
+ if (pdata->no_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (pdata->wprotect_invert);
+ mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
+
+ if (pdata->detect_invert)
+ mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
+
+ if (gpio_is_valid(pdata->gpio_detect)) {
+ ret = mmc_gpio_request_cd(mmc, pdata->gpio_detect, 0);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for CD %d\n",
+ ret);
+ return ret;
}
}
+ if (gpio_is_valid(pdata->gpio_wprotect)) {
+ ret = mmc_gpio_request_ro(mmc, pdata->gpio_wprotect);
+ if (ret) {
+ dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
+ ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int s3cmci_probe_dt(struct s3cmci_host *host)
+{
+ struct platform_device *pdev = host->pdev;
+ struct s3c24xx_mci_pdata *pdata;
+ struct mmc_host *mmc = host->mmc;
+ int ret;
+
+ host->is2440 = (int) of_device_get_match_data(&pdev->dev);
+
+ ret = mmc_of_parse(mmc);
+ if (ret)
+ return ret;
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ pdev->dev.platform_data = pdata;
+
+ return 0;
+}
+
+static int s3cmci_probe(struct platform_device *pdev)
+{
+ struct s3cmci_host *host;
+ struct mmc_host *mmc;
+ int ret;
+ int i;
+
+ mmc = mmc_alloc_host(sizeof(struct s3cmci_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto probe_out;
+ }
+
host = mmc_priv(mmc);
host->mmc = mmc;
host->pdev = pdev;
- host->is2440 = is2440;
+
+ if (pdev->dev.of_node)
+ ret = s3cmci_probe_dt(host);
+ else
+ ret = s3cmci_probe_pdata(host);
+
+ if (ret)
+ goto probe_free_host;
host->pdata = pdev->dev.platform_data;
- if (!host->pdata) {
- pdev->dev.platform_data = &s3cmci_def_pdata;
- host->pdata = &s3cmci_def_pdata;
- }
spin_lock_init(&host->complete_lock);
tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host);
- if (is2440) {
+ if (host->is2440) {
host->sdiimsk = S3C2440_SDIIMSK;
host->sdidata = S3C2440_SDIDATA;
host->clk_div = 1;
@@ -1645,43 +1677,6 @@ static int s3cmci_probe(struct platform_device *pdev)
disable_irq(host->irq);
host->irq_state = false;
- if (!host->pdata->no_detect) {
- ret = gpio_request(host->pdata->gpio_detect, "s3cmci detect");
- if (ret) {
- dev_err(&pdev->dev, "failed to get detect gpio\n");
- goto probe_free_irq;
- }
-
- host->irq_cd = gpio_to_irq(host->pdata->gpio_detect);
-
- if (host->irq_cd >= 0) {
- if (request_irq(host->irq_cd, s3cmci_irq_cd,
- IRQF_TRIGGER_RISING |
- IRQF_TRIGGER_FALLING,
- DRIVER_NAME, host)) {
- dev_err(&pdev->dev,
- "can't get card detect irq.\n");
- ret = -ENOENT;
- goto probe_free_gpio_cd;
- }
- } else {
- dev_warn(&pdev->dev,
- "host detect has no irq available\n");
- gpio_direction_input(host->pdata->gpio_detect);
- }
- } else
- host->irq_cd = -1;
-
- if (!host->pdata->no_wprotect) {
- ret = gpio_request(host->pdata->gpio_wprotect, "s3cmci wp");
- if (ret) {
- dev_err(&pdev->dev, "failed to get writeprotect\n");
- goto probe_free_irq_cd;
- }
-
- gpio_direction_input(host->pdata->gpio_wprotect);
- }
-
/* Depending on the dma state, get a DMA channel to use. */
if (s3cmci_host_usedma(host)) {
@@ -1689,7 +1684,7 @@ static int s3cmci_probe(struct platform_device *pdev)
ret = PTR_ERR_OR_ZERO(host->dma);
if (ret) {
dev_err(&pdev->dev, "cannot get DMA channel.\n");
- goto probe_free_gpio_wp;
+ goto probe_free_irq;
}
}
@@ -1768,18 +1763,6 @@ static int s3cmci_probe(struct platform_device *pdev)
if (s3cmci_host_usedma(host))
dma_release_channel(host->dma);
- probe_free_gpio_wp:
- if (!host->pdata->no_wprotect)
- gpio_free(host->pdata->gpio_wprotect);
-
- probe_free_gpio_cd:
- if (!host->pdata->no_detect)
- gpio_free(host->pdata->gpio_detect);
-
- probe_free_irq_cd:
- if (host->irq_cd >= 0)
- free_irq(host->irq_cd, host);
-
probe_free_irq:
free_irq(host->irq, host);
@@ -1790,8 +1773,9 @@ static int s3cmci_probe(struct platform_device *pdev)
release_mem_region(host->mem->start, resource_size(host->mem));
probe_free_gpio:
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
probe_free_host:
mmc_free_host(mmc);
@@ -1818,7 +1802,6 @@ static int s3cmci_remove(struct platform_device *pdev)
{
struct mmc_host *mmc = platform_get_drvdata(pdev);
struct s3cmci_host *host = mmc_priv(mmc);
- struct s3c24xx_mci_pdata *pd = host->pdata;
int i;
s3cmci_shutdown(pdev);
@@ -1832,15 +1815,9 @@ static int s3cmci_remove(struct platform_device *pdev)
free_irq(host->irq, host);
- if (!pd->no_wprotect)
- gpio_free(pd->gpio_wprotect);
-
- if (!pd->no_detect)
- gpio_free(pd->gpio_detect);
-
- for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
- gpio_free(i);
-
+ if (!pdev->dev.of_node)
+ for (i = S3C2410_GPE(5); i <= S3C2410_GPE(10); i++)
+ gpio_free(i);
iounmap(host->base);
release_mem_region(host->mem->start, resource_size(host->mem));
@@ -1849,6 +1826,23 @@ static int s3cmci_remove(struct platform_device *pdev)
return 0;
}
+static const struct of_device_id s3cmci_dt_match[] = {
+ {
+ .compatible = "samsung,s3c2410-sdi",
+ .data = (void *)0,
+ },
+ {
+ .compatible = "samsung,s3c2412-sdi",
+ .data = (void *)1,
+ },
+ {
+ .compatible = "samsung,s3c2440-sdi",
+ .data = (void *)1,
+ },
+ { /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, s3cmci_dt_match);
+
static const struct platform_device_id s3cmci_driver_ids[] = {
{
.name = "s3c2410-sdi",
@@ -1868,6 +1862,7 @@ static int s3cmci_remove(struct platform_device *pdev)
static struct platform_driver s3cmci_driver = {
.driver = {
.name = "s3c-sdi",
+ .of_match_table = s3cmci_dt_match,
},
.id_table = s3cmci_driver_ids,
.probe = s3cmci_probe,
--
1.9.1
^ permalink raw reply related
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