* Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.
From: Paweł Chmiel @ 2018-07-18 16:21 UTC (permalink / raw)
To: Nick Dyer
Cc: dmitry.torokhov, robh+dt, mark.rutland, nicolas.ferre,
alexandre.belloni, linux-input, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <20180717210005.GA21416@hairyalien>
On Tuesday, July 17, 2018 10:00:05 PM CEST Nick Dyer wrote:
> On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> > This patch adds optional regulators, which can be used to power
> > up touchscreen. After enabling regulators, we need to wait 150msec.
> > This value is taken from official driver.
> >
> > It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> >
> > Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > ---
> > Changes from v1:
> > - Enable regulators only if reset_gpio is present.
> > - Switch from devm_regulator_get_optional to devm_regulator_get
> > ---
> > drivers/input/touchscreen/atmel_mxt_ts.c | 46 ++++++++++++++++++++++++++++++--
> > 1 file changed, 44 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> > index 54fe190fd4bc..005f0fee9fc8 100644
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -27,6 +27,7 @@
> > #include <linux/interrupt.h>
> > #include <linux/of.h>
> > #include <linux/property.h>
> > +#include <linux/regulator/consumer.h>
> > #include <linux/slab.h>
> > #include <linux/gpio/consumer.h>
> > #include <linux/property.h>
> > @@ -194,10 +195,10 @@ enum t100_type {
> >
> > /* Delay times */
> > #define MXT_BACKUP_TIME 50 /* msec */
> > -#define MXT_RESET_GPIO_TIME 20 /* msec */
> > #define MXT_RESET_INVALID_CHG 100 /* msec */
> > #define MXT_RESET_TIME 200 /* msec */
> > #define MXT_RESET_TIMEOUT 3000 /* msec */
> > +#define MXT_REGULATOR_DELAY 150 /* msec */
> > #define MXT_CRC_TIMEOUT 1000 /* msec */
> > #define MXT_FW_RESET_TIME 3000 /* msec */
> > #define MXT_FW_CHG_TIMEOUT 300 /* msec */
> > @@ -310,6 +311,8 @@ struct mxt_data {
> > struct t7_config t7_cfg;
> > struct mxt_dbg dbg;
> > struct gpio_desc *reset_gpio;
> > + struct regulator *vdd_reg;
> > + struct regulator *avdd_reg;
> >
> > /* Cached parameters from object table */
> > u16 T5_address;
> > @@ -3076,6 +3079,22 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> > return error;
> > }
> >
> > + data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
> > + if (IS_ERR(data->vdd_reg)) {
> > + error = PTR_ERR(data->vdd_reg);
> > + dev_err(&client->dev, "Failed to get vdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > + data->avdd_reg = devm_regulator_get(&client->dev, "avdd");
> > + if (IS_ERR(data->avdd_reg)) {
> > + error = PTR_ERR(data->avdd_reg);
> > + dev_err(&client->dev, "Failed to get avdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > error = devm_request_threaded_irq(&client->dev, client->irq,
> > NULL, mxt_interrupt, IRQF_ONESHOT,
> > client->name, data);
> > @@ -3087,7 +3106,26 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> > disable_irq(client->irq);
> >
> > if (data->reset_gpio) {
> > - msleep(MXT_RESET_GPIO_TIME);
> > + error = regulator_enable(data->vdd_reg);
> > + if (error) {
> > + dev_err(&client->dev, "Failed to enable vdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > + error = regulator_enable(data->avdd_reg);
> > + if (error) {
> > + dev_err(&client->dev, "Failed to enable avdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > + /*
> > + * According to maXTouch power sequencing specification, RESET line
> > + * must be kept low until some time after regulators come up to
> > + * voltage
> > + */
> > + msleep(MXT_REGULATOR_DELAY);
> > gpiod_set_value(data->reset_gpio, 1);
> > msleep(MXT_RESET_INVALID_CHG);
>
> Hi Pawel-
>
> I see you've borrowed some of the logic from the patch I wrote a while
> back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )
Actually, i was looking at https://github.com/atmel-maxtouch/linux/blob/maxtouch-v3.14/drivers/input/touchscreen/atmel_mxt_ts.c (and didn't saw Your patch till now).
Are You going to submit it? (it has more functionalities - for example suspend mode read from device tree).
>
> The correct behaviour according to Atmel should be:
>
> * Make RESET zero
> * Bring up regulators
> * Wait for a period to settle (150 msec)
> * Release RESET
> * Wait for 100 msec whilst device gets through bootloader
> * Wait for CHG line assert before reading info block
>
> I can't see the first and last steps in your patch at present.
About first step - reset_gpio is readed by using devm_gpiod_get_optional with GPIOD_OUT_LOW flag, so i think (but might be wrong) that we don't need to set this gpio value again to 0 before enabling regulators,
since currently only place where reset_gpio is used is in driver probe (in Your patch it is used in other cases/places - for example in mxt_start/stop, when we enable regulators).
About missing wait after releasing reset, shouldn't this be separate patch (since currently driver is not doing it)? I can prepare it and send with other in next version.
Thanks for feedback
>
> The only downside with this approach is that there are a lot of
> delays during driver probe, but I believe the asynchronous probe stuff
> that's landed since I wrote the original patch should address that.
>
> cheers
>
> Nick
>
> > }
> > @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
> > struct mxt_data *data = i2c_get_clientdata(client);
> >
> > disable_irq(data->irq);
> > + if (data->reset_gpio) {
> > + regulator_disable(data->avdd_reg);
> > + regulator_disable(data->vdd_reg);
> > + }
> > sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
> > mxt_free_input_device(data);
> > mxt_free_object_table(data);
>
^ permalink raw reply
* Re: [PATCH] drivers: input: Add SPDX-License-Identifier
From: Dmitry Torokhov @ 2018-07-18 16:13 UTC (permalink / raw)
To: Christian Thoms
Cc: rydberg, linux-input, linux-kernel, linux-kernel,
Sebastian Hillert
In-Reply-To: <1530879112-3388-1-git-send-email-christian.thoms93@gmail.com>
Hi Christian,
On Fri, Jul 06, 2018 at 02:11:52PM +0200, Christian Thoms wrote:
> diff --git a/drivers/input/ff-core.c b/drivers/input/ff-core.c
> index 66a46c8..3086166 100644
> --- a/drivers/input/ff-core.c
> +++ b/drivers/input/ff-core.c
> @@ -1,3 +1,4 @@
> +// SPDX-License-Identifier: GPL-2.0+
> /*
> * Force feedback support for Linux input subsystem
> *
> @@ -6,11 +7,6 @@
> */
>
> /*
> - * This program is free software; you can redistribute it and/or modify
> - * it under the terms of the GNU General Public License as published by
> - * the Free Software Foundation; either version 2 of the License, or
> - * (at your option) any later version.
> - *
> * This program is distributed in the hope that it will be useful,
> * but WITHOUT ANY WARRANTY; without even the implied warranty of
> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Why did you keep this block here? Also, below, there is another
paragraph about obtaining a copy of GPL from an old FSF address. If we
are cleaning it I believe it all needs to go.
I see the similar issue in several other files in this patch.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH] HID: intel-ish-hid: Prevent loading of driver on Mehlow
From: Srinivas Pandruvada @ 2018-07-18 14:21 UTC (permalink / raw)
To: Benjamin Tissoires; +Cc: Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <CAO-hwJ+b6aSSC7UGDtdivfh69+ZZaV5uwJH_ramLM0FeAZwRDQ@mail.gmail.com>
On Wed, 2018-07-18 at 09:53 +0200, Benjamin Tissoires wrote:
> On Tue, Jul 17, 2018 at 10:06 PM Srinivas Pandruvada
> <srinivas.pandruvada@linux.intel.com> wrote:
> >
> > On Mehlow Xeon-E workstation, ISH PCI device is enabled but without
> > ISH
> > firmware. Here the ISH device PCI device id was reused for some non
> > Linux
> > storage drivers. So this was not done for enabling ISH. But this
> > has a
> > undesirable side effect for Linux.
> >
> > Here the ISH driver will be loaded via PCI enumeration and will try
> > to do
> > reset sequence. But reset sequence will wait till timeout as there
> > is no
> > real ISH firmware is present to take action. This delay will add to
> > boot
> > time of Linux (This platform will still continue to boot after this
> > timeout).
> >
> > To avoid this boot delay we need to prevent loading of ISH drivers
> > on
> > this platform. So we need to have hack to avoid treating this
> > device as
> > ISH on this platform. To identify this workstation, we need some
> > runtime
> > method. Luckily there are special PCI id on this workstation to
> > distinguish from the client version of this platform. On client
> > version,
> > the ISH is supported using same PCI device id. So this change look
> > for
> > the presence of PCI device IDs A309 and A30A and exit.
> >
> > Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel
> > .com>
> > ---
> > This is not a change for 4.18-rc.
> >
> > drivers/hid/intel-ish-hid/ipc/pci-ish.c | 23
> > +++++++++++++++++++++++
> > 1 file changed, 23 insertions(+)
> >
> > diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> > b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> > index a2c53ea3b5ed..d6e7156c36d9 100644
> > --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> > +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> > @@ -95,6 +95,26 @@ static int ish_init(struct ishtp_device *dev)
> > return 0;
> > }
> >
> > +
> > +static bool ish_invalid_firmware(void)
> > +{
> > + struct pci_dev *pdev;
> > +
> > + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA309, NULL);
> > + if (pdev) {
> > + pci_dev_put(pdev);
> > + return true;
> > + }
> > +
> > + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA30A, NULL);
> > + if (pdev) {
> > + pci_dev_put(pdev);
> > + return true;
> > + }
>
> I think this duplicated code should be merged in a for loop on an
> array of blacklisted items :)
Good idea.
Thanks,
Srinivas
>
> Cheers,
> Benjamin
>
> > +
> > + return false;
> > +}
> > +
> > /**
> > * ish_probe() - PCI driver probe callback
> > * @pdev: pci device
> > @@ -110,6 +130,9 @@ static int ish_probe(struct pci_dev *pdev,
> > const struct pci_device_id *ent)
> > struct ish_hw *hw;
> > int ret;
> >
> > + if (ish_invalid_firmware())
> > + return -ENODEV;
> > +
> > /* enable pci dev */
> > ret = pci_enable_device(pdev);
> > if (ret) {
> > --
> > 2.17.1
> >
^ permalink raw reply
* Re: [PATCH 0/5] m68k: IO Fixes and Cleanups
From: Geert Uytterhoeven @ 2018-07-18 11:37 UTC (permalink / raw)
To: Greg Ungerer
Cc: Dmitry Torokhov, Helge Deller, linux-m68k, netdev, linux-input,
Linux Kernel Mailing List
In-Reply-To: <0f38c6fd-82f1-7211-3b2e-425bbd44b157@linux-m68k.org>
On Tue, Jul 10, 2018 at 3:48 AM Greg Ungerer <gerg@linux-m68k.org> wrote:
> On 09/07/18 19:30, Geert Uytterhoeven wrote:
> > This patch series contains fixes and cleanups for I/O accessors on m68k
> > platforms (with MMU).
> >
> > The first patch contains small fixes without any dependencies.
> > Patches 2 and 3 make small adjustments to drivers that are dependencies
> > for further cleanup.
> > Patch 4 and 5 complete the cleanup.
> >
> > Changes compared to v1:
> > - Move ARCH_HAS_IOREMAP_WT to fix "ioremap_wt redefined" warnings with
> > m5475evb defconfig,
> > - Add Acked-by.
> >
> > Given the dependencies, I think it's easiest if the respective
> > maintainers would provide their Acked-by, so all patches can go in
> > through the m68k tree.
>
> Retested on ColdFire 5475, looks good.
> For the whole series:
>
> Acked-by: Greg Ungerer <gerg@linux-m68k.org>
Thanks, applied and queued for v4.19.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH] HID: intel-ish-hid: Prevent loading of driver on Mehlow
From: Benjamin Tissoires @ 2018-07-18 7:53 UTC (permalink / raw)
To: Srinivas Pandruvada; +Cc: Jiri Kosina, open list:HID CORE LAYER, lkml
In-Reply-To: <20180717200557.39925-1-srinivas.pandruvada@linux.intel.com>
On Tue, Jul 17, 2018 at 10:06 PM Srinivas Pandruvada
<srinivas.pandruvada@linux.intel.com> wrote:
>
> On Mehlow Xeon-E workstation, ISH PCI device is enabled but without ISH
> firmware. Here the ISH device PCI device id was reused for some non Linux
> storage drivers. So this was not done for enabling ISH. But this has a
> undesirable side effect for Linux.
>
> Here the ISH driver will be loaded via PCI enumeration and will try to do
> reset sequence. But reset sequence will wait till timeout as there is no
> real ISH firmware is present to take action. This delay will add to boot
> time of Linux (This platform will still continue to boot after this
> timeout).
>
> To avoid this boot delay we need to prevent loading of ISH drivers on
> this platform. So we need to have hack to avoid treating this device as
> ISH on this platform. To identify this workstation, we need some runtime
> method. Luckily there are special PCI id on this workstation to
> distinguish from the client version of this platform. On client version,
> the ISH is supported using same PCI device id. So this change look for
> the presence of PCI device IDs A309 and A30A and exit.
>
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> ---
> This is not a change for 4.18-rc.
>
> drivers/hid/intel-ish-hid/ipc/pci-ish.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> index a2c53ea3b5ed..d6e7156c36d9 100644
> --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
> @@ -95,6 +95,26 @@ static int ish_init(struct ishtp_device *dev)
> return 0;
> }
>
> +
> +static bool ish_invalid_firmware(void)
> +{
> + struct pci_dev *pdev;
> +
> + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA309, NULL);
> + if (pdev) {
> + pci_dev_put(pdev);
> + return true;
> + }
> +
> + pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA30A, NULL);
> + if (pdev) {
> + pci_dev_put(pdev);
> + return true;
> + }
I think this duplicated code should be merged in a for loop on an
array of blacklisted items :)
Cheers,
Benjamin
> +
> + return false;
> +}
> +
> /**
> * ish_probe() - PCI driver probe callback
> * @pdev: pci device
> @@ -110,6 +130,9 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> struct ish_hw *hw;
> int ret;
>
> + if (ish_invalid_firmware())
> + return -ENODEV;
> +
> /* enable pci dev */
> ret = pci_enable_device(pdev);
> if (ret) {
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCH 0/5] ti_am335x_tsc: Enable wakeup capability
From: Lee Jones @ 2018-07-18 7:47 UTC (permalink / raw)
To: Vignesh R
Cc: Jonathan Cameron, Dmitry Torokhov, linux-iio, linux-omap,
linux-kernel, linux-input
In-Reply-To: <dcb4a63b-9ecb-a72e-bfb8-ebb62017b4f7@ti.com>
On Tue, 17 Jul 2018, Vignesh R wrote:
> Hi Dmitry,
>
> On Saturday 30 June 2018 04:03 PM, Vignesh R wrote:
> > On AM335x, resistive TSC can wakeup the system from low power state.
> > Currently, parent MFD device is marked as wakeup source, which is
> > inaccurate as its the touch event generated by TSC thats the wakeup
> > source. This series moves all wakeup related calls to operate on TSC
> > device instead of MFD. It also marks TSC IRQ as wakeup capable, so that
> > its not disabled during system suspend.
> >
> > This series is based on Dmitry's comments here:
> > https://lkml.org/lkml/2018/4/24/65
> >
> > There are many new patches in this series, hence did not mark this as v4.
> >
> > Vignesh R (5):
> > mfd: ti_am335x_tscadc: Don't mark TSCADC MFD as wakeup capable
> > Input: ti_am335x_tsc: Mark TSC device as wakeup source
> > mfd: ti_am335x_tscadc: Keep ADC interface on if child is wakeup
> > capable
> > iio: adc: ti_am335x_adc: Disable ADC during suspend unconditionally
> > Input: ti_am335x_tsc: Mark IRQ as wakeup capable
> >
> > drivers/iio/adc/ti_am335x_adc.c | 12 ++++--------
> > drivers/input/touchscreen/ti_am335x_tsc.c | 22 +++++++++++++++++-----
> > drivers/mfd/ti_am335x_tscadc.c | 14 +++++++++++++-
> > 3 files changed, 34 insertions(+), 14 deletions(-)
> >
>
> Gentle ping... Could you review/pick this series? MFD amd IIO bits are
> already ACKed
MFD patches are reviewed "for my own reference" meaning that we
haven't yet agreed on a merge plan yet.
--
Lee Jones [李琼斯]
Linaro Services Technical Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* [PATCH v7 4/4] kexec_file: Load kernel at top of system RAM if required
From: Baoquan He @ 2018-07-18 2:49 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, davem
In-Reply-To: <20180718024944.577-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
For kexec_file loading, if kexec_buf.top_down is 'true', the memory which
is used to load kernel/initrd/purgatory is supposed to be allocated from
top to down. This is what we have been doing all along in the old kexec
loading interface and the kexec loading is still default setting in some
distributions. However, the current kexec_file loading interface doesn't
do like this. The function arch_kexec_walk_mem() it calls ignores checking
kexec_buf.top_down, but calls walk_system_ram_res() directly to go through
all resources of System RAM from bottom to up, to try to find memory region
which can contain the specific kexec buffer, then call locate_mem_hole_callback()
to allocate memory in that found memory region from top to down. This brings
confusion especially when KASLR is widely supported , users have to make clear
why kexec/kdump kernel loading position is different between these two
interfaces in order to exclude unnecessary noises. Hence these two interfaces
need be unified on behaviour.
Here add checking if kexec_buf.top_down is 'true' in arch_kexec_walk_mem(),
if yes, call the newly added walk_system_ram_res_rev() to find memory region
from top to down to load kernel.
Signed-off-by: Baoquan He <bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Eric Biederman <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
Cc: Vivek Goyal <vgoyal-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Dave Young <dyoung-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
Cc: Yinghai Lu <yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
Cc: kexec-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
---
kernel/kexec_file.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index c6a3b6851372..75226c1d08ce 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -518,6 +518,8 @@ int __weak arch_kexec_walk_mem(struct kexec_buf *kbuf,
IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY,
crashk_res.start, crashk_res.end,
kbuf, func);
+ else if (kbuf->top_down)
+ return walk_system_ram_res_rev(0, ULONG_MAX, kbuf, func);
else
return walk_system_ram_res(0, ULONG_MAX, kbuf, func);
}
--
2.13.6
^ permalink raw reply related
* [PATCH v7 3/4] resource: add walk_system_ram_res_rev()
From: Baoquan He @ 2018-07-18 2:49 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q
In-Reply-To: <20180718024944.577-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
This function, being a variant of walk_system_ram_res() introduced in
commit 8c86e70acead ("resource: provide new functions to walk through
resources"), walks through a list of all the resources of System RAM
in reversed order, i.e., from higher to lower.
It will be used in kexec_file code.
Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
---
include/linux/ioport.h | 3 +++
kernel/resource.c | 40 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index b7456ae889dd..066cc263e2cc 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -279,6 +279,9 @@ extern int
walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *));
+extern int
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
void *arg, int (*func)(struct resource *, void *));
diff --git a/kernel/resource.c b/kernel/resource.c
index c96e58d3d2f8..3e18f24b90c4 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -23,6 +23,8 @@
#include <linux/pfn.h>
#include <linux/mm.h>
#include <linux/resource_ext.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -443,6 +445,44 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
}
/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *))
+{
+ unsigned long flags;
+ struct resource *res;
+ int ret = -1;
+
+ flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+
+ read_lock(&resource_lock);
+ list_for_each_entry_reverse(res, &iomem_resource.child, sibling) {
+ if (start >= end)
+ break;
+ if ((res->flags & flags) != flags)
+ continue;
+ if (res->desc != IORES_DESC_NONE)
+ continue;
+ if (res->end < start)
+ break;
+
+ if ((res->end >= start) && (res->start < end)) {
+ ret = (*func)(res, arg);
+ if (ret)
+ break;
+ }
+ end = res->start - 1;
+
+ }
+ read_unlock(&resource_lock);
+ return ret;
+}
+
+/*
* This function calls the @func callback against all memory ranges, which
* are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
*/
--
2.13.6
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related
* [PATCH v7 2/4] resource: Use list_head to link sibling resource
From: Baoquan He @ 2018-07-18 2:49 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA, brijesh.singh-5C7GfCeVMHo,
devicetree-u79uwXL29TY76Z2rM5mHXA, airlied-cv59FeDIM0c,
linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w, Paul Mackerras,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Michael Ellerman,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w, Benjamin
In-Reply-To: <20180718024944.577-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
The struct resource uses singly linked list to link siblings, implemented
by pointer operation. Replace it with list_head for better code readability.
Based on this list_head replacement, it will be very easy to do reverse
iteration on iomem_resource's sibling list in later patch.
Besides, type of member variables of struct resource, sibling and child, are
changed from 'struct resource *' to 'struct list_head'. This brings two
pointers of size increase.
Suggested-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Baoquan He <bhe@redhat.com>
Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Cc: David Airlie <airlied@linux.ie>
Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Rob Herring <robh+dt@kernel.org>
Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Keith Busch <keith.busch@intel.com>
Cc: Jonathan Derrick <jonathan.derrick@intel.com>
Cc: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Brijesh Singh <brijesh.singh@amd.com>
Cc: "Jérôme Glisse" <jglisse@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Yaowei Bai <baiyaowei@cmss.chinamobile.com>
Cc: Wei Yang <richard.weiyang@gmail.com>
Cc: devel@linuxdriverproject.org
Cc: linux-input@vger.kernel.org
Cc: linux-nvdimm@lists.01.org
Cc: devicetree@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: Michal Simek <monstr@monstr.eu>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: linux-mips@linux-mips.org
---
arch/arm/plat-samsung/pm-check.c | 6 +-
arch/ia64/sn/kernel/io_init.c | 2 +-
arch/microblaze/pci/pci-common.c | 4 +-
arch/mips/pci/pci-rc32434.c | 12 +-
arch/powerpc/kernel/pci-common.c | 4 +-
arch/sparc/kernel/ioport.c | 2 +-
arch/xtensa/include/asm/pci-bridge.h | 4 +-
drivers/eisa/eisa-bus.c | 2 +
drivers/gpu/drm/drm_memory.c | 3 +-
drivers/gpu/drm/gma500/gtt.c | 5 +-
drivers/hv/vmbus_drv.c | 52 +++----
drivers/input/joystick/iforce/iforce-main.c | 4 +-
drivers/nvdimm/namespace_devs.c | 6 +-
drivers/nvdimm/nd.h | 5 +-
drivers/of/address.c | 4 +-
drivers/parisc/lba_pci.c | 4 +-
drivers/pci/controller/vmd.c | 8 +-
drivers/pci/probe.c | 2 +
drivers/pci/setup-bus.c | 2 +-
include/linux/ioport.h | 17 ++-
kernel/resource.c | 206 ++++++++++++++--------------
21 files changed, 183 insertions(+), 171 deletions(-)
diff --git a/arch/arm/plat-samsung/pm-check.c b/arch/arm/plat-samsung/pm-check.c
index cd2c02c68bc3..5494355b1c49 100644
--- a/arch/arm/plat-samsung/pm-check.c
+++ b/arch/arm/plat-samsung/pm-check.c
@@ -46,8 +46,8 @@ typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
{
while (ptr != NULL) {
- if (ptr->child != NULL)
- s3c_pm_run_res(ptr->child, fn, arg);
+ if (!list_empty(&ptr->child))
+ s3c_pm_run_res(resource_first_child(&ptr->child), fn, arg);
if ((ptr->flags & IORESOURCE_SYSTEM_RAM)
== IORESOURCE_SYSTEM_RAM) {
@@ -57,7 +57,7 @@ static void s3c_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
arg = (fn)(ptr, arg);
}
- ptr = ptr->sibling;
+ ptr = resource_sibling(ptr);
}
}
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c
index d63809a6adfa..338a7b7f194d 100644
--- a/arch/ia64/sn/kernel/io_init.c
+++ b/arch/ia64/sn/kernel/io_init.c
@@ -192,7 +192,7 @@ sn_io_slot_fixup(struct pci_dev *dev)
* if it's already in the device structure, remove it before
* inserting
*/
- if (res->parent && res->parent->child)
+ if (res->parent && !list_empty(&res->parent->child))
release_resource(res);
if (res->flags & IORESOURCE_IO)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 7899bafab064..2bf73e27e231 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -533,7 +533,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->flags = range.flags;
res->start = range.cpu_addr;
res->end = range.cpu_addr + range.size - 1;
- res->parent = res->child = res->sibling = NULL;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
}
}
diff --git a/arch/mips/pci/pci-rc32434.c b/arch/mips/pci/pci-rc32434.c
index 7f6ce6d734c0..e80283df7925 100644
--- a/arch/mips/pci/pci-rc32434.c
+++ b/arch/mips/pci/pci-rc32434.c
@@ -53,8 +53,8 @@ static struct resource rc32434_res_pci_mem1 = {
.start = 0x50000000,
.end = 0x5FFFFFFF,
.flags = IORESOURCE_MEM,
- .sibling = NULL,
- .child = &rc32434_res_pci_mem2
+ .sibling = LIST_HEAD_INIT(rc32434_res_pci_mem1.sibling),
+ .child = LIST_HEAD_INIT(rc32434_res_pci_mem1.child),
};
static struct resource rc32434_res_pci_mem2 = {
@@ -63,8 +63,8 @@ static struct resource rc32434_res_pci_mem2 = {
.end = 0x6FFFFFFF,
.flags = IORESOURCE_MEM,
.parent = &rc32434_res_pci_mem1,
- .sibling = NULL,
- .child = NULL
+ .sibling = LIST_HEAD_INIT(rc32434_res_pci_mem2.sibling),
+ .child = LIST_HEAD_INIT(rc32434_res_pci_mem2.child),
};
static struct resource rc32434_res_pci_io1 = {
@@ -72,6 +72,8 @@ static struct resource rc32434_res_pci_io1 = {
.start = 0x18800000,
.end = 0x188FFFFF,
.flags = IORESOURCE_IO,
+ .sibling = LIST_HEAD_INIT(rc32434_res_pci_io1.sibling),
+ .child = LIST_HEAD_INIT(rc32434_res_pci_io1.child),
};
extern struct pci_ops rc32434_pci_ops;
@@ -208,6 +210,8 @@ static int __init rc32434_pci_init(void)
pr_info("PCI: Initializing PCI\n");
+ list_add(&rc32434_res_pci_mem2.sibling, &rc32434_res_pci_mem1.child);
+
ioport_resource.start = rc32434_res_pci_io1.start;
ioport_resource.end = rc32434_res_pci_io1.end;
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 926035bb378d..28fbe83c9daf 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -761,7 +761,9 @@ void pci_process_bridge_OF_ranges(struct pci_controller *hose,
res->flags = range.flags;
res->start = range.cpu_addr;
res->end = range.cpu_addr + range.size - 1;
- res->parent = res->child = res->sibling = NULL;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
}
}
}
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index cca9134cfa7d..99efe4e98b16 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -669,7 +669,7 @@ static int sparc_io_proc_show(struct seq_file *m, void *v)
struct resource *root = m->private, *r;
const char *nm;
- for (r = root->child; r != NULL; r = r->sibling) {
+ list_for_each_entry(r, &root->child, sibling) {
if ((nm = r->name) == NULL) nm = "???";
seq_printf(m, "%016llx-%016llx: %s\n",
(unsigned long long)r->start,
diff --git a/arch/xtensa/include/asm/pci-bridge.h b/arch/xtensa/include/asm/pci-bridge.h
index 0b68c76ec1e6..f487b06817df 100644
--- a/arch/xtensa/include/asm/pci-bridge.h
+++ b/arch/xtensa/include/asm/pci-bridge.h
@@ -71,8 +71,8 @@ static inline void pcibios_init_resource(struct resource *res,
res->flags = flags;
res->name = name;
res->parent = NULL;
- res->sibling = NULL;
- res->child = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
}
diff --git a/drivers/eisa/eisa-bus.c b/drivers/eisa/eisa-bus.c
index 1e8062f6dbfc..dba78f75fd06 100644
--- a/drivers/eisa/eisa-bus.c
+++ b/drivers/eisa/eisa-bus.c
@@ -408,6 +408,8 @@ static struct resource eisa_root_res = {
.start = 0,
.end = 0xffffffff,
.flags = IORESOURCE_IO,
+ .sibling = LIST_HEAD_INIT(eisa_root_res.sibling),
+ .child = LIST_HEAD_INIT(eisa_root_res.child),
};
static int eisa_bus_count;
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index d69e4fc1ee77..33baa7fa5e41 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -155,9 +155,8 @@ u64 drm_get_max_iomem(void)
struct resource *tmp;
resource_size_t max_iomem = 0;
- for (tmp = iomem_resource.child; tmp; tmp = tmp->sibling) {
+ list_for_each_entry(tmp, &iomem_resource.child, sibling)
max_iomem = max(max_iomem, tmp->end);
- }
return max_iomem;
}
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 3949b0990916..addd3bc009af 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -565,7 +565,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
int psb_gtt_restore(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- struct resource *r = dev_priv->gtt_mem->child;
+ struct resource *r;
struct gtt_range *range;
unsigned int restored = 0, total = 0, size = 0;
@@ -573,14 +573,13 @@ int psb_gtt_restore(struct drm_device *dev)
mutex_lock(&dev_priv->gtt_mutex);
psb_gtt_init(dev, 1);
- while (r != NULL) {
+ list_for_each_entry(r, &dev_priv->gtt_mem->child, sibling) {
range = container_of(r, struct gtt_range, resource);
if (range->pages) {
psb_gtt_insert(dev, range, 1);
size += range->resource.end - range->resource.start;
restored++;
}
- r = r->sibling;
total++;
}
mutex_unlock(&dev_priv->gtt_mutex);
diff --git a/drivers/hv/vmbus_drv.c b/drivers/hv/vmbus_drv.c
index b10fe26c4891..d87ec5a1bc4c 100644
--- a/drivers/hv/vmbus_drv.c
+++ b/drivers/hv/vmbus_drv.c
@@ -1412,9 +1412,8 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
{
resource_size_t start = 0;
resource_size_t end = 0;
- struct resource *new_res;
+ struct resource *new_res, *tmp;
struct resource **old_res = &hyperv_mmio;
- struct resource **prev_res = NULL;
switch (res->type) {
@@ -1461,44 +1460,36 @@ static acpi_status vmbus_walk_resources(struct acpi_resource *res, void *ctx)
/*
* If two ranges are adjacent, merge them.
*/
- do {
- if (!*old_res) {
- *old_res = new_res;
- break;
- }
-
- if (((*old_res)->end + 1) == new_res->start) {
- (*old_res)->end = new_res->end;
+ if (!*old_res) {
+ *old_res = new_res;
+ return AE_OK;
+ }
+ tmp = *old_res;
+ list_for_each_entry_from(tmp, &tmp->parent->child, sibling) {
+ if ((tmp->end + 1) == new_res->start) {
+ tmp->end = new_res->end;
kfree(new_res);
break;
}
- if ((*old_res)->start == new_res->end + 1) {
- (*old_res)->start = new_res->start;
+ if (tmp->start == new_res->end + 1) {
+ tmp->start = new_res->start;
kfree(new_res);
break;
}
- if ((*old_res)->start > new_res->end) {
- new_res->sibling = *old_res;
- if (prev_res)
- (*prev_res)->sibling = new_res;
- *old_res = new_res;
+ if (tmp->start > new_res->end) {
+ list_add(&new_res->sibling, tmp->sibling.prev);
break;
}
-
- prev_res = old_res;
- old_res = &(*old_res)->sibling;
-
- } while (1);
+ }
return AE_OK;
}
static int vmbus_acpi_remove(struct acpi_device *device)
{
- struct resource *cur_res;
- struct resource *next_res;
+ struct resource *res;
if (hyperv_mmio) {
if (fb_mmio) {
@@ -1507,10 +1498,9 @@ static int vmbus_acpi_remove(struct acpi_device *device)
fb_mmio = NULL;
}
- for (cur_res = hyperv_mmio; cur_res; cur_res = next_res) {
- next_res = cur_res->sibling;
- kfree(cur_res);
- }
+ res = hyperv_mmio;
+ list_for_each_entry_from(res, &res->parent->child, sibling)
+ kfree(res);
}
return 0;
@@ -1596,7 +1586,8 @@ int vmbus_allocate_mmio(struct resource **new, struct hv_device *device_obj,
}
}
- for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ iter = hyperv_mmio;
+ list_for_each_entry_from(iter, &iter->parent->child, sibling) {
if ((iter->start >= max) || (iter->end <= min))
continue;
@@ -1639,7 +1630,8 @@ void vmbus_free_mmio(resource_size_t start, resource_size_t size)
struct resource *iter;
down(&hyperv_mmio_lock);
- for (iter = hyperv_mmio; iter; iter = iter->sibling) {
+ iter = hyperv_mmio;
+ list_for_each_entry_from(iter, &iter->parent->child, sibling) {
if ((iter->start >= start + size) || (iter->end <= start))
continue;
diff --git a/drivers/input/joystick/iforce/iforce-main.c b/drivers/input/joystick/iforce/iforce-main.c
index daeeb4c7e3b0..5c0be27b33ff 100644
--- a/drivers/input/joystick/iforce/iforce-main.c
+++ b/drivers/input/joystick/iforce/iforce-main.c
@@ -305,8 +305,8 @@ int iforce_init_device(struct iforce *iforce)
iforce->device_memory.end = 200;
iforce->device_memory.flags = IORESOURCE_MEM;
iforce->device_memory.parent = NULL;
- iforce->device_memory.child = NULL;
- iforce->device_memory.sibling = NULL;
+ INIT_LIST_HEAD(&iforce->device_memory.child);
+ INIT_LIST_HEAD(&iforce->device_memory.sibling);
/*
* Wait until device ready - until it sends its first response.
diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c
index 28afdd668905..f53d410d9981 100644
--- a/drivers/nvdimm/namespace_devs.c
+++ b/drivers/nvdimm/namespace_devs.c
@@ -637,7 +637,7 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
retry:
first = 0;
for_each_dpa_resource(ndd, res) {
- struct resource *next = res->sibling, *new_res = NULL;
+ struct resource *next = resource_sibling(res), *new_res = NULL;
resource_size_t allocate, available = 0;
enum alloc_loc loc = ALLOC_ERR;
const char *action;
@@ -763,7 +763,7 @@ static resource_size_t scan_allocate(struct nd_region *nd_region,
* an initial "pmem-reserve pass". Only do an initial BLK allocation
* when none of the DPA space is reserved.
*/
- if ((is_pmem || !ndd->dpa.child) && n == to_allocate)
+ if ((is_pmem || list_empty(&ndd->dpa.child)) && n == to_allocate)
return init_dpa_allocation(label_id, nd_region, nd_mapping, n);
return n;
}
@@ -779,7 +779,7 @@ static int merge_dpa(struct nd_region *nd_region,
retry:
for_each_dpa_resource(ndd, res) {
int rc;
- struct resource *next = res->sibling;
+ struct resource *next = resource_sibling(res);
resource_size_t end = res->start + resource_size(res);
if (!next || strcmp(res->name, label_id->id) != 0
diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h
index 32e0364b48b9..da7da15e03e7 100644
--- a/drivers/nvdimm/nd.h
+++ b/drivers/nvdimm/nd.h
@@ -102,11 +102,10 @@ unsigned sizeof_namespace_label(struct nvdimm_drvdata *ndd);
(unsigned long long) (res ? res->start : 0), ##arg)
#define for_each_dpa_resource(ndd, res) \
- for (res = (ndd)->dpa.child; res; res = res->sibling)
+ list_for_each_entry(res, &(ndd)->dpa.child, sibling)
#define for_each_dpa_resource_safe(ndd, res, next) \
- for (res = (ndd)->dpa.child, next = res ? res->sibling : NULL; \
- res; res = next, next = next ? next->sibling : NULL)
+ list_for_each_entry_safe(res, next, &(ndd)->dpa.child, sibling)
struct nd_percpu_lane {
int count;
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 53349912ac75..e2e25719ab52 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -330,7 +330,9 @@ int of_pci_range_to_resource(struct of_pci_range *range,
{
int err;
res->flags = range->flags;
- res->parent = res->child = res->sibling = NULL;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
res->name = np->full_name;
if (res->flags & IORESOURCE_IO) {
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 69bd98421eb1..7482bdfd1959 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -170,8 +170,8 @@ lba_dump_res(struct resource *r, int d)
for (i = d; i ; --i) printk(" ");
printk(KERN_DEBUG "%p [%lx,%lx]/%lx\n", r,
(long)r->start, (long)r->end, r->flags);
- lba_dump_res(r->child, d+2);
- lba_dump_res(r->sibling, d);
+ lba_dump_res(resource_first_child(&r->child), d+2);
+ lba_dump_res(resource_sibling(r), d);
}
diff --git a/drivers/pci/controller/vmd.c b/drivers/pci/controller/vmd.c
index 942b64fc7f1f..e3ace20345c7 100644
--- a/drivers/pci/controller/vmd.c
+++ b/drivers/pci/controller/vmd.c
@@ -542,14 +542,14 @@ static struct pci_ops vmd_ops = {
static void vmd_attach_resources(struct vmd_dev *vmd)
{
- vmd->dev->resource[VMD_MEMBAR1].child = &vmd->resources[1];
- vmd->dev->resource[VMD_MEMBAR2].child = &vmd->resources[2];
+ list_add(&vmd->resources[1].sibling, &vmd->dev->resource[VMD_MEMBAR1].child);
+ list_add(&vmd->resources[2].sibling, &vmd->dev->resource[VMD_MEMBAR2].child);
}
static void vmd_detach_resources(struct vmd_dev *vmd)
{
- vmd->dev->resource[VMD_MEMBAR1].child = NULL;
- vmd->dev->resource[VMD_MEMBAR2].child = NULL;
+ INIT_LIST_HEAD(&vmd->dev->resource[VMD_MEMBAR1].child);
+ INIT_LIST_HEAD(&vmd->dev->resource[VMD_MEMBAR2].child);
}
/*
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index ac876e32de4b..9624dd1dfd49 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -59,6 +59,8 @@ static struct resource *get_pci_domain_busn_res(int domain_nr)
r->res.start = 0;
r->res.end = 0xff;
r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED;
+ INIT_LIST_HEAD(&r->res.child);
+ INIT_LIST_HEAD(&r->res.sibling);
list_add_tail(&r->list, &pci_domain_busn_res_list);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 79b1824e83b4..8e685af8938d 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -2107,7 +2107,7 @@ int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type)
continue;
/* Ignore BARs which are still in use */
- if (res->child)
+ if (!list_empty(&res->child))
continue;
ret = add_to_list(&saved, bridge, res, 0, 0);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index dfdcd0bfe54e..b7456ae889dd 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -12,6 +12,7 @@
#ifndef __ASSEMBLY__
#include <linux/compiler.h>
#include <linux/types.h>
+#include <linux/list.h>
/*
* Resources are tree-like, allowing
* nesting etc..
@@ -22,7 +23,8 @@ struct resource {
const char *name;
unsigned long flags;
unsigned long desc;
- struct resource *parent, *sibling, *child;
+ struct list_head child, sibling;
+ struct resource *parent;
};
/*
@@ -216,7 +218,6 @@ static inline bool resource_contains(struct resource *r1, struct resource *r2)
return r1->start <= r2->start && r1->end >= r2->end;
}
-
/* Convenience shorthand with allocation */
#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), 0)
#define request_muxed_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name), IORESOURCE_MUXED)
@@ -287,6 +288,18 @@ static inline bool resource_overlaps(struct resource *r1, struct resource *r2)
return (r1->start <= r2->end && r1->end >= r2->start);
}
+static inline struct resource *resource_sibling(struct resource *res)
+{
+ if (res->parent && !list_is_last(&res->sibling, &res->parent->child))
+ return list_next_entry(res, sibling);
+ return NULL;
+}
+
+static inline struct resource *resource_first_child(struct list_head *head)
+{
+ return list_first_entry_or_null(head, struct resource, sibling);
+}
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_IOPORT_H */
diff --git a/kernel/resource.c b/kernel/resource.c
index 81ccd19c1d9f..c96e58d3d2f8 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -31,6 +31,8 @@ struct resource ioport_resource = {
.start = 0,
.end = IO_SPACE_LIMIT,
.flags = IORESOURCE_IO,
+ .sibling = LIST_HEAD_INIT(ioport_resource.sibling),
+ .child = LIST_HEAD_INIT(ioport_resource.child),
};
EXPORT_SYMBOL(ioport_resource);
@@ -39,6 +41,8 @@ struct resource iomem_resource = {
.start = 0,
.end = -1,
.flags = IORESOURCE_MEM,
+ .sibling = LIST_HEAD_INIT(iomem_resource.sibling),
+ .child = LIST_HEAD_INIT(iomem_resource.child),
};
EXPORT_SYMBOL(iomem_resource);
@@ -57,20 +61,20 @@ static DEFINE_RWLOCK(resource_lock);
* by boot mem after the system is up. So for reusing the resource entry
* we need to remember the resource.
*/
-static struct resource *bootmem_resource_free;
+static struct list_head bootmem_resource_free = LIST_HEAD_INIT(bootmem_resource_free);
static DEFINE_SPINLOCK(bootmem_resource_lock);
static struct resource *next_resource(struct resource *p, bool sibling_only)
{
/* Caller wants to traverse through siblings only */
if (sibling_only)
- return p->sibling;
+ return resource_sibling(p);
- if (p->child)
- return p->child;
- while (!p->sibling && p->parent)
+ if (!list_empty(&p->child))
+ return resource_first_child(&p->child);
+ while (!resource_sibling(p) && p->parent)
p = p->parent;
- return p->sibling;
+ return resource_sibling(p);
}
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
@@ -90,7 +94,7 @@ static void *r_start(struct seq_file *m, loff_t *pos)
struct resource *p = PDE_DATA(file_inode(m->file));
loff_t l = 0;
read_lock(&resource_lock);
- for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
+ for (p = resource_first_child(&p->child); p && l < *pos; p = r_next(m, p, &l))
;
return p;
}
@@ -153,8 +157,7 @@ static void free_resource(struct resource *res)
if (!PageSlab(virt_to_head_page(res))) {
spin_lock(&bootmem_resource_lock);
- res->sibling = bootmem_resource_free;
- bootmem_resource_free = res;
+ list_add(&res->sibling, &bootmem_resource_free);
spin_unlock(&bootmem_resource_lock);
} else {
kfree(res);
@@ -166,10 +169,9 @@ static struct resource *alloc_resource(gfp_t flags)
struct resource *res = NULL;
spin_lock(&bootmem_resource_lock);
- if (bootmem_resource_free) {
- res = bootmem_resource_free;
- bootmem_resource_free = res->sibling;
- }
+ res = resource_first_child(&bootmem_resource_free);
+ if (res)
+ list_del(&res->sibling);
spin_unlock(&bootmem_resource_lock);
if (res)
@@ -177,6 +179,8 @@ static struct resource *alloc_resource(gfp_t flags)
else
res = kzalloc(sizeof(struct resource), flags);
+ INIT_LIST_HEAD(&res->child);
+ INIT_LIST_HEAD(&res->sibling);
return res;
}
@@ -185,7 +189,7 @@ static struct resource * __request_resource(struct resource *root, struct resour
{
resource_size_t start = new->start;
resource_size_t end = new->end;
- struct resource *tmp, **p;
+ struct resource *tmp;
if (end < start)
return root;
@@ -193,64 +197,62 @@ static struct resource * __request_resource(struct resource *root, struct resour
return root;
if (end > root->end)
return root;
- p = &root->child;
- for (;;) {
- tmp = *p;
- if (!tmp || tmp->start > end) {
- new->sibling = tmp;
- *p = new;
+
+ if (list_empty(&root->child)) {
+ list_add(&new->sibling, &root->child);
+ new->parent = root;
+ INIT_LIST_HEAD(&new->child);
+ return NULL;
+ }
+
+ list_for_each_entry(tmp, &root->child, sibling) {
+ if (tmp->start > end) {
+ list_add(&new->sibling, tmp->sibling.prev);
new->parent = root;
+ INIT_LIST_HEAD(&new->child);
return NULL;
}
- p = &tmp->sibling;
if (tmp->end < start)
continue;
return tmp;
}
+
+ list_add_tail(&new->sibling, &root->child);
+ new->parent = root;
+ INIT_LIST_HEAD(&new->child);
+ return NULL;
}
static int __release_resource(struct resource *old, bool release_child)
{
- struct resource *tmp, **p, *chd;
+ struct resource *tmp, *next, *chd;
- p = &old->parent->child;
- for (;;) {
- tmp = *p;
- if (!tmp)
- break;
+ list_for_each_entry_safe(tmp, next, &old->parent->child, sibling) {
if (tmp == old) {
- if (release_child || !(tmp->child)) {
- *p = tmp->sibling;
+ if (release_child || list_empty(&tmp->child)) {
+ list_del(&tmp->sibling);
} else {
- for (chd = tmp->child;; chd = chd->sibling) {
+ list_for_each_entry(chd, &tmp->child, sibling)
chd->parent = tmp->parent;
- if (!(chd->sibling))
- break;
- }
- *p = tmp->child;
- chd->sibling = tmp->sibling;
+ list_splice(&tmp->child, tmp->sibling.prev);
+ list_del(&tmp->sibling);
}
+
old->parent = NULL;
return 0;
}
- p = &tmp->sibling;
}
return -EINVAL;
}
static void __release_child_resources(struct resource *r)
{
- struct resource *tmp, *p;
+ struct resource *tmp, *next;
resource_size_t size;
- p = r->child;
- r->child = NULL;
- while (p) {
- tmp = p;
- p = p->sibling;
-
+ list_for_each_entry_safe(tmp, next, &r->child, sibling) {
tmp->parent = NULL;
- tmp->sibling = NULL;
+ list_del_init(&tmp->sibling);
__release_child_resources(tmp);
printk(KERN_DEBUG "release child resource %pR\n", tmp);
@@ -259,6 +261,8 @@ static void __release_child_resources(struct resource *r)
tmp->start = 0;
tmp->end = size - 1;
}
+
+ INIT_LIST_HEAD(&tmp->child);
}
void release_child_resources(struct resource *r)
@@ -343,7 +347,8 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
read_lock(&resource_lock);
- for (p = iomem_resource.child; p; p = next_resource(p, sibling_only)) {
+ for (p = resource_first_child(&iomem_resource.child); p;
+ p = next_resource(p, sibling_only)) {
if ((p->flags & res->flags) != res->flags)
continue;
if ((desc != IORES_DESC_NONE) && (desc != p->desc))
@@ -532,7 +537,7 @@ int region_intersects(resource_size_t start, size_t size, unsigned long flags,
struct resource *p;
read_lock(&resource_lock);
- for (p = iomem_resource.child; p ; p = p->sibling) {
+ list_for_each_entry(p, &iomem_resource.child, sibling) {
bool is_type = (((p->flags & flags) == flags) &&
((desc == IORES_DESC_NONE) ||
(desc == p->desc)));
@@ -586,7 +591,7 @@ static int __find_resource(struct resource *root, struct resource *old,
resource_size_t size,
struct resource_constraint *constraint)
{
- struct resource *this = root->child;
+ struct resource *this = resource_first_child(&root->child);
struct resource tmp = *new, avail, alloc;
tmp.start = root->start;
@@ -596,7 +601,7 @@ static int __find_resource(struct resource *root, struct resource *old,
*/
if (this && this->start == root->start) {
tmp.start = (this == old) ? old->start : this->end + 1;
- this = this->sibling;
+ this = resource_sibling(this);
}
for(;;) {
if (this)
@@ -632,7 +637,7 @@ next: if (!this || this->end == root->end)
if (this != old)
tmp.start = this->end + 1;
- this = this->sibling;
+ this = resource_sibling(this);
}
return -EBUSY;
}
@@ -676,7 +681,7 @@ static int reallocate_resource(struct resource *root, struct resource *old,
goto out;
}
- if (old->child) {
+ if (!list_empty(&old->child)) {
err = -EBUSY;
goto out;
}
@@ -757,7 +762,7 @@ struct resource *lookup_resource(struct resource *root, resource_size_t start)
struct resource *res;
read_lock(&resource_lock);
- for (res = root->child; res; res = res->sibling) {
+ list_for_each_entry(res, &root->child, sibling) {
if (res->start == start)
break;
}
@@ -790,32 +795,27 @@ static struct resource * __insert_resource(struct resource *parent, struct resou
break;
}
- for (next = first; ; next = next->sibling) {
+ for (next = first; ; next = resource_sibling(next)) {
/* Partial overlap? Bad, and unfixable */
if (next->start < new->start || next->end > new->end)
return next;
- if (!next->sibling)
+ if (!resource_sibling(next))
break;
- if (next->sibling->start > new->end)
+ if (resource_sibling(next)->start > new->end)
break;
}
-
new->parent = parent;
- new->sibling = next->sibling;
- new->child = first;
+ list_add(&new->sibling, &next->sibling);
+ INIT_LIST_HEAD(&new->child);
- next->sibling = NULL;
- for (next = first; next; next = next->sibling)
+ /*
+ * From first to next, they all fall into new's region, so change them
+ * as new's children.
+ */
+ list_cut_position(&new->child, first->sibling.prev, &next->sibling);
+ list_for_each_entry(next, &new->child, sibling)
next->parent = new;
- if (parent->child == first) {
- parent->child = new;
- } else {
- next = parent->child;
- while (next->sibling != first)
- next = next->sibling;
- next->sibling = new;
- }
return NULL;
}
@@ -937,19 +937,17 @@ static int __adjust_resource(struct resource *res, resource_size_t start,
if ((start < parent->start) || (end > parent->end))
goto out;
- if (res->sibling && (res->sibling->start <= end))
+ if (resource_sibling(res) && (resource_sibling(res)->start <= end))
goto out;
- tmp = parent->child;
- if (tmp != res) {
- while (tmp->sibling != res)
- tmp = tmp->sibling;
+ if (res->sibling.prev != &parent->child) {
+ tmp = list_prev_entry(res, sibling);
if (start <= tmp->end)
goto out;
}
skip:
- for (tmp = res->child; tmp; tmp = tmp->sibling)
+ list_for_each_entry(tmp, &res->child, sibling)
if ((tmp->start < start) || (tmp->end > end))
goto out;
@@ -996,27 +994,30 @@ EXPORT_SYMBOL(adjust_resource);
*/
int reparent_resources(struct resource *parent, struct resource *res)
{
- struct resource *p, **pp;
- struct resource **firstpp = NULL;
+ struct resource *p, *first = NULL;
- for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+ list_for_each_entry(p, &parent->child, sibling) {
if (p->end < res->start)
continue;
if (res->end < p->start)
break;
if (p->start < res->start || p->end > res->end)
return -ENOTSUPP; /* not completely contained */
- if (firstpp == NULL)
- firstpp = pp;
+ if (first == NULL)
+ first = p;
}
- if (firstpp == NULL)
+ if (first == NULL)
return -ECANCELED; /* didn't find any conflicting entries? */
res->parent = parent;
- res->child = *firstpp;
- res->sibling = *pp;
- *firstpp = res;
- *pp = NULL;
- for (p = res->child; p != NULL; p = p->sibling) {
+ list_add(&res->sibling, p->sibling.prev);
+ INIT_LIST_HEAD(&res->child);
+
+ /*
+ * From first to p's previous sibling, they all fall into
+ * res's region, change them as res's children.
+ */
+ list_cut_position(&res->child, first->sibling.prev, res->sibling.prev);
+ list_for_each_entry(p, &res->child, sibling) {
p->parent = res;
pr_debug("PCI: Reparented %s %pR under %s\n",
p->name, p, res->name);
@@ -1216,34 +1217,32 @@ EXPORT_SYMBOL(__request_region);
void __release_region(struct resource *parent, resource_size_t start,
resource_size_t n)
{
- struct resource **p;
+ struct resource *res;
resource_size_t end;
- p = &parent->child;
+ res = resource_first_child(&parent->child);
end = start + n - 1;
write_lock(&resource_lock);
for (;;) {
- struct resource *res = *p;
-
if (!res)
break;
if (res->start <= start && res->end >= end) {
if (!(res->flags & IORESOURCE_BUSY)) {
- p = &res->child;
+ res = resource_first_child(&res->child);
continue;
}
if (res->start != start || res->end != end)
break;
- *p = res->sibling;
+ list_del(&res->sibling);
write_unlock(&resource_lock);
if (res->flags & IORESOURCE_MUXED)
wake_up(&muxed_resource_wait);
free_resource(res);
return;
}
- p = &res->sibling;
+ res = resource_sibling(res);
}
write_unlock(&resource_lock);
@@ -1278,9 +1277,7 @@ EXPORT_SYMBOL(__release_region);
int release_mem_region_adjustable(struct resource *parent,
resource_size_t start, resource_size_t size)
{
- struct resource **p;
- struct resource *res;
- struct resource *new_res;
+ struct resource *res, *new_res;
resource_size_t end;
int ret = -EINVAL;
@@ -1291,16 +1288,16 @@ int release_mem_region_adjustable(struct resource *parent,
/* The alloc_resource() result gets checked later */
new_res = alloc_resource(GFP_KERNEL);
- p = &parent->child;
+ res = resource_first_child(&parent->child);
write_lock(&resource_lock);
- while ((res = *p)) {
+ while ((res)) {
if (res->start >= end)
break;
/* look for the next resource if it does not fit into */
if (res->start > start || res->end < end) {
- p = &res->sibling;
+ res = resource_sibling(res);
continue;
}
@@ -1308,14 +1305,14 @@ int release_mem_region_adjustable(struct resource *parent,
break;
if (!(res->flags & IORESOURCE_BUSY)) {
- p = &res->child;
+ res = resource_first_child(&res->child);
continue;
}
/* found the target resource; let's adjust accordingly */
if (res->start == start && res->end == end) {
/* free the whole entry */
- *p = res->sibling;
+ list_del(&res->sibling);
free_resource(res);
ret = 0;
} else if (res->start == start && res->end != end) {
@@ -1338,14 +1335,13 @@ int release_mem_region_adjustable(struct resource *parent,
new_res->flags = res->flags;
new_res->desc = res->desc;
new_res->parent = res->parent;
- new_res->sibling = res->sibling;
- new_res->child = NULL;
+ INIT_LIST_HEAD(&new_res->child);
ret = __adjust_resource(res, res->start,
start - res->start);
if (ret)
break;
- res->sibling = new_res;
+ list_add(&new_res->sibling, &res->sibling);
new_res = NULL;
}
@@ -1526,7 +1522,7 @@ static int __init reserve_setup(char *str)
res->end = io_start + io_num - 1;
res->flags |= IORESOURCE_BUSY;
res->desc = IORES_DESC_NONE;
- res->child = NULL;
+ INIT_LIST_HEAD(&res->child);
if (request_resource(parent, res) == 0)
reserved = x+1;
}
@@ -1546,7 +1542,7 @@ int iomem_map_sanity_check(resource_size_t addr, unsigned long size)
loff_t l;
read_lock(&resource_lock);
- for (p = p->child; p ; p = r_next(NULL, p, &l)) {
+ for (p = resource_first_child(&p->child); p; p = r_next(NULL, p, &l)) {
/*
* We can probably skip the resources without
* IORESOURCE_IO attribute?
@@ -1602,7 +1598,7 @@ bool iomem_is_exclusive(u64 addr)
addr = addr & PAGE_MASK;
read_lock(&resource_lock);
- for (p = p->child; p ; p = r_next(NULL, p, &l)) {
+ for (p = resource_first_child(&p->child); p; p = r_next(NULL, p, &l)) {
/*
* We can probably skip the resources without
* IORESOURCE_IO attribute?
--
2.13.6
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm
^ permalink raw reply related
* [PATCH v7 1/4] resource: Move reparent_resources() to kernel/resource.c and make it public
From: Baoquan He @ 2018-07-18 2:49 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w, Paul Mackerras,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw, Michael Ellerman,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w, Benjamin Herrenschmidt
In-Reply-To: <20180718024944.577-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
reparent_resources() is duplicated in arch/microblaze/pci/pci-common.c
and arch/powerpc/kernel/pci-common.c, so move it to kernel/resource.c
so that it's shared.
Reviewed-by: Andy Shevchenko <andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Signed-off-by: Baoquan He <bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: Michal Simek <monstr-pSz03upnqPeHXe+LvDLADg@public.gmane.org>
Cc: Benjamin Herrenschmidt <benh-XVmvHMARGAS8U2dJNN8I7kB+6BGkLq7r@public.gmane.org>
Cc: Paul Mackerras <paulus-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
Cc: Michael Ellerman <mpe-Gsx/Oe8HsFggBc27wqDAHg@public.gmane.org>
Cc: linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org
---
arch/microblaze/pci/pci-common.c | 37 -----------------------------------
arch/powerpc/kernel/pci-common.c | 35 ---------------------------------
include/linux/ioport.h | 1 +
kernel/resource.c | 42 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 43 insertions(+), 72 deletions(-)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index f34346d56095..7899bafab064 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -619,43 +619,6 @@ int pcibios_add_device(struct pci_dev *dev)
EXPORT_SYMBOL(pcibios_add_device);
/*
- * Reparent resource children of pr that conflict with res
- * under res, and make res replace those children.
- */
-static int __init reparent_resources(struct resource *parent,
- struct resource *res)
-{
- struct resource *p, **pp;
- struct resource **firstpp = NULL;
-
- for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
- if (p->end < res->start)
- continue;
- if (res->end < p->start)
- break;
- if (p->start < res->start || p->end > res->end)
- return -1; /* not completely contained */
- if (firstpp == NULL)
- firstpp = pp;
- }
- if (firstpp == NULL)
- return -1; /* didn't find any conflicting entries? */
- res->parent = parent;
- res->child = *firstpp;
- res->sibling = *pp;
- *firstpp = res;
- *pp = NULL;
- for (p = res->child; p != NULL; p = p->sibling) {
- p->parent = res;
- pr_debug("PCI: Reparented %s [%llx..%llx] under %s\n",
- p->name,
- (unsigned long long)p->start,
- (unsigned long long)p->end, res->name);
- }
- return 0;
-}
-
-/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
* On the other hand, we cannot just re-allocate all devices, as it would
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index fe9733ffffaa..926035bb378d 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1088,41 +1088,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
EXPORT_SYMBOL(pcibios_align_resource);
/*
- * Reparent resource children of pr that conflict with res
- * under res, and make res replace those children.
- */
-static int reparent_resources(struct resource *parent,
- struct resource *res)
-{
- struct resource *p, **pp;
- struct resource **firstpp = NULL;
-
- for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
- if (p->end < res->start)
- continue;
- if (res->end < p->start)
- break;
- if (p->start < res->start || p->end > res->end)
- return -1; /* not completely contained */
- if (firstpp == NULL)
- firstpp = pp;
- }
- if (firstpp == NULL)
- return -1; /* didn't find any conflicting entries? */
- res->parent = parent;
- res->child = *firstpp;
- res->sibling = *pp;
- *firstpp = res;
- *pp = NULL;
- for (p = res->child; p != NULL; p = p->sibling) {
- p->parent = res;
- pr_debug("PCI: Reparented %s %pR under %s\n",
- p->name, p, res->name);
- }
- return 0;
-}
-
-/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
* On the other hand, we cannot just re-allocate all devices, as it would
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..dfdcd0bfe54e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -192,6 +192,7 @@ extern int allocate_resource(struct resource *root, struct resource *new,
struct resource *lookup_resource(struct resource *root, resource_size_t start);
int adjust_resource(struct resource *res, resource_size_t start,
resource_size_t size);
+int reparent_resources(struct resource *parent, struct resource *res);
resource_size_t resource_alignment(struct resource *res);
static inline resource_size_t resource_size(const struct resource *res)
{
diff --git a/kernel/resource.c b/kernel/resource.c
index 30e1bc68503b..81ccd19c1d9f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -983,6 +983,48 @@ int adjust_resource(struct resource *res, resource_size_t start,
}
EXPORT_SYMBOL(adjust_resource);
+/**
+ * reparent_resources - reparent resource children of parent that res covers
+ * @parent: parent resource descriptor
+ * @res: resource descriptor desired by caller
+ *
+ * Returns 0 on success, -ENOTSUPP if child resource is not completely
+ * contained by 'res', -ECANCELED if no any conflicting entry found.
+ *
+ * Reparent resource children of 'parent' that conflict with 'res'
+ * under 'res', and make 'res' replace those children.
+ */
+int reparent_resources(struct resource *parent, struct resource *res)
+{
+ struct resource *p, **pp;
+ struct resource **firstpp = NULL;
+
+ for (pp = &parent->child; (p = *pp) != NULL; pp = &p->sibling) {
+ if (p->end < res->start)
+ continue;
+ if (res->end < p->start)
+ break;
+ if (p->start < res->start || p->end > res->end)
+ return -ENOTSUPP; /* not completely contained */
+ if (firstpp == NULL)
+ firstpp = pp;
+ }
+ if (firstpp == NULL)
+ return -ECANCELED; /* didn't find any conflicting entries? */
+ res->parent = parent;
+ res->child = *firstpp;
+ res->sibling = *pp;
+ *firstpp = res;
+ *pp = NULL;
+ for (p = res->child; p != NULL; p = p->sibling) {
+ p->parent = res;
+ pr_debug("PCI: Reparented %s %pR under %s\n",
+ p->name, p, res->name);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(reparent_resources);
+
static void __init __reserve_region_with_split(struct resource *root,
resource_size_t start, resource_size_t end,
const char *name)
--
2.13.6
^ permalink raw reply related
* [PATCH v7 0/4] resource: Use list_head to link sibling resource
From: Baoquan He @ 2018-07-18 2:49 UTC (permalink / raw)
To: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
dan.j.williams-ral2JQCrhuEAvxtiuMwx3w,
nicolas.pitre-QSEj5FYQhm4dnm+yROfE0A, josh-iaAMLnmF4UmaiuxdJuQwMA,
fengguang.wu-ral2JQCrhuEAvxtiuMwx3w, bp-l3A5Bk7waGM,
andy.shevchenko-Re5JQEeQqe8AvxtiuMwx3w
Cc: brijesh.singh-5C7GfCeVMHo, devicetree-u79uwXL29TY76Z2rM5mHXA,
airlied-cv59FeDIM0c, linux-pci-u79uwXL29TY76Z2rM5mHXA,
richard.weiyang-Re5JQEeQqe8AvxtiuMwx3w,
jcmvbkbc-Re5JQEeQqe8AvxtiuMwx3w,
baiyaowei-0p4V/sDNsUmm0O/7XYngnFaTQe2KTcn/,
kys-0li6OtcxBFHby3iVrkZq2A, frowand.list-Re5JQEeQqe8AvxtiuMwx3w,
lorenzo.pieralisi-5wv7dgnIgG8, sthemmin-0li6OtcxBFHby3iVrkZq2A,
Baoquan He, linux-nvdimm-hn68Rpc1hR1g9hUCZPvPmw,
patrik.r.jakobsson-Re5JQEeQqe8AvxtiuMwx3w,
linux-input-u79uwXL29TY76Z2rM5mHXA,
gustavo-THi1TnShQwVAfugRpC6u6w, dyoung-H+wXaHxf7aLQT0dZR+AlfA,
thomas.lendacky-5C7GfCeVMHo, haiyangz-0li6OtcxBFHby3iVrkZq2A,
maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA,
jglisse-H+wXaHxf7aLQT0dZR+AlfA, seanpaul-F7+t8E8rja9g9hUCZPvPmw,
bhelgaas-hpIqsD4AKlfQT0dZR+AlfA, tglx-hfZtesqFncYOwBW4kG4KsQ,
yinghai-DgEjT+Ai2ygdnm+yROfE0A,
jonathan.derrick-ral2JQCrhuEAvxtiuMwx3w,
chris-YvXeqwSYzG2sTnJN9+BGXg, monstr-pSz03upnqPeHXe+LvDLADg,
linux-parisc-u79uwXL29TY76Z2rM5mHXA,
gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
dmitry.torokhov-Re5JQEeQqe8AvxtiuMwx3w,
ebiederm-aS9lmoZGLiVWk0Htik3J/w,
devel-tBiZLqfeLfOHmIFyCCdPziST3g8Odh+X,
linuxppc-dev-uLR06cmDAlY/bJ5BZ2RsiQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q
This patchset is doing:
1) Move reparent_resources() to kernel/resource.c to clean up duplicated
code in arch/microblaze/pci/pci-common.c and
arch/powerpc/kernel/pci-common.c .
2) Replace struct resource's sibling list from singly linked list to
list_head. Clearing out those pointer operation within singly linked
list for better code readability.
2) Based on list_head replacement, add a new function
walk_system_ram_res_rev() which can does reversed iteration on
iomem_resource's siblings.
3) Change kexec_file loading to search system RAM top down for kernel
loadin, using walk_system_ram_res_rev().
Note:
This patchset only passed testing on x86_64 arch with network
enabling. The thing we need pay attetion to is that a root resource's
child member need be initialized specifically with LIST_HEAD_INIT() if
statically defined or INIT_LIST_HEAD() for dynamically definition. Here
Just like we do for iomem_resource/ioport_resource, or the change in
get_pci_domain_busn_res().
v6:
http://lkml.kernel.org/r/20180704041038.8190-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
v5:
http://lkml.kernel.org/r/20180612032831.29747-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
v4:
http://lkml.kernel.org/r/20180507063224.24229-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
v3:
http://lkml.kernel.org/r/20180419001848.3041-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
v2:
http://lkml.kernel.org/r/20180408024724.16812-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
v1:
http://lkml.kernel.org/r/20180322033722.9279-1-bhe-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Changelog:
v6->v7:
Fix code bugs that test robot reported on mips and ia64.
Add error code description in reparent_resources() according to
Andy's comment, and fix minor log typo.
v5->v6:
Fix code style problems in reparent_resources() and use existing
error codes, according to Andy's suggestion.
Fix bugs test robot reported.
v4->v5:
Add new patch 0001 to move duplicated reparent_resources() to
kernel/resource.c to make it be shared by different ARCH-es.
Fix several code bugs reported by test robot on ARCH powerpc and
microblaze.
v3->v4:
Fix several bugs test robot reported. Rewrite cover letter and patch
log according to reviewer's comment.
v2->v3:
Rename resource functions first_child() and sibling() to
resource_first_chils() and resource_sibling(). Dan suggested this.
Move resource_first_chils() and resource_sibling() to linux/ioport.h
and make them as inline function. Rob suggested this. Accordingly add
linux/list.h including in linux/ioport.h, please help review if this
bring efficiency degradation or code redundancy.
The change on struct resource {} bring two pointers of size increase,
mention this in git log to make it more specifically, Rob suggested
this.
v1->v2:
Use list_head instead to link resource siblings. This is suggested by
Andrew.
Rewrite walk_system_ram_res_rev() after list_head is taken to link
resouce siblings.
Baoquan He (4):
resource: Move reparent_resources() to kernel/resource.c and make it
public
resource: Use list_head to link sibling resource
resource: add walk_system_ram_res_rev()
kexec_file: Load kernel at top of system RAM if required
arch/arm/plat-samsung/pm-check.c | 6 +-
arch/ia64/sn/kernel/io_init.c | 2 +-
arch/microblaze/pci/pci-common.c | 41 +----
arch/mips/pci/pci-rc32434.c | 12 +-
arch/powerpc/kernel/pci-common.c | 39 +---
arch/sparc/kernel/ioport.c | 2 +-
arch/xtensa/include/asm/pci-bridge.h | 4 +-
drivers/eisa/eisa-bus.c | 2 +
drivers/gpu/drm/drm_memory.c | 3 +-
drivers/gpu/drm/gma500/gtt.c | 5 +-
drivers/hv/vmbus_drv.c | 52 +++---
drivers/input/joystick/iforce/iforce-main.c | 4 +-
drivers/nvdimm/namespace_devs.c | 6 +-
drivers/nvdimm/nd.h | 5 +-
drivers/of/address.c | 4 +-
drivers/parisc/lba_pci.c | 4 +-
drivers/pci/controller/vmd.c | 8 +-
drivers/pci/probe.c | 2 +
drivers/pci/setup-bus.c | 2 +-
include/linux/ioport.h | 21 ++-
kernel/kexec_file.c | 2 +
kernel/resource.c | 266 ++++++++++++++++++----------
22 files changed, 260 insertions(+), 232 deletions(-)
--
2.13.6
^ permalink raw reply
* Re: [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.
From: Nick Dyer @ 2018-07-17 21:00 UTC (permalink / raw)
To: Paweł Chmiel
Cc: dmitry.torokhov, robh+dt, mark.rutland, nicolas.ferre,
alexandre.belloni, linux-input, devicetree, linux-arm-kernel,
linux-kernel
In-Reply-To: <1531851386-17840-2-git-send-email-pawel.mikolaj.chmiel@gmail.com>
On Tue, Jul 17, 2018 at 08:16:25PM +0200, Paweł Chmiel wrote:
> This patch adds optional regulators, which can be used to power
> up touchscreen. After enabling regulators, we need to wait 150msec.
> This value is taken from official driver.
>
> It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
>
> Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> ---
> Changes from v1:
> - Enable regulators only if reset_gpio is present.
> - Switch from devm_regulator_get_optional to devm_regulator_get
> ---
> drivers/input/touchscreen/atmel_mxt_ts.c | 46 ++++++++++++++++++++++++++++++--
> 1 file changed, 44 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> index 54fe190fd4bc..005f0fee9fc8 100644
> --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> @@ -27,6 +27,7 @@
> #include <linux/interrupt.h>
> #include <linux/of.h>
> #include <linux/property.h>
> +#include <linux/regulator/consumer.h>
> #include <linux/slab.h>
> #include <linux/gpio/consumer.h>
> #include <linux/property.h>
> @@ -194,10 +195,10 @@ enum t100_type {
>
> /* Delay times */
> #define MXT_BACKUP_TIME 50 /* msec */
> -#define MXT_RESET_GPIO_TIME 20 /* msec */
> #define MXT_RESET_INVALID_CHG 100 /* msec */
> #define MXT_RESET_TIME 200 /* msec */
> #define MXT_RESET_TIMEOUT 3000 /* msec */
> +#define MXT_REGULATOR_DELAY 150 /* msec */
> #define MXT_CRC_TIMEOUT 1000 /* msec */
> #define MXT_FW_RESET_TIME 3000 /* msec */
> #define MXT_FW_CHG_TIMEOUT 300 /* msec */
> @@ -310,6 +311,8 @@ struct mxt_data {
> struct t7_config t7_cfg;
> struct mxt_dbg dbg;
> struct gpio_desc *reset_gpio;
> + struct regulator *vdd_reg;
> + struct regulator *avdd_reg;
>
> /* Cached parameters from object table */
> u16 T5_address;
> @@ -3076,6 +3079,22 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> return error;
> }
>
> + data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
> + if (IS_ERR(data->vdd_reg)) {
> + error = PTR_ERR(data->vdd_reg);
> + dev_err(&client->dev, "Failed to get vdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> + data->avdd_reg = devm_regulator_get(&client->dev, "avdd");
> + if (IS_ERR(data->avdd_reg)) {
> + error = PTR_ERR(data->avdd_reg);
> + dev_err(&client->dev, "Failed to get avdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> error = devm_request_threaded_irq(&client->dev, client->irq,
> NULL, mxt_interrupt, IRQF_ONESHOT,
> client->name, data);
> @@ -3087,7 +3106,26 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> disable_irq(client->irq);
>
> if (data->reset_gpio) {
> - msleep(MXT_RESET_GPIO_TIME);
> + error = regulator_enable(data->vdd_reg);
> + if (error) {
> + dev_err(&client->dev, "Failed to enable vdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> + error = regulator_enable(data->avdd_reg);
> + if (error) {
> + dev_err(&client->dev, "Failed to enable avdd regulator: %d\n",
> + error);
> + return error;
> + }
> +
> + /*
> + * According to maXTouch power sequencing specification, RESET line
> + * must be kept low until some time after regulators come up to
> + * voltage
> + */
> + msleep(MXT_REGULATOR_DELAY);
> gpiod_set_value(data->reset_gpio, 1);
> msleep(MXT_RESET_INVALID_CHG);
Hi Pawel-
I see you've borrowed some of the logic from the patch I wrote a while
back (see https://github.com/ndyer/linux/commit/8e9687e41ed062 )
The correct behaviour according to Atmel should be:
* Make RESET zero
* Bring up regulators
* Wait for a period to settle (150 msec)
* Release RESET
* Wait for 100 msec whilst device gets through bootloader
* Wait for CHG line assert before reading info block
I can't see the first and last steps in your patch at present.
The only downside with this approach is that there are a lot of
delays during driver probe, but I believe the asynchronous probe stuff
that's landed since I wrote the original patch should address that.
cheers
Nick
> }
> @@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
> struct mxt_data *data = i2c_get_clientdata(client);
>
> disable_irq(data->irq);
> + if (data->reset_gpio) {
> + regulator_disable(data->avdd_reg);
> + regulator_disable(data->vdd_reg);
> + }
> sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
> mxt_free_input_device(data);
> mxt_free_object_table(data);
> --
> 2.7.4
>
^ permalink raw reply
* [PATCH] HID: intel-ish-hid: Prevent loading of driver on Mehlow
From: Srinivas Pandruvada @ 2018-07-17 20:05 UTC (permalink / raw)
To: jikos; +Cc: benjamin.tissoires, linux-input, linux-kernel,
Srinivas Pandruvada
On Mehlow Xeon-E workstation, ISH PCI device is enabled but without ISH
firmware. Here the ISH device PCI device id was reused for some non Linux
storage drivers. So this was not done for enabling ISH. But this has a
undesirable side effect for Linux.
Here the ISH driver will be loaded via PCI enumeration and will try to do
reset sequence. But reset sequence will wait till timeout as there is no
real ISH firmware is present to take action. This delay will add to boot
time of Linux (This platform will still continue to boot after this
timeout).
To avoid this boot delay we need to prevent loading of ISH drivers on
this platform. So we need to have hack to avoid treating this device as
ISH on this platform. To identify this workstation, we need some runtime
method. Luckily there are special PCI id on this workstation to
distinguish from the client version of this platform. On client version,
the ISH is supported using same PCI device id. So this change look for
the presence of PCI device IDs A309 and A30A and exit.
Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
---
This is not a change for 4.18-rc.
drivers/hid/intel-ish-hid/ipc/pci-ish.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
index a2c53ea3b5ed..d6e7156c36d9 100644
--- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c
+++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c
@@ -95,6 +95,26 @@ static int ish_init(struct ishtp_device *dev)
return 0;
}
+
+static bool ish_invalid_firmware(void)
+{
+ struct pci_dev *pdev;
+
+ pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA309, NULL);
+ if (pdev) {
+ pci_dev_put(pdev);
+ return true;
+ }
+
+ pdev = pci_get_device(PCI_VENDOR_ID_INTEL, 0xA30A, NULL);
+ if (pdev) {
+ pci_dev_put(pdev);
+ return true;
+ }
+
+ return false;
+}
+
/**
* ish_probe() - PCI driver probe callback
* @pdev: pci device
@@ -110,6 +130,9 @@ static int ish_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct ish_hw *hw;
int ret;
+ if (ish_invalid_firmware())
+ return -ENODEV;
+
/* enable pci dev */
ret = pci_enable_device(pdev);
if (ret) {
--
2.17.1
^ permalink raw reply related
* [PATCH v2 2/2] Input: atmel_mxt_ts: Document optional voltage regulators
From: Paweł Chmiel @ 2018-07-17 18:16 UTC (permalink / raw)
To: nick
Cc: dmitry.torokhov, robh+dt, mark.rutland, nicolas.ferre,
alexandre.belloni, linux-input, devicetree, linux-arm-kernel,
linux-kernel, Paweł Chmiel
In-Reply-To: <1531851386-17840-1-git-send-email-pawel.mikolaj.chmiel@gmail.com>
Document new optional voltage regulators, which can be used
to power down/up touchscreen.
Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
---
Documentation/devicetree/bindings/input/atmel,maxtouch.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
index c88919480d37..17930ecadad3 100644
--- a/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
+++ b/Documentation/devicetree/bindings/input/atmel,maxtouch.txt
@@ -31,6 +31,12 @@ Optional properties for main touchpad device:
- reset-gpios: GPIO specifier for the touchscreen's reset pin (active low)
+- avdd-supply: Analog power supply. It powers up the analog channel block
+ of the controller to detect the touches.
+
+- vdd-supply: Digital power supply. It powers up the digital block
+ of the controller to enable i2c communication.
+
Example:
touch@4b {
@@ -38,4 +44,6 @@ Example:
reg = <0x4b>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(W, 3) IRQ_TYPE_LEVEL_LOW>;
+ avdd-supply = <&atsp_reg>;
+ vdd-supply = <&tsp_reg>;
};
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/2] Input: atmel_mxt_ts: Add support for optional regulators.
From: Paweł Chmiel @ 2018-07-17 18:16 UTC (permalink / raw)
To: nick
Cc: dmitry.torokhov, robh+dt, mark.rutland, nicolas.ferre,
alexandre.belloni, linux-input, devicetree, linux-arm-kernel,
linux-kernel, Paweł Chmiel
In-Reply-To: <1531851386-17840-1-git-send-email-pawel.mikolaj.chmiel@gmail.com>
This patch adds optional regulators, which can be used to power
up touchscreen. After enabling regulators, we need to wait 150msec.
This value is taken from official driver.
It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
---
Changes from v1:
- Enable regulators only if reset_gpio is present.
- Switch from devm_regulator_get_optional to devm_regulator_get
---
drivers/input/touchscreen/atmel_mxt_ts.c | 46 ++++++++++++++++++++++++++++++--
1 file changed, 44 insertions(+), 2 deletions(-)
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 54fe190fd4bc..005f0fee9fc8 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -27,6 +27,7 @@
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/property.h>
+#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/property.h>
@@ -194,10 +195,10 @@ enum t100_type {
/* Delay times */
#define MXT_BACKUP_TIME 50 /* msec */
-#define MXT_RESET_GPIO_TIME 20 /* msec */
#define MXT_RESET_INVALID_CHG 100 /* msec */
#define MXT_RESET_TIME 200 /* msec */
#define MXT_RESET_TIMEOUT 3000 /* msec */
+#define MXT_REGULATOR_DELAY 150 /* msec */
#define MXT_CRC_TIMEOUT 1000 /* msec */
#define MXT_FW_RESET_TIME 3000 /* msec */
#define MXT_FW_CHG_TIMEOUT 300 /* msec */
@@ -310,6 +311,8 @@ struct mxt_data {
struct t7_config t7_cfg;
struct mxt_dbg dbg;
struct gpio_desc *reset_gpio;
+ struct regulator *vdd_reg;
+ struct regulator *avdd_reg;
/* Cached parameters from object table */
u16 T5_address;
@@ -3076,6 +3079,22 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
return error;
}
+ data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
+ if (IS_ERR(data->vdd_reg)) {
+ error = PTR_ERR(data->vdd_reg);
+ dev_err(&client->dev, "Failed to get vdd regulator: %d\n",
+ error);
+ return error;
+ }
+
+ data->avdd_reg = devm_regulator_get(&client->dev, "avdd");
+ if (IS_ERR(data->avdd_reg)) {
+ error = PTR_ERR(data->avdd_reg);
+ dev_err(&client->dev, "Failed to get avdd regulator: %d\n",
+ error);
+ return error;
+ }
+
error = devm_request_threaded_irq(&client->dev, client->irq,
NULL, mxt_interrupt, IRQF_ONESHOT,
client->name, data);
@@ -3087,7 +3106,26 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
disable_irq(client->irq);
if (data->reset_gpio) {
- msleep(MXT_RESET_GPIO_TIME);
+ error = regulator_enable(data->vdd_reg);
+ if (error) {
+ dev_err(&client->dev, "Failed to enable vdd regulator: %d\n",
+ error);
+ return error;
+ }
+
+ error = regulator_enable(data->avdd_reg);
+ if (error) {
+ dev_err(&client->dev, "Failed to enable avdd regulator: %d\n",
+ error);
+ return error;
+ }
+
+ /*
+ * According to maXTouch power sequencing specification, RESET line
+ * must be kept low until some time after regulators come up to
+ * voltage
+ */
+ msleep(MXT_REGULATOR_DELAY);
gpiod_set_value(data->reset_gpio, 1);
msleep(MXT_RESET_INVALID_CHG);
}
@@ -3116,6 +3154,10 @@ static int mxt_remove(struct i2c_client *client)
struct mxt_data *data = i2c_get_clientdata(client);
disable_irq(data->irq);
+ if (data->reset_gpio) {
+ regulator_disable(data->avdd_reg);
+ regulator_disable(data->vdd_reg);
+ }
sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
mxt_free_input_device(data);
mxt_free_object_table(data);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/2] Input: atmel_mxt_ts: Add support for optional regulators
From: Paweł Chmiel @ 2018-07-17 18:16 UTC (permalink / raw)
To: nick
Cc: dmitry.torokhov, robh+dt, mark.rutland, nicolas.ferre,
alexandre.belloni, linux-input, devicetree, linux-arm-kernel,
linux-kernel, Paweł Chmiel
This two patches add optional regulator support to atmel_mxt_ts.
First patch adds regulators to driver.
Second patch updates documentation.
Changes from v1:
- Enable regulators only if reset_gpio is present.
- Switch from devm_regulator_get_optional to devm_regulator_get.
Paweł Chmiel (2):
Input: atmel_mxt_ts: Add support for optional regulators.
Input: atmel_mxt_ts: Document optional voltage regulators
.../devicetree/bindings/input/atmel,maxtouch.txt | 8 ++++
drivers/input/touchscreen/atmel_mxt_ts.c | 46 +++++++++++++++++++++-
2 files changed, 52 insertions(+), 2 deletions(-)
--
2.7.4
^ permalink raw reply
* Re: [PATCH 1/2] Input: atmel_mxt_ts: Add support for optional regulators.
From: Paweł Chmiel @ 2018-07-17 16:08 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: nick, robh+dt, mark.rutland, nicolas.ferre, alexandre.belloni,
linux-input, devicetree, linux-arm-kernel, linux-kernel
In-Reply-To: <20180715102547.afu57hbjcbizn3kc@penguin>
On Sunday, July 15, 2018 10:25:47 AM CEST Dmitry Torokhov wrote:
> Hi Paweł,
>
> On Fri, Jul 13, 2018 at 08:30:07PM +0200, Paweł Chmiel wrote:
> > This patch adds optional regulators, which can be used to power
> > up touchscreen. After enabling regulators, we need to wait 150msec.
> > This value is taken from official driver.
> >
> > It was tested on Samsung Galaxy i9000 (based on Samsung S5PV210 SOC).
> >
> > Signed-off-by: Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
> > ---
> > drivers/input/touchscreen/atmel_mxt_ts.c | 45 ++++++++++++++++++++++++++++++++
> > 1 file changed, 45 insertions(+)
> >
> > diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
> > index 54fe190fd4bc..a7625ec8fb9f 100644
> > --- a/drivers/input/touchscreen/atmel_mxt_ts.c
> > +++ b/drivers/input/touchscreen/atmel_mxt_ts.c
> > @@ -27,6 +27,7 @@
> > #include <linux/interrupt.h>
> > #include <linux/of.h>
> > #include <linux/property.h>
> > +#include <linux/regulator/consumer.h>
> > #include <linux/slab.h>
> > #include <linux/gpio/consumer.h>
> > #include <linux/property.h>
> > @@ -198,6 +199,7 @@ enum t100_type {
> > #define MXT_RESET_INVALID_CHG 100 /* msec */
> > #define MXT_RESET_TIME 200 /* msec */
> > #define MXT_RESET_TIMEOUT 3000 /* msec */
> > +#define MXT_REGULATOR_DELAY 150 /* msec */
> > #define MXT_CRC_TIMEOUT 1000 /* msec */
> > #define MXT_FW_RESET_TIME 3000 /* msec */
> > #define MXT_FW_CHG_TIMEOUT 300 /* msec */
> > @@ -310,6 +312,8 @@ struct mxt_data {
> > struct t7_config t7_cfg;
> > struct mxt_dbg dbg;
> > struct gpio_desc *reset_gpio;
> > + struct regulator *vdd_reg;
> > + struct regulator *avdd_reg;
> >
> > /* Cached parameters from object table */
> > u16 T5_address;
> > @@ -3076,6 +3080,40 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> > return error;
> > }
> >
> > + data->vdd_reg = devm_regulator_get_optional(&client->dev, "vdd");
> > + if (IS_ERR(data->vdd_reg)) {
> > + error = PTR_ERR(data->vdd_reg);
> > + dev_err(&client->dev, "Failed to get vdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > + if (data->vdd_reg) {
> > + error = regulator_enable(data->vdd_reg);
> > + if (error) {
> > + dev_err(&client->dev, "Failed to enable vdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > + }
> > +
> > + data->avdd_reg = devm_regulator_get_optional(&client->dev, "avdd");
> > + if (IS_ERR(data->avdd_reg)) {
> > + error = PTR_ERR(data->avdd_reg);
> > + dev_err(&client->dev, "Failed to get avdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > +
> > + if (data->avdd_reg) {
>
> devm_regulator_get_optional() does not return NULL for regulators
> not present in device tree, but rather -ENOENT, so this code is not
> correct; neither is the simple IS_ERR() check above.
>
> Moreover, the optional regulators should be used when there is a part of
> IP block that can be optionally powered up, but the device can work
> (with limited functionality) even when it is powered down. They should
> not be used in cases when supplies are mandatory (such as vdd/avdd) but
> may not be exposed to the kernel by the firmware.
>
> Simply use devm_regulator_get() and rely on the fact that on fully
> constrained system you will get a dummy regulator.
>
> > + error = regulator_enable(data->avdd_reg);
> > + if (error) {
> > + dev_err(&client->dev, "Failed to enable avdd regulator: %d\n",
> > + error);
> > + return error;
> > + }
> > + }
> > +
> > error = devm_request_threaded_irq(&client->dev, client->irq,
> > NULL, mxt_interrupt, IRQF_ONESHOT,
> > client->name, data);
> > @@ -3086,6 +3124,9 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
> >
> > disable_irq(client->irq);
> >
> > + if (!IS_ERR(data->vdd_reg) || !IS_ERR(data->avdd_reg))
> > + msleep(MXT_REGULATOR_DELAY);
> > +
> > if (data->reset_gpio) {
>
> I think you should require that if regulators are exposed then reset
> gpio should also be present to ensure proper power up timings.
Thanks for comments. I'll prepare v2 version with those changes applied.
>
> > msleep(MXT_RESET_GPIO_TIME);
> > gpiod_set_value(data->reset_gpio, 1);
> > @@ -3116,6 +3157,10 @@ static int mxt_remove(struct i2c_client *client)
> > struct mxt_data *data = i2c_get_clientdata(client);
> >
> > disable_irq(data->irq);
> > + if (!IS_ERR(data->avdd_reg))
> > + regulator_disable(data->avdd_reg);
> > + if (!IS_ERR(data->vdd_reg))
> > + regulator_disable(data->vdd_reg);
> > sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
> > mxt_free_input_device(data);
> > mxt_free_object_table(data);
>
> Thanks.
>
>
^ permalink raw reply
* Re: [PATCH v4 00/12] Hid multitouch rewrite, support os system multi-axis devices, take 4
From: Jiri Kosina @ 2018-07-17 14:21 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Dmitry Torokhov, Mario.Limonciello, Peter Hutterer, linux-input,
linux-kernel
In-Reply-To: <20180713141354.7286-1-benjamin.tissoires@redhat.com>
On Fri, 13 Jul 2018, Benjamin Tissoires wrote:
> this is the v4 of my hid-multitouch rewrite series.
Nice work, thanks a lot. Applied,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: roccat: Mark expected switch fall-through
From: Jiri Kosina @ 2018-07-17 13:53 UTC (permalink / raw)
To: Gustavo A. R. Silva
Cc: Stefan Achatz, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20180702182907.GA22465@embeddedor.com>
On Mon, 2 Jul 2018, Gustavo A. R. Silva wrote:
> In preparation to enabling -Wimplicit-fallthrough, mark switch cases
> where we are expecting to fall through.
>
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> ---
> drivers/hid/hid-roccat-kone.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c
> index bf4675a..c4dd616 100644
> --- a/drivers/hid/hid-roccat-kone.c
> +++ b/drivers/hid/hid-roccat-kone.c
> @@ -783,6 +783,7 @@ static void kone_keep_values_up_to_date(struct kone_device *kone,
> case kone_mouse_event_switch_profile:
> kone->actual_dpi = kone->profiles[event->value - 1].
> startup_dpi;
> + /* fall through */
> case kone_mouse_event_osd_profile:
> kone->actual_profile = event->value;
> break;
I *think* the fall-through is correct thing to do here, but I'd like to
get explicit Ack from Stefan. Stefan, please?
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: intel-ish-hid: remove redundant variable num_frags
From: Jiri Kosina @ 2018-07-17 13:52 UTC (permalink / raw)
To: Colin King
Cc: Srinivas Pandruvada, Benjamin Tissoires, linux-input,
kernel-janitors, linux-kernel
In-Reply-To: <20180702094028.15428-1-colin.king@canonical.com>
On Mon, 2 Jul 2018, Colin King wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> Variable num_frags is being assigned but is never used hence it is
> redundant and can be removed.
>
> Cleans up clang warning:
> warning: variable 'num_frags' set but not used [-Wunused-but-set-variable]
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] Patch enabling Fn function keys for Laptop Asus G730 (keyboard 0x1869)
From: Jiri Kosina @ 2018-07-17 13:51 UTC (permalink / raw)
To: jan; +Cc: linux-kernel, linux-input, benjamin.tissoires
In-Reply-To: <dc860e3a-c837-5571-95f4-e62065f1a7f4@vereecke.mooo.com>
On Thu, 5 Jul 2018, jan wrote:
> Thanks for your reply. However, I am confused. Pleas bear with me as this is
> the very first time that I submit a patch and I followed some guidance that I
> found on the internet (obviously not the correct one).
>
> I suppose I just need to delete the parts of the email where you write "this
> doesn't go in the changelog".
Yeah, please put into the patch changelog only the things that should end
up in the actual commit log (the thing you see when doing git log / git
show etc).
> I am not sure what my signoff should contain. Could you point me to a correct
> guide for this ?
Please read
Documentation/process/submitting-patches.rst
signoffs specifically are discussed in paragraph 11.
Thanks!
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 0/5] ti_am335x_tsc: Enable wakeup capability
From: Vignesh R @ 2018-07-17 11:45 UTC (permalink / raw)
To: Jonathan Cameron, Dmitry Torokhov, Lee Jones
Cc: linux-iio, linux-omap, linux-kernel, linux-input
In-Reply-To: <20180630103318.25355-1-vigneshr@ti.com>
Hi Dmitry,
On Saturday 30 June 2018 04:03 PM, Vignesh R wrote:
> On AM335x, resistive TSC can wakeup the system from low power state.
> Currently, parent MFD device is marked as wakeup source, which is
> inaccurate as its the touch event generated by TSC thats the wakeup
> source. This series moves all wakeup related calls to operate on TSC
> device instead of MFD. It also marks TSC IRQ as wakeup capable, so that
> its not disabled during system suspend.
>
> This series is based on Dmitry's comments here:
> https://lkml.org/lkml/2018/4/24/65
>
> There are many new patches in this series, hence did not mark this as v4.
>
> Vignesh R (5):
> mfd: ti_am335x_tscadc: Don't mark TSCADC MFD as wakeup capable
> Input: ti_am335x_tsc: Mark TSC device as wakeup source
> mfd: ti_am335x_tscadc: Keep ADC interface on if child is wakeup
> capable
> iio: adc: ti_am335x_adc: Disable ADC during suspend unconditionally
> Input: ti_am335x_tsc: Mark IRQ as wakeup capable
>
> drivers/iio/adc/ti_am335x_adc.c | 12 ++++--------
> drivers/input/touchscreen/ti_am335x_tsc.c | 22 +++++++++++++++++-----
> drivers/mfd/ti_am335x_tscadc.c | 14 +++++++++++++-
> 3 files changed, 34 insertions(+), 14 deletions(-)
>
Gentle ping... Could you review/pick this series? MFD amd IIO bits are
already ACKed
--
Regards
Vignesh
^ permalink raw reply
* Re: [PATCH 3/8] dt-bindings: regulator: document stpmu1 pmic regulators
From: Rob Herring @ 2018-07-16 22:21 UTC (permalink / raw)
To: Pascal PAILLET-LME
Cc: dmitry.torokhov@gmail.com, mark.rutland@arm.com,
lee.jones@linaro.org, lgirdwood@gmail.com, broonie@kernel.org,
wim@linux-watchdog.org, linux@roeck-us.net,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
benjamin.gaignard@linaro.org
In-Reply-To: <1530803657-17684-4-git-send-email-p.paillet@st.com>
On Thu, Jul 05, 2018 at 03:14:23PM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
>
> The STPMU1 regulators supply power to the application processor as well as
> to the external system peripherals such as DDR, Flash memories and system
> devices.
>
> Signed-off-by: pascal paillet <p.paillet@st.com>
> ---
> .../bindings/regulator/st,stpmu1-regulator.txt | 72 ++++++++++++++++++++++
> 1 file changed, 72 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/regulator/st,stpmu1-regulator.txt
>
> diff --git a/Documentation/devicetree/bindings/regulator/st,stpmu1-regulator.txt b/Documentation/devicetree/bindings/regulator/st,stpmu1-regulator.txt
> new file mode 100644
> index 0000000..888e759
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/regulator/st,stpmu1-regulator.txt
> @@ -0,0 +1,72 @@
> +STMicroelectronics STPMU1 Voltage regulators
> +
> +Regulator Nodes are optional depending on needs.
> +
> +Available Regulators in STPMU1 device are:
> + - buck1 for Buck BUCK1
> + - buck2 for Buck BUCK2
> + - buck3 for Buck BUCK3
> + - buck4 for Buck BUCK4
> + - ldo1 for LDO LDO1
> + - ldo2 for LDO LDO2
> + - ldo3 for LDO LDO3
> + - ldo4 for LDO LDO4
> + - ldo5 for LDO LDO5
> + - ldo6 for LDO LDO6
> + - vref_ddr for LDO Vref DDR
> + - boost for Buck BOOST
> + - pwr_sw1 for VBUS_OTG switch
> + - pwr_sw2 for SW_OUT switch
> +
> +Switches are fixed voltage regulators with only enable/disable capability.
> +
> +Optional properties:
> +- st,mask_reset: stay on during Reset for particular regulator
s/_/-/
What's the type? 'mask' in the name makes it sound like a bitmask.
> +- regulator-pull-down: enable high pull down
> + if not specified light pull down is used
> +- regulator-over-current-protection:
> + if set, all regulators are switched off in case of over-current detection
> + on this regulator,
> + if not set, the driver only send an over-current event.
> +- interrupt-parent: phandle to the parent interrupt controller
> +- interrupts: index of current limit detection interrupt
> +- <regulator>-supply: phandle to the parent supply/regulator node
> + each regulator supply can be described except vref_ddr.
> +
> +Example:
> +regulators {
> + compatible = "st,stpmu1-regulators";
> +
> + ldo6-supply = <&v3v3>;
> +
> + vdd_core: regulator@0 {
Drop the unit address.
> + regulator-compatible = "buck1";
> + regulator-name = "vdd_core";
I think you have the names backwards here. Plus, regulator-compatible is
not generally used.
> + interrupts = <IT_CURLIM_BUCK1 0>;
> + interrupt-parent = <&pmic>;
> + st,mask_reset;
> + regulator-pull-down;
> + st,pulldown_config = <2>;
> + regulator-min-microvolt = <700000>;
> + regulator-max-microvolt = <1200000>;
> + };
> +
> + v3v3: buck4 {
> + regulator-compatible = "buck4";
> + regulator-name = "v3v3";
> + interrupts = <IT_CURLIM_BUCK4 0>;
> + interrupt-parent = <&mypmic>;
> +
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + v1v8: ldo6 {
> + regulator-compatible = "ldo6";
> + regulator-name = "v1v8";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-over-current-protection;
> + };
> +
> +};
> --
> 1.9.1
^ permalink raw reply
* Re: [PATCH 2/8] mfd: stpmu1: add stpmu1 pmic driver
From: Rob Herring @ 2018-07-16 22:15 UTC (permalink / raw)
To: Pascal PAILLET-LME
Cc: dmitry.torokhov@gmail.com, mark.rutland@arm.com,
lee.jones@linaro.org, lgirdwood@gmail.com, broonie@kernel.org,
wim@linux-watchdog.org, linux@roeck-us.net,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
benjamin.gaignard@linaro.org
In-Reply-To: <1530803657-17684-3-git-send-email-p.paillet@st.com>
On Thu, Jul 05, 2018 at 03:14:22PM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
>
> stpmu1 is a pmic from STMicroelectronics. The stpmu1 integrates 10
> regulators and 3 switches with various capabilities.
>
> Signed-off-by: pascal paillet <p.paillet@st.com>
> ---
> drivers/mfd/Kconfig | 14 ++
> drivers/mfd/Makefile | 1 +
> drivers/mfd/stpmu1.c | 490 ++++++++++++++++++++++++++++++++++++
> include/dt-bindings/mfd/st,stpmu1.h | 46 ++++
This belongs with patch 1.
> include/linux/mfd/stpmu1.h | 220 ++++++++++++++++
> 5 files changed, 771 insertions(+)
> create mode 100644 drivers/mfd/stpmu1.c
> create mode 100644 include/dt-bindings/mfd/st,stpmu1.h
> create mode 100644 include/linux/mfd/stpmu1.h
^ permalink raw reply
* Re: [PATCH 1/8] dt-bindings: mfd: document stpmu1 pmic
From: Rob Herring @ 2018-07-16 22:14 UTC (permalink / raw)
To: Pascal PAILLET-LME
Cc: dmitry.torokhov@gmail.com, mark.rutland@arm.com,
lee.jones@linaro.org, lgirdwood@gmail.com, broonie@kernel.org,
wim@linux-watchdog.org, linux@roeck-us.net,
linux-input@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org,
benjamin.gaignard@linaro.org
In-Reply-To: <1530803657-17684-2-git-send-email-p.paillet@st.com>
On Thu, Jul 05, 2018 at 03:14:22PM +0000, Pascal PAILLET-LME wrote:
> From: pascal paillet <p.paillet@st.com>
>
> stpmu1 is a pmic from STMicroelectronics. The stpmu1 integrates 10
> regulators and 3 switches with various capabilities.
>
> Signed-off-by: pascal paillet <p.paillet@st.com>
> ---
> .../devicetree/bindings/mfd/st,stpmu1.txt | 138 +++++++++++++++++++++
> 1 file changed, 138 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mfd/st,stpmu1.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/st,stpmu1.txt b/Documentation/devicetree/bindings/mfd/st,stpmu1.txt
> new file mode 100644
> index 0000000..53bdab4
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/st,stpmu1.txt
> @@ -0,0 +1,138 @@
> +* STMicroelectronics STPMU1 Power Management IC
> +
> +Required parent device properties:
> +- compatible: "st,stpmu1"
> +- reg: the I2C slave address for the stpmu1 chip
> +- interrupts-extended: interrupt lines to use: second irq is for wakeup.
> +- #interrupt-cells: should be 2.
> +- interrupt-controller: describes the STPMU1 as an interrupt
> + controller (has its own domain). interrupt number are the following:
> + /* Interrupt Register 1 (0x50 for latch) */
> + IT_SWOUT_R=0
> + IT_SWOUT_F=1
> + IT_VBUS_OTG_R=2
> + IT_VBUS_OTG_F=3
> + IT_WAKEUP_R=4
> + IT_WAKEUP_F=5
> + IT_PONKEY_R=6
> + IT_PONKEY_F=7
> + /* Interrupt Register 2 (0x51 for latch) */
> + IT_OVP_BOOST=8
> + IT_OCP_BOOST=9
> + IT_OCP_SWOUT=10
> + IT_OCP_OTG=11
> + IT_CURLIM_BUCK4=12
> + IT_CURLIM_BUCK3=13
> + IT_CURLIM_BUCK2=14
> + IT_CURLIM_BUCK1=15
> + /* Interrupt Register 3 (0x52 for latch) */
> + IT_SHORT_SWOUT=16
> + IT_SHORT_SWOTG=17
> + IT_CURLIM_LDO6=18
> + IT_CURLIM_LDO5=19
> + IT_CURLIM_LDO4=20
> + IT_CURLIM_LDO3=21
> + IT_CURLIM_LDO2=22
> + IT_CURLIM_LDO1=23
> + /* Interrupt Register 3 (0x52 for latch) */
> + IT_SWIN_R=24
> + IT_SWIN_F=25
> + IT_RESERVED_1=26
> + IT_RESERVED_2=27
> + IT_VINLOW_R=28
> + IT_VINLOW_F=29
> + IT_TWARN_R=30
> + IT_TWARN_F=31
> +
> +Optional parent device properties:
> +- st,main_control_register:
s/_/-/
And elsewhere...
> + -bit 1: Power cycling will be performed on turn OFF condition
> + -bit 2: PWRCTRL is functional
> + -bit 3: PWRCTRL active high
> +- st,pads_pull_register:
> + -bit 1: WAKEUP pull down is not active
> + -bit 2: PWRCTRL pull up is active
> + -bit 3: PWRCTRL pull down is active
> + -bit 4: WAKEUP detector is disabled
> +- st,vin_control_register:
> + -bit 0: VINLOW monitoring is enabled
> + -bit [1...3]: VINLOW rising threshold
> + 000 VINOK_f + 50mV
> + 001 VINOK_f + 100mV
> + 010 VINOK_f + 150mV
> + 011 VINOK_f + 200mV
> + 100 VINOK_f + 250mV
> + 101 VINOK_f + 300mV
> + 110 VINOK_f + 350mV
> + 111 VINOK_f + 400mV
> + -bit [4...5]: VINLOW hyst
> + 00 100mV
> + 01 200mV
> + 10 300mV
> + 11 400mV
> + -bit 6: SW_OUT detector is disabled
> + -bit 7: SW_IN detector is enabled.
> +- st,usb_control_register:
> + -bit 3: SW_OUT current limit
> + 0: 600mA
> + 1: 1.1A
> + -bit 4: VBUS_OTG discharge is enabled
> + -bit 5: SW_OUT discharge is enabled
> + -bit 6: VBUS_OTG detection is enabled
> + -bit 7: BOOST_OVP is disabled
Just dumping register values into DT is not the greatest design.
> +
> +
> +stpmu1 consists is a varied group of sub-devices:
> +
> +Device Description
> +------ ------------
> +stpmu1-onkey : On key
> +stpmu1-regulators : Regulators
> +stpmu1-wdt : Watchdog
These should match the node name below.
> +
> +each sub-device bindings is be described in associated driver
> +documentation section.
> +
> +Example:
> +
> +pmic: stpmu1@33 {
> + compatible = "st,stpmu1";
> + reg = <0x33>;
> + interrupts = <0 2>;
> + interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_NONE>,
> + <&exti 55 1>;
> + st,version_status = <0x10>;
> + st,main_control_register=<0x0c>;
> + interrupt-controller;
> + #interrupt-cells = <2>;
> + onkey {
> + compatible = "st,stpmu1-onkey";
> + interrupt-parent = <&pmic>;
> + interrupts = <7 0>,<6 1>;
> + st,onkey-pwroff-enabled;
> + st,onkey-press-seconds = <10>;
IIRC, we have some standard properties for these.
> + };
> +
> + watchdog {
> + compatible = "st,stpmu1-wdt";
> + };
> +
> + regulators {
> + compatible = "st,stpmu1-regulators";
> +
> + vdd_core: regulator@0 {
unit-address without reg is not valid. regulator-buck1, etc. instead.
> + regulator-compatible = "buck1";
> + regulator-name = "vdd_core";
> + regulator-boot-on;
> + regulator-min-microvolt = <700000>;
> + regulator-max-microvolt = <1200000>;
> + };
> + vdd: regulator@1 {
> + regulator-compatible = "buck3";
> + regulator-name = "vdd";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-boot-on;
> + regulator-pull-down;
> + };
> + };
> --
> 1.9.1
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox