* 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: [PATCH RESEND] i2c: move of helpers into the core
From: Wolfram Sang @ 2013-08-19 21:16 UTC (permalink / raw)
To: Thierry Reding
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: <20130819194603.GC4961@mithrandir>
[-- Attachment #1: Type: text/plain, Size: 460 bytes --]
On Mon, Aug 19, 2013 at 09:46:04PM +0200, Thierry Reding wrote:
> 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.
Argh, will fix...
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH v8 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Stephen Warren @ 2013-08-19 21:35 UTC (permalink / raw)
To: Nicolin Chen
Cc: mark.rutland, devicetree, alsa-devel, lars, Pawel Moll, festevam,
s.hauer, Kumar Gala, timur, rob.herring, tomasz.figa, broonie,
p.zabel, R65777, shawn.guo, linuxppc-dev
In-Reply-To: <a5b34243c0323e7692fab6a52a7adf4e3e8a5844.1376912873.git.b42378@freescale.com>
On 08/19/2013 06:08 AM, Nicolin Chen wrote:
> This patch implements a device-tree-only CPU DAI driver for Freescale
> S/PDIF controller that supports stereo playback and record feature.
> diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
> +Freescale Sony/Philips Digital Interface Format (S/PDIF) Controller
> +
> +The Freescale S/PDIF audio block is a stereo transceiver that allows the
> +processor to receive and transmit digital audio via an coaxial cable or
> +a fibre cable.
Well, the cable type is more a property of the components that are
hooked to the SoC signals that this module drives, so are somewhat out
of scope of this binding document. However, this is nit-picky comment,
and I'm not too worried about it.
> + - clock-names : Includes the following entries:
> + "core" The core clock of spdif controller
> + "rxtx<0-7>" Clock source list for tx and rx clock.
> + This clock list should be identical to
> + the source list connecting to the spdif
> + clock mux in "SPDIF Transceiver Clock
> + Diagram" of SoC reference manual. It
> + can also be referred to TxClk_Source
> + bit of register SPDIF_STC.
So, the HW block has 1 clock input, yet there's a mux somewhere else in
the SoC which has 8 inputs?
If so, I'm not completely sure it's correct to reference anything other
than the "core" clock in this binding. I think the other clocks would be
more suitably represented in the system-level "sound card" binding that
I guess patch 2/2 (which I haven't read yet) adds, since I assume those
clock are more to do with system-level clock tree setup decisions, and
might not even exist in some other SoC that included this IP block.
What do others think, assuming I'm correct about my HW design assumptions?
^ permalink raw reply
* Re: [PATCH v8 2/2] ASoC: fsl: Add S/PDIF machine driver
From: Stephen Warren @ 2013-08-19 21:39 UTC (permalink / raw)
To: Nicolin Chen
Cc: mark.rutland, devicetree, alsa-devel, lars, festevam, s.hauer,
timur, rob.herring, tomasz.figa, broonie, p.zabel, R65777,
shawn.guo, linuxppc-dev
In-Reply-To: <ca3061d70ab8bf59afc59031fa7befcfaed26d51.1376912873.git.b42378@freescale.com>
On 08/19/2013 06:08 AM, Nicolin Chen wrote:
> This patch implements a device-tree-only machine driver for Freescale
> i.MX series Soc. It works with spdif_transmitter/spdif_receiver and
> fsl_spdif.c drivers.
> diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
> +Optional properties:
> +
> + - spdif-transmitter : The phandle of the spdif-transmitter dummy codec
> +
> + - spdif-receiver : The phandle of the spdif-receiver dummy codec
> +
> +* Note: At least one of these two properties should be set in the DT binding.
Those object truly don't exist in HW and only exist due to internal
details of Linux's ASoC subsystem.
Instead, you should register any SPDIF rx/tx dummy CODEC internally to
the machine driver.
Perhaps you'll still need properties to indicate which of the RX and TX
paths of the HW block are actually connected to anything on the board.
Perhaps a Boolean property "spdif-tx" to indicate TX support, otherwise
RX support is assumed?
Or, to map the properties more directly to HW, perhaps name the property
"spdif-tx-jack-exists", or even "spdif-tx-jack" and make it a phandle to
a node that represents the actual S/PDIF connector?
^ permalink raw reply
* Re: [PATCH RESEND] i2c: move of helpers into the core
From: Rob Herring @ 2013-08-19 22:01 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 12: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>
> ---
Glad to see this.
Acked-by: Rob Herring <rob.herring@calxeda.com>
>
> 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 */
>
^ permalink raw reply
* Re: [PATCH] i2c: move of helpers into the core
From: Rafael J. Wysocki @ 2013-08-19 23:04 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-doc, Kevin Hilman, Linus Walleij, Sekhar Nori, linux-i2c,
Sylwester Nawrocki, Kukjin Kim, linux-acpi, Stephen Warren,
Tony Lindgren, Grant Likely, Alessandro Rubini, devicetree,
linux-media, Rob Herring, Jean Delvare, linux-samsung-soc,
Ben Dooks, Barry Song, linux-tegra, linux-omap, linux-arm-kernel,
davinci-linux-open-source, linux-kernel, Tony Prisk,
Kyungmin Park, Ludovic Desroches, Rob Landley, STEricsson,
Haavard Skinnemoen, linuxppc-dev, Len Brown,
Mauro Carvalho Chehab
In-Reply-To: <1376918361-7014-1-git-send-email-wsa@the-dreams.de>
On Monday, August 19, 2013 03:19:18 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.
Perhaps we should do the analogous for ACPI then?
Rafael
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
> ---
> 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 */
>
--
I speak only for myself.
Rafael J. Wysocki, Intel Open Source Technology Center.
^ permalink raw reply
* Re: [PATCH] i2c: move of helpers into the core
From: Stephen Warren @ 2013-08-19 22:56 UTC (permalink / raw)
To: Rafael J. Wysocki
Cc: Wolfram Sang, Kevin Hilman, Linus Walleij, Sekhar Nori, linux-i2c,
Sylwester Nawrocki, Kukjin Kim, linux-acpi, Tony Lindgren,
Grant Likely, Alessandro Rubini, devicetree, linux-media,
Rob Herring, Jean Delvare, linux-samsung-soc, Ben Dooks,
Barry Song, linux-tegra, linux-omap, linux-arm-kernel,
davinci-linux-open-source, linux-kernel, Tony Prisk,
Kyungmin Park, Ludovic Desroches, Rob Landley, STEricsson,
Haavard Skinnemoen, linuxppc-dev, Len Brown,
Mauro Carvalho Chehab
In-Reply-To: <3792014.HtzPVmLjnf@vostro.rjw.lan>
On 08/19/2013 05:04 PM, Rafael J. Wysocki wrote:
> On Monday, August 19, 2013 03:19:18 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.
>
> Perhaps we should do the analogous for ACPI then?
>
> Rafael
Aargh. Why quote the entire patch just to say one line?
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Scott Wood @ 2013-08-19 22:56 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1376514060.4255.73.camel@pasglop>
On Thu, 2013-08-15 at 07:01 +1000, Benjamin Herrenschmidt wrote:
> On Wed, 2013-08-14 at 12:02 -0500, Scott Wood wrote:
> > On Wed, 2013-08-14 at 14:18 +1000, Benjamin Herrenschmidt wrote:
> > > On Thu, 2013-08-08 at 17:45 -0500, Scott Wood wrote:
> > > > powerpc/e500: Update compilation flags with core specific
> > > > options
> > >
> > > This breaks the build for my FSL test configs. For some reason gcc 4.7.3
> > > doesn't know about -mcpu=e5500
> >
> > Ugh. I guess that's what I get for using toolchains provided internally
> > rather than building them myself
>
> :-)
>
> I recommend you use one of tony's on kernel.org, that way you have
> something that matches what other people use :-)
It looks like -mcpu=e500mc64 has been supported for a while.
> > > Additionally, on 64-bit, that means one can no longer make a kernel that
> > > does both A2 and e5500...
> >
> > Other than the toolchain issue, I'm not sure how this is worse than it
> > was before, when such a kernel would have had -Wa,-me500 forced.
>
> Probably similarly bad though it did work ... but if you are touching
> it, may as well do it right...
There are worms inside that can...
> > What -mcpu value should be used in such a combined kernel?
>
> Good question. We lack a generic booke option. What about powerpc64 ?
>
> A default like that is fine as long as tricky asm uses the macros for
> that and the *optional* -mcpu=<xxx> option is available (and you can put
> it in defconfig).
>
> It might be worth asking gcc to add something like -march=<arch version>
> or something like that though.
If we use the generic CPU target then mftb won't get turned into mfspr
(I assume this is what you meant by "tricky asm"). Does mfspr work
everywhere, including from userspace? Or do we need to patch? What
about 403GCX which seems to need some special SPR (I could leave the
existing ifdef alone, but what about vdso)?
-Scott
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Benjamin Herrenschmidt @ 2013-08-19 23:47 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <1376952992.31636.382.camel@snotra.buserror.net>
On Mon, 2013-08-19 at 17:56 -0500, Scott Wood wrote:
> If we use the generic CPU target then mftb won't get turned into mfspr
> (I assume this is what you meant by "tricky asm"). Does mfspr work
> everywhere, including from userspace? Or do we need to patch? What
> about 403GCX which seems to need some special SPR (I could leave the
> existing ifdef alone, but what about vdso)?
I think mfspr works everywhere we care about but I might be mistaken :-)
I don't think anybody have tried booting a 403 in a looooong time. I
would be surprised if it still worked.
Cheers,
Ben.
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Josh Boyer @ 2013-08-19 23:49 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <1376956039.25016.103.camel@pasglop>
On Mon, Aug 19, 2013 at 7:47 PM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> On Mon, 2013-08-19 at 17:56 -0500, Scott Wood wrote:
>> If we use the generic CPU target then mftb won't get turned into mfspr
>> (I assume this is what you meant by "tricky asm"). Does mfspr work
>> everywhere, including from userspace? Or do we need to patch? What
>> about 403GCX which seems to need some special SPR (I could leave the
>> existing ifdef alone, but what about vdso)?
>
> I think mfspr works everywhere we care about but I might be mistaken :-)
> I don't think anybody have tried booting a 403 in a looooong time. I
> would be surprised if it still worked.
I think I have one buried somewhere in my garage. I'm not digging it out.
josh
^ permalink raw reply
* Re: [PATCH v5 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Mike Turquette @ 2013-08-20 0:06 UTC (permalink / raw)
To: Mark Rutland, Tomasz Figa
Cc: devicetree@vger.kernel.org, alsa-devel@alsa-project.org,
lars@metafoo.de, ian.campbell@citrix.com, Pawel Moll,
swarren@wwwdotorg.org, festevam@gmail.com, Sascha Hauer,
Nicolin Chen, timur@tabi.org, rob.herring@calxeda.com,
broonie@kernel.org, p.zabel@pengutronix.de, galak@codeaurora.org,
shawn.guo@linaro.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <20130819093543.GF3719@e106331-lin.cambridge.arm.com>
Quoting Mark Rutland (2013-08-19 02:35:43)
> On Sat, Aug 17, 2013 at 04:17:18PM +0100, Tomasz Figa wrote:
> > On Saturday 17 of August 2013 16:53:16 Sascha Hauer wrote:
> > > On Sat, Aug 17, 2013 at 02:28:04PM +0200, Tomasz Figa wrote:
> > > > > > > Also I would make this option required. Use a dummy clock for
> > > > > > > mux
> > > > > > > inputs that are grounded for a specific SoC.
> > > > > > =
> > > > > > Some clocks are not from CCM and we haven't defined in
> > > > > > imx6q-clk.txt,
> > > > > > so in most cases we can't provide a phandle for them, eg:
> > > > > > spdif_ext.
> > > > > > I think it's a bit hard to force it to be 'required'. An
> > > > > > 'optional'
> > > > > > looks more flexible to me and a default one is ensured even if
> > > > > > it's
> > > > > > missing.
> > > > > =
> > > > > <&clks 0> is the dummy clock. This can be used for all input cloc=
ks
> > > > > not
> > > > > defined by the SoC.
> > > > =
> > > > Where does this assumption come from? Is it documented anywhere?
> > > =
> > > This is how all i.MX clock bindings currently are. See
> > > Documentation/devicetree/bindings/clock/imx*-clock.txt
> > =
> > OK, thanks.
> > =
> > I guess we need some discussion on dummy clocks vs skipped clocks. I th=
ink =
> > we want some consistency on this, don't we?
> > =
> > If we really need a dummy clock, then we might also want a generic way =
to =
> > specify it.
> =
> What do we actually mean by a "dummy clock"? We already have bindings
> for "fixed-clock" and co friends describe relatively simple
> preconfigured clocks.
Some platforms have a fake clock which defines noops callbacks and
basically doesn't do anything. This is analogous to the dummy regulator
implementation. A central one could be registered by the clock core, as
is done by the regulator core.
I'll add this to the todo list.
Regards,
Mike
> =
> If a clock isn't actually wired, we shouldn't describe it at all, or
> we're describing what Linux wants to think rather than what the hardware
> actually is. That can easily be handled with clock-names.
> =
> Thanks,
> Mark.
^ permalink raw reply
* Re: [PATCH v8 2/2] ASoC: fsl: Add S/PDIF machine driver
From: Mark Brown @ 2013-08-20 0:18 UTC (permalink / raw)
To: Stephen Warren
Cc: mark.rutland, devicetree, alsa-devel, lars, festevam, s.hauer,
Nicolin Chen, timur, rob.herring, tomasz.figa, p.zabel, R65777,
shawn.guo, linuxppc-dev
In-Reply-To: <5212908E.6050104@wwwdotorg.org>
[-- Attachment #1: Type: text/plain, Size: 2089 bytes --]
On Mon, Aug 19, 2013 at 03:39:26PM -0600, Stephen Warren wrote:
> On 08/19/2013 06:08 AM, Nicolin Chen wrote:
> > This patch implements a device-tree-only machine driver for Freescale
> > i.MX series Soc. It works with spdif_transmitter/spdif_receiver and
> > fsl_spdif.c drivers.
>
> > diff --git a/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt b/Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
> > +Optional properties:
> > + - spdif-transmitter : The phandle of the spdif-transmitter dummy codec
> > + - spdif-receiver : The phandle of the spdif-receiver dummy codec
> > +* Note: At least one of these two properties should be set in the DT binding.
> Those object truly don't exist in HW and only exist due to internal
> details of Linux's ASoC subsystem.
They will physically exist if they're usefully present on the board (in
the sense that they're there and can be pointed at) - there will be
either a TOSLINK optical connector or (less commonly) an electrical
connector breaking the signal out to go elsewhere though they don't have
any interaction with software usually which is more what you mean here.
> Or, to map the properties more directly to HW, perhaps name the property
> "spdif-tx-jack-exists", or even "spdif-tx-jack" and make it a phandle to
> a node that represents the actual S/PDIF connector?
S/PDIF is also sometimes used as an interconnect between devices - some
CODECs have S/PDIF I/O (more normally used as an external connector on
the box). This is most frequently seen as a way to plumb HDMI in since
some HDMI devices seem to provide this as a legacy interconnect, though
it can get used just for regular CODECs as well. Using this machine
driver would probably be a bit of an abuse for some applications, though
with things like the HDMI one the goal of the hardware is to be dropped
into a driver like this so perhaps it makes sense and is useful anyway.
Equally well it'd be good to get this stuff actually merged, it seems to
have been surprisingly time consuming thus far...
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* Re: [PATCH] sata: fsl: save irqs while coalescing
From: Scott Wood @ 2013-08-20 0:21 UTC (permalink / raw)
To: Anthony Foiani; +Cc: Anthony Foiani, linuxppc-dev, Bhushan Bharat-R65777
In-Reply-To: <1376936128-1624-1-git-send-email-anthony.foiani@gmail.com>
On Mon, 2013-08-19 at 12:15 -0600, Anthony Foiani wrote:
> 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);
This should go to the SATA list and maintainer.
-Scott
^ permalink raw reply
* Re: [PATCH 1/2] powerpc/85xx: add hardware automatically enter altivec idle state
From: Scott Wood @ 2013-08-20 0:38 UTC (permalink / raw)
To: Wang Dongsheng-B40534; +Cc: Wood Scott-B07421, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <ABB05CD9C9F68C46A5CEDC7F154392590101E5A5@039-SN2MPN1-021.039d.mgd.msft.net>
On Sun, 2013-08-18 at 21:53 -0500, Wang Dongsheng-B40534 wrote:
> Thanks for your feedback.
>
> > -----Original Message-----
> > From: Wood Scott-B07421
> > Sent: Saturday, August 17, 2013 12:51 AM
> > To: Kumar Gala
> > Cc: Wang Dongsheng-B40534; linuxppc-dev@lists.ozlabs.org
> > Subject: Re: [PATCH 1/2] powerpc/85xx: add hardware automatically enter
> > altivec idle state
> >
> > On Fri, 2013-08-16 at 06:02 -0500, Kumar Gala wrote:
> > > On Aug 16, 2013, at 2:23 AM, Dongsheng Wang wrote:
> > >
> > > > From: Wang Dongsheng <dongsheng.wang@freescale.com>
> > > >
> > > > Each core's AltiVec unit may be placed into a power savings mode
> > > > by turning off power to the unit. Core hardware will automatically
> > > > power down the AltiVec unit after no AltiVec instructions have
> > > > executed in N cycles. The AltiVec power-control is triggered by
> > hardware.
> > > >
> > > > Signed-off-by: Wang Dongsheng <dongsheng.wang@freescale.com>
> > >
> > > Why treat this as a idle HW governor vs just some one time setup at
> > boot of the time delay?
> >
> > It is being done as one-time setup, despite the function name.
> >
> > Maybe it should be moved into __setup/restore_cpu_e6500 (BTW, we really
> > should refactor those to reduce duplication) with the timebase bit
> > number hardcoded rather than a time in us.
> >
> The frequency of the different platforms timebase is not the same.
It's close enough. Remember, this number is a vague initial guess, not
something that's been carefully calibrated. Though, it would make it
harder to substitute the number with one that's been more carefully
calibrated... but wouldn't different chips possibly have different
optimal delays anyway?
> If we use it, we need to set different timebase bit on each platform.
> That is why I did not put the code in __setup/restore_cpu_e6500, I need
> use tb_ticks_per_usec to get timebase bit. So we only need to set a time
> for each platform, and not set different timebase bit.
It just seems wrong to have an ad-hoc mechanism for running
core-specific code when we have cputable... If we really need this,
maybe we should add a "cpu_setup_late" function pointer.
With your patch, when does the power management register get set when
hot plugging a cpu?
> > As for the PVR check, the upstream kernel doesn't need to care about
> > rev1, so knowing it's an e6500 is good enough.
> >
> But AltiVec idle & PW20 cannot work on rev1 platform.
> We didn't have to deal with it?
Upstream does not run on rev1.
-Scott
^ permalink raw reply
* Re: [RFC PATCH 1/1] powerpc/embedded6xx: Add support for Motorola/Emerson MVME5100.
From: Scott Wood @ 2013-08-20 0:44 UTC (permalink / raw)
To: Stephen N Chivers; +Cc: Chris Proctor, linuxppc-dev, paulus
In-Reply-To: <OFE77F59FB.5CB18F2A-ONCA257BCB.007040E3-CA257BCB.00733D8F@csc.com>
On Mon, 2013-08-19 at 07:58 +1100, Stephen N Chivers wrote:
> The serial console setup in 'legacy_serial' does not support reg-shift
> or reg-offset properties and so a preferred_console is not added by it.
> The DTS file for the board does specify the register shift so that
> 'of_serial' will correctly setup the UARTS. But that is too late, the
> preferred console will be tty0 as the .config derived from
> ppc6xx_defconfig
> has CONF_VT_CONSOLE set. In the test kernels I have built 'con_init' in
> the VT support is always called before serial8250_console_init.
Are you setting console=ttyS0,<baud> on the kernel command line?
> I did try modifying legacy_serial to correctly support the tsi-bridge
> UARTS and add the preferred console but encountered even more problems
> in 8250_core when registering the serial console (to the point of
> having a silently panic'ing kernel).
>
> So I think for the moment, the board will need its own default config.
Which config symbol is relevant here?
-Scott
^ permalink raw reply
* Re: Pull request: scottwood/linux.git next
From: Benjamin Herrenschmidt @ 2013-08-20 0:49 UTC (permalink / raw)
To: Josh Boyer; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <CA+5PVA49T3gWCb-tt83iabNPwB7=xA8qLw3CY06z4mpZHjj7OA@mail.gmail.com>
On Mon, 2013-08-19 at 19:49 -0400, Josh Boyer wrote:
> > I think mfspr works everywhere we care about but I might be mistaken :-)
> > I don't think anybody have tried booting a 403 in a looooong time. I
> > would be surprised if it still worked.
>
> I think I have one buried somewhere in my garage. I'm not digging it out.
Don't :-)
I'm thinking of removing the code... been wanting to do that for a while,
I'd be surprised if it still worked anyway. How much RAM do these things
have ? Probably not enough for a recent kernel...
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH 1/3 V4] mmc:core: parse voltage from device-tree
From: Zhang Haijun @ 2013-08-20 1:10 UTC (permalink / raw)
To: Haijun Zhang; +Cc: linux-mmc, cbouatmailru, scottwood, cjb, linuxppc-dev, X.Xie
In-Reply-To: <1376271546-25085-1-git-send-email-Haijun.Zhang@freescale.com>
Hi, Anton and all
I had update this patchset.
Is there any change need?
If so let me know.
Thanks.
On 08/12/2013 09:39 AM, Haijun Zhang wrote:
> Add function to support get voltage from device-tree.
> If there are voltage-range specified in device-tree node, this function
> will parse it and return the available voltage mask.
>
> Signed-off-by: Haijun Zhang <haijun.zhang@freescale.com>
> ---
> changes for V4:
> - Add new parameter mask to return voltages.
> changes for V3:
> - Correct the type of return value.
>
> drivers/mmc/core/core.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/mmc/core.h | 2 ++
> 2 files changed, 46 insertions(+)
>
> diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
> index 49a5bca..b9b9fb6 100644
> --- a/drivers/mmc/core/core.c
> +++ b/drivers/mmc/core/core.c
> @@ -27,6 +27,7 @@
> #include <linux/fault-inject.h>
> #include <linux/random.h>
> #include <linux/slab.h>
> +#include <linux/of.h>
>
> #include <linux/mmc/card.h>
> #include <linux/mmc/host.h>
> @@ -1196,6 +1197,49 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
> }
> EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
>
> +#ifdef CONFIG_OF
> +
> +/**
> + * mmc_of_parse_voltage - return mask of supported voltages
> + * @np: The device node need to be parsed.
> + * @mask: mask of voltages available for MMC/SD/SDIO
> + *
> + * 1. Return zero on success.
> + * 2. Return negative errno: voltage-range is invalid.
> + */
> +int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
> +{
> + const u32 *voltage_ranges;
> + int num_ranges, i;
> +
> + voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
> + num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
> + if (!voltage_ranges || !num_ranges) {
> + pr_info("%s: voltage-ranges unspecified\n", np->full_name);
> + return -EINVAL;
> + }
> +
> + for (i = 0; i < num_ranges; i++) {
> + const int j = i * 2;
> + u32 ocr_mask;
> +
> + ocr_mask = mmc_vddrange_to_ocrmask(
> + be32_to_cpu(voltage_ranges[j]),
> + be32_to_cpu(voltage_ranges[j + 1]));
> + if (!ocr_mask) {
> + pr_err("%s: voltage-range #%d is invalid\n",
> + np->full_name, i);
> + return -EINVAL;
> + }
> + *mask |= ocr_mask;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(mmc_of_parse_voltage);
> +
> +#endif /* CONFIG_OF */
> +
> #ifdef CONFIG_REGULATOR
>
> /**
> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
> index 443243b..da51bec 100644
> --- a/include/linux/mmc/core.h
> +++ b/include/linux/mmc/core.h
> @@ -208,6 +208,8 @@ static inline void mmc_claim_host(struct mmc_host *host)
> __mmc_claim_host(host, NULL);
> }
>
> +struct device_node;
> extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
> +extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask);
>
> #endif /* LINUX_MMC_CORE_H */
^ permalink raw reply
* [PATCH] sata: fsl: save irqs while coalescing
From: Anthony Foiani @ 2013-08-20 1:20 UTC (permalink / raw)
To: linuxppc-dev, linux-ide
Cc: Tejun Heo, Anthony Foiani, Anthony Foiani, Scott Wood,
Bhushan Bharat-R65777
In-Reply-To: <gsiy6olhp.fsf@dworkin.scrye.com>
Scott Wood indicated this should go to the SATA addresses as well as,
or maybe even instead of, the PPC list.
-- 8< --
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
* Re: [RFC PATCH 1/1] powerpc/embedded6xx: Add support for Motorola/Emerson MVME5100.
From: Stephen N Chivers @ 2013-08-20 2:28 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, Stephen N Chivers, paulus, Chris Proctor
In-Reply-To: <1376012120.4514.86.camel@snotra.buserror.net>
Scott Wood <scottwood@freescale.com> wrote on 08/09/2013 11:35:20 AM:
> From: Scott Wood <scottwood@freescale.com>
> To: Stephen N Chivers <schivers@csc.com.au>
> Cc: <benh@kernel.crashing.org>, <paulus@samba.org>, Chris Proctor
> <cproctor@csc.com.au>, <linuxppc-dev@lists.ozlabs.org>
> Date: 08/09/2013 11:36 AM
> Subject: Re: [RFC PATCH 1/1] powerpc/embedded6xx: Add support for
> Motorola/Emerson MVME5100.
>
> On Thu, 2013-08-08 at 11:03 +1100, Stephen N Chivers wrote:
> > Add support for the Motorola/Emerson MVME5100 Single Board Computer.
> >
> > The MVME5100 is a 6U form factor VME64 computer with:
> >
> > - A single MPC7410 or MPC750 CPU
> > - A HAWK Processor Host Bridge (CPU to PCI) and
> > MultiProcessor Interrupt Controller (MPIC)
> > - Up to 500Mb of onboard memory
> > - A M48T37 Real Time Clock (RTC) and Non-Volatile Memory chip
> > - Two 16550 compatible UARTS
> > - Two Intel E100 Fast Ethernets
> > - Two PCI Mezzanine Card (PMC) Slots
> > - PPCBug Firmware
> >
> > The HAWK PHB/MPIC is compatible with the MPC10x devices.
> >
> > There is no onboard disk support. This is usually provided by
installing a
> > PMC
> > in first PMC slot.
> >
> > This patch revives the board support, it was present in early 2.6
> > series kernels. The board support in those days was by Matt Porter of
> > MontaVista Software.
> >
> > CSC Australia has around 31 of these boards in service. The kernel in
use
> > for the boards is based on 2.6.31. The boards are operated without
disks
> > from a file server.
> >
> > This patch is based on linux-3.11-rc4 and has been boot tested.
> >
> > Signed-off-by: Stephen Chivers <schivers@csc.com>
> > ---
> > arch/powerpc/boot/dts/mvme5100.dts | 195 ++
> > arch/powerpc/boot/mvme5100.c | 28 +
> > arch/powerpc/configs/mvme5100_defconfig | 2597
> > +++++++++++++++++++++++++
> > arch/powerpc/platforms/embedded6xx/mvme5100.c | 288 +++
> > 4 files changed, 3108 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/powerpc/boot/dts/mvme5100.dts
> > b/arch/powerpc/boot/dts/mvme5100.dts
> > new file mode 100644
> > index 0000000..17fdbc7
> > --- /dev/null
> > +++ b/arch/powerpc/boot/dts/mvme5100.dts
> > @@ -0,0 +1,195 @@
> > +/*
> > + * Device Tree Souce for Motorola/Emerson MVME5100.
> > + *
> > + * Copyright 2013 CSC Australia Pty. Ltd.
> > + *
> > + * This file is licensed under the terms of the GNU General Public
> > + * License version 2. This program is licensed "as is" without
> > + * any warranty of any kind, whether express or implied.
> > + */
> > +
> > +/dts-v1/;
> > +
> > +/ {
> > + model = "MVME5100";
> > + compatible = "MVME5100";
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > +
> > + aliases {
> > + serial0 = &serial0;
> > + pci0 = &pci0;
> > + };
> > +
> > + cpus {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + PowerPC,7410 {
> > + device_type = "cpu";
> > + reg = <0x0>;
> > + /* Following required by dtc but not used */
> > + d-cache-line-size = <32>;
> > + i-cache-line-size = <32>;
> > + i-cache-size = <32768>;
> > + d-cache-size = <32768>;
> > + timebase-frequency = <25000000>;
> > + clock-frequency = <500000000>;
> > + bus-frequency = <100000000>;
>
> What does "following" mean? certainly some of those are used, such as
> timebase-frequency. In any case, it's not the device tree's job to
> document which properties are used by Linux.
>
Agreed. Will remove.
The words were/are in the KuroboxHG.dts I modelled this dts on.
> > + };
> > + };
> > +
> > + memory {
> > + device_type = "memory";
> > + reg = <0x0 0x20000000>;
> > + };
> > +
> > + hawk@fef8 {
>
> Unit address does not match reg.
>
Will make it hawk@fef80000.
> > + #address-cells = <1>;
> > + #size-cells = <1>;
> > + device_type = "soc";
>
> Is this really an SoC? In any case, this use of device_type is
> deprecated.
>
That was part of my early attempts to get legacy_serial to set up
the UARTS.
> > + compatible = "mpc10x";
>
> Don't use wildcards in compatible strings.
>
> simple-bus may be applicable here (in addition to a specific
> compatible).
>
The HAWK ASIC is a difficult beast. I still cannot get a positive
identification as to what it is (Motorola/Freescale part number
unknown, not even the part number on the chip on the board helps....).
The best I can come up with is that it is a tsi108 without
the ethenets.
So device_type will be tsi-bridge and compatible will be
tsi108-bridge.
> > + store-gathering = <0>;
> > + ranges = <0x0 0xfef80000 0x10000>;
> > + reg = <0xfef80000 0x10000>;
>
> Where is "store-gathering" documented?
>
Good question. Again copied from the KuroboxHG dts (which
still has it).
> > + serial0: serial@8000 {
> > + cell-index = <0>;
> > + device_type = "serial";
> > + compatible = "ns16550";
> > + reg = <0x8000 0x80>;
> > + reg-shift = <4>;
> > + clock-frequency = <1843200>;
> > + current-speed = <9600>;
> > + interrupts = <1 1>; // IRQ1 Level Active Low.
> > + interrupt-parent = <&mpic>;
> > + };
> > +
> > + serial1: serial@8200 {
> > + cell-index = <1>;
> > + device_type = "serial";
> > + compatible = "ns16550";
> > + reg = <0x8200 0x80>;
> > + reg-shift = <4>;
> > + clock-frequency = <1843200>;
> > + current-speed = <9600>;
> > + interrupts = <1 1>; // IRQ1 Level Active Low.
> > + interrupt-parent = <&mpic>;
> > + };
>
> What specifically does cell-index mean here? Is it describing the
> hardware or just the terminology used in documentation?
>
Another case of a copying of what was already there. Will remove.
> > + pci0: pci@feff0000 {
> > + #address-cells = <3>;
> > + #size-cells = <2>;
> > + #interrupt-cells = <1>;
> > + device_type = "pci";
> > + compatible = "mpc10x-pci";
> > + reg = <0xfec00000 0x400000>;
> > + 8259-interrupt-acknowledge = <0xfeff0030>;
>
> Where is 8259-interrupt-acknowledge documented?
>
Good question. It is used in platforms/chrp/setup.c. It is also in the
amigaone dts, but that platform uses the PNP approach to managing its
8259 interrupts.
Will set compatible to "tsi108-pci" here.
> > + ranges = <0x1000000 0x0 0x0 0xfe000000 0x0
0x800000
> > + 0x2000000 0x0 0x80000000 0x80000000 0x0
> > 0x74000000>;
> > + bus-range = <0 255>;
> > + clock-frequency = <33333333>;
> > + interrupt-parent = <&mpic>;
> > + interrupt-map-mask = <0xf800 0x0 0x0 0x7>;
> > + interrupt-map = <
> > +
> > + /*
> > + * This definition (IDSEL 11) duplicates the
> > + * interrupts definition in the i8259
> > + * interrupt controller below.
> > + *
> > + * It isn't essential to provide it and the
> > + * board will run happily without it.
>
> Should it be present then?
>
The interrupt comes via the PCI as it is sourced from a winbond
PCI to ISA bridge (and that is on a iPMC712 PMC).
But the interrupt has to be acknowledged via the
8259 interrupt acknowledge. Will remove the "essential" comment.
> > + isa {
> > + #address-cells = <2>;
> > + #size-cells = <1>;
> > + #interrupt-cells = <2>;
> > + device_type = "isa";
> > + compatible = "isa";
> > + ranges = <0x00000001 0 0x01000000 0 0x00000000
> > 0x00001000>;
> > + interrupt-parent = <&i8259>;
> > +
> > + i8259: interrupt-controller@20 {
> > + #interrupt-cells = <2>;
> > + #address-cells = <0>;
> > + interrupts = <0 2>;
> > + device_type = "interrupt-controller";
> > + compatible = "chrp,iic";
> > + interrupt-controller;
> > + reg = <1 0x00000020 0x00000002
> > + 1 0x000000a0 0x00000002
> > + 1 0x000004d0 0x00000002>;
> > + clock-frequency = <0>;
>
> Why does an i8259 have a clock-frequency?
>
Cut and paste considered harmful. Will remove.
> > + built-in;
>
> What does this mean?
>
Don't know where I got that one from. Will remove.
> > diff --git a/arch/powerpc/platforms/embedded6xx/mvme5100.c
> > b/arch/powerpc/platforms/embedded6xx/mvme5100.c
> > new file mode 100644
> > index 0000000..cc9ed8a
> > --- /dev/null
> > +++ b/arch/powerpc/platforms/embedded6xx/mvme5100.c
> > @@ -0,0 +1,288 @@
> > +/*
> > + * Board setup routines for the Motorola/Emerson MVME5100.
> > + *
> > + * Copyright 2013 CSC Australia Pty. Ltd.
> > + *
> > + * Based on earlier code by:
> > + *
> > + * Matt Porter, MontaVista Software Inc.
> > + * Copyright 2001 MontaVista Software Inc.
> > + *
> > + * 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.
> > + *
> > + * Author: Stephen Chivers <schivers@csc.com>
> > + *
> > + */
> > +
> > +#include <linux/of_platform.h>
> > +
> > +#include <asm/i8259.h>
> > +#include <asm/pci-bridge.h>
> > +#include <asm/mpic.h>
> > +#include <asm/prom.h>
> > +#include <mm/mmu_decl.h>
> > +#include <asm/udbg.h>
> > +
> > +
> > +#define HAWK_MPIC_SIZE 0x00040000U
> > +#define MVME5100_PCI_MEM_OFFSET 0x00000000
> > +
> > +/* Board register addresses. */
> > +#define BOARD_STATUS_REG 0xfef88080
> > +#define BOARD_MODFAIL_REG 0xfef88090
> > +#define BOARD_MODRST_REG 0xfef880a0
> > +#define BOARD_TBEN_REG 0xfef880c0
> > +#define BOARD_SW_READ_REG 0xfef880e0
> > +#define BOARD_GEO_ADDR_REG 0xfef880e8
> > +#define BOARD_EXT_FEATURE1_REG 0xfef880f0
> > +#define BOARD_EXT_FEATURE2_REG 0xfef88100
> > +
> > +static unsigned int pci_membase;
> > +
> > +
> > +#ifdef DEBUG
> > +#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __func__, ##
args)
> > +#else
> > +#define DBG(fmt, args...)
> > +#endif
>
> Use pr_debug().
>
Ok.
> > +static void
> > +mvme5100_8259_cascade(unsigned int irq, struct irq_desc *desc)
> > +{
> > + struct irq_chip *chip = irq_desc_get_chip(desc);
> > + unsigned int cascade_irq = i8259_irq();
> > +
> > +
>
> Only one blank line.
>
Ok.
> > + if (cascade_irq != NO_IRQ)
> > + generic_handle_irq(cascade_irq);
> > +
> > + chip->irq_eoi(&desc->irq_data);
> > +}
> > +
> > +
>
> Only one blank line. Likewise elsewhere.
>
Ok.
> > +static void __init
> > +mvme5100_pic_init(void)
>
> Don't put a newline before the function name.
>
Ok. Old habits..... (from 1980 when I was writing stuff for
Level 7 Unix on PDP11s....).
> > +{
> > + struct mpic *mpic;
> > + void __iomem *mpic_addr;
> > + struct device_node *np;
> > + struct device_node *cp = NULL;
> > + unsigned int cirq;
> > + unsigned long intack = 0;
> > + const unsigned long *prop = NULL;
>
> Do not use non-fixed-size-types to decode properties. In particular,
> non-string properties are normally composed of 32-bit cells.
>
Ok.
> > + np = of_find_node_by_type(NULL, "open-pic");
> > + if (!np) {
> > + pr_err("Could not find open-pic node\n");
> > + return;
> > + }
> > +
> > +
> > + pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
> > +
> > + mpic_addr = ioremap(pci_membase + MVME5100_PCI_MEM_OFFSET,
> > + HAWK_MPIC_SIZE);
> > +
> > + pr_info("mvme5100_pic_init: mapped mpic_addr: 0x%p\n",
mpic_addr);
>
> The only thing you use this ioremap for is to print out the address.
>
Debug from initial port.
> > + for_each_node_by_type(np, "interrupt-controller")
> > + if (of_device_is_compatible(np, "chrp,iic")) {
> > + cp = np;
> > + break;
> > + }
> > +
>
> Please use braces around multi-line loop bodies.
>
Ok.
> Why not just look for a chrp,iic node directly?
>
I was following the model used in other places, like chrp/setup.c.
> > + if ((np = of_find_compatible_node(NULL, "pci", "mpc10x-pci")))
{
>
> Why insist on the device_type?
>
Following the model in the linkstation (kurobox) platform support.
> > +static int __init
> > +mvme5100_add_bridge(struct device_node *dev)
> > +{
> > + const int *bus_range;
> > + int len;
> > + struct pci_controller *hose;
> > + unsigned short devid;
> > +
> > +
> > + pr_info("Adding PCI host bridge %s\n", dev->full_name);
> > +
> > + bus_range = of_get_property(dev, "bus-range", &len);
> > +
> > + if (bus_range == NULL || len < 2 * sizeof(int))
> > + pr_warn("Can't get bus-range for %s, assuming bus
0\n",
> > + dev->full_name);
>
> Is this worth warning about?
>
Ok.
> > + if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
> > + pr_err("HAWK PHB not present?\n");
> > +
> > + return 0;
> > + }
> > +
> > + early_read_config_dword( hose, 0, 0, PCI_BASE_ADDRESS_1,
> > &pci_membase);
>
> Patch is linewrapped.
>
Yes. Lotus Notes strikes again.
> > +static void
> > +mvme5100_restart(char *cmd)
> > +{
> > + volatile ulong i = 10000000;
> > +
> > +
> > + local_irq_disable();
> > + _nmask_and_or_msr(0, MSR_IP);
>
> Does "mtmsr(mfmsr() | MSR_IP)" not work?
>
Don't know. Is from the original code by Matt Porter.
> > + out_8((u_char *) BOARD_MODRST_REG, 0x01);
> > +
> > + while (i-- > 0);
>
> Do not use a loop to implement a delay.
>
Taken from the original code. But at this point the board
is going to reset and reboot via firmware, as /sbin/reboot
or /sbin/halt has been invoked.
> > +static void __init
> > +mvme5100_set_bat(void)
> > +{
> > +
> > +
> > + mb();
> > + mtspr(SPRN_DBAT1U, 0xf0001ffe);
> > + mtspr(SPRN_DBAT1L, 0xf000002a);
> > + mb();
> > + setbat(1, 0xfe000000, 0xfe000000, 0x02000000,
PAGE_KERNEL_NCG);
> > +}
>
> It is no longer allowed to squat on random virtual address space like
> this. If you really need a BAT you'll have to allocate the virtual
> address properly.
>
Yes. I found that this was an anathema when researching the port in
2010 but I couldn't find any practical solution at the time.
The code is called early to ensure that the hawk registers are available.
sysdev/cpm_common.c does the same thing.
What is the correct solution?
> -Scott
>
>
>
Thanks for all the comments, they are appreciated.
^ permalink raw reply
* Re: [PATCH v8 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Nicolin Chen @ 2013-08-20 2:21 UTC (permalink / raw)
To: Sascha Hauer
Cc: mark.rutland, devicetree, alsa-devel, lars, swarren, festevam,
timur, rob.herring, tomasz.figa, broonie, p.zabel, R65777,
shawn.guo, linuxppc-dev
In-Reply-To: <20130819123449.GE31036@pengutronix.de>
Thank you Sascha, I'll revise them all in v9
On Mon, Aug 19, 2013 at 02:34:49PM +0200, Sascha Hauer wrote:
> Hi Nicolas,
>
> Some misc other comments inline.
>
> On Mon, Aug 19, 2013 at 08:08:48PM +0800, Nicolin Chen wrote:
> > This patch implements a device-tree-only CPU DAI driver for Freescale
> > +
> > +struct fsl_spdif_priv {
> > + struct spdif_mixer_control fsl_spdif_control;
> > + struct snd_soc_dai_driver cpu_dai_drv;
> > + struct platform_device *pdev;
> > + struct regmap *regmap;
> > + atomic_t dpll_locked;
>
> You don't need an atomic_t to track a bool variable. Use a plain bool or
> int instead.
>
> > + u8 txclk_div[SPDIF_TXRATE_MAX];
> > + u8 txclk_src[SPDIF_TXRATE_MAX];
> > + u8 rxclk_src;
> > + struct clk *txclk[SPDIF_TXRATE_MAX];
> > + struct clk *rxclk;
> > + struct snd_dmaengine_dai_dma_data dma_params_tx;
> > + struct snd_dmaengine_dai_dma_data dma_params_rx;
> > +
> > + /* The name space will be allocated dynamically */
> > + char name[0];
> > +};
> > +
> > +
> > +#ifdef DEBUG
> > +static void dumpregs(struct fsl_spdif_priv *spdif_priv)
> > +{
> > + struct regmap *regmap = spdif_priv->regmap;
> > + struct platform_device *pdev = spdif_priv->pdev;
> > + u32 val, i;
> > + int ret;
> > +
> > + /* Valid address set of SPDIF is {[0x0-0x38], 0x44, 0x50} */
> > + for (i = 0 ; i <= REG_SPDIF_STC; i += 4) {
> > + ret = regmap_read(regmap, REG_SPDIF_SCR + i, &val);
> > + if (!ret)
> > + dev_dbg(&pdev->dev, "REG 0x%02x = 0x%06x\n", i, val);
> > + }
> > +}
> > +#else
> > +static void dumpregs(struct fsl_spdif_priv *spdif_priv) {}
> > +#endif
>
> Is this needed? regmap provides a register dump in debugfs.
>
> > +
> > +static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > + unsigned long rate_actual;
> > +
> > + rate_actual = clk_round_rate(clk, rate);
> > + return clk_set_rate(clk, rate_actual);
> > +}
>
> clk_round_rate returns the rate which clk_set_rate would set if called
> with the same rate. The clk_round_rate() is unnecessary.
>
> > +
> > + dev_dbg(&pdev->dev, "expected clock rate = %d\n",
> > + (int)(64 * sample_rate * div));
> > + dev_dbg(&pdev->dev, "acutal clock rate = %d\n",
> > + (int)clk_get_rate(spdif_priv->txclk[rate]));
>
> s/acutal/actual/
>
> Also please use %ld instead of casting the unsigned long to int.
>
> > +
> > + dev_dbg(&pdev->dev, "FreqMeas: %d\n", (int)freqmeas);
> > + dev_dbg(&pdev->dev, "BusclkFreq: %d\n", (int)busclk_freq);
> > + dev_dbg(&pdev->dev, "RxRate: %d\n", (int)tmpval64);
>
> Get rid of the casts
>
> > +
> > + spdif_priv = devm_kzalloc(&pdev->dev,
> > + sizeof(struct fsl_spdif_priv) + strlen(np->name) + 1, GFP_KERNEL);
> > + if (!spdif_priv) {
> > + dev_err(&pdev->dev, "could not allocate DAI object\n");
>
> Please drop this message. You'll never see it.
>
> > +
> > + for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
> > + ret = fsl_spdif_probe_txclk(spdif_priv, i);
> > + if (ret)
> > + return ret;
> > + }
> > +
> > + /* Prepare rx/tx clock */
> > + clk_prepare(spdif_priv->rxclk);
> > + for (i = 0; i < SPDIF_TXRATE_MAX; i++)
> > + clk_prepare(spdif_priv->txclk[i]);
>
> Why do you prepare all clocks instead of the one you actually use? Also,
> no need to do this here. You can use clk_prepare_enable instead where
> you have clk_enable now.
>
> > +
> > +/* SPDIF rx clock source */
> > +enum spdif_rxclk_src {
> > + SRPC_CLKSRC_0 = 0,
> > + SRPC_CLKSRC_1,
> > + SRPC_CLKSRC_2,
> > + SRPC_CLKSRC_3,
> > + SRPC_CLKSRC_4,
> > + SRPC_CLKSRC_5,
> > + SRPC_CLKSRC_6,
> > + SRPC_CLKSRC_7,
> > + SRPC_CLKSRC_8,
> > + SRPC_CLKSRC_9,
> > + SRPC_CLKSRC_10,
> > + SRPC_CLKSRC_11,
> > + SRPC_CLKSRC_12,
> > + SRPC_CLKSRC_13,
> > + SRPC_CLKSRC_14,
> > + SRPC_CLKSRC_15,
> > +};
>
> These are unused and look unnecessary.
>
> > +
> > +/* SPDIF tx clksrc */
> > +enum spdif_txclk_src {
> > + STC_TXCLK_SRC_0 = 0,
> > + STC_TXCLK_SRC_1,
> > + STC_TXCLK_SRC_2,
> > + STC_TXCLK_SRC_3,
> > + STC_TXCLK_SRC_4,
> > + STC_TXCLK_SRC_5,
> > + STC_TXCLK_SRC_6,
> > + STC_TXCLK_SRC_7,
> > +};
>
> Also unused.
>
> Sascha
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
^ permalink raw reply
* BUG_ON and gcc don't mix
From: Anton Blanchard @ 2013-08-20 2:37 UTC (permalink / raw)
To: benh, paulus, Alan Modra, wschmidt; +Cc: linuxppc-dev
Hi,
I noticed our BUG_ON macros were taking a large number of instructions.
I've built a testcase to analyse it:
#if defined(ASMBUG)
#define BUG_ON(x) do { \
__asm__ __volatile__("tdnei %0,0\n" : : "r" ((long)(x))); \
} while (0)
#elif defined(BUILTIN)
#define BUG_ON(x) do { \
if (x) \
__builtin_trap(); \
} while (0)
#else
#define BUG_ON(x) do { \
if (x) { \
__asm__ __volatile__("twi 31,0,0\n"); \
__builtin_unreachable(); \
} \
} while (0)
#endif
int foo(unsigned int *bar)
{
unsigned int holder_cpu;
holder_cpu = *bar & 0xffff;
BUG_ON(holder_cpu >= 32);
return 1;
}
3 versions. First our current upstream behaviour (-DASMBUG):
0: 00 00 23 a1 lhz r9,0(r3)
4: 1f 00 89 2b cmplwi cr7,r9,31
8: 26 00 20 7d mfcr r9
c: fe f7 29 55 rlwinm r9,r9,30,31,31
10: 00 00 09 0b tdnei r9,0
14: 01 00 60 38 li r3,1
18: 20 00 80 4e blr
What a load of work. We do the compare, then pull it out of the
condition register and do some more work. We are trying to help gcc
but it seems to be backfiring. Let's try doing a simple version in c:
0: 00 00 23 a1 lhz r9,0(r3)
4: 1f 00 89 2b cmplwi cr7,r9,31
8: 0c 00 9d 41 bgt cr7,14
c: 01 00 60 38 li r3,1
10: 20 00 80 4e blr
14: 00 00 e0 0f twui r0,0
Better, we branch out of line to do the trap. But if we could do a
conditional trap properly then we should be able to do even better
(-DBUILTIN):
0: 00 00 23 a1 lhz r9,0(r3)
4: 01 00 60 38 li r3,1
8: 20 00 a9 0c twlgei r9,32
c: 20 00 80 4e blr
Nice! I remember chasing this down before and the issue is we need the
address of the trap instruction for our bug exception table. Maybe
we need a gcc builtin in which we can get a label on the trap
instruction. Would that be possible?
Anton
^ permalink raw reply
* Re: [PATCH v8 1/2] ASoC: fsl: Add S/PDIF CPU DAI driver
From: Nicolin Chen @ 2013-08-20 2:28 UTC (permalink / raw)
To: Stephen Warren
Cc: mark.rutland, devicetree, alsa-devel, lars, Pawel Moll, festevam,
s.hauer, Kumar Gala, timur, rob.herring, tomasz.figa, broonie,
p.zabel, R65777, shawn.guo, linuxppc-dev
In-Reply-To: <52128FBE.4080103@wwwdotorg.org>
On Mon, Aug 19, 2013 at 03:35:58PM -0600, Stephen Warren wrote:
> > + "core" The core clock of spdif controller
> > + "rxtx<0-7>" Clock source list for tx and rx clock.
> > + This clock list should be identical to
> > + the source list connecting to the spdif
> > + clock mux in "SPDIF Transceiver Clock
> > + Diagram" of SoC reference manual. It
> > + can also be referred to TxClk_Source
> > + bit of register SPDIF_STC.
>
> So, the HW block has 1 clock input, yet there's a mux somewhere else in
> the SoC which has 8 inputs?
>
> If so, I'm not completely sure it's correct to reference anything other
> than the "core" clock in this binding. I think the other clocks would be
> more suitably represented in the system-level "sound card" binding that
> I guess patch 2/2 (which I haven't read yet) adds, since I assume those
> clock are more to do with system-level clock tree setup decisions, and
> might not even exist in some other SoC that included this IP block.
>
> What do others think, assuming I'm correct about my HW design assumptions?
The core clock is being only needed when accessing registers of this IP.
Thus, in the driver, I let regmap handle it.
While the other 8 clocks are actual reference clocks for Tx. Tx clock needs
to select one of them that can easily derive a child clock matching the tx
sample rate. This is essential for the IP, so I don't think it's nicer to
put into machine driver.
Thank you
Nicolin
^ permalink raw reply
* [PATCH v2] Correct Memory Hotplug for Power
From: Nathan Fontenot @ 2013-08-20 2:50 UTC (permalink / raw)
To: linuxppc-dev
Memory hotplug on Power is currently broken, these two patches correct the
issues needed to get memory hotplug working again.
This update marks memory resources that are added at boot time are also
marked as busy. It sounds a bit counter intuitive but the core mm code will
not free memory resources if they are not marked as busy.
This also ensures that bootmem memory is is registered at boot time. A
previous commit (46723bfa540...) that enabled memory hotplug remove with
SPARSE_VMEMMAP enabled broke this on Power.
Additional patches to follow to correct the current memory hotplug
implementation on Power.
Nathan Fontenot
Updates for v2:
- The WARN_ONCE is removed from the added register_page_bootmem_memmap()
routine. I have been able to verify that memory hotplug works with
SPARSE_VMEMMAP enabled and do not think the warning is needed.
---
arch/powerpc/mm/mem.c | 9 +++++++++
linux/arch/powerpc/mm/init_64.c | 4 ++++
linux/arch/powerpc/mm/mem.c | 2 +-
linux/mm/Kconfig | 2 +-
4 files changed, 15 insertions(+), 2 deletions(-)
^ permalink raw reply
* [PATCH v2 1/2] Mark Memory Resources as busy
From: Nathan Fontenot @ 2013-08-20 2:52 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <5212D989.8090103@linux.vnet.ibm.com>
Memory I/O resources need to be marked as busy or else we cannot remove
them when doing memory hot remove.
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
arch/powerpc/mm/mem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux/arch/powerpc/mm/mem.c
===================================================================
--- linux.orig/arch/powerpc/mm/mem.c
+++ linux/arch/powerpc/mm/mem.c
@@ -514,7 +514,7 @@ static int add_system_ram_resources(void
res->name = "System RAM";
res->start = base;
res->end = base + size - 1;
- res->flags = IORESOURCE_MEM;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
WARN_ON(request_resource(&iomem_resource, res) < 0);
}
}
^ permalink raw reply
* [PATCH v2 2/2] Register bootmem pages
From: Nathan Fontenot @ 2013-08-20 2:53 UTC (permalink / raw)
To: linuxppc-dev
In-Reply-To: <5212D989.8090103@linux.vnet.ibm.com>
Previous commit 46723bfa540... introduced a new config option
HAVE_BOOTMEM_INFO_NODE that ended up breaking memory hot-remove for ppc
when sparse vmemmap is not defined.
This patch defines HAVE_BOOTMEM_INFO_NODE for ppc and adds the call to
register_page_bootmem_info_node. Without this we get a BUG_ON for memory
hot remove in put_page_bootmem().
This also adds a stub for register_page_bootmem_memmap to allow ppc to build
with sparse vmemmap defined.
Signed-off-by: Nathan Fontenot <nfont@linux.vnet.ibm.com>
---
---
arch/powerpc/mm/init_64.c | 4 ++++
arch/powerpc/mm/mem.c | 9 +++++++++
mm/Kconfig | 2 +-
3 files changed, 14 insertions(+), 1 deletion(-)
Index: linux/arch/powerpc/mm/init_64.c
===================================================================
--- linux.orig/arch/powerpc/mm/init_64.c
+++ linux/arch/powerpc/mm/init_64.c
@@ -300,5 +300,9 @@ void vmemmap_free(unsigned long start, u
{
}
+void register_page_bootmem_memmap(unsigned long section_nr,
+ struct page *start_page, unsigned long size)
+{
+}
#endif /* CONFIG_SPARSEMEM_VMEMMAP */
Index: linux/arch/powerpc/mm/mem.c
===================================================================
--- linux.orig/arch/powerpc/mm/mem.c
+++ linux/arch/powerpc/mm/mem.c
@@ -297,12 +297,21 @@ void __init paging_init(void)
}
#endif /* ! CONFIG_NEED_MULTIPLE_NODES */
+static void __init register_page_bootmem_info(void)
+{
+ int i;
+
+ for_each_online_node(i)
+ register_page_bootmem_info_node(NODE_DATA(i));
+}
+
void __init mem_init(void)
{
#ifdef CONFIG_SWIOTLB
swiotlb_init(0);
#endif
+ register_page_bootmem_info();
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
set_max_mapnr(max_pfn);
free_all_bootmem();
Index: linux/mm/Kconfig
===================================================================
--- linux.orig/mm/Kconfig
+++ linux/mm/Kconfig
@@ -183,7 +183,7 @@ config MEMORY_HOTPLUG_SPARSE
config MEMORY_HOTREMOVE
bool "Allow for memory hot remove"
select MEMORY_ISOLATION
- select HAVE_BOOTMEM_INFO_NODE if X86_64
+ select HAVE_BOOTMEM_INFO_NODE if (X86_64 || PPC64)
depends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE
depends on MIGRATION
^ 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