* Re: Critical Interrupt Input
From: Denis Kirjanov @ 2013-08-19 21:04 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev, hbausley
In-Reply-To: <1376945799.25016.77.camel@pasglop>
The easy thing is to start to experimenting with scratch/preserve registers=
:)
On 8/20/13, Benjamin Herrenschmidt <benh@kernel.crashing.org> wrote:
> On Mon, 2013-08-19 at 12:00 -0700, Henry Bausley wrote:
>>
>> Support does appear to be present but there is a problem returning
>> back to user space I suspect.
>
> Probably a problem with TLB misses vs. crit interrupts.
>
> A critical interrupt can re-enter a TLB miss.
>
> I can see two potential issues there:
>
> - A bug where we don't properly restore "something" (I thought we did
> save and restore MMUCR though, but that's worth dbl checking if it works
> properly) accross the crit entry/exit
>
> - Something in your crit code causing a TLB miss (the
> kernel .text/.data/.bss should be bolted but anything else can). We
> don't currently support re-entering the TLB miss that way.
>
> If we were to support the latter, we'd need to detect on entering a crit
> that the PC is within the TLB miss handler, and setup a return context
> to the original instruction (replay the miss) rather than trying to
> resume it..
>
> Cheers,
> Ben.
>
>> What fails is it causes Linux user space programs to get Segmentation
>> errors.
>> Issuing a simple ls causes a segmentation fault sometimes. The shell
>> gets terminated
>> and you cannot log back in. INIT: Id "T0" respawning too fast:
>> disabled for 5 minutes pops up.
>>
>> However, the critical interrupt handler keeps running. I know this by
>> adding the reading
>> of a physical I/O location in the handler and can see it is being read
>> on the scope.
>>
>>
>> The only code in the handler is below.
>>
>> void critintr_handler(void *dev)
>> {
>> critintrcount++; // increment a variable
>> iodata =3D *piom; // read an I/O location
>> mtdcr(0x0c0, 0x00002000); // clear critical interrupt
>> }
>>
>>
>> Below is a log of the type of crashes that occur:
>>
>> root@10.34.9.213:/opt/ppmac/ktest# ls
>> Segmentation fault
>> root@10.34.9.213:/opt/ppmac/ktest# ls
>> Segmentation fault
>> root@10.34.9.213:/opt/ppmac/ktest# ls
>> Makefile ktest.c ktest.ko ktest.mod.o modules.order
>> Module.symvers ktest.cbp ktest.mod.c ktest.o
>> root@10.34.9.213:/opt/ppmac/ktest# ls
>>
>> Debian GNU/Linux 7 powerpmac ttyS0
>>
>> powerpmac login: root
>>
>> Debian GNU/Linux 7 powerpmac ttyS0
>>
>> powerpmac login: root
>>
>> Debian GNU/Linux 7 powerpmac ttyS0
>>
>> powerpmac login: root
>>
>> Debian GNU/Linux 7 powerpmac ttyS0
>>
>> powerpmac login: root
>> Password:
>> Last login: Thu Nov 30 20:42:16 UTC 1933 on ttyS0
>> Linux powerpmac 3.2.21-aspen_2.01.09 #10 Mon Aug 19 08:49:12 PDT 2013
>> ppc
>>
>> The programs included with the Debian GNU/Linux system are free
>> software;
>> the exact distribution terms for each program are described in the
>> individual files in /usr/share/doc/*/copyright.
>>
>> Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
>> permitted by applicable law.
>> INIT: Id "T0" respawning too fast: disabled for 5 minutes
>>
>>
>> ______________________________________________________________________
>> From: "Benjamin Herrenschmidt" <benh@kernel.crashing.org>
>> Sent: Saturday, August 17, 2013 3:05 PM
>> To: "Kumar Gala" <galak@kernel.crashing.org>
>> Cc: linuxppc-dev@lists.ozlabs.org, hbausley@deltatau.com
>> Subject: Re: Critical Interrupt Input
>>
>> On Fri, 2013-08-16 at 06:04 -0500, Kumar Gala wrote:
>> > The 44x low level code needs to handle exception stacks properly for
>> > this to work. Since its possible to have a critical exception occur
>> > while in a normal exception level, you have to have proper saving of
>> > additional register state and a stack frame for the critical
>> > exception, etc. I'm not sure if that was ever done for 44x.
>>
>> Don't 44x and FSL BookE share the same macros ? I would think 44x does
>> indeed implement the same crit support as e500...
>>
>> What does the crash look like ?
>>
>> Ben.
>>
>>
>> _______________________________________________
>> Linuxppc-dev mailing list
>> Linuxppc-dev@lists.ozlabs.org
>> https://lists.ozlabs.org/listinfo/linuxppc-dev
>>
>>
>> =AD=AD
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
--=20
Regards,
Denis
^ permalink raw reply
* Re: Critical Interrupt Input
From: Benjamin Herrenschmidt @ 2013-08-19 20:56 UTC (permalink / raw)
To: hbausley; +Cc: linuxppc-dev
In-Reply-To: <63d2635a$648939a4$b3aeac8$@deltatau.com>
On Mon, 2013-08-19 at 12:00 -0700, Henry Bausley wrote:
>
> Support does appear to be present but there is a problem returning
> back to user space I suspect.
Probably a problem with TLB misses vs. crit interrupts.
A critical interrupt can re-enter a TLB miss.
I can see two potential issues there:
- A bug where we don't properly restore "something" (I thought we did
save and restore MMUCR though, but that's worth dbl checking if it works
properly) accross the crit entry/exit
- Something in your crit code causing a TLB miss (the
kernel .text/.data/.bss should be bolted but anything else can). We
don't currently support re-entering the TLB miss that way.
If we were to support the latter, we'd need to detect on entering a crit
that the PC is within the TLB miss handler, and setup a return context
to the original instruction (replay the miss) rather than trying to
resume it..
Cheers,
Ben.
> What fails is it causes Linux user space programs to get Segmentation
> errors.
> Issuing a simple ls causes a segmentation fault sometimes. The shell
> gets terminated
> and you cannot log back in. INIT: Id "T0" respawning too fast:
> disabled for 5 minutes pops up.
>
> However, the critical interrupt handler keeps running. I know this by
> adding the reading
> of a physical I/O location in the handler and can see it is being read
> on the scope.
>
>
> The only code in the handler is below.
>
> void critintr_handler(void *dev)
> {
> critintrcount++; // increment a variable
> iodata = *piom; // read an I/O location
> mtdcr(0x0c0, 0x00002000); // clear critical interrupt
> }
>
>
> Below is a log of the type of crashes that occur:
>
> root@10.34.9.213:/opt/ppmac/ktest# ls
> Segmentation fault
> root@10.34.9.213:/opt/ppmac/ktest# ls
> Segmentation fault
> root@10.34.9.213:/opt/ppmac/ktest# ls
> Makefile ktest.c ktest.ko ktest.mod.o modules.order
> Module.symvers ktest.cbp ktest.mod.c ktest.o
> root@10.34.9.213:/opt/ppmac/ktest# ls
>
> Debian GNU/Linux 7 powerpmac ttyS0
>
> powerpmac login: root
>
> Debian GNU/Linux 7 powerpmac ttyS0
>
> powerpmac login: root
>
> Debian GNU/Linux 7 powerpmac ttyS0
>
> powerpmac login: root
>
> Debian GNU/Linux 7 powerpmac ttyS0
>
> powerpmac login: root
> Password:
> Last login: Thu Nov 30 20:42:16 UTC 1933 on ttyS0
> Linux powerpmac 3.2.21-aspen_2.01.09 #10 Mon Aug 19 08:49:12 PDT 2013
> ppc
>
> The programs included with the Debian GNU/Linux system are free
> software;
> the exact distribution terms for each program are described in the
> individual files in /usr/share/doc/*/copyright.
>
> Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
> permitted by applicable law.
> INIT: Id "T0" respawning too fast: disabled for 5 minutes
>
>
> ______________________________________________________________________
> From: "Benjamin Herrenschmidt" <benh@kernel.crashing.org>
> Sent: Saturday, August 17, 2013 3:05 PM
> To: "Kumar Gala" <galak@kernel.crashing.org>
> Cc: linuxppc-dev@lists.ozlabs.org, hbausley@deltatau.com
> Subject: Re: Critical Interrupt Input
>
> On Fri, 2013-08-16 at 06:04 -0500, Kumar Gala wrote:
> > The 44x low level code needs to handle exception stacks properly for
> > this to work. Since its possible to have a critical exception occur
> > while in a normal exception level, you have to have proper saving of
> > additional register state and a stack frame for the critical
> > exception, etc. I'm not sure if that was ever done for 44x.
>
> Don't 44x and FSL BookE share the same macros ? I would think 44x does
> indeed implement the same crit support as e500...
>
> What does the crash look like ?
>
> Ben.
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
>
^ permalink raw reply
* Re: [PATCH RESEND] i2c: move of helpers into the core
From: Felipe Balbi @ 2013-08-19 20:10 UTC (permalink / raw)
To: Wolfram Sang
Cc: devicetree, davinci-linux-open-source, linux-samsung-soc,
linux-doc, linux-kernel, linux-acpi, linux-i2c, linux-tegra,
linux-omap, linuxppc-dev, linux-arm-kernel, linux-media
In-Reply-To: <1376935183-11218-1-git-send-email-wsa@the-dreams.de>
[-- Attachment #1: Type: text/plain, Size: 552 bytes --]
On Mon, Aug 19, 2013 at 07:59:40PM +0200, Wolfram Sang wrote:
> I2C of helpers used to live in of_i2c.c but experience (from SPI) shows
> that it is much cleaner to have this in the core. This also removes a
> circular dependency between the helpers and the core, and so we can
> finally register child nodes in the core instead of doing this manually
> in each driver. So, fix the drivers and documentation, too.
>
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
for i2c-omap.c:
Reviewed-by: Felipe Balbi <balbi@ti.com>
--
balbi
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH RESEND] i2c: move of helpers into the core
From: Thierry Reding @ 2013-08-19 19:46 UTC (permalink / raw)
To: Wolfram Sang
Cc: devicetree, davinci-linux-open-source, linux-samsung-soc,
linux-doc, linux-kernel, linux-acpi, linux-i2c, linux-tegra,
linux-omap, linuxppc-dev, linux-arm-kernel, linux-media
In-Reply-To: <1376935183-11218-1-git-send-email-wsa@the-dreams.de>
[-- Attachment #1: Type: text/plain, Size: 986 bytes --]
On Mon, Aug 19, 2013 at 07:59:40PM +0200, Wolfram Sang wrote:
[...]
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
[...]
> +#if IS_ENABLED(CONFIG_OF)
> +static void of_i2c_register_devices(struct i2c_adapter *adap)
> +{
[...]
> +}
[...]
> +#endif /* CONFIG_OF */
Isn't this missing the dummy implementation for !OF.
> static int i2c_do_add_adapter(struct i2c_driver *driver,
> struct i2c_adapter *adap)
> {
> @@ -1058,6 +1160,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
>
> exit_recovery:
> /* create pre-declared device nodes */
> + of_i2c_register_devices(adap);
Alternatively you could remove the of_i2c_register_devices() from the
"#ifdef CONFIG_OF" block so that it will always be compiled. You could
turn the above into
if (IS_ENABLED(CONFIG_OF))
of_i2c_register_devices(adap);
and let the compiler throw the static function away if it sees that the
condition is always false.
Thierry
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: Critical Interrupt Input
From: Henry Bausley @ 2013-08-19 19:00 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Kumar Gala; +Cc: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2903 bytes --]
Support does appear to be present but there is a problem returning back to
user space I suspect.
What fails is it causes Linux user space programs to get Segmentation
errors.
Issuing a simple ls causes a segmentation fault sometimes. The shell gets
terminated
and you cannot log back in. INIT: Id "T0" respawning too fast: disabled
for 5 minutes pops up.
However, the critical interrupt handler keeps running. I know this by
adding the reading
of a physical I/O location in the handler and can see it is being read on
the scope.
The only code in the handler is below.
void critintr_handler(void *dev)
{
critintrcount++; // increment a variable
iodata = *piom; // read an I/O location
mtdcr(0x0c0, 0x00002000); // clear critical interrupt
}
Below is a log of the type of crashes that occur:
root@10.34.9.213:/opt/ppmac/ktest# ls
Segmentation fault
root@10.34.9.213:/opt/ppmac/ktest# ls
Segmentation fault
root@10.34.9.213:/opt/ppmac/ktest# ls
Makefile ktest.c ktest.ko ktest.mod.o modules.order
Module.symvers ktest.cbp ktest.mod.c ktest.o
root@10.34.9.213:/opt/ppmac/ktest# ls
Debian GNU/Linux 7 powerpmac ttyS0
powerpmac login: root
Debian GNU/Linux 7 powerpmac ttyS0
powerpmac login: root
Debian GNU/Linux 7 powerpmac ttyS0
powerpmac login: root
Debian GNU/Linux 7 powerpmac ttyS0
powerpmac login: root
Password:
Last login: Thu Nov 30 20:42:16 UTC 1933 on ttyS0
Linux powerpmac 3.2.21-aspen_2.01.09 #10 Mon Aug 19 08:49:12 PDT 2013 ppc
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
INIT: Id "T0" respawning too fast: disabled for 5 minutes
----------------------------------------
From: "Benjamin Herrenschmidt" <benh@kernel.crashing.org>
Sent: Saturday, August 17, 2013 3:05 PM
To: "Kumar Gala" <galak@kernel.crashing.org>
Cc: linuxppc-dev@lists.ozlabs.org, hbausley@deltatau.com
Subject: Re: Critical Interrupt Input
On Fri, 2013-08-16 at 06:04 -0500, Kumar Gala wrote:
> The 44x low level code needs to handle exception stacks properly for
> this to work. Since its possible to have a critical exception occur
> while in a normal exception level, you have to have proper saving of
> additional register state and a stack frame for the critical
> exception, etc. I'm not sure if that was ever done for 44x.
Don't 44x and FSL BookE share the same macros ? I would think 44x does
indeed implement the same crit support as e500...
What does the crash look like ?
Ben.
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev
Outbound scan for Spam or Virus by Barracuda at Delta Tau
[-- Attachment #2: Type: text/html, Size: 3570 bytes --]
^ permalink raw reply
* Re: [PATCH RESEND] i2c: move of helpers into the core
From: Wolfram Sang @ 2013-08-19 18:56 UTC (permalink / raw)
To: Sylwester Nawrocki
Cc: devicetree, davinci-linux-open-source, linux-samsung-soc,
linux-doc, linux-kernel, linux-acpi, linux-i2c, linux-tegra,
linux-omap, linuxppc-dev, linux-arm-kernel, linux-media
In-Reply-To: <5212624D.5090708@samsung.com>
[-- Attachment #1: Type: text/plain, Size: 338 bytes --]
> However this patch fails to apply onto either v3.11-rc4 or v3.11-rc6:
Argh, did not drop the MPC patch before rebasing :( So either pick the
patch "i2c: powermac: fix return path on error" before, pull the branch
[1], or force me to resend ;)
Thanks!
[1] git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux.git i2c/core-with-of
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH RESEND] i2c: move of helpers into the core
From: Sylwester Nawrocki @ 2013-08-19 18:22 UTC (permalink / raw)
To: Wolfram Sang
Cc: devicetree, davinci-linux-open-source, linux-samsung-soc,
linux-doc, linux-kernel, linux-acpi, linux-i2c, linux-tegra,
linux-omap, linuxppc-dev, linux-arm-kernel, linux-media
In-Reply-To: <1376935183-11218-1-git-send-email-wsa@the-dreams.de>
On 08/19/2013 07:59 PM, Wolfram Sang wrote:
> I2C of helpers used to live in of_i2c.c but experience (from SPI) shows
> that it is much cleaner to have this in the core. This also removes a
> circular dependency between the helpers and the core, and so we can
> finally register child nodes in the core instead of doing this manually
> in each driver. So, fix the drivers and documentation, too.
>
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
> ---
>
> Sigh, hitting the CC threshold on vger again. So resending to the lists only.
> BTW this patch is based on -rc4 and was tested on an AT91 board. More tests
> very welcome. Thanks!
>
>
> drivers/i2c/busses/i2c-s3c2410.c | 2 -
> drivers/media/platform/exynos4-is/fimc-is-i2c.c | 3 -
For these:
Acked-by: Sylwester Nawrocki <s.nawrocki@amsung.com>
However this patch fails to apply onto either v3.11-rc4 or v3.11-rc6:
Applying: i2c: move of helpers into the core
fatal: sha1 information is lacking or useless (drivers/i2c/busses/i2c-powermac.c).
Repository lacks necessary blobs to fall back on 3-way merge.
Cannot fall back to three-way merge.
Patch failed at 0001 i2c: move of helpers into the core
One nitpick below..
[...]
> diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
> index f32ca29..321b7ca 100644
> --- a/drivers/i2c/i2c-core.c
> +++ b/drivers/i2c/i2c-core.c
> @@ -23,7 +23,11 @@
> SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
> Jean Delvare <khali@linux-fr.org>
> Mux support by Rodolfo Giometti <giometti@enneenne.com> and
> - Michael Lawnick <michael.lawnick.ext@nsn.com> */
> + Michael Lawnick <michael.lawnick.ext@nsn.com>
> + OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
> + (based on a previous patch from Jon Smirl <jonsmirl@gmail.com>) and
> + (c) 2013 Wolfram Sang <wsa@the-dreams.de>
> + */
>
> #include <linux/module.h>
> #include <linux/kernel.h>
> @@ -35,7 +39,9 @@
> #include <linux/init.h>
> #include <linux/idr.h>
> #include <linux/mutex.h>
> +#include <linux/of.h>
> #include <linux/of_device.h>
> +#include <linux/of_irq.h>
> #include <linux/completion.h>
> #include <linux/hardirq.h>
> #include <linux/irqflags.h>
> @@ -954,6 +960,102 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
> up_read(&__i2c_board_lock);
> }
>
> +/* of support code */
/* OF support code */
or
/*
* Device Tree support code.
*/
?
> +#if IS_ENABLED(CONFIG_OF)
> +static void of_i2c_register_devices(struct i2c_adapter *adap)
> +{
> + void *result;
> + struct device_node *node;
> +
> + /* Only register child devices if the adapter has a node pointer set */
> + if (!adap->dev.of_node)
> + return;
> +
> + dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
> +
> + for_each_available_child_of_node(adap->dev.of_node, node) {
> + struct i2c_board_info info = {};
> + struct dev_archdata dev_ad = {};
> + const __be32 *addr;
> + int len;
> +
> + dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
> +
> + if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
> + dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
> + node->full_name);
> + continue;
> + }
> +
> + addr = of_get_property(node, "reg", &len);
> + if (!addr || (len < sizeof(int))) {
> + dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
> + node->full_name);
> + continue;
> + }
> +
> + info.addr = be32_to_cpup(addr);
> + if (info.addr > (1 << 10) - 1) {
> + dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
> + info.addr, node->full_name);
> + continue;
> + }
> +
> + info.irq = irq_of_parse_and_map(node, 0);
> + info.of_node = of_node_get(node);
> + info.archdata = &dev_ad;
> +
> + if (of_get_property(node, "wakeup-source", NULL))
> + info.flags |= I2C_CLIENT_WAKE;
> +
> + request_module("%s%s", I2C_MODULE_PREFIX, info.type);
> +
> + result = i2c_new_device(adap, &info);
> + if (result == NULL) {
> + dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
> + node->full_name);
> + of_node_put(node);
> + irq_dispose_mapping(info.irq);
> + continue;
> + }
> + }
> +}
> +
> +static int of_dev_node_match(struct device *dev, void *data)
> +{
> + return dev->of_node == data;
> +}
> +
> +/* must call put_device() when done with returned i2c_client device */
> +struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
> +{
> + struct device *dev;
> +
> + dev = bus_find_device(&i2c_bus_type, NULL, node,
> + of_dev_node_match);
> + if (!dev)
> + return NULL;
> +
> + return i2c_verify_client(dev);
> +}
> +EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
> +
> +/* must call put_device() when done with returned i2c_adapter device */
> +struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
> +{
> + struct device *dev;
> +
> + dev = bus_find_device(&i2c_bus_type, NULL, node,
> + of_dev_node_match);
> + if (!dev)
> + return NULL;
> +
> + return i2c_verify_adapter(dev);
> +}
> +EXPORT_SYMBOL(of_find_i2c_device_by_node);
> +#endif /* CONFIG_OF */
Thanks,
Sylwester
^ permalink raw reply
* Re: [RFC PATCH V3 3/5] powerpc/cpuidle: Generic powerpc backend cpuidle driver.
From: Scott Wood @ 2013-08-19 18:17 UTC (permalink / raw)
To: Deepthi Dharwar
Cc: Wood Scott-B07421, daniel.lezcano@linaro.org,
Wang Dongsheng-B40534, preeti@linux.vnet.ibm.com,
linux-pm@lists.linux-foundation.org,
linuxppc-dev@lists.ozlabs.org
In-Reply-To: <5211F0E0.7080507@linux.vnet.ibm.com>
On Mon, 2013-08-19 at 15:48 +0530, Deepthi Dharwar wrote:
> Hi Dongsheng,
>
> On 08/19/2013 11:22 AM, Wang Dongsheng-B40534 wrote:
> > I think we should move the states and handle function to arch/power/platform*
> > The states and handle function is belong to backend driver, not for this, different platform have different state.
> > Different platforms to make their own deal with these states.
> >
> > I think we cannot put all the status of different platforms and handler in this driver.
>
> The idea here is a single powerpc back-end driver, which does a runtime
> detection of the platform it is running and choose the right
> idle states table. This was one of outcome of V2 discussion.
I see a lot more in there than just detecting a platform and choosing a
driver.
> I feel there is no harm in keeping the state information in the same
> file. We do have x86, which has all its variants information in one
> file. One place will have all the idle consolidated information of
> all the platform variants. If community does feel, we need to
> have just the states information in arch specific file, we can do so.
What actual functionality is common to all powerpc but not common to
other arches?
> >> diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
> >> index 0e2cd5c..99ee5d4 100644
> >> --- a/drivers/cpuidle/Kconfig
> >> +++ b/drivers/cpuidle/Kconfig
> >> @@ -42,6 +42,13 @@ config CPU_IDLE_ZYNQ
> >> help
> >> Select this to enable cpuidle on Xilinx Zynq processors.
> >>
> >> +config CPU_IDLE_POWERPC
> >> + bool "CPU Idle driver for POWERPC platforms"
> >> + depends on PPC64
> >
> > Why not PPC?
>
> PPC64 seems to a good place to began the consolidation work. This
> patch-set has not been tested for PPC32 currently.
PPC64 is a bad place to start if you want it to be generic, because it
means you'll end up growing dependencies on other things that are PPC64
only. There are too many arbitrary 32/64 differences as is.
-Scott
^ permalink raw reply
* [PATCH] sata: fsl: save irqs while coalescing
From: Anthony Foiani @ 2013-08-19 18:15 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Anthony Foiani, Anthony Foiani, Bhushan Bharat-R65777
In-Reply-To: <gsiy6olhp.fsf@dworkin.scrye.com>
Before this patch, I was seeing the following lockdep splat on my
MPC8315 (PPC32) target:
[ 9.086051] =================================
[ 9.090393] [ INFO: inconsistent lock state ]
[ 9.094744] 3.9.7-ajf-gc39503d #1 Not tainted
[ 9.099087] ---------------------------------
[ 9.103432] inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
[ 9.109431] scsi_eh_1/39 [HC1[1]:SC0[0]:HE0:SE1] takes:
[ 9.114642] (&(&host->lock)->rlock){?.+...}, at: [<c02f4168>] sata_fsl_interrupt+0x50/0x250
[ 9.123137] {HARDIRQ-ON-W} state was registered at:
[ 9.128004] [<c006cdb8>] lock_acquire+0x90/0xf4
[ 9.132737] [<c043ef04>] _raw_spin_lock+0x34/0x4c
[ 9.137645] [<c02f3560>] fsl_sata_set_irq_coalescing+0x68/0x100
[ 9.143750] [<c02f36a0>] sata_fsl_init_controller+0xa8/0xc0
[ 9.149505] [<c02f3f10>] sata_fsl_probe+0x17c/0x2e8
[ 9.154568] [<c02acc90>] driver_probe_device+0x90/0x248
[ 9.159987] [<c02acf0c>] __driver_attach+0xc4/0xc8
[ 9.164964] [<c02aae74>] bus_for_each_dev+0x5c/0xa8
[ 9.170028] [<c02ac218>] bus_add_driver+0x100/0x26c
[ 9.175091] [<c02ad638>] driver_register+0x88/0x198
[ 9.180155] [<c0003a24>] do_one_initcall+0x58/0x1b4
[ 9.185226] [<c05aeeac>] kernel_init_freeable+0x118/0x1c0
[ 9.190823] [<c0004110>] kernel_init+0x18/0x108
[ 9.195542] [<c000f6b8>] ret_from_kernel_thread+0x64/0x6c
[ 9.201142] irq event stamp: 160
[ 9.204366] hardirqs last enabled at (159): [<c043f778>] _raw_spin_unlock_irq+0x30/0x50
[ 9.212469] hardirqs last disabled at (160): [<c000f414>] reenable_mmu+0x30/0x88
[ 9.219867] softirqs last enabled at (144): [<c002ae5c>] __do_softirq+0x168/0x218
[ 9.227435] softirqs last disabled at (137): [<c002b0d4>] irq_exit+0xa8/0xb4
[ 9.234481]
[ 9.234481] other info that might help us debug this:
[ 9.240995] Possible unsafe locking scenario:
[ 9.240995]
[ 9.246898] CPU0
[ 9.249337] ----
[ 9.251776] lock(&(&host->lock)->rlock);
[ 9.255878] <Interrupt>
[ 9.258492] lock(&(&host->lock)->rlock);
[ 9.262765]
[ 9.262765] *** DEADLOCK ***
[ 9.262765]
[ 9.268684] no locks held by scsi_eh_1/39.
[ 9.272767]
[ 9.272767] stack backtrace:
[ 9.277117] Call Trace:
[ 9.279589] [cfff9da0] [c0008504] show_stack+0x48/0x150 (unreliable)
[ 9.285972] [cfff9de0] [c0447d5c] print_usage_bug.part.35+0x268/0x27c
[ 9.292425] [cfff9e10] [c006ace4] mark_lock+0x2ac/0x658
[ 9.297660] [cfff9e40] [c006b7e4] __lock_acquire+0x754/0x1840
[ 9.303414] [cfff9ee0] [c006cdb8] lock_acquire+0x90/0xf4
[ 9.308745] [cfff9f20] [c043ef04] _raw_spin_lock+0x34/0x4c
[ 9.314250] [cfff9f30] [c02f4168] sata_fsl_interrupt+0x50/0x250
[ 9.320187] [cfff9f70] [c0079ff0] handle_irq_event_percpu+0x90/0x254
[ 9.326547] [cfff9fc0] [c007a1fc] handle_irq_event+0x48/0x78
[ 9.332220] [cfff9fe0] [c007c95c] handle_level_irq+0x9c/0x104
[ 9.337981] [cfff9ff0] [c000d978] call_handle_irq+0x18/0x28
[ 9.343568] [cc7139f0] [c000608c] do_IRQ+0xf0/0x1a8
[ 9.348464] [cc713a20] [c000fc8c] ret_from_except+0x0/0x14
[ 9.353983] --- Exception: 501 at _raw_spin_unlock_irq+0x40/0x50
[ 9.353983] LR = _raw_spin_unlock_irq+0x30/0x50
[ 9.364839] [cc713af0] [c043db10] wait_for_common+0xac/0x188
[ 9.370513] [cc713b30] [c02ddee4] ata_exec_internal_sg+0x2b0/0x4f0
[ 9.376699] [cc713be0] [c02de18c] ata_exec_internal+0x68/0xa8
[ 9.382454] [cc713c20] [c02de4b8] ata_dev_read_id+0x158/0x594
[ 9.388205] [cc713ca0] [c02ec244] ata_eh_recover+0xd88/0x13d0
[ 9.393962] [cc713d20] [c02f2520] sata_pmp_error_handler+0xc0/0x8ac
[ 9.400234] [cc713dd0] [c02ecdc8] ata_scsi_port_error_handler+0x464/0x5e8
[ 9.407023] [cc713e10] [c02ecfd0] ata_scsi_error+0x84/0xb8
[ 9.412528] [cc713e40] [c02c4974] scsi_error_handler+0xd8/0x47c
[ 9.418457] [cc713eb0] [c004737c] kthread+0xa8/0xac
[ 9.423355] [cc713f40] [c000f6b8] ret_from_kernel_thread+0x64/0x6c
This fix was suggested by Bhushan Bharat <R65777@freescale.com>, and
was discussed in email at:
http://linuxppc.10917.n7.nabble.com/MPC8315-reboot-failure-lockdep-splat-possibly-related-tp75162.html
Same patch successfully tested with 3.9.7. linux-next compiled but
not tested on hardware.
This patch is based off linux-next tag next-20130819
(which is commit 66a01bae29d11916c09f9f5a937cafe7d402e4a5 )
Signed-off-by: Anthony Foiani <anthony.foiani@gmail.com>
---
drivers/ata/sata_fsl.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 19720a0..851bd3f 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -293,6 +293,7 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host,
{
struct sata_fsl_host_priv *host_priv = host->private_data;
void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned long flags;
if (count > ICC_MAX_INT_COUNT_THRESHOLD)
count = ICC_MAX_INT_COUNT_THRESHOLD;
@@ -305,12 +306,12 @@ static void fsl_sata_set_irq_coalescing(struct ata_host *host,
(count > ICC_MIN_INT_COUNT_THRESHOLD))
ticks = ICC_SAFE_INT_TICKS;
- spin_lock(&host->lock);
+ spin_lock_irqsave(&host->lock, flags);
iowrite32((count << 24 | ticks), hcr_base + ICC);
intr_coalescing_count = count;
intr_coalescing_ticks = ticks;
- spin_unlock(&host->lock);
+ spin_unlock_irqrestore(&host->lock, flags);
DPRINTK("interrupt coalescing, count = 0x%x, ticks = %x\n",
intr_coalescing_count, intr_coalescing_ticks);
--
1.8.1.4
^ permalink raw reply related
* [PATCH RESEND] i2c: move of helpers into the core
From: Wolfram Sang @ 2013-08-19 17:59 UTC (permalink / raw)
To: linux-i2c
Cc: devicetree, davinci-linux-open-source, linux-samsung-soc,
linux-doc, Wolfram Sang, linux-kernel, linux-acpi, linux-tegra,
linux-omap, linuxppc-dev, linux-arm-kernel, linux-media
In-Reply-To: <1376918361-7014-1-git-send-email-wsa@the-dreams.de>
I2C of helpers used to live in of_i2c.c but experience (from SPI) shows
that it is much cleaner to have this in the core. This also removes a
circular dependency between the helpers and the core, and so we can
finally register child nodes in the core instead of doing this manually
in each driver. So, fix the drivers and documentation, too.
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
---
Sigh, hitting the CC threshold on vger again. So resending to the lists only.
BTW this patch is based on -rc4 and was tested on an AT91 board. More tests
very welcome. Thanks!
Documentation/acpi/enumeration.txt | 1 -
drivers/i2c/busses/i2c-at91.c | 3 -
drivers/i2c/busses/i2c-cpm.c | 6 --
drivers/i2c/busses/i2c-davinci.c | 2 -
drivers/i2c/busses/i2c-designware-platdrv.c | 2 -
drivers/i2c/busses/i2c-gpio.c | 3 -
drivers/i2c/busses/i2c-i801.c | 2 -
drivers/i2c/busses/i2c-ibm_iic.c | 4 -
drivers/i2c/busses/i2c-imx.c | 3 -
drivers/i2c/busses/i2c-mpc.c | 2 -
drivers/i2c/busses/i2c-mv64xxx.c | 3 -
drivers/i2c/busses/i2c-mxs.c | 3 -
drivers/i2c/busses/i2c-nomadik.c | 3 -
drivers/i2c/busses/i2c-ocores.c | 3 -
drivers/i2c/busses/i2c-octeon.c | 3 -
drivers/i2c/busses/i2c-omap.c | 3 -
drivers/i2c/busses/i2c-pnx.c | 3 -
drivers/i2c/busses/i2c-powermac.c | 9 +-
drivers/i2c/busses/i2c-pxa.c | 2 -
drivers/i2c/busses/i2c-s3c2410.c | 2 -
drivers/i2c/busses/i2c-sh_mobile.c | 2 -
drivers/i2c/busses/i2c-sirf.c | 3 -
drivers/i2c/busses/i2c-stu300.c | 2 -
drivers/i2c/busses/i2c-tegra.c | 3 -
drivers/i2c/busses/i2c-versatile.c | 2 -
drivers/i2c/busses/i2c-wmt.c | 3 -
drivers/i2c/busses/i2c-xiic.c | 3 -
drivers/i2c/i2c-core.c | 107 ++++++++++++++++++++-
drivers/i2c/i2c-mux.c | 3 -
drivers/i2c/muxes/i2c-arb-gpio-challenge.c | 1 -
drivers/i2c/muxes/i2c-mux-gpio.c | 1 -
drivers/i2c/muxes/i2c-mux-pinctrl.c | 1 -
drivers/media/platform/exynos4-is/fimc-is-i2c.c | 3 -
drivers/of/Kconfig | 6 --
drivers/of/Makefile | 1 -
drivers/of/of_i2c.c | 114 -----------------------
include/linux/i2c.h | 20 ++++
include/linux/of_i2c.h | 46 ---------
38 files changed, 130 insertions(+), 253 deletions(-)
delete mode 100644 drivers/of/of_i2c.c
delete mode 100644 include/linux/of_i2c.h
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt
index d9be7a9..958266e 100644
--- a/Documentation/acpi/enumeration.txt
+++ b/Documentation/acpi/enumeration.txt
@@ -238,7 +238,6 @@ An I2C bus (controller) driver does:
if (ret)
/* handle error */
- of_i2c_register_devices(adapter);
/* Enumerate the slave devices behind this bus via ACPI */
acpi_i2c_register_devices(adapter);
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 6bb839b..fd05930 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -28,7 +28,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/platform_data/dma-atmel.h>
@@ -775,8 +774,6 @@ static int at91_twi_probe(struct platform_device *pdev)
return rc;
}
- of_i2c_register_devices(&dev->adapter);
-
dev_info(dev->dev, "AT91 i2c bus driver.\n");
return 0;
}
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index 2e1f7eb..b2b8aa9 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -42,7 +42,6 @@
#include <linux/dma-mapping.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
#include <sysdev/fsl_soc.h>
#include <asm/cpm.h>
@@ -681,11 +680,6 @@ static int cpm_i2c_probe(struct platform_device *ofdev)
dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
cpm->adap.name);
- /*
- * register OF I2C devices
- */
- of_i2c_register_devices(&cpm->adap);
-
return 0;
out_shut:
cpm_i2c_shutdown(cpm);
diff --git a/drivers/i2c/busses/i2c-davinci.c b/drivers/i2c/busses/i2c-davinci.c
index fa55605..62be3b3 100644
--- a/drivers/i2c/busses/i2c-davinci.c
+++ b/drivers/i2c/busses/i2c-davinci.c
@@ -38,7 +38,6 @@
#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/gpio.h>
-#include <linux/of_i2c.h>
#include <linux/of_device.h>
#include <mach/hardware.h>
@@ -728,7 +727,6 @@ static int davinci_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failure adding adapter\n");
goto err_unuse_clocks;
}
- of_i2c_register_devices(adap);
return 0;
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c
index 4c5fada..27ea436 100644
--- a/drivers/i2c/busses/i2c-designware-platdrv.c
+++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -35,7 +35,6 @@
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/of.h>
-#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
@@ -172,7 +171,6 @@ static int dw_i2c_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "failure adding adapter\n");
return r;
}
- of_i2c_register_devices(adap);
acpi_i2c_register_devices(adap);
pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c
index bc6e139..e5da9fe 100644
--- a/drivers/i2c/busses/i2c-gpio.c
+++ b/drivers/i2c/busses/i2c-gpio.c
@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
-#include <linux/of_i2c.h>
struct i2c_gpio_private_data {
struct i2c_adapter adap;
@@ -224,8 +223,6 @@ static int i2c_gpio_probe(struct platform_device *pdev)
if (ret)
goto err_add_bus;
- of_i2c_register_devices(adap);
-
platform_set_drvdata(pdev, priv);
dev_info(&pdev->dev, "using pins %u (SDA) and %u (SCL%s)\n",
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 4ebceed..4296d17 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -87,7 +87,6 @@
#include <linux/slab.h>
#include <linux/wait.h>
#include <linux/err.h>
-#include <linux/of_i2c.h>
#if (defined CONFIG_I2C_MUX_GPIO || defined CONFIG_I2C_MUX_GPIO_MODULE) && \
defined CONFIG_DMI
@@ -1230,7 +1229,6 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
goto exit_free_irq;
}
- of_i2c_register_devices(&priv->adapter);
i801_probe_optional_slaves(priv);
/* We ignore errors - multiplexing is optional */
i801_add_mux(priv);
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 973f516..ff3caa0 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -42,7 +42,6 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
#include "i2c-ibm_iic.h"
@@ -759,9 +758,6 @@ static int iic_probe(struct platform_device *ofdev)
dev_info(&ofdev->dev, "using %s mode\n",
dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
- /* Now register all the child nodes */
- of_i2c_register_devices(adap);
-
return 0;
error_cleanup:
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index e242797..bbbea6b 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -50,7 +50,6 @@
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_i2c.h>
#include <linux/platform_data/i2c-imx.h>
/** Defines ********************************************************************
@@ -570,8 +569,6 @@ static int __init i2c_imx_probe(struct platform_device *pdev)
return ret;
}
- of_i2c_register_devices(&i2c_imx->adapter);
-
/* Set up platform driver data */
platform_set_drvdata(pdev, i2c_imx);
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 7607dc0..9f2513d 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -18,7 +18,6 @@
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/of_platform.h>
-#include <linux/of_i2c.h>
#include <linux/slab.h>
#include <linux/io.h>
@@ -691,7 +690,6 @@ static int fsl_i2c_probe(struct platform_device *op)
dev_err(i2c->dev, "failed to add adapter\n");
goto fail_add;
}
- of_i2c_register_devices(&i2c->adap);
return result;
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index b1f42bf..8220322 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -21,7 +21,6 @@
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
-#include <linux/of_i2c.h>
#include <linux/clk.h>
#include <linux/err.h>
@@ -689,8 +688,6 @@ mv64xxx_i2c_probe(struct platform_device *pd)
goto exit_free_irq;
}
- of_i2c_register_devices(&drv_data->adapter);
-
return 0;
exit_free_irq:
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index df8ff5a..62ed07d 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -27,7 +27,6 @@
#include <linux/stmp_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_i2c.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
@@ -701,8 +700,6 @@ static int mxs_i2c_probe(struct platform_device *pdev)
return err;
}
- of_i2c_register_devices(adap);
-
return 0;
}
diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c
index 512dfe6..519df17 100644
--- a/drivers/i2c/busses/i2c-nomadik.c
+++ b/drivers/i2c/busses/i2c-nomadik.c
@@ -24,7 +24,6 @@
#include <linux/pm_runtime.h>
#include <linux/platform_data/i2c-nomadik.h>
#include <linux/of.h>
-#include <linux/of_i2c.h>
#include <linux/pinctrl/consumer.h>
#define DRIVER_NAME "nmk-i2c"
@@ -1045,8 +1044,6 @@ static int nmk_i2c_probe(struct amba_device *adev, const struct amba_id *id)
goto err_add_adap;
}
- of_i2c_register_devices(adap);
-
pm_runtime_put(&adev->dev);
return 0;
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 0e1f824..0a52b78 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -24,7 +24,6 @@
#include <linux/i2c-ocores.h>
#include <linux/slab.h>
#include <linux/io.h>
-#include <linux/of_i2c.h>
#include <linux/log2.h>
struct ocores_i2c {
@@ -435,8 +434,6 @@ static int ocores_i2c_probe(struct platform_device *pdev)
if (pdata) {
for (i = 0; i < pdata->num_devices; i++)
i2c_new_device(&i2c->adap, pdata->devices + i);
- } else {
- of_i2c_register_devices(&i2c->adap);
}
return 0;
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c
index 956fe32..b929ba2 100644
--- a/drivers/i2c/busses/i2c-octeon.c
+++ b/drivers/i2c/busses/i2c-octeon.c
@@ -15,7 +15,6 @@
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/of_i2c.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/slab.h>
@@ -599,8 +598,6 @@ static int octeon_i2c_probe(struct platform_device *pdev)
}
dev_info(i2c->dev, "version %s\n", DRV_VERSION);
- of_i2c_register_devices(&i2c->adap);
-
return 0;
out:
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c
index 142b694d..a9f0f80 100644
--- a/drivers/i2c/busses/i2c-omap.c
+++ b/drivers/i2c/busses/i2c-omap.c
@@ -38,7 +38,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/of.h>
-#include <linux/of_i2c.h>
#include <linux/of_device.h>
#include <linux/slab.h>
#include <linux/i2c-omap.h>
@@ -1245,8 +1244,6 @@ omap_i2c_probe(struct platform_device *pdev)
dev_info(dev->dev, "bus %d rev%d.%d at %d kHz\n", adap->nr,
major, minor, dev->speed);
- of_i2c_register_devices(adap);
-
pm_runtime_mark_last_busy(dev->dev);
pm_runtime_put_autosuspend(dev->dev);
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c
index 5f39c6d..7b57d67 100644
--- a/drivers/i2c/busses/i2c-pnx.c
+++ b/drivers/i2c/busses/i2c-pnx.c
@@ -23,7 +23,6 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/slab.h>
-#include <linux/of_i2c.h>
#define I2C_PNX_TIMEOUT_DEFAULT 10 /* msec */
#define I2C_PNX_SPEED_KHZ_DEFAULT 100
@@ -741,8 +740,6 @@ static int i2c_pnx_probe(struct platform_device *pdev)
goto out_irq;
}
- of_i2c_register_devices(&alg_data->adapter);
-
dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
alg_data->adapter.name, res->start, alg_data->irq);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index bb81773..25f25d2 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -440,7 +440,9 @@ static int i2c_powermac_probe(struct platform_device *dev)
adapter->algo = &i2c_powermac_algorithm;
i2c_set_adapdata(adapter, bus);
adapter->dev.parent = &dev->dev;
- adapter->dev.of_node = dev->dev.of_node;
+
+ /* Clear of_node to skip automatic registration of i2c child nodes */
+ adapter->dev.of_node = NULL;
rc = i2c_add_adapter(adapter);
if (rc) {
printk(KERN_ERR "i2c-powermac: Adapter %s registration "
@@ -451,9 +453,8 @@ static int i2c_powermac_probe(struct platform_device *dev)
printk(KERN_INFO "PowerMac i2c bus %s registered\n", adapter->name);
- /* Cannot use of_i2c_register_devices() due to Apple device-tree
- * funkyness
- */
+ /* Use custom child registration due to Apple device-tree funkyness */
+ adapter->dev.of_node = dev->dev.of_node;
i2c_powermac_register_devices(adapter, bus);
return 0;
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index fbafed2..bc65014 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -31,7 +31,6 @@
#include <linux/i2c-pxa.h>
#include <linux/of.h>
#include <linux/of_device.h>
-#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
@@ -1185,7 +1184,6 @@ static int i2c_pxa_probe(struct platform_device *dev)
printk(KERN_INFO "I2C: Failed to add bus\n");
goto eadapt;
}
- of_i2c_register_devices(&i2c->adap);
platform_set_drvdata(dev, i2c);
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c
index cab1c91..643426e 100644
--- a/drivers/i2c/busses/i2c-s3c2410.c
+++ b/drivers/i2c/busses/i2c-s3c2410.c
@@ -36,7 +36,6 @@
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
-#include <linux/of_i2c.h>
#include <linux/of_gpio.h>
#include <linux/pinctrl/consumer.h>
@@ -1154,7 +1153,6 @@ static int s3c24xx_i2c_probe(struct platform_device *pdev)
return ret;
}
- of_i2c_register_devices(&i2c->adap);
platform_set_drvdata(pdev, i2c);
pm_runtime_enable(&pdev->dev);
diff --git a/drivers/i2c/busses/i2c-sh_mobile.c b/drivers/i2c/busses/i2c-sh_mobile.c
index debf745..aa1268f 100644
--- a/drivers/i2c/busses/i2c-sh_mobile.c
+++ b/drivers/i2c/busses/i2c-sh_mobile.c
@@ -27,7 +27,6 @@
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
-#include <linux/of_i2c.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include <linux/clk.h>
@@ -758,7 +757,6 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
"I2C adapter %d with bus speed %lu Hz (L/H=%x/%x)\n",
adap->nr, pd->bus_speed, pd->iccl, pd->icch);
- of_i2c_register_devices(adap);
return 0;
err_all:
diff --git a/drivers/i2c/busses/i2c-sirf.c b/drivers/i2c/busses/i2c-sirf.c
index a63c7d5..0ff22e2 100644
--- a/drivers/i2c/busses/i2c-sirf.c
+++ b/drivers/i2c/busses/i2c-sirf.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
-#include <linux/of_i2c.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
@@ -366,8 +365,6 @@ static int i2c_sirfsoc_probe(struct platform_device *pdev)
clk_disable(clk);
- of_i2c_register_devices(adap);
-
dev_info(&pdev->dev, " I2C adapter ready to operate\n");
return 0;
diff --git a/drivers/i2c/busses/i2c-stu300.c b/drivers/i2c/busses/i2c-stu300.c
index d1a6b20..047546c 100644
--- a/drivers/i2c/busses/i2c-stu300.c
+++ b/drivers/i2c/busses/i2c-stu300.c
@@ -17,7 +17,6 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
-#include <linux/of_i2c.h>
/* the name of this kernel module */
#define NAME "stu300"
@@ -936,7 +935,6 @@ stu300_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dev);
dev_info(&pdev->dev, "ST DDC I2C @ %p, irq %d\n",
dev->virtbase, dev->irq);
- of_i2c_register_devices(adap);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index 9aa1b60..c457cb4 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -25,7 +25,6 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/slab.h>
-#include <linux/of_i2c.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/clk/tegra.h>
@@ -802,8 +801,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
return ret;
}
- of_i2c_register_devices(&i2c_dev->adapter);
-
return 0;
}
diff --git a/drivers/i2c/busses/i2c-versatile.c b/drivers/i2c/busses/i2c-versatile.c
index f3a8790..6bb3a89 100644
--- a/drivers/i2c/busses/i2c-versatile.c
+++ b/drivers/i2c/busses/i2c-versatile.c
@@ -16,7 +16,6 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/io.h>
-#include <linux/of_i2c.h>
#define I2C_CONTROL 0x00
#define I2C_CONTROLS 0x00
@@ -108,7 +107,6 @@ static int i2c_versatile_probe(struct platform_device *dev)
ret = i2c_bit_add_numbered_bus(&i2c->adap);
if (ret >= 0) {
platform_set_drvdata(dev, i2c);
- of_i2c_register_devices(&i2c->adap);
return 0;
}
diff --git a/drivers/i2c/busses/i2c-wmt.c b/drivers/i2c/busses/i2c-wmt.c
index baaa7d1..c65da3d 100644
--- a/drivers/i2c/busses/i2c-wmt.c
+++ b/drivers/i2c/busses/i2c-wmt.c
@@ -21,7 +21,6 @@
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
-#include <linux/of_i2c.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
@@ -439,8 +438,6 @@ static int wmt_i2c_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, i2c_dev);
- of_i2c_register_devices(adap);
-
return 0;
}
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index 3d0f052..8823db7 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -40,7 +40,6 @@
#include <linux/i2c-xiic.h>
#include <linux/io.h>
#include <linux/slab.h>
-#include <linux/of_i2c.h>
#define DRIVER_NAME "xiic-i2c"
@@ -752,8 +751,6 @@ static int xiic_i2c_probe(struct platform_device *pdev)
i2c_new_device(&i2c->adap, pdata->devices + i);
}
- of_i2c_register_devices(&i2c->adap);
-
return 0;
add_adapter_failed:
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
index f32ca29..321b7ca 100644
--- a/drivers/i2c/i2c-core.c
+++ b/drivers/i2c/i2c-core.c
@@ -23,7 +23,11 @@
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
Jean Delvare <khali@linux-fr.org>
Mux support by Rodolfo Giometti <giometti@enneenne.com> and
- Michael Lawnick <michael.lawnick.ext@nsn.com> */
+ Michael Lawnick <michael.lawnick.ext@nsn.com>
+ OF support is copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
+ (based on a previous patch from Jon Smirl <jonsmirl@gmail.com>) and
+ (c) 2013 Wolfram Sang <wsa@the-dreams.de>
+ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -35,7 +39,9 @@
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/mutex.h>
+#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/of_irq.h>
#include <linux/completion.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
@@ -954,6 +960,102 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
up_read(&__i2c_board_lock);
}
+/* of support code */
+
+#if IS_ENABLED(CONFIG_OF)
+static void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+ void *result;
+ struct device_node *node;
+
+ /* Only register child devices if the adapter has a node pointer set */
+ if (!adap->dev.of_node)
+ return;
+
+ dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
+
+ for_each_available_child_of_node(adap->dev.of_node, node) {
+ struct i2c_board_info info = {};
+ struct dev_archdata dev_ad = {};
+ const __be32 *addr;
+ int len;
+
+ dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
+
+ if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
+ dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
+ node->full_name);
+ continue;
+ }
+
+ addr = of_get_property(node, "reg", &len);
+ if (!addr || (len < sizeof(int))) {
+ dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+ node->full_name);
+ continue;
+ }
+
+ info.addr = be32_to_cpup(addr);
+ if (info.addr > (1 << 10) - 1) {
+ dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+ info.addr, node->full_name);
+ continue;
+ }
+
+ info.irq = irq_of_parse_and_map(node, 0);
+ info.of_node = of_node_get(node);
+ info.archdata = &dev_ad;
+
+ if (of_get_property(node, "wakeup-source", NULL))
+ info.flags |= I2C_CLIENT_WAKE;
+
+ request_module("%s%s", I2C_MODULE_PREFIX, info.type);
+
+ result = i2c_new_device(adap, &info);
+ if (result == NULL) {
+ dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+ node->full_name);
+ of_node_put(node);
+ irq_dispose_mapping(info.irq);
+ continue;
+ }
+ }
+}
+
+static int of_dev_node_match(struct device *dev, void *data)
+{
+ return dev->of_node == data;
+}
+
+/* must call put_device() when done with returned i2c_client device */
+struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&i2c_bus_type, NULL, node,
+ of_dev_node_match);
+ if (!dev)
+ return NULL;
+
+ return i2c_verify_client(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+ struct device *dev;
+
+ dev = bus_find_device(&i2c_bus_type, NULL, node,
+ of_dev_node_match);
+ if (!dev)
+ return NULL;
+
+ return i2c_verify_adapter(dev);
+}
+EXPORT_SYMBOL(of_find_i2c_device_by_node);
+#endif /* CONFIG_OF */
+
static int i2c_do_add_adapter(struct i2c_driver *driver,
struct i2c_adapter *adap)
{
@@ -1058,6 +1160,8 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
exit_recovery:
/* create pre-declared device nodes */
+ of_i2c_register_devices(adap);
+
if (adap->nr < __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
@@ -1282,7 +1386,6 @@ void i2c_del_adapter(struct i2c_adapter *adap)
}
EXPORT_SYMBOL(i2c_del_adapter);
-
/* ------------------------------------------------------------------------- */
int i2c_for_each_dev(void *data, int (*fn)(struct device *, void *))
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c
index 7409ebb..797e311 100644
--- a/drivers/i2c/i2c-mux.c
+++ b/drivers/i2c/i2c-mux.c
@@ -25,7 +25,6 @@
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/of.h>
-#include <linux/of_i2c.h>
/* multiplexer per channel data */
struct i2c_mux_priv {
@@ -185,8 +184,6 @@ struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
i2c_adapter_id(&priv->adap));
- of_i2c_register_devices(&priv->adap);
-
return &priv->adap;
}
EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
diff --git a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
index 210b6f7..b901638 100644
--- a/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
+++ b/drivers/i2c/muxes/i2c-arb-gpio-challenge.c
@@ -21,7 +21,6 @@
#include <linux/i2c-mux.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/of_i2c.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
diff --git a/drivers/i2c/muxes/i2c-mux-gpio.c b/drivers/i2c/muxes/i2c-mux-gpio.c
index 5a0ce00..128a981 100644
--- a/drivers/i2c/muxes/i2c-mux-gpio.c
+++ b/drivers/i2c/muxes/i2c-mux-gpio.c
@@ -16,7 +16,6 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/gpio.h>
-#include <linux/of_i2c.h>
#include <linux/of_gpio.h>
struct gpiomux {
diff --git a/drivers/i2c/muxes/i2c-mux-pinctrl.c b/drivers/i2c/muxes/i2c-mux-pinctrl.c
index a43c0ce..859a6d2 100644
--- a/drivers/i2c/muxes/i2c-mux-pinctrl.c
+++ b/drivers/i2c/muxes/i2c-mux-pinctrl.c
@@ -20,7 +20,6 @@
#include <linux/i2c-mux.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/of_i2c.h>
#include <linux/pinctrl/consumer.h>
#include <linux/i2c-mux-pinctrl.h>
#include <linux/platform_device.h>
diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
index 617a798..c283186 100644
--- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c
+++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c
@@ -12,7 +12,6 @@
#include <linux/clk.h>
#include <linux/module.h>
-#include <linux/of_i2c.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
@@ -67,8 +66,6 @@ static int fimc_is_i2c_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_enable(&i2c_adap->dev);
- of_i2c_register_devices(i2c_adap);
-
return 0;
}
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 80e5c13..78cc760 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -48,12 +48,6 @@ config OF_IRQ
def_bool y
depends on !SPARC
-config OF_I2C
- def_tristate I2C
- depends on I2C
- help
- OpenFirmware I2C accessors
-
config OF_NET
depends on NETDEVICES
def_bool y
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index 1f9c0c4..efd0510 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_OF_FLATTREE) += fdt.o
obj-$(CONFIG_OF_PROMTREE) += pdt.o
obj-$(CONFIG_OF_ADDRESS) += address.o
obj-$(CONFIG_OF_IRQ) += irq.o
-obj-$(CONFIG_OF_I2C) += of_i2c.o
obj-$(CONFIG_OF_NET) += of_net.o
obj-$(CONFIG_OF_SELFTEST) += selftest.o
obj-$(CONFIG_OF_MDIO) += of_mdio.o
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c
deleted file mode 100644
index b667264..0000000
--- a/drivers/of/of_i2c.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * OF helpers for the I2C API
- *
- * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
- *
- * Based on a previous patch from Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#include <linux/i2c.h>
-#include <linux/irq.h>
-#include <linux/of.h>
-#include <linux/of_i2c.h>
-#include <linux/of_irq.h>
-#include <linux/module.h>
-
-void of_i2c_register_devices(struct i2c_adapter *adap)
-{
- void *result;
- struct device_node *node;
-
- /* Only register child devices if the adapter has a node pointer set */
- if (!adap->dev.of_node)
- return;
-
- dev_dbg(&adap->dev, "of_i2c: walking child nodes\n");
-
- for_each_available_child_of_node(adap->dev.of_node, node) {
- struct i2c_board_info info = {};
- struct dev_archdata dev_ad = {};
- const __be32 *addr;
- int len;
-
- dev_dbg(&adap->dev, "of_i2c: register %s\n", node->full_name);
-
- if (of_modalias_node(node, info.type, sizeof(info.type)) < 0) {
- dev_err(&adap->dev, "of_i2c: modalias failure on %s\n",
- node->full_name);
- continue;
- }
-
- addr = of_get_property(node, "reg", &len);
- if (!addr || (len < sizeof(int))) {
- dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
- node->full_name);
- continue;
- }
-
- info.addr = be32_to_cpup(addr);
- if (info.addr > (1 << 10) - 1) {
- dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
- info.addr, node->full_name);
- continue;
- }
-
- info.irq = irq_of_parse_and_map(node, 0);
- info.of_node = of_node_get(node);
- info.archdata = &dev_ad;
-
- if (of_get_property(node, "wakeup-source", NULL))
- info.flags |= I2C_CLIENT_WAKE;
-
- request_module("%s%s", I2C_MODULE_PREFIX, info.type);
-
- result = i2c_new_device(adap, &info);
- if (result == NULL) {
- dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
- node->full_name);
- of_node_put(node);
- irq_dispose_mapping(info.irq);
- continue;
- }
- }
-}
-EXPORT_SYMBOL(of_i2c_register_devices);
-
-static int of_dev_node_match(struct device *dev, void *data)
-{
- return dev->of_node == data;
-}
-
-/* must call put_device() when done with returned i2c_client device */
-struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
- struct device *dev;
-
- dev = bus_find_device(&i2c_bus_type, NULL, node,
- of_dev_node_match);
- if (!dev)
- return NULL;
-
- return i2c_verify_client(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_device_by_node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
-{
- struct device *dev;
-
- dev = bus_find_device(&i2c_bus_type, NULL, node,
- of_dev_node_match);
- if (!dev)
- return NULL;
-
- return i2c_verify_adapter(dev);
-}
-EXPORT_SYMBOL(of_find_i2c_adapter_by_node);
-
-MODULE_LICENSE("GPL");
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index e988fa9..2189189 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -542,6 +542,26 @@ static inline int i2c_adapter_id(struct i2c_adapter *adap)
#endif /* I2C */
+#if IS_ENABLED(CONFIG_OF)
+/* must call put_device() when done with returned i2c_client device */
+extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+
+/* must call put_device() when done with returned i2c_adapter device */
+extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
+
+#else
+
+static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
+{
+ return NULL;
+}
+
+static inline struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF */
+
#if IS_ENABLED(CONFIG_ACPI_I2C)
extern void acpi_i2c_register_devices(struct i2c_adapter *adap);
#else
diff --git a/include/linux/of_i2c.h b/include/linux/of_i2c.h
deleted file mode 100644
index cfb545c..0000000
--- a/include/linux/of_i2c.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Generic I2C API implementation for PowerPC.
- *
- * Copyright (c) 2008 Jochen Friedrich <jochen@scram.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef __LINUX_OF_I2C_H
-#define __LINUX_OF_I2C_H
-
-#if defined(CONFIG_OF_I2C) || defined(CONFIG_OF_I2C_MODULE)
-#include <linux/i2c.h>
-
-extern void of_i2c_register_devices(struct i2c_adapter *adap);
-
-/* must call put_device() when done with returned i2c_client device */
-extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
-
-/* must call put_device() when done with returned i2c_adapter device */
-extern struct i2c_adapter *of_find_i2c_adapter_by_node(
- struct device_node *node);
-
-#else
-static inline void of_i2c_register_devices(struct i2c_adapter *adap)
-{
- return;
-}
-
-static inline struct i2c_client *of_find_i2c_device_by_node(struct device_node *node)
-{
- return NULL;
-}
-
-/* must call put_device() when done with returned i2c_adapter device */
-static inline struct i2c_adapter *of_find_i2c_adapter_by_node(
- struct device_node *node)
-{
- return NULL;
-}
-#endif /* CONFIG_OF_I2C */
-
-#endif /* __LINUX_OF_I2C_H */
--
1.7.10.4
^ permalink raw reply related
* Re: [RFC PATCH v2 00/11] Add (de)compression support to pstore
From: Tony Luck @ 2013-08-19 17:29 UTC (permalink / raw)
To: Kees Cook
Cc: jkenisto@linux.vnet.ibm.com, ccross@android.com,
linux-kernel@vger.kernel.org, mahesh@linux.vnet.ibm.com,
linuxppc-dev@ozlabs.org, Aruna Balakrishnaiah,
cbouatmailru@gmail.com
In-Reply-To: <CAGXu5jLFa+bC-atqy9X7yFJipB69qnPP_MqDRBgag10Q2Fas6A@mail.gmail.com>
On Sat, Aug 17, 2013 at 11:32 AM, Kees Cook <keescook@chromium.org> wrote:
> Yeah, this is great. While I haven't tested it myself yet, the code
> seems to be in good shape. I acked the ram piece separately, but
> consider the entire series:
>
> Reviewed-by: Kees Cook <keescook@chromium.org>
Applied. This should show up in linux-next tomorrow.
Anyone using efivars as the pstore backend? Testing reports (positive
or negative) appreciated.
-Tony
^ permalink raw reply
* Re: [PATCH 4/4] hotplug, powerpc, x86: Remove cpu_hotplug_driver_lock()
From: Toshi Kani @ 2013-08-19 15:23 UTC (permalink / raw)
To: Nathan Fontenot
Cc: fenghua.yu, bp, gregkh, x86, linux-kernel, rjw, isimatu.yasuaki,
mingo, srivatsa.bhat, tglx, hpa, linuxppc-dev
In-Reply-To: <521237A9.8010109@linux.vnet.ibm.com>
On Mon, 2013-08-19 at 10:20 -0500, Nathan Fontenot wrote:
> On 08/17/2013 02:46 PM, Toshi Kani wrote:
> > cpu_hotplug_driver_lock() serializes CPU online/offline operations
> > when ARCH_CPU_PROBE_RELEASE is set. This lock interface is no longer
> > necessary with the following reason:
> >
> > - lock_device_hotplug() now protects CPU online/offline operations,
> > including the probe & release interfaces enabled by
> > ARCH_CPU_PROBE_RELEASE. The use of cpu_hotplug_driver_lock() is
> > redundant.
> > - cpu_hotplug_driver_lock() is only valid when ARCH_CPU_PROBE_RELEASE
> > is defined, which is misleading and is only enabled on powerpc.
> >
> > This patch removes the cpu_hotplug_driver_lock() interface. As
> > a result, ARCH_CPU_PROBE_RELEASE only enables / disables the cpu
> > probe & release interface as intended. There is no functional change
> > in this patch.
> >
> > Signed-off-by: Toshi Kani <toshi.kani@hp.com>
>
> Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
Thanks Nathan!
-Toshi
^ permalink raw reply
* Re: [PATCH 4/4] hotplug, powerpc, x86: Remove cpu_hotplug_driver_lock()
From: Nathan Fontenot @ 2013-08-19 15:20 UTC (permalink / raw)
To: Toshi Kani
Cc: fenghua.yu, bp, gregkh, x86, linux-kernel, rjw, isimatu.yasuaki,
mingo, srivatsa.bhat, tglx, hpa, linuxppc-dev
In-Reply-To: <1376768819-28975-5-git-send-email-toshi.kani@hp.com>
On 08/17/2013 02:46 PM, Toshi Kani wrote:
> cpu_hotplug_driver_lock() serializes CPU online/offline operations
> when ARCH_CPU_PROBE_RELEASE is set. This lock interface is no longer
> necessary with the following reason:
>
> - lock_device_hotplug() now protects CPU online/offline operations,
> including the probe & release interfaces enabled by
> ARCH_CPU_PROBE_RELEASE. The use of cpu_hotplug_driver_lock() is
> redundant.
> - cpu_hotplug_driver_lock() is only valid when ARCH_CPU_PROBE_RELEASE
> is defined, which is misleading and is only enabled on powerpc.
>
> This patch removes the cpu_hotplug_driver_lock() interface. As
> a result, ARCH_CPU_PROBE_RELEASE only enables / disables the cpu
> probe & release interface as intended. There is no functional change
> in this patch.
>
> Signed-off-by: Toshi Kani <toshi.kani@hp.com>
Reviewed-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> Performed build test only on powerpc.
> ---
> arch/powerpc/kernel/smp.c | 12 ----------
> arch/powerpc/platforms/pseries/dlpar.c | 40 ++++++++++++--------------------
> arch/x86/kernel/topology.c | 2 --
> drivers/base/cpu.c | 10 +-------
> include/linux/cpu.h | 13 ----------
> 5 files changed, 16 insertions(+), 61 deletions(-)
>
> diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
> index 38b0ba6..1667269 100644
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -763,18 +763,6 @@ void __cpu_die(unsigned int cpu)
> smp_ops->cpu_die(cpu);
> }
>
> -static DEFINE_MUTEX(powerpc_cpu_hotplug_driver_mutex);
> -
> -void cpu_hotplug_driver_lock()
> -{
> - mutex_lock(&powerpc_cpu_hotplug_driver_mutex);
> -}
> -
> -void cpu_hotplug_driver_unlock()
> -{
> - mutex_unlock(&powerpc_cpu_hotplug_driver_mutex);
> -}
> -
> void cpu_die(void)
> {
> if (ppc_md.cpu_die)
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index a1a7b9a..e39325d 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -387,18 +387,13 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
> char *cpu_name;
> int rc;
>
> - cpu_hotplug_driver_lock();
> rc = strict_strtoul(buf, 0, &drc_index);
> - if (rc) {
> - rc = -EINVAL;
> - goto out;
> - }
> + if (rc)
> + return -EINVAL;
>
> dn = dlpar_configure_connector(drc_index);
> - if (!dn) {
> - rc = -EINVAL;
> - goto out;
> - }
> + if (!dn)
> + return -EINVAL;
>
> /* configure-connector reports cpus as living in the base
> * directory of the device tree. CPUs actually live in the
> @@ -407,8 +402,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
> cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name);
> if (!cpu_name) {
> dlpar_free_cc_nodes(dn);
> - rc = -ENOMEM;
> - goto out;
> + return -ENOMEM;
> }
>
> kfree(dn->full_name);
> @@ -417,22 +411,21 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
> rc = dlpar_acquire_drc(drc_index);
> if (rc) {
> dlpar_free_cc_nodes(dn);
> - rc = -EINVAL;
> - goto out;
> + return -EINVAL;
> }
>
> rc = dlpar_attach_node(dn);
> if (rc) {
> dlpar_release_drc(drc_index);
> dlpar_free_cc_nodes(dn);
> - goto out;
> + return rc;
> }
>
> rc = dlpar_online_cpu(dn);
> -out:
> - cpu_hotplug_driver_unlock();
> + if (rc)
> + return rc;
>
> - return rc ? rc : count;
> + return count;
> }
>
> static int dlpar_offline_cpu(struct device_node *dn)
> @@ -505,30 +498,27 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
> return -EINVAL;
> }
>
> - cpu_hotplug_driver_lock();
> rc = dlpar_offline_cpu(dn);
> if (rc) {
> of_node_put(dn);
> - rc = -EINVAL;
> - goto out;
> + return -EINVAL;
> }
>
> rc = dlpar_release_drc(*drc_index);
> if (rc) {
> of_node_put(dn);
> - goto out;
> + return rc;
> }
>
> rc = dlpar_detach_node(dn);
> if (rc) {
> dlpar_acquire_drc(*drc_index);
> - goto out;
> + return rc;
> }
>
> of_node_put(dn);
> -out:
> - cpu_hotplug_driver_unlock();
> - return rc ? rc : count;
> +
> + return count;
> }
>
> static int __init pseries_dlpar_init(void)
> diff --git a/arch/x86/kernel/topology.c b/arch/x86/kernel/topology.c
> index a3f35eb..649b010 100644
> --- a/arch/x86/kernel/topology.c
> +++ b/arch/x86/kernel/topology.c
> @@ -66,7 +66,6 @@ int __ref _debug_hotplug_cpu(int cpu, int action)
> return -EINVAL;
>
> lock_device_hotplug();
> - cpu_hotplug_driver_lock();
>
> switch (action) {
> case 0:
> @@ -91,7 +90,6 @@ int __ref _debug_hotplug_cpu(int cpu, int action)
> ret = -EINVAL;
> }
>
> - cpu_hotplug_driver_unlock();
> unlock_device_hotplug();
>
> return ret;
> diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
> index 4cc6928..b4ebd7b 100644
> --- a/drivers/base/cpu.c
> +++ b/drivers/base/cpu.c
> @@ -45,8 +45,6 @@ static int __ref cpu_subsys_online(struct device *dev)
> int from_nid, to_nid;
> int ret;
>
> - cpu_hotplug_driver_lock();
> -
> from_nid = cpu_to_node(cpuid);
> ret = cpu_up(cpuid);
> /*
> @@ -57,18 +55,12 @@ static int __ref cpu_subsys_online(struct device *dev)
> if (from_nid != to_nid)
> change_cpu_under_node(cpu, from_nid, to_nid);
>
> - cpu_hotplug_driver_unlock();
> return ret;
> }
>
> static int cpu_subsys_offline(struct device *dev)
> {
> - int ret;
> -
> - cpu_hotplug_driver_lock();
> - ret = cpu_down(dev->id);
> - cpu_hotplug_driver_unlock();
> - return ret;
> + return cpu_down(dev->id);
> }
>
> void unregister_cpu(struct cpu *cpu)
> diff --git a/include/linux/cpu.h b/include/linux/cpu.h
> index ab0eade..e847ef8 100644
> --- a/include/linux/cpu.h
> +++ b/include/linux/cpu.h
> @@ -182,19 +182,6 @@ extern void cpu_hotplug_enable(void);
> void clear_tasks_mm_cpumask(int cpu);
> int cpu_down(unsigned int cpu);
>
> -#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
> -extern void cpu_hotplug_driver_lock(void);
> -extern void cpu_hotplug_driver_unlock(void);
> -#else
> -static inline void cpu_hotplug_driver_lock(void)
> -{
> -}
> -
> -static inline void cpu_hotplug_driver_unlock(void)
> -{
> -}
> -#endif
> -
> #else /* CONFIG_HOTPLUG_CPU */
>
> #define get_online_cpus() do { } while (0)
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
^ permalink raw reply
* Re: [PATCH 0/4] Unify CPU hotplug lock interface
From: Toshi Kani @ 2013-08-19 14:54 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: fenghua.yu, bp, gregkh, x86, linux-kernel, isimatu.yasuaki, mingo,
srivatsa.bhat, tglx, hpa, linuxppc-dev
In-Reply-To: <1449558.tneKXFMIWE@vostro.rjw.lan>
On Sun, 2013-08-18 at 03:02 +0200, Rafael J. Wysocki wrote:
> On Saturday, August 17, 2013 01:46:55 PM Toshi Kani wrote:
> > lock_device_hotplug() was recently introduced to serialize CPU & Memory
> > online/offline and hotplug operations, along with sysfs online interface
> > restructure (commit 4f3549d7). With this new locking scheme,
> > cpu_hotplug_driver_lock() is redundant and is no longer necessary.
> >
> > This patchset makes sure that lock_device_hotplug() covers all CPU online/
> > offline interfaces, and then removes cpu_hotplug_driver_lock().
> >
> > The patchset is based on Linus's tree, 3.11.0-rc5.
>
> Nice series, thanks a lot for taking care of this!
Thanks Rafael!
-Toshi
^ permalink raw reply
* Re: [PATCH 2/4] hotplug, x86: Add hotplug lock to missing places
From: Toshi Kani @ 2013-08-19 14:53 UTC (permalink / raw)
To: Greg KH
Cc: fenghua.yu, bp, x86, linux-kernel, rjw, isimatu.yasuaki, mingo,
srivatsa.bhat, tglx, hpa, linuxppc-dev
In-Reply-To: <20130817231552.GA20169@kroah.com>
On Sat, 2013-08-17 at 16:15 -0700, Greg KH wrote:
> On Sat, Aug 17, 2013 at 01:46:57PM -0600, Toshi Kani wrote:
> > lock_device_hotplug() serializes CPU & Memory online/offline and hotplug
> > operations. However, this lock is not held in the debug interfaces below
> > that initiate CPU online/offline operations.
> >
> > - _debug_hotplug_cpu(), cpu0 hotplug test interface enabled by
> > CONFIG_DEBUG_HOTPLUG_CPU0.
> > - cpu_probe_store() and cpu_release_store(), cpu hotplug test interface
> > enabled by CONFIG_ARCH_CPU_PROBE_RELEASE.
> >
> > This patch changes the above interfaces to hold lock_device_hotplug().
> >
> > Signed-off-by: Toshi Kani <toshi.kani@hp.com>
> > ---
> > arch/x86/kernel/topology.c | 2 ++
> > drivers/base/cpu.c | 16 ++++++++++++++--
> > 2 files changed, 16 insertions(+), 2 deletions(-)
>
> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Thanks Greg!
-Toshi
^ permalink raw reply
* Re: [PATCH 8/8] powerpc/pseries: child nodes are not detached by dlpar_detach_node
From: Nathan Fontenot @ 2013-08-19 13:56 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-9-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> Calls to dlpar_detach_node do not iterate over child nodes detaching them as
> well. By iterating and detaching the child nodes we ensure that they have the
> OF_DETACHED flag set and that their reference counts are decremented such that
> the node will be freed from memory by of_node_release.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/dlpar.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index 4ea667d..7cfdaae 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -286,8 +286,15 @@ int dlpar_attach_node(struct device_node *dn)
>
> int dlpar_detach_node(struct device_node *dn)
> {
> + struct device_node *child;
> int rc;
>
> + child = of_get_next_child(dn, NULL);
> + while (child) {
> + dlpar_detach_node(child);
> + child = of_get_next_child(dn, child);
> + }
> +
> rc = of_detach_node(dn);
> if (rc)
> return rc;
>
^ permalink raw reply
* Re: [RFC PATCH v2 3/4] powerpc: refactor of_get_cpu_node to support other architectures
From: Sudeep KarkadaNagesha @ 2013-08-19 13:56 UTC (permalink / raw)
To: Rob Herring
Cc: Mark Rutland, Jonas Bonn, Michal Simek, Lorenzo Pieralisi,
linux-pm@vger.kernel.org, Sudeep KarkadaNagesha, Tomasz Figa,
rob.herring@calxeda.com, linux-kernel@vger.kernel.org,
Rafael J. Wysocki, devicetree@vger.kernel.org,
grant.likely@linaro.org, linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <5212177C.8000709@gmail.com>
On 19/08/13 14:02, Rob Herring wrote:
> On 08/19/2013 05:19 AM, Mark Rutland wrote:
>> On Sat, Aug 17, 2013 at 11:09:36PM +0100, Benjamin Herrenschmidt wrote:
>>> On Sat, 2013-08-17 at 12:50 +0200, Tomasz Figa wrote:
>>>> I wonder how would this handle uniprocessor ARM (pre-v7) cores, for
>>>> which=20
>>>> the updated bindings[1] define #address-cells =3D <0> and so no reg=20
>>>> property.
>>>>
>>>> [1] - http://thread.gmane.org/gmane.linux.ports.arm.kernel/260795
>>>
>>> Why did you do that in the binding ? That sounds like looking to create
>>> problems ...=20
>>>
>>> Traditionally, UP setups just used "0" as the "reg" property on other
>>> architectures, why do differently ?
>>
>> The decision was taken because we defined our reg property to refer to
>> the MPIDR register's Aff{2,1,0} bitfields, and on UP cores before v7
>> there's no MPIDR register at all. Given there can only be a single CPU
>> in that case, describing a register that wasn't present didn't seem
>> necessary or helpful.
>=20
> What exactly reg represents is up to the binding definition, but it
> still should be present IMO. I don't see any issue with it being
> different for pre-v7.
>=20
Yes it's better to have 'reg' with value 0 than not having it.
Otherwise this generic of_get_cpu_node implementation would need some
_hack_ to handle that case.
Regards,
Sudeep
^ permalink raw reply
* Re: [PATCH 7/8] powerpc/pseries: add mising of_node_put in delete_dt_node
From: Nathan Fontenot @ 2013-08-19 13:54 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-8-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> The node to be detached is retrieved via its phandle by a call to
> of_find_node_by_phandle which increments the ref count. We need a matching
> call to of_node_put to decrement the ref count and ensure the node is
> actually freed.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/mobility.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index ff102e2..cde4e0a 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -62,6 +62,7 @@ static int delete_dt_node(u32 phandle)
> return -ENOENT;
>
> dlpar_detach_node(dn);
> + of_node_put(dn);
> return 0;
> }
>
>
^ permalink raw reply
* Re: [PATCH 6/8] powerpc/pseries: make dlpar_configure_connector parent node aware
From: Nathan Fontenot @ 2013-08-19 13:53 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-7-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> Currently the device nodes created in the device subtree returned by a call to
> dlpar_configure_connector are all named in the root node. This is because the
> the node name in the work area returned by ibm,configure-connector rtas call
> only contains the node name and not the entire node path. Passing the parent
> node where the new subtree will be created to dlpar_configure_connector allows
> the correct node path to be prefixed in the full_name field.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/dlpar.c | 55 ++++++++++++++++---------------
> arch/powerpc/platforms/pseries/mobility.c | 11 +++----
> arch/powerpc/platforms/pseries/pseries.h | 2 +-
> 3 files changed, 34 insertions(+), 34 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index c855233..4ea667d 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -63,21 +63,24 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa)
> return prop;
> }
>
> -static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
> +static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa,
> + const char *path)
> {
> struct device_node *dn;
> char *name;
>
> + /* If parent node path is "/" advance path to NULL terminator to
> + * prevent double leading slashs in full_name.
> + */
> + if (!path[1])
> + path++;
> +
> dn = kzalloc(sizeof(*dn), GFP_KERNEL);
> if (!dn)
> return NULL;
>
> - /* The configure connector reported name does not contain a
> - * preceding '/', so we allocate a buffer large enough to
> - * prepend this to the full_name.
> - */
> name = (char *)ccwa + ccwa->name_offset;
> - dn->full_name = kasprintf(GFP_KERNEL, "/%s", name);
> + dn->full_name = kasprintf(GFP_KERNEL, "%s/%s", path, name);
> if (!dn->full_name) {
> kfree(dn);
> return NULL;
> @@ -123,7 +126,8 @@ void dlpar_free_cc_nodes(struct device_node *dn)
> #define CALL_AGAIN -2
> #define ERR_CFG_USE -9003
>
> -struct device_node *dlpar_configure_connector(u32 drc_index)
> +struct device_node *dlpar_configure_connector(u32 drc_index,
> + struct device_node *parent)
> {
> struct device_node *dn;
> struct device_node *first_dn = NULL;
> @@ -132,6 +136,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
> struct property *last_property = NULL;
> struct cc_workarea *ccwa;
> char *data_buf;
> + const char *parent_path = parent->full_name;
> int cc_token;
> int rc = -1;
>
> @@ -165,7 +170,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
> break;
>
> case NEXT_SIBLING:
> - dn = dlpar_parse_cc_node(ccwa);
> + dn = dlpar_parse_cc_node(ccwa, parent_path);
> if (!dn)
> goto cc_error;
>
> @@ -175,13 +180,17 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
> break;
>
> case NEXT_CHILD:
> - dn = dlpar_parse_cc_node(ccwa);
> + if (first_dn)
> + parent_path = last_dn->full_name;
> +
> + dn = dlpar_parse_cc_node(ccwa, parent_path);
> if (!dn)
> goto cc_error;
>
> - if (!first_dn)
> + if (!first_dn) {
> + dn->parent = parent;
> first_dn = dn;
> - else {
> + } else {
> dn->parent = last_dn;
> if (last_dn)
> last_dn->child = dn;
> @@ -205,6 +214,7 @@ struct device_node *dlpar_configure_connector(u32 drc_index)
>
> case PREV_PARENT:
> last_dn = last_dn->parent;
> + parent_path = last_dn->parent->full_name;
> break;
>
> case CALL_AGAIN:
> @@ -383,9 +393,8 @@ out:
>
> static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
> {
> - struct device_node *dn;
> + struct device_node *dn, *parent;
> unsigned long drc_index;
> - char *cpu_name;
> int rc;
>
> cpu_hotplug_driver_lock();
> @@ -395,25 +404,19 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
> goto out;
> }
>
> - dn = dlpar_configure_connector(drc_index);
> - if (!dn) {
> - rc = -EINVAL;
> + parent = of_find_node_by_path("/cpus");
> + if (!parent) {
> + rc = -ENODEV;
> goto out;
> }
>
> - /* configure-connector reports cpus as living in the base
> - * directory of the device tree. CPUs actually live in the
> - * cpus directory so we need to fixup the full_name.
> - */
> - cpu_name = kasprintf(GFP_KERNEL, "/cpus%s", dn->full_name);
> - if (!cpu_name) {
> - dlpar_free_cc_nodes(dn);
> - rc = -ENOMEM;
> + dn = dlpar_configure_connector(drc_index, parent);
> + if (!dn) {
> + rc = -EINVAL;
> goto out;
> }
>
> - kfree(dn->full_name);
> - dn->full_name = cpu_name;
> + of_node_put(parent);
>
> rc = dlpar_acquire_drc(drc_index);
> if (rc) {
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index ed5426f..ff102e2 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -216,17 +216,14 @@ static int add_dt_node(u32 parent_phandle, u32 drc_index)
> struct device_node *parent_dn;
> int rc;
>
> - dn = dlpar_configure_connector(drc_index);
> - if (!dn)
> + parent_dn = of_find_node_by_phandle(parent_phandle);
> + if (!parent_dn)
> return -ENOENT;
>
> - parent_dn = of_find_node_by_phandle(parent_phandle);
> - if (!parent_dn) {
> - dlpar_free_cc_nodes(dn);
> + dn = dlpar_configure_connector(drc_index, parent_dn);
> + if (!dn)
> return -ENOENT;
> - }
>
> - dn->parent = parent_dn;
> rc = dlpar_attach_node(dn);
> if (rc)
> dlpar_free_cc_nodes(dn);
> diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
> index c2a3a25..defb3c9 100644
> --- a/arch/powerpc/platforms/pseries/pseries.h
> +++ b/arch/powerpc/platforms/pseries/pseries.h
> @@ -56,7 +56,7 @@ extern void hvc_vio_init_early(void);
> /* Dynamic logical Partitioning/Mobility */
> extern void dlpar_free_cc_nodes(struct device_node *);
> extern void dlpar_free_cc_property(struct property *);
> -extern struct device_node *dlpar_configure_connector(u32);
> +extern struct device_node *dlpar_configure_connector(u32, struct device_node *);
> extern int dlpar_attach_node(struct device_node *);
> extern int dlpar_detach_node(struct device_node *);
>
>
^ permalink raw reply
* Re: [PATCH 5/8] powerpc/pseries: do all node initialization in dlpar_parse_cc_node
From: Nathan Fontenot @ 2013-08-19 13:49 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-6-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> Currently the OF_DYNAMIC and kref initialization for a node happens in
> dlpar_attach_node. However, a node passed to dlpar_attach_node may be a tree
> containing child nodes, and no initialization traversal is done on the
> tree. Since the children never get their kref initialized or the OF_DYNAMIC
> flag set these nodes are prevented from ever being released from memory
> should they become detached. This initialization step is better done at the
> time each node is allocated in dlpar_parse_cc_node.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/dlpar.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
> index a1a7b9a..c855233 100644
> --- a/arch/powerpc/platforms/pseries/dlpar.c
> +++ b/arch/powerpc/platforms/pseries/dlpar.c
> @@ -83,6 +83,9 @@ static struct device_node *dlpar_parse_cc_node(struct cc_workarea *ccwa)
> return NULL;
> }
>
> + of_node_set_flag(dn, OF_DYNAMIC);
> + kref_init(&dn->kref);
> +
> return dn;
> }
>
> @@ -256,8 +259,6 @@ int dlpar_attach_node(struct device_node *dn)
> {
> int rc;
>
> - of_node_set_flag(dn, OF_DYNAMIC);
> - kref_init(&dn->kref);
> dn->parent = derive_parent(dn->full_name);
> if (!dn->parent)
> return -ENOMEM;
>
^ permalink raw reply
* Re: [PATCH 4/8] powerpc/pseries: fix parsing of initial node path in update_dt_node
From: Nathan Fontenot @ 2013-08-19 13:48 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-5-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> On the first call to ibm,update-properties for a node the first property
> returned is the full node path. Currently this is not parsed correctly by the
> update_dt_node function. Commit 2e9b7b0 attempted to fix this, but was
> incorrect as it made a wrong assumption about the layout of the first
> property in the work area. Further, if ibm,update-properties must be called
> multiple times for the same node this special property should only be skipped
> after the initial call. The first property descriptor returned consists of
> the property name, property value length, and property value. The property
> name is an empty string, property length is encoded in 4 byte integer, and
> the property value is the node path.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/mobility.c | 21 +++++++++++----------
> 1 file changed, 11 insertions(+), 10 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index 023e354..ed5426f 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -161,18 +161,19 @@ static int update_dt_node(u32 phandle, s32 scope)
>
> prop_data = rtas_buf + sizeof(*upwa);
>
> - /* The first element of the buffer is the path of the node
> - * being updated in the form of a 8 byte string length
> - * followed by the string. Skip past this to get to the
> - * properties being updated.
> + /* On the first call to ibm,update-properties for a node the
> + * the first property value descriptor contains an empty
> + * property name, the property value length encoded as u32,
> + * and the property value is the node path being updated.
> */
> - vd = *prop_data++;
> - prop_data += vd;
> + if (*prop_data == 0) {
> + prop_data++;
> + vd = *(u32 *)prop_data;
> + prop_data += vd + sizeof(vd);
> + upwa->nprops--;
> + }
>
> - /* The path we skipped over is counted as one of the elements
> - * returned so start counting at one.
> - */
> - for (i = 1; i < upwa->nprops; i++) {
> + for (i = 0; i < upwa->nprops; i++) {
> char *prop_name;
>
> prop_name = prop_data;
>
^ permalink raw reply
* Re: [PATCH 3/8] powerpc/pseries: pack update_props_workarea to map correctly to rtas buffer header
From: Nathan Fontenot @ 2013-08-19 13:46 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-4-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> The work area buffer returned by the ibm,update-properties rtas call contains
> 20 bytes of header information prior to the property value descriptor data.
> Currently update_dt_node tries to advance over this header using sizeof(upwa).
> The update_props_workarea struct contains 20 bytes worth of fields, that map
> to the relevant header data, but the sizeof the structure is 24 bytes due to
> 4 bytes of padding at the end of the structure. Packing the structure ensures
> that we don't advance too far over the rtas buffer.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/mobility.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index aaae85d..023e354 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -28,7 +28,7 @@ struct update_props_workarea {
> u32 state;
> u64 reserved;
> u32 nprops;
> -};
> +} __packed;
>
> #define NODE_ACTION_MASK 0xff000000
> #define NODE_COUNT_MASK 0x00ffffff
>
^ permalink raw reply
* Re: [PATCH 2/8] powerpc/pseries: fix over writing of rtas return code in update_dt_node
From: Nathan Fontenot @ 2013-08-19 13:44 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-3-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> The rc variable is initially used to store the return code from the
> ibm,update-properties rtas call which returns 0 or 1 on success. A return
> code of 1 indicates that ibm,update-properties must be called again for the
> node. However, the rc variable is overwritten by a call to update_dt_prop
> which returns 0 on success. This results in ibm,update-properties not being
> called again for the given node when the rtas call rc was previously 1.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/mobility.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index f28abee..aaae85d 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -130,7 +130,7 @@ static int update_dt_node(u32 phandle, s32 scope)
> struct update_props_workarea *upwa;
> struct device_node *dn;
> struct property *prop = NULL;
> - int i, rc;
> + int i, rc, rtas_rc;
> char *prop_data;
> char *rtas_buf;
> int update_properties_token;
> @@ -154,9 +154,9 @@ static int update_dt_node(u32 phandle, s32 scope)
> upwa->phandle = phandle;
>
> do {
> - rc = mobility_rtas_call(update_properties_token, rtas_buf,
> + rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
> scope);
> - if (rc < 0)
> + if (rtas_rc < 0)
> break;
>
> prop_data = rtas_buf + sizeof(*upwa);
> @@ -202,7 +202,7 @@ static int update_dt_node(u32 phandle, s32 scope)
> prop_data += vd;
> }
> }
> - } while (rc == 1);
> + } while (rtas_rc == 1);
>
> of_node_put(dn);
> kfree(rtas_buf);
>
^ permalink raw reply
* Re: [PATCH 1/8] powerpc/pseries: fix creation of loop in device node property list
From: Nathan Fontenot @ 2013-08-19 13:43 UTC (permalink / raw)
To: Tyrel Datwyler; +Cc: linuxppc-dev
In-Reply-To: <1376544232-24936-2-git-send-email-tyreld@linux.vnet.ibm.com>
On 08/15/2013 12:23 AM, Tyrel Datwyler wrote:
> The update_dt_prop helper function fails to set the IN/OUT parameter prop to
> NULL after a complete property has been parsed from the work area returned by
> the ibm,update-properties rtas function. This results in the property list of
> the device node being updated is corrupted and becomes a loop since the same
> property structure is used repeatedly.
>
> Signed-off-by: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
Acked-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
> ---
> arch/powerpc/platforms/pseries/mobility.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
> index 3d01eee..f28abee 100644
> --- a/arch/powerpc/platforms/pseries/mobility.c
> +++ b/arch/powerpc/platforms/pseries/mobility.c
> @@ -119,7 +119,7 @@ static int update_dt_property(struct device_node *dn, struct property **prop,
>
> if (!more) {
> of_update_property(dn, new_prop);
> - new_prop = NULL;
> + *prop = NULL;
> }
>
> return 0;
>
^ permalink raw reply
* Re: [RFC PATCH v2 4/4] of: move of_get_cpu_node implementation to DT core library
From: Sudeep KarkadaNagesha @ 2013-08-19 13:24 UTC (permalink / raw)
To: Rob Herring
Cc: Jonas Bonn, devicetree@vger.kernel.org, Michal Simek,
linux-pm@vger.kernel.org, Sudeep KarkadaNagesha,
linux-kernel@vger.kernel.org, rob.herring@calxeda.com,
Rafael J. Wysocki, grant.likely@linaro.org,
linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <5212196F.4060708@gmail.com>
On 19/08/13 14:11, Rob Herring wrote:
> On 08/16/2013 12:39 PM, Sudeep KarkadaNagesha wrote:
>> From: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
>>
>> This patch moves the generalized implementation of of_get_cpu_node from
>> PowerPC to DT core library, thereby adding support for retrieving cpu
>> node for a given logical cpu index on any architecture.
>>
>> The CPU subsystem can now use this function to assign of_node in the
>> cpu device while registering CPUs.
>>
>> It is recommended to use these helper function only in pre-SMP/early
>> initialisation stages to retrieve CPU device node pointers in logical
>> ordering. Once the cpu devices are registered, it can be retrieved easil=
y
>> from cpu device of_node which avoids unnecessary parsing and matching.
>>
>> Cc: Rob Herring <rob.herring@calxeda.com>
>> Cc: Grant Likely <grant.likely@linaro.org>
>> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
>> Signed-off-by: Sudeep KarkadaNagesha <sudeep.karkadanagesha@arm.com>
>=20
> [snip]
>=20
>> +/**
>> + * of_get_cpu_node - Get device node associated with the given logical =
CPU
>> + *
>> + * @cpu: CPU number(logical index) for which device node is required
>> + * @thread: if not NULL, local thread number within the physical core i=
s
>> + * returned
>> + *
>> + * The main purpose of this function is to retrieve the device node for=
the
>> + * given logical CPU index. It should be used to initialize the of_node=
in
>> + * cpu device. Once of_node in cpu device is populated, all the further
>> + * references can use that instead.
>> + *
>> + * CPU logical to physical index mapping is architecture specific and i=
s built
>> + * before booting secondary cores. This function uses arch_match_cpu_ph=
ys_id
>> + * which can be overridden by architecture specific implementation.
>> + *
>> + * Returns a node pointer for the logical cpu if found, else NULL.
>> + */
>> +struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
>> +{
>> +=09struct device_node *cpun, *cpus;
>> +
>> +=09cpus =3D of_find_node_by_path("/cpus");
>> +=09if (!cpus) {
>> +=09=09pr_warn("Missing cpus node, bailing out\n");
>> +=09=09return NULL;
>> +=09}
>> +
>> +=09for_each_child_of_node(cpus, cpun) {
>> +=09=09if (of_node_cmp(cpun->type, "cpu"))
>> +=09=09=09continue;
>> +#ifdef CONFIG_PPC
>=20
> You don't really need this ifdef as this function should never succeed
> on other arches. Alternatively, you can use "IS_ENABLED(CONFIG_PPC)"
> instead.
>=20
Agreed, I can remove it as long as no other architecture use that
property. It's just to avoid checking for it on other architectures.
I will use IS_ENABLED as you suggested.
> Otherwise,
>=20
> Acked-by: Rob Herring <rob.herring@calxeda.com>
>=20
Thanks.
Regards,
Sudeep
^ 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