LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 2/5] ASoC: fsl: mpc5200 combine psc_dma platform data
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt
In-Reply-To: <1347416089-23393-1-git-send-email-emillbrandt@dekaresearch.com>

The mpc5200_psc_ac97 and mpc5200_psc_i2s modules rely on shared platform data
with mpc5200_dma.

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---
 sound/soc/fsl/mpc5200_dma.c      |   24 ++++--------------------
 sound/soc/fsl/mpc5200_dma.h      |    3 +++
 sound/soc/fsl/mpc5200_psc_ac97.c |    5 +++++
 sound/soc/fsl/mpc5200_psc_i2s.c  |    5 +++++
 4 files changed, 17 insertions(+), 20 deletions(-)

diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 46fb518..4fabc85 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -370,7 +370,7 @@ static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
 	.pcm_free	= psc_dma_free,
 };
 
-static int mpc5200_hpcd_probe(struct platform_device *op)
+int mpc5200_audio_dma_create(struct platform_device *op)
 {
 	phys_addr_t fifo;
 	struct psc_dma *psc_dma;
@@ -487,8 +487,9 @@ out_unmap:
 	iounmap(regs);
 	return ret;
 }
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_create);
 
-static int mpc5200_hpcd_remove(struct platform_device *op)
+int mpc5200_audio_dma_destroy(struct platform_device *op)
 {
 	struct psc_dma *psc_dma = dev_get_drvdata(&op->dev);
 
@@ -510,24 +511,7 @@ static int mpc5200_hpcd_remove(struct platform_device *op)
 
 	return 0;
 }
-
-static struct of_device_id mpc5200_hpcd_match[] = {
-	{ .compatible = "fsl,mpc5200-pcm", },
-	{}
-};
-MODULE_DEVICE_TABLE(of, mpc5200_hpcd_match);
-
-static struct platform_driver mpc5200_hpcd_of_driver = {
-	.probe		= mpc5200_hpcd_probe,
-	.remove		= mpc5200_hpcd_remove,
-	.driver = {
-		.owner		= THIS_MODULE,
-		.name		= "mpc5200-pcm-audio",
-		.of_match_table    = mpc5200_hpcd_match,
-	}
-};
-
-module_platform_driver(mpc5200_hpcd_of_driver);
+EXPORT_SYMBOL_GPL(mpc5200_audio_dma_destroy);
 
 MODULE_AUTHOR("Grant Likely <grant.likely@secretlab.ca>");
 MODULE_DESCRIPTION("Freescale MPC5200 PSC in DMA mode ASoC Driver");
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index a3c0cd5..dff253f 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -81,4 +81,7 @@ to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
 	return &psc_dma->playback;
 }
 
+int mpc5200_audio_dma_create(struct platform_device *op);
+int mpc5200_audio_dma_destroy(struct platform_device *op);
+
 #endif /* __SOUND_SOC_FSL_MPC5200_DMA_H__ */
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index 2f70729..17b17b8 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -283,6 +283,10 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op)
 	struct snd_ac97 ac97;
 	struct mpc52xx_psc __iomem *regs;
 
+	rc = mpc5200_audio_dma_create(op);
+	if (rc != 0)
+		return rc;
+
 	rc = snd_soc_register_dais(&op->dev, psc_ac97_dai, ARRAY_SIZE(psc_ac97_dai));
 	if (rc != 0) {
 		dev_err(&op->dev, "Failed to register DAI\n");
@@ -308,6 +312,7 @@ static int __devinit psc_ac97_of_probe(struct platform_device *op)
 
 static int __devexit psc_ac97_of_remove(struct platform_device *op)
 {
+	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_ac97_dai));
 	return 0;
 }
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 3cf21df..5710dc8 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -159,6 +159,10 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op)
 	struct psc_dma *psc_dma;
 	struct mpc52xx_psc __iomem *regs;
 
+	rc = mpc5200_audio_dma_create(op);
+	if (rc != 0)
+		return rc;
+
 	rc = snd_soc_register_dais(&op->dev, psc_i2s_dai, ARRAY_SIZE(psc_i2s_dai));
 	if (rc != 0) {
 		pr_err("Failed to register DAI\n");
@@ -203,6 +207,7 @@ static int __devinit psc_i2s_of_probe(struct platform_device *op)
 
 static int __devexit psc_i2s_of_remove(struct platform_device *op)
 {
+	mpc5200_audio_dma_destroy(op);
 	snd_soc_unregister_dais(&op->dev, ARRAY_SIZE(psc_i2s_dai));
 	return 0;
 }
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 4/5] arch/powerpc/boot/dts pcm030 add mpc5200-soc-audio node
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt
In-Reply-To: <1347416089-23393-1-git-send-email-emillbrandt@dekaresearch.com>

Describe the audio codec on the pcm030 baseboard.

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---
 arch/powerpc/boot/dts/pcm030.dts |   23 ++++++++++++++++++++++-
 1 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts
index 9e35499..e9475e9 100644
--- a/arch/powerpc/boot/dts/pcm030.dts
+++ b/arch/powerpc/boot/dts/pcm030.dts
@@ -59,7 +59,7 @@
 			#gpio-cells = <2>;
 		};
 
-		psc@2000 { /* PSC1 in ac97 mode */
+		audio_platform: psc@2000 { /* PSC1 in ac97 mode */
 			compatible = "mpc5200b-psc-ac97","fsl,mpc5200b-psc-ac97";
 			cell-index = <0>;
 		};
@@ -134,4 +134,25 @@
 	localbus {
 		status = "disabled";
 	};
+
+	sound {
+		compatible = "fsl,mpc5200b-soc-audio","fsl,mpc5200-soc-audio";
+		card-name = "pcm030";
+		audio-platform = <&audio_platform>;
+		number-of-dais = <2>;
+
+		analog@0 {
+			stream-name = "AC97 Analog";
+			codec-name = "wm9712-codec.0";
+			codec-dai-name = "wm9712-hifi";
+			cpu-dai-name = "mpc5200-psc-ac97.0";
+		};
+
+		digital@1 {
+			stream-name = "AC97 IEC958";
+			codec-name = "wm9712-codec.0";
+			codec-dai-name = "wm9712-aux";
+			cpu-dai-name = "mpc5200-psc-ac97.0";
+		};
+	};
 };
-- 
1.7.2.5

^ permalink raw reply related

* [RFC PATCH 0/5] mpc5200 asoc fixups
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt

The mpc5200 asoc code did not run after the multi-codec patches.  This series
fixes the existing code and adds a generic platform driver that allows the
audio layout to be described in the device tree.

Eric Millbrandt (5):
  ASoC: fsl: mpc5200 multi-codec fixups
  ASoC: fsl: mpc5200 combine psc_dma platform data
  ASoC: fsl: mpc5200-soc-audio driver
  arch/powerpc/boot/dts pcm030 add mpc5200-soc-audio node
  ASoC: fsl: mpc5200 remove pcm030 and efika audio fabric

 .../devicetree/bindings/powerpc/fsl/mpc5200.txt    |   17 ++
 arch/powerpc/boot/dts/pcm030.dts                   |   23 ++-
 arch/powerpc/platforms/52xx/Kconfig                |    1 +
 sound/soc/fsl/Kconfig                              |   20 +--
 sound/soc/fsl/Makefile                             |    3 +-
 sound/soc/fsl/efika-audio-fabric.c                 |   91 --------
 sound/soc/fsl/mpc5200_dma.c                        |   28 +--
 sound/soc/fsl/mpc5200_dma.h                        |    3 +
 sound/soc/fsl/mpc5200_psc_ac97.c                   |   13 +-
 sound/soc/fsl/mpc5200_psc_i2s.c                    |    8 +
 sound/soc/fsl/mpc5200_soc_audio.c                  |  232 ++++++++++++++++++++
 sound/soc/fsl/pcm030-audio-fabric.c                |   91 --------
 12 files changed, 306 insertions(+), 224 deletions(-)
 delete mode 100644 sound/soc/fsl/efika-audio-fabric.c
 create mode 100644 sound/soc/fsl/mpc5200_soc_audio.c
 delete mode 100644 sound/soc/fsl/pcm030-audio-fabric.c

-- 
1.7.2.5

^ permalink raw reply

* [PATCH 5/5] ASoC: fsl: mpc5200 remove pcm030 and efika audio fabric
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt
In-Reply-To: <1347416089-23393-1-git-send-email-emillbrandt@dekaresearch.com>

MPC5200 ASoC setup can now be done in the device tree.

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---
 sound/soc/fsl/Kconfig               |   17 -------
 sound/soc/fsl/Makefile              |    2 -
 sound/soc/fsl/efika-audio-fabric.c  |   91 -----------------------------------
 sound/soc/fsl/pcm030-audio-fabric.c |   91 -----------------------------------
 4 files changed, 0 insertions(+), 201 deletions(-)
 delete mode 100644 sound/soc/fsl/efika-audio-fabric.c
 delete mode 100644 sound/soc/fsl/pcm030-audio-fabric.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index b3eee63..54ba798 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -70,23 +70,6 @@ config SND_MPC52xx_SOC_AUDIO
 	  Say Y if you want to generic device-tree support for sound on the
 	  Freescale MPC5200
 
-config SND_MPC52xx_SOC_PCM030
-	tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712"
-	depends on PPC_MPC5200_SIMPLE
-	select SND_SOC_MPC5200_AC97
-	select SND_SOC_WM9712
-	help
-	  Say Y if you want to add support for sound on the Phytec pcm030
-	  baseboard.
-
-config SND_MPC52xx_SOC_EFIKA
-	tristate "SoC AC97 Audio support for bbplan Efika and STAC9766"
-	depends on PPC_EFIKA
-	select SND_SOC_MPC5200_AC97
-	select SND_SOC_STAC9766
-	help
-	  Say Y if you want to add support for sound on the Efika.
-
 endif # SND_POWERPC_SOC
 
 menuconfig SND_IMX_SOC
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index d2e2e68..bd5f511 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -21,8 +21,6 @@ obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
 
 # MPC5200 Machine Support
 obj-$(CONFIG_SND_MPC52xx_SOC_AUDIO) += mpc5200_soc_audio.o
-obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
-obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
 
 # i.MX Platform Support
 snd-soc-imx-ssi-objs := imx-ssi.o
diff --git a/sound/soc/fsl/efika-audio-fabric.c b/sound/soc/fsl/efika-audio-fabric.c
deleted file mode 100644
index b2acd329..0000000
--- a/sound/soc/fsl/efika-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Efika driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/stac9766.h"
-
-#define DRV_NAME "efika-audio-fabric"
-
-static struct snd_soc_dai_link efika_fabric_dai[] = {
-{
-	.name = "AC97",
-	.stream_name = "AC97 Analog",
-	.codec_dai_name = "stac9766-hifi-analog",
-	.cpu_dai_name = "mpc5200-psc-ac97.0",
-	.platform_name = "mpc5200-pcm-audio",
-	.codec_name = "stac9766-codec",
-},
-{
-	.name = "AC97",
-	.stream_name = "AC97 IEC958",
-	.codec_dai_name = "stac9766-hifi-IEC958",
-	.cpu_dai_name = "mpc5200-psc-ac97.1",
-	.platform_name = "mpc5200-pcm-audio",
-	.codec_name = "stac9766-codec",
-},
-};
-
-static struct snd_soc_card card = {
-	.name = "Efika",
-	.owner = THIS_MODULE,
-	.dai_link = efika_fabric_dai,
-	.num_links = ARRAY_SIZE(efika_fabric_dai),
-};
-
-static __init int efika_fabric_init(void)
-{
-	struct platform_device *pdev;
-	int rc;
-
-	if (!of_machine_is_compatible("bplan,efika"))
-		return -ENODEV;
-
-	pdev = platform_device_alloc("soc-audio", 1);
-	if (!pdev) {
-		pr_err("efika_fabric_init: platform_device_alloc() failed\n");
-		return -ENODEV;
-	}
-
-	platform_set_drvdata(pdev, &card);
-
-	rc = platform_device_add(pdev);
-	if (rc) {
-		pr_err("efika_fabric_init: platform_device_add() failed\n");
-		platform_device_put(pdev);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-module_init(efika_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 Efika fabric driver");
-MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
deleted file mode 100644
index b3af55d..0000000
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Phytec pcm030 driver for the PSC of the Freescale MPC52xx
- * configured as AC97 interface
- *
- * Copyright 2008 Jon Smirl, Digispeaker
- * Author: Jon Smirl <jonsmirl@gmail.com>
- *
- * 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.
- */
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/device.h>
-#include <linux/delay.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/dma-mapping.h>
-
-#include <sound/core.h>
-#include <sound/pcm.h>
-#include <sound/pcm_params.h>
-#include <sound/initval.h>
-#include <sound/soc.h>
-
-#include "mpc5200_dma.h"
-#include "mpc5200_psc_ac97.h"
-#include "../codecs/wm9712.h"
-
-#define DRV_NAME "pcm030-audio-fabric"
-
-static struct snd_soc_dai_link pcm030_fabric_dai[] = {
-{
-	.name = "AC97",
-	.stream_name = "AC97 Analog",
-	.codec_dai_name = "wm9712-hifi",
-	.cpu_dai_name = "mpc5200-psc-ac97.0",
-	.platform_name = "mpc5200-pcm-audio",
-	.codec_name = "wm9712-codec",
-},
-{
-	.name = "AC97",
-	.stream_name = "AC97 IEC958",
-	.codec_dai_name = "wm9712-aux",
-	.cpu_dai_name = "mpc5200-psc-ac97.1",
-	.platform_name = "mpc5200-pcm-audio",
-	.codec_name = "wm9712-codec",
-},
-};
-
-static struct snd_soc_card card = {
-	.name = "pcm030",
-	.owner = THIS_MODULE,
-	.dai_link = pcm030_fabric_dai,
-	.num_links = ARRAY_SIZE(pcm030_fabric_dai),
-};
-
-static __init int pcm030_fabric_init(void)
-{
-	struct platform_device *pdev;
-	int rc;
-
-	if (!of_machine_is_compatible("phytec,pcm030"))
-		return -ENODEV;
-
-	pdev = platform_device_alloc("soc-audio", 1);
-	if (!pdev) {
-		pr_err("pcm030_fabric_init: platform_device_alloc() failed\n");
-		return -ENODEV;
-	}
-
-	platform_set_drvdata(pdev, &card);
-
-	rc = platform_device_add(pdev);
-	if (rc) {
-		pr_err("pcm030_fabric_init: platform_device_add() failed\n");
-		platform_device_put(pdev);
-		return -ENODEV;
-	}
-	return 0;
-}
-
-module_init(pcm030_fabric_init);
-
-
-MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
-MODULE_DESCRIPTION(DRV_NAME ": mpc5200 pcm030 fabric driver");
-MODULE_LICENSE("GPL");
-
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 3/5] ASoC: fsl: mpc5200-soc-audio driver
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt
In-Reply-To: <1347416089-23393-1-git-send-email-emillbrandt@dekaresearch.com>

Add a generic mpc5200 driver that allows asoc cards to be defined in the
device tree.

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---
 .../devicetree/bindings/powerpc/fsl/mpc5200.txt    |   17 ++
 sound/soc/fsl/Kconfig                              |    7 +
 sound/soc/fsl/Makefile                             |    1 +
 sound/soc/fsl/mpc5200_soc_audio.c                  |  232 ++++++++++++++++++++
 4 files changed, 257 insertions(+), 0 deletions(-)
 create mode 100644 sound/soc/fsl/mpc5200_soc_audio.c

diff --git a/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
index 4ccb2cd..399d159 100644
--- a/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
+++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
@@ -196,3 +196,20 @@ External interrupts:
 fsl,mpc5200-mscan nodes
 -----------------------
 See file can.txt in this directory.
+
+fsl,mpc5200-soc-audio
+---------------------
+The mpc5200 soc-audio driver allows the snd_soc_dai_link to be filled
+in based on the node properties described below.
+
+A sound node is defined for each asoc platform.  A sound node must
+have at least one child DAI node.
+- card-name           - The card name to register in asoc
+- audio-platform      - Contains a phandle to a ac97 or i2s node
+- number-of-dais      - The number of DAIs defined
+
+Multiple DAI nodes may be attached to a sound node
+- stream-name         - The asoc name of the platform DAI stream
+- codec-name          - The name of codec to bind to
+- codec-dai-name      - The codec DAI to bind to
+- cpu-dai-name        - The cpu DAI to bind to
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index d701330..b3eee63 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -63,6 +63,13 @@ config SND_SOC_MPC5200_AC97
 	help
 	  Say Y here to support the MPC5200 PSCs in AC97 mode.
 
+config SND_MPC52xx_SOC_AUDIO
+	tristate "SoC Generic Audio support for MPC5200"
+	depends on (SND_SOC_MPC5200_AC97 || SND_SOC_MPC5200_I2S)
+	help
+	  Say Y if you want to generic device-tree support for sound on the
+	  Freescale MPC5200
+
 config SND_MPC52xx_SOC_PCM030
 	tristate "SoC AC97 Audio support for Phytec pcm030 and WM9712"
 	depends on PPC_MPC5200_SIMPLE
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 5f3cf3f..d2e2e68 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_SND_SOC_MPC5200_I2S) += mpc5200_psc_i2s.o
 obj-$(CONFIG_SND_SOC_MPC5200_AC97) += mpc5200_psc_ac97.o
 
 # MPC5200 Machine Support
+obj-$(CONFIG_SND_MPC52xx_SOC_AUDIO) += mpc5200_soc_audio.o
 obj-$(CONFIG_SND_MPC52xx_SOC_PCM030) += pcm030-audio-fabric.o
 obj-$(CONFIG_SND_MPC52xx_SOC_EFIKA) += efika-audio-fabric.o
 
diff --git a/sound/soc/fsl/mpc5200_soc_audio.c b/sound/soc/fsl/mpc5200_soc_audio.c
new file mode 100644
index 0000000..8004563
--- /dev/null
+++ b/sound/soc/fsl/mpc5200_soc_audio.c
@@ -0,0 +1,232 @@
+/*
+ * Freescale MPC5200 audio bindings
+ *
+ * Copyright 2012 DEKA R&D
+ * Author: Eric Millbrandt <emillbrandt@dekaresearch.com>
+ *
+ * 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.
+ */
+#define DEBUG
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/slab.h>
+#include <sound/soc.h>
+
+#include "mpc5200_dma.h"
+
+#define DRV_NAME "mpc5200-soc-audio"
+struct mpc5200_soc_audio_data {
+	struct snd_soc_card *card;
+	struct platform_device *codec_device[AC97_BUS_MAX_DEVICES];
+};
+
+static void of_register_ac97_devices(struct platform_device *op,
+				     struct device_node *np,
+				     struct mpc5200_soc_audio_data *pdata)
+{
+	struct device_node *nc;
+	const u32 *addr;
+	char modalias[PLATFORM_NAME_SIZE];
+	char codec[PLATFORM_NAME_SIZE];
+	int len;
+	int rc;
+	int i = 0;
+
+	if (!np) {
+		dev_err(&op->dev, "No device node found!!!\n");
+		return;
+	}
+
+	for_each_child_of_node(np, nc) {
+
+		if (nc->full_name)
+			dev_dbg(&op->dev, "loading %s\n", nc->full_name);
+
+		/* Select codec */
+		if (of_modalias_node(nc, modalias,
+				     sizeof(modalias)) < 0) {
+			dev_err(&op->dev, "cannot find modalias for %s\n",
+				nc->full_name);
+			continue;
+		}
+		strlcpy(codec, modalias, sizeof(codec));
+		strlcat(codec, "-codec", sizeof(codec));
+
+		/* Device address */
+		addr = of_get_property(nc, "reg", &len);
+		if (!addr || len < sizeof(*addr)) {
+			dev_err(&op->dev, "%s has no 'reg' property\n",
+				nc->full_name);
+			continue;
+		}
+
+		/* Allocate a platform device for the attached codec */
+		pdata->codec_device[i] = platform_device_alloc(codec, *addr);
+		if (!pdata->codec_device[i]) {
+			dev_err(&op->dev, "device allocation failed\n");
+			continue;
+		}
+
+		rc = platform_device_add(pdata->codec_device[i]);
+		if (rc) {
+			dev_err(&op->dev, "device assignment failed\n");
+			continue;
+		}
+
+		/* Register the new codec */
+		dev_dbg(&op->dev, "Registering snd-soc-%s\n", modalias);
+		rc = request_module("snd-soc-%s", modalias);
+		if (rc)
+			dev_err(&op->dev, "request_module returned: %d\n", rc);
+
+		i++;
+	}
+}
+
+static int __init mpc5200_soc_audio_probe(struct platform_device *op)
+{
+	struct device_node *np = op->dev.of_node;
+	struct device_node *nc;
+	struct device_node *cpu_platform_np;
+	struct snd_soc_card *card;
+	struct mpc5200_soc_audio_data *pdata;
+	int ret;
+	int i = 0;
+
+	card = kzalloc(sizeof(struct snd_soc_card), GFP_KERNEL);
+	if (!card) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	pdata = kzalloc(sizeof(struct mpc5200_soc_audio_data), GFP_KERNEL);
+	if (!pdata) {
+		ret = -ENOMEM;
+		goto no_mem;
+	}
+
+	pdata->card = card;
+
+	card->owner = THIS_MODULE;
+	ret = of_property_read_u32(np, "number-of-dais", &card->num_links);
+	if (ret || card->num_links < 1) {
+		dev_err(&op->dev, "number-of-dais not setup\n");
+		ret = -EINVAL;
+		goto no_dais;
+	}
+
+	card->dai_link = kzalloc(card->num_links *
+				 sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+	if (!card->dai_link) {
+		ret = -ENOMEM;
+		goto no_dais;
+	}
+
+	cpu_platform_np = of_parse_phandle(np, "audio-platform", 0);
+	if (!cpu_platform_np)
+		dev_err(&op->dev, "ac97 not enabled!\n");
+
+	/* Register attached codecs */
+	dev_dbg(&op->dev, "Registering attached codecs\n");
+	of_register_ac97_devices(op, cpu_platform_np, pdata);
+
+	card->dev = &op->dev;
+
+	/* Set card name */
+	snd_soc_of_parse_card_name(card, "card-name");
+
+	/* Add devices to dai_link */
+	for_each_child_of_node(np, nc) {
+		card->dai_link[i].name = nc->name;
+		card->dai_link[i].platform_of_node = cpu_platform_np;
+		of_property_read_string(nc, "stream-name",
+					&card->dai_link[i].stream_name);
+		of_property_read_string(nc, "codec-name",
+					&card->dai_link[i].codec_name);
+		of_property_read_string(nc, "codec-dai-name",
+					&card->dai_link[i].codec_dai_name);
+		of_property_read_string(nc, "cpu-dai-name",
+					&card->dai_link[i].cpu_dai_name);
+
+		dev_dbg(&op->dev, "%d: name: %s\n", i,
+			card->dai_link[i].name);
+		dev_dbg(&op->dev, "%d: stream-name: %s\n", i,
+			card->dai_link[i].stream_name);
+		dev_dbg(&op->dev, "%d: codec-name: %s\n", i,
+			card->dai_link[i].codec_name);
+		dev_dbg(&op->dev, "%d: codec-dai-name: %s\n", i,
+			card->dai_link[i].codec_dai_name);
+		dev_dbg(&op->dev, "%d: cpu-dai-name: %s\n", i,
+			card->dai_link[i].cpu_dai_name);
+
+		i++;
+	}
+
+	ret = snd_soc_register_card(card);
+	if (ret) {
+		dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
+		goto no_card;
+	}
+
+	platform_set_drvdata(op, pdata);
+
+	return ret;
+no_card:
+	kfree(card->dai_link);
+no_dais:
+	kfree(pdata);
+no_mem:
+	kfree(card);
+out:
+	return ret;
+}
+
+static int mpc5200_soc_audio_remove(struct platform_device *op)
+{
+	struct mpc5200_soc_audio_data *pdata = platform_get_drvdata(op);
+	struct snd_soc_card *card = pdata->card;
+	int i;
+	int ret;
+
+	ret = snd_soc_unregister_card(card);
+
+	if (ret == 0) {
+		kfree(card->dai_link);
+		kfree(card);
+
+		for (i = 0; i < AC97_BUS_MAX_DEVICES; i++)
+			if (pdata->codec_device[i])
+				platform_device_unregister(
+					pdata->codec_device[i]);
+		kfree(pdata);
+	}
+
+	return ret;
+}
+
+static struct of_device_id mpc5200_audio_match[] = {
+	{ .compatible = "fsl,mpc5200b-soc-audio", },
+	{ .compatible = "fsl,mpc5200-soc-audio", },
+	{}
+};
+MODULE_DEVICE_TABLE(of, mpc5200_audio_match);
+
+static struct platform_driver mpc5200_soc_audio_driver = {
+	.probe		= mpc5200_soc_audio_probe,
+	.remove		= mpc5200_soc_audio_remove,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+		.of_match_table    = mpc5200_audio_match,
+	},
+};
+
+module_platform_driver(mpc5200_soc_audio_driver);
+
+MODULE_AUTHOR("Eric Millbrandt <emillbrandt@dekaresearch.com>");
+MODULE_DESCRIPTION(DRV_NAME ": mpc5200 audio fabric driver");
+MODULE_LICENSE("GPL");
-- 
1.7.2.5

^ permalink raw reply related

* [PATCH 1/5] ASoC: fsl: mpc5200 multi-codec fixups
From: Eric Millbrandt @ 2012-09-12  2:14 UTC (permalink / raw)
  To: Grant Likely, Liam Girdwood, Mark Brown, Anatolij Gustschin
  Cc: alsa-devel, linuxppc-dev, Eric Millbrandt
In-Reply-To: <1347416089-23393-1-git-send-email-emillbrandt@dekaresearch.com>

Add platform DAI information that is needed to successfully register the
mpc5200 platform.

Signed-off-by: Eric Millbrandt <emillbrandt@dekaresearch.com>
---
 arch/powerpc/platforms/52xx/Kconfig |    1 +
 sound/soc/fsl/mpc5200_dma.c         |    4 ++--
 sound/soc/fsl/mpc5200_psc_ac97.c    |    8 ++++++--
 sound/soc/fsl/mpc5200_psc_i2s.c     |    3 +++
 4 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/platforms/52xx/Kconfig b/arch/powerpc/platforms/52xx/Kconfig
index 90f4496..fb35944 100644
--- a/arch/powerpc/platforms/52xx/Kconfig
+++ b/arch/powerpc/platforms/52xx/Kconfig
@@ -1,6 +1,7 @@
 config PPC_MPC52xx
 	bool "52xx-based boards"
 	depends on 6xx
+	select FSL_SOC
 	select PPC_CLOCK
 	select PPC_PCI_CHOICE
 
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 9a3f7c5..46fb518 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -366,8 +366,8 @@ static void psc_dma_free(struct snd_pcm *pcm)
 
 static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
 	.ops		= &psc_dma_ops,
-	.pcm_new	= &psc_dma_new,
-	.pcm_free	= &psc_dma_free,
+	.pcm_new	= psc_dma_new,
+	.pcm_free	= psc_dma_free,
 };
 
 static int mpc5200_hpcd_probe(struct platform_device *op)
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index ffa00a2..2f70729 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -28,7 +28,7 @@
 
 #define DRV_NAME "mpc5200-psc-ac97"
 
-/* ALSA only supports a single AC97 device so static is recommend here */
+/* ALSA only supports a single AC97 bus device so static is recommend here */
 static struct psc_dma *psc_dma;
 
 static unsigned short psc_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
@@ -237,15 +237,18 @@ static const struct snd_soc_dai_ops psc_ac97_digital_ops = {
 
 static struct snd_soc_dai_driver psc_ac97_dai[] = {
 {
+	.name = "mpc5200_psc_ac97.0",
 	.ac97_control = 1,
 	.probe	= psc_ac97_probe,
 	.playback = {
+		.stream_name	= "AC97 Playback",
 		.channels_min   = 1,
 		.channels_max   = 6,
 		.rates          = SNDRV_PCM_RATE_8000_48000,
 		.formats = SNDRV_PCM_FMTBIT_S32_BE,
 	},
 	.capture = {
+		.stream_name	= "AC97 Capture",
 		.channels_min   = 1,
 		.channels_max   = 2,
 		.rates          = SNDRV_PCM_RATE_8000_48000,
@@ -254,8 +257,10 @@ static struct snd_soc_dai_driver psc_ac97_dai[] = {
 	.ops = &psc_ac97_analog_ops,
 },
 {
+	.name = "mpc5200_psc_ac97.1",
 	.ac97_control = 1,
 	.playback = {
+		.stream_name	= "AC97 SPDIF",
 		.channels_min   = 1,
 		.channels_max   = 2,
 		.rates          = SNDRV_PCM_RATE_32000 | \
@@ -330,4 +335,3 @@ module_platform_driver(psc_ac97_driver);
 MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
 MODULE_DESCRIPTION("mpc5200 AC97 module");
 MODULE_LICENSE("GPL");
-
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 7b53032..3cf21df 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -130,13 +130,16 @@ static const struct snd_soc_dai_ops psc_i2s_dai_ops = {
 };
 
 static struct snd_soc_dai_driver psc_i2s_dai[] = {{
+	.name = "mpc5200_psc_i2s.0",
 	.playback = {
+		.stream_name = "I2S Playback",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = PSC_I2S_RATES,
 		.formats = PSC_I2S_FORMATS,
 	},
 	.capture = {
+		.stream_name = "I2S Capture",
 		.channels_min = 2,
 		.channels_max = 2,
 		.rates = PSC_I2S_RATES,
-- 
1.7.2.5

^ permalink raw reply related

* Re: [alsa-devel] [PATCH 3/5] ASoC: fsl: mpc5200-soc-audio driver
From: Stephen Warren @ 2012-09-12  2:33 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Mark Brown, Anatolij Gustschin, linuxppc-dev,
	Liam Girdwood
In-Reply-To: <1347416089-23393-4-git-send-email-emillbrandt@dekaresearch.com>

On 09/11/2012 08:14 PM, Eric Millbrandt wrote:
> Add a generic mpc5200 driver that allows asoc cards to be defined in the
> device tree.

> +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt

> +A sound node is defined for each asoc platform.  A sound node must
> +have at least one child DAI node.
> +- card-name           - The card name to register in asoc
> +- audio-platform      - Contains a phandle to a ac97 or i2s node
> +- number-of-dais      - The number of DAIs defined

Can't you get that value simply by counting all the child nodes? It
seems redundant.

^ permalink raw reply

* Re: [alsa-devel] [PATCH 4/5] arch/powerpc/boot/dts pcm030 add mpc5200-soc-audio node
From: Stephen Warren @ 2012-09-12  2:41 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Mark Brown, Anatolij Gustschin, linuxppc-dev,
	Liam Girdwood
In-Reply-To: <1347416089-23393-5-git-send-email-emillbrandt@dekaresearch.com>

On 09/11/2012 08:14 PM, Eric Millbrandt wrote:
> Describe the audio codec on the pcm030 baseboard.

> +++ b/arch/powerpc/boot/dts/pcm030.dts

> +	sound {
> +		compatible = "fsl,mpc5200b-soc-audio","fsl,mpc5200-soc-audio";
> +		card-name = "pcm030";
> +		audio-platform = <&audio_platform>;
> +		number-of-dais = <2>;
> +
> +		analog@0 {

Purely from a DT perspective (i.e. I didn't look at the code that parses
this), you don't need to include the "@0" and "@1" in the node names,
because the two node names "analog" and "digital" are already unique.

However, in general I can see that you might want multiple analog DAIs.
There are a couple choices for differentiating the node names in that case:

1) If you want to use the "@0" unit address syntax in the node names to
differentiate them, each child node needs a reg property containing the
same value, and the parent node needs properties #address-cells=<1>,
#size-cells=<0>;

2) Or, since this is within an individual device binding rather than
something within a standardized bus, you can simply choose to make the
node names unique in some other way, such as "analog0", "analog1", i.e.
without the "@"; I believe the "@" syntax would be explicitly reserved
for representing a unit address as in (1).

Of course, I could be wrong about this assertion that the "@n" is
reserved for the unit address even with the privacy of an individual
binding; it'd be best to validate it by posting to the
devicetree-discuss mailing list.

> +			stream-name = "AC97 Analog";
> +			codec-name = "wm9712-codec.0";
> +			codec-dai-name = "wm9712-hifi";
> +			cpu-dai-name = "mpc5200-psc-ac97.0";
> +		};
> +
> +		digital@1 {
> +			stream-name = "AC97 IEC958";
> +			codec-name = "wm9712-codec.0";
> +			codec-dai-name = "wm9712-aux";
> +			cpu-dai-name = "mpc5200-psc-ac97.0";
> +		};
> +	};
>  };

^ permalink raw reply

* Re: [PATCH 1/5] ASoC: fsl: mpc5200 multi-codec fixups
From: Mark Brown @ 2012-09-12  3:04 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Anatolij Gustschin, linuxppc-dev, Liam Girdwood
In-Reply-To: <1347416089-23393-2-git-send-email-emillbrandt@dekaresearch.com>

On Tue, Sep 11, 2012 at 10:14:45PM -0400, Eric Millbrandt wrote:
> Add platform DAI information that is needed to successfully register the
> mpc5200 platform.

I'm really not clear what this patch is supposed to be doing.  What are
the problems you are trying to fix and how does your patch fix them?
This should almost certainly be split into a bunch of smaller patches
with focused changelogs.

> --- a/arch/powerpc/platforms/52xx/Kconfig
> +++ b/arch/powerpc/platforms/52xx/Kconfig
> @@ -1,6 +1,7 @@
>  config PPC_MPC52xx
>  	bool "52xx-based boards"
>  	depends on 6xx
> +	select FSL_SOC
>  	select PPC_CLOCK
>  	select PPC_PCI_CHOICE

This doesnt seem to have much to do with the commit message...

> diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
> index 9a3f7c5..46fb518 100644
> --- a/sound/soc/fsl/mpc5200_dma.c
> +++ b/sound/soc/fsl/mpc5200_dma.c
> @@ -366,8 +366,8 @@ static void psc_dma_free(struct snd_pcm *pcm)
>  
>  static struct snd_soc_platform_driver mpc5200_audio_dma_platform = {
>  	.ops		= &psc_dma_ops,
> -	.pcm_new	= &psc_dma_new,
> -	.pcm_free	= &psc_dma_free,
> +	.pcm_new	= psc_dma_new,
> +	.pcm_free	= psc_dma_free,
>  };

Nor does this.

> -/* ALSA only supports a single AC97 device so static is recommend here */
> +/* ALSA only supports a single AC97 bus device so static is recommend here */
>  static struct psc_dma *psc_dma;

Or this.

^ permalink raw reply

* Re: [PATCH 3/5] ASoC: fsl: mpc5200-soc-audio driver
From: Mark Brown @ 2012-09-12  3:11 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Anatolij Gustschin, linuxppc-dev, Liam Girdwood
In-Reply-To: <1347416089-23393-4-git-send-email-emillbrandt@dekaresearch.com>

On Tue, Sep 11, 2012 at 10:14:47PM -0400, Eric Millbrandt wrote:
> Add a generic mpc5200 driver that allows asoc cards to be defined in the
> device tree.

ASoC - you've misspelt this throughout.

This changelog should discuss the subset of devices supported by your
binding, it's only possible to define bindings like this for a subset of
possible cards.  Looking at the code it seems like this driver can only
work for CODECs which require no runtime configuration (which is a very
small subset of CODEC drivers).

> --- a/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt
> +++ b/Documentation/devicetree/bindings/powerpc/fsl/mpc5200.txt

Audio bindings generally go under sound.

> +Multiple DAI nodes may be attached to a sound node
> +- stream-name         - The asoc name of the platform DAI stream
> +- codec-name          - The name of codec to bind to
> +- codec-dai-name      - The codec DAI to bind to
> +- cpu-dai-name        - The cpu DAI to bind to

What are the allowable values for these strings?

> +config SND_MPC52xx_SOC_AUDIO
> +	tristate "SoC Generic Audio support for MPC5200"
> +	depends on (SND_SOC_MPC5200_AC97 || SND_SOC_MPC5200_I2S)

It seems wrong that this depends on both AC'97 and I2S - users should be
able to use one or the other.  Given how AC'97 works we really should be
defining it as a bus in the device tree anyway, and ideally trying to
enumerate the CODECs at runtime, so it should probably be a separate
binding.

> +#define DEBUG

Remove this for mainline.

> +	card = kzalloc(sizeof(struct snd_soc_card), GFP_KERNEL);

devm_kzalloc()

^ permalink raw reply

* Re: [PATCH 4/5] arch/powerpc/boot/dts pcm030 add mpc5200-soc-audio node
From: Mark Brown @ 2012-09-12  3:17 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Anatolij Gustschin, linuxppc-dev, Liam Girdwood
In-Reply-To: <1347416089-23393-5-git-send-email-emillbrandt@dekaresearch.com>

On Tue, Sep 11, 2012 at 10:14:48PM -0400, Eric Millbrandt wrote:

> +		analog@0 {
> +			stream-name = "AC97 Analog";
> +			codec-name = "wm9712-codec.0";

This name is fairly clearly an internal implementation detail of how
Linux does audio drivers, we shouldn't be using it in device tree
bindings.  We should instead be doing something like referencing a
device tree node for the CODEC.  Look at how drivers like the nVidia
Tegra ones handle this, though for AC'97 we should really be able to
figure out a standard hookup like this automatically at runtime, it's
all enumerable.

^ permalink raw reply

* RE: [PATCH 2/3] powerpc/esdhc: add property to disable the CMD23
From: Huang Changming-R66093 @ 2012-09-12  3:19 UTC (permalink / raw)
  To: Wood Scott-B07421, Anton Vorontsov
  Cc: linux-mmc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <504F82C1.2000907@freescale.com>

DQoNCkJlc3QgUmVnYXJkcw0KSmVycnkgSHVhbmcNCg0KDQo+IC0tLS0tT3JpZ2luYWwgTWVzc2Fn
ZS0tLS0tDQo+IEZyb206IFdvb2QgU2NvdHQtQjA3NDIxDQo+IFNlbnQ6IFdlZG5lc2RheSwgU2Vw
dGVtYmVyIDEyLCAyMDEyIDI6MjggQU0NCj4gVG86IEFudG9uIFZvcm9udHNvdg0KPiBDYzogSHVh
bmcgQ2hhbmdtaW5nLVI2NjA5MzsgbGludXhwcGMtZGV2QGxpc3RzLm96bGFicy5vcmc7IGxpbnV4
LQ0KPiBtbWNAdmdlci5rZXJuZWwub3JnDQo+IFN1YmplY3Q6IFJlOiBbUEFUQ0ggMi8zXSBwb3dl
cnBjL2VzZGhjOiBhZGQgcHJvcGVydHkgdG8gZGlzYWJsZSB0aGUgQ01EMjMNCj4gDQo+IE9uIDA5
LzExLzIwMTIgMDM6MDQgQU0sIEFudG9uIFZvcm9udHNvdiB3cm90ZToNCj4gPiBPbiBUdWUsIFNl
cCAxMSwgMjAxMiBhdCAxMjo1NDoyOUFNIC0wNzAwLCBBbnRvbiBWb3JvbnRzb3Ygd3JvdGU6DQo+
ID4+IE9uIFR1ZSwgU2VwIDExLCAyMDEyIGF0IDAzOjEyOjQ0UE0gKzA4MDAsIENoYW5nLQ0KPiBN
aW5nLkh1YW5nQGZyZWVzY2FsZS5jb20gd3JvdGU6DQo+ID4+PiBGcm9tOiBKZXJyeSBIdWFuZyA8
Q2hhbmctTWluZy5IdWFuZ0BmcmVlc2NhbGUuY29tPg0KPiA+Pj4NCj4gPj4+IEJlbG93IFNPQ3Mg
ZG9uJ3Qgc3VwcG9ydCB0aGUgY21kMjMgY29tbWFuZCBmb3IgTU1DIGNhcmQsIHRoZXJlZm9yZSwN
Cj4gPj4+IGRpc2FibGUgaXQgaW4gZGV2aWNlIHRyZWU6DQo+ID4+PiBQMTAyMCwgUDEwMjEsIFAx
MDIyLCBQMTAyNCwgUDEwMjUgYW5kIFA0MDgwDQo+ID4+Pg0KPiA+Pj4gU2lnbmVkLW9mZi1ieTog
SmVycnkgSHVhbmcgPENoYW5nLU1pbmcuSHVhbmdAZnJlZXNjYWxlLmNvbT4NCj4gPj4NCj4gPj4g
QWNrZWQtYnk6IEFudG9uIFZvcm9udHNvdiA8Y2JvdWF0bWFpbHJ1QGdtYWlsLmNvbT4NCj4gPg0K
PiA+IEJ0dywgYWx0aG91Z2ggdGhlIHBhdGNoIGlzIHRyaXZpYWwsIEkgZ3Vlc3MgeW91IHN0aWxs
IHdhbnQgdG8gbGV0IGtub3cNCj4gPiBQb3dlclBDIGZvbGtzIGFib3V0IGl0LiBBZGRpbmcgQ2Mg
YW5kIGNvcHlpbmcgdGhlIHBhdGNoOg0KPiA+DQo+ID4gLSAtIC0gLQ0KPiA+IEZyb206IEplcnJ5
IEh1YW5nIDxDaGFuZy1NaW5nLkh1YW5nQGZyZWVzY2FsZS5jb20+DQo+ID4NCj4gPiBCZWxvdyBT
T0NzIGRvbid0IHN1cHBvcnQgdGhlIGNtZDIzIGNvbW1hbmQgZm9yIE1NQyBjYXJkLCB0aGVyZWZv
cmUsDQo+ID4gZGlzYWJsZSBpdCBpbiBkZXZpY2UgdHJlZToNCj4gPiBQMTAyMCwgUDEwMjEsIFAx
MDIyLCBQMTAyNCwgUDEwMjUgYW5kIFA0MDgwDQo+ID4NCj4gPiBTaWduZWQtb2ZmLWJ5OiBKZXJy
eSBIdWFuZyA8Q2hhbmctTWluZy5IdWFuZ0BmcmVlc2NhbGUuY29tPg0KPiA+IENDOiBBbnRvbiBW
b3JvbnRzb3YgPGNib3VhdG1haWxydUBnbWFpbC5jb20+DQo+ID4gLS0tDQo+ID4gIGFyY2gvcG93
ZXJwYy9ib290L2R0cy9mc2wvcDEwMjBzaS1wb3N0LmR0c2kgfCAgICAxICsNCj4gPiAgYXJjaC9w
b3dlcnBjL2Jvb3QvZHRzL2ZzbC9wMTAyMXNpLXBvc3QuZHRzaSB8ICAgIDEgKw0KPiA+ICBhcmNo
L3Bvd2VycGMvYm9vdC9kdHMvZnNsL3AxMDIyc2ktcG9zdC5kdHNpIHwgICAgMSArDQo+ID4gIGFy
Y2gvcG93ZXJwYy9ib290L2R0cy9mc2wvcDQwODBzaS1wb3N0LmR0c2kgfCAgICAxICsNCj4gPiAg
NCBmaWxlcyBjaGFuZ2VkLCA0IGluc2VydGlvbnMoKykNCj4gPg0KPiA+IGRpZmYgLS1naXQgYS9h
cmNoL3Bvd2VycGMvYm9vdC9kdHMvZnNsL3AxMDIwc2ktcG9zdC5kdHNpDQo+ID4gYi9hcmNoL3Bv
d2VycGMvYm9vdC9kdHMvZnNsL3AxMDIwc2ktcG9zdC5kdHNpDQo+ID4gaW5kZXggNjhjYzVlNy4u
NzkzYTMwYiAxMDA2NDQNCj4gPiAtLS0gYS9hcmNoL3Bvd2VycGMvYm9vdC9kdHMvZnNsL3AxMDIw
c2ktcG9zdC5kdHNpDQo+ID4gKysrIGIvYXJjaC9wb3dlcnBjL2Jvb3QvZHRzL2ZzbC9wMTAyMHNp
LXBvc3QuZHRzaQ0KPiA+IEBAIC0xNTQsNiArMTU0LDcgQEANCj4gPiAgCXNkaGNAMmUwMDAgew0K
PiA+ICAJCWNvbXBhdGlibGUgPSAiZnNsLHAxMDIwLWVzZGhjIiwgImZzbCxlc2RoYyI7DQo+ID4g
IAkJc2RoY2ksYXV0by1jbWQxMjsNCj4gPiArCQlzZGhjaSxuby1jbWQyMzsNCj4gPiAgCX07DQo+
ID4gIC9pbmNsdWRlLyAicHEzLXNlYzMuMy0wLmR0c2kiDQo+ID4NCj4gPiBkaWZmIC0tZ2l0IGEv
YXJjaC9wb3dlcnBjL2Jvb3QvZHRzL2ZzbC9wMTAyMXNpLXBvc3QuZHRzaQ0KPiA+IGIvYXJjaC9w
b3dlcnBjL2Jvb3QvZHRzL2ZzbC9wMTAyMXNpLXBvc3QuZHRzaQ0KPiA+IGluZGV4IGFkYjgyZmQu
LjJiN2ZkMmEgMTAwNjQ0DQo+ID4gLS0tIGEvYXJjaC9wb3dlcnBjL2Jvb3QvZHRzL2ZzbC9wMTAy
MXNpLXBvc3QuZHRzaQ0KPiA+ICsrKyBiL2FyY2gvcG93ZXJwYy9ib290L2R0cy9mc2wvcDEwMjFz
aS1wb3N0LmR0c2kNCj4gPiBAQCAtMTQ5LDYgKzE0OSw3IEBADQo+ID4gIC9pbmNsdWRlLyAicHEz
LWVzZGhjLTAuZHRzaSINCj4gPiAgCXNkaGNAMmUwMDAgew0KPiA+ICAJCXNkaGNpLGF1dG8tY21k
MTI7DQo+ID4gKwkJc2RoY2ksbm8tY21kMjM7DQo+ID4gIAl9Ow0KPiA+DQo+ID4gIC9pbmNsdWRl
LyAicHEzLXNlYzMuMy0wLmR0c2kiDQo+ID4gZGlmZiAtLWdpdCBhL2FyY2gvcG93ZXJwYy9ib290
L2R0cy9mc2wvcDEwMjJzaS1wb3N0LmR0c2kNCj4gPiBiL2FyY2gvcG93ZXJwYy9ib290L2R0cy9m
c2wvcDEwMjJzaS1wb3N0LmR0c2kNCj4gPiBpbmRleCAwNjIxNmI4Li4yMzM0YTUyIDEwMDY0NA0K
PiA+IC0tLSBhL2FyY2gvcG93ZXJwYy9ib290L2R0cy9mc2wvcDEwMjJzaS1wb3N0LmR0c2kNCj4g
PiArKysgYi9hcmNoL3Bvd2VycGMvYm9vdC9kdHMvZnNsL3AxMDIyc2ktcG9zdC5kdHNpDQo+ID4g
QEAgLTIxNSw2ICsyMTUsNyBAQA0KPiA+ICAJc2RoY0AyZTAwMCB7DQo+ID4gIAkJY29tcGF0aWJs
ZSA9ICJmc2wscDEwMjItZXNkaGMiLCAiZnNsLGVzZGhjIjsNCj4gPiAgCQlzZGhjaSxhdXRvLWNt
ZDEyOw0KPiA+ICsJCXNkaGNpLG5vLWNtZDIzOw0KPiA+ICAJfTsNCj4gPg0KPiA+ICAvaW5jbHVk
ZS8gInBxMy1zZWMzLjMtMC5kdHNpIg0KPiA+IGRpZmYgLS1naXQgYS9hcmNoL3Bvd2VycGMvYm9v
dC9kdHMvZnNsL3A0MDgwc2ktcG9zdC5kdHNpDQo+ID4gYi9hcmNoL3Bvd2VycGMvYm9vdC9kdHMv
ZnNsL3A0MDgwc2ktcG9zdC5kdHNpDQo+ID4gaW5kZXggOGQzNWQyYy4uNWIzOTk1MiAxMDA2NDQN
Cj4gPiAtLS0gYS9hcmNoL3Bvd2VycGMvYm9vdC9kdHMvZnNsL3A0MDgwc2ktcG9zdC5kdHNpDQo+
ID4gKysrIGIvYXJjaC9wb3dlcnBjL2Jvb3QvZHRzL2ZzbC9wNDA4MHNpLXBvc3QuZHRzaQ0KPiA+
IEBAIC0zMzcsNiArMzM3LDcgQEANCj4gPiAgCXNkaGNAMTE0MDAwIHsNCj4gPiAgCQl2b2x0YWdl
LXJhbmdlcyA9IDwzMzAwIDMzMDA+Ow0KPiA+ICAJCXNkaGNpLGF1dG8tY21kMTI7DQo+ID4gKwkJ
c2RoY2ksbm8tY21kMjM7DQo+ID4gIAl9Ow0KPiA+DQo+ID4gIC9pbmNsdWRlLyAicW9yaXEtaTJj
LTAuZHRzaSINCj4gPg0KPiANCj4gVGhpcyB3b24ndCBoZWxwIHBlb3BsZSB3aXRoIG9sZCBkZXZp
Y2UgdHJlZXMgKGZvcmtlZCBmb3IgYSBjdXN0b20gYm9hcmQsDQo+IHRpZWQgdG8gYW4gb2xkIFUt
Qm9vdCwgZXRjKS4gIFRoZSBkcml2ZXIgc2hvdWxkIGluZmVyIHRoaXMgZnJvbSB0aGUNCj4gY29t
cGF0aWJsZSBzdHJpbmcgb3IgdmVyc2lvbiByZWdpc3RlcnMgKGlkZWFsbHkgYmxvY2stc3BlY2lm
aWMgdmVyc2lvbg0KPiByZWdpc3RlcnMsIGJ1dCBpZiB0aGVzZSBhcmUgYWJzZW50IG9yIGluY29u
Y2x1c2l2ZSwgU1ZSIGNhbiBiZSB1c2VkKS4NCj4gDQoNCkkgZG9uJ3QgdGhpbmsgaXQgaXMgdGhl
IGJlc3Qgd2F5IHRvIGRvIGl0Lg0KRm9yIHRoZSBWVk4yLjIgb3Igb2xkZXIsIHNvbWUgc2lsaWNv
biBzdXBwb3J0IHRoaXMgZmVhdHVyZSAobXBjODUzNiBhbmQgcDIwMjApLCBidXQgb3RoZXIgc2ls
aWNvbmVzIGRvbid0IHN1cHBvcnQgaXQgKGUuZy4gcDQwODAsIHAxMDJ4KS4NClRob3VnaCwgdGhl
IGN1cnJlbnQgcDUvcDQvcDMgaGFzIHN1cHBvcnRlZCB0aGlzIGZlYXR1cmUsIGNhbiB3ZSBzdXJl
IHRoZSBmdXR1cmUgc2lsaWNvbiBzdXBwb3J0IGl0Pw0KU28gSSB0aGluayB0aGUgYmVzdCB3YXkg
aXMgdG8gc3BlY2lmeSBpdCBpbiBkZXZpY2UgdHJlZSBhcyAnc2RoY2ksYXV0by1jbWQxMicNCg==

^ permalink raw reply

* Re: [PATCH 5/5] ASoC: fsl: mpc5200 remove pcm030 and efika audio fabric
From: Mark Brown @ 2012-09-12  3:20 UTC (permalink / raw)
  To: Eric Millbrandt
  Cc: alsa-devel, Anatolij Gustschin, linuxppc-dev, Liam Girdwood
In-Reply-To: <1347416089-23393-6-git-send-email-emillbrandt@dekaresearch.com>

On Tue, Sep 11, 2012 at 10:14:49PM -0400, Eric Millbrandt wrote:
> MPC5200 ASoC setup can now be done in the device tree.

I only noticed DT bindings being added for pcm030, not for efika?

^ permalink raw reply

* Re: [PATCH 2/3] powerpc/esdhc: add property to disable the CMD23
From: Anton Vorontsov @ 2012-09-12  3:38 UTC (permalink / raw)
  To: Huang Changming-R66093
  Cc: Wood Scott-B07421, linux-mmc@vger.kernel.org,
	linuxppc-dev@lists.ozlabs.org
In-Reply-To: <110EED8CC96DFC488B7E717A2027A27C176E94@039-SN1MPN1-002.039d.mgd.msft.net>

On Wed, Sep 12, 2012 at 03:19:18AM +0000, Huang Changming-R66093 wrote:
[...]
> I don't think it is the best way to do it.  For the VVN2.2 or older,
> some silicon support this feature (mpc8536 and p2020), but other
> silicones don't support it (e.g. p4080, p102x).  Though, the current
> p5/p4/p3 has supported this feature, can we sure the future silicon
> support it?  So I think the best way is to specify it in device tree
> as 'sdhci,auto-cmd12'

In addition to your current patches, you could just add another patch
that blacklists affected SOC revisions based on the info from PVR/SVR.

For example, see gfar_detect_errata() in
drivers/net/ethernet/freescale/gianfar.c.

That way you could help users that don't have the newest device trees.

Thanks,
Anton.

^ permalink raw reply

* Re: [PATCH V3 1/3] drivers/char/tpm: Add new device driver to support IBM vTPM
From: James Morris @ 2012-09-12  3:16 UTC (permalink / raw)
  To: Kent Yoder
  Cc: linux-kernel, Ashley Lai, linux-security-module, tpmdd-devel,
	adlai, rcj, linuxppc-dev
In-Reply-To: <20120907173809.GA19704@linux.vnet.ibm.com>

On Fri, 7 Sep 2012, Kent Yoder wrote:

> > >   James did accept my pull request, so these are already in
> > > security-next...
> > 
> > For the driver itself, it's not a big issue (though I did found issue
> > while reviewing it so it will need another round of updates). For the
> > code that changes arch/powerpc, especially prom_init.c, that stuff must
> > at the very least be acked by me (or the acting powerpc person if I'm
> > away) if it's going to go via a different tree.
> 
>   Sorry about that.  Hopefully there won't be any changes there and we
> can amend with your ack.
> 
>   As for the driver updates, I'd hate to see everyone else's code in the
> pull request get delayed yet again.  James, will it be ok to apply the
> update on top of security-next?

I guess?

-- 
James Morris
<jmorris@namei.org>

^ permalink raw reply

* [PATCH 3/3] ppc/eeh: global mutex to protect PE tree
From: Gavin Shan @ 2012-09-12  5:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1347426978-6194-1-git-send-email-shangw@linux.vnet.ibm.com>

We have missed lots of situations where the PE hierarchy tree need
protection through the EEH global mutex. The patch fixes that for
those public APIs implemented in eeh_pe.c. The only exception is
eeh_pe_restore_bars() because it calls eeh_pe_dev_traverse(), which
has been protected by the mutex.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/pseries/eeh_pe.c |   39 +++++++++++++++++++++++++-----
 1 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index a2646cf..07b6e4b 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -99,8 +99,6 @@ static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
 {
 	struct eeh_pe *pe;
 
-	eeh_lock();
-
 	list_for_each_entry(pe, &eeh_phb_pe, child) {
 		/*
 		 * Actually, we needn't check the type since
@@ -114,8 +112,6 @@ static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
 		}
 	}
 
-	eeh_unlock();
-
 	return NULL;
 }
 
@@ -192,14 +188,21 @@ void *eeh_pe_dev_traverse(struct eeh_pe *root,
 		return NULL;
 	}
 
+	eeh_lock();
+
 	/* Traverse root PE */
 	for (pe = root; pe; pe = eeh_pe_next(pe, root)) {
 		eeh_pe_for_each_dev(pe, edev) {
 			ret = fn(edev, flag);
-			if (ret) return ret;
+			if (ret) {
+				eeh_unlock();
+				return ret;
+			}
 		}
 	}
 
+	eeh_unlock();
+
 	return NULL;
 }
 
@@ -251,9 +254,7 @@ static struct eeh_pe *eeh_pe_get(struct eeh_dev *edev)
 	struct eeh_pe *root = eeh_phb_pe_get(edev->phb);
 	struct eeh_pe *pe;
 
-	eeh_lock();
 	pe = eeh_pe_traverse(root, __eeh_pe_get, edev);
-	eeh_unlock();
 
 	return pe;
 }
@@ -307,6 +308,8 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 {
 	struct eeh_pe *pe, *parent;
 
+	eeh_lock();
+
 	/*
 	 * Search the PE has been existing or not according
 	 * to the PE address. If that has been existing, the
@@ -316,6 +319,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 	pe = eeh_pe_get(edev);
 	if (pe && !(pe->type & EEH_PE_INVALID)) {
 		if (!edev->pe_config_addr) {
+			eeh_unlock();
 			pr_err("%s: PE with addr 0x%x already exists\n",
 				__func__, edev->config_addr);
 			return -EEXIST;
@@ -327,6 +331,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 
 		/* Put the edev to PE */
 		list_add_tail(&edev->list, &pe->edevs);
+		eeh_unlock();
 		pr_debug("EEH: Add %s to Bus PE#%x\n",
 			edev->dn->full_name, pe->addr);
 
@@ -345,6 +350,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 			parent->type &= ~EEH_PE_INVALID;
 			parent = parent->parent;
 		}
+		eeh_unlock();
 		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
 			edev->dn->full_name, pe->addr, pe->parent->addr);
 
@@ -354,6 +360,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 	/* Create a new EEH PE */
 	pe = eeh_pe_alloc(edev->phb, EEH_PE_DEVICE);
 	if (!pe) {
+		eeh_unlock();
 		pr_err("%s: out of memory!\n", __func__);
 		return -ENOMEM;
 	}
@@ -370,6 +377,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 	if (!parent) {
 		parent = eeh_phb_pe_get(edev->phb);
 		if (!parent) {
+			eeh_unlock();
 			pr_err("%s: No PHB PE is found (PHB Domain=%d)\n",
 				__func__, edev->phb->global_number);
 			edev->pe = NULL;
@@ -386,6 +394,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 	list_add_tail(&pe->child, &parent->child_list);
 	list_add_tail(&edev->list, &pe->edevs);
 	edev->pe = pe;
+	eeh_unlock();
 	pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
 		edev->dn->full_name, pe->addr, pe->parent->addr);
 
@@ -413,6 +422,8 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
 		return -EEXIST;
 	}
 
+	eeh_lock();
+
 	/* Remove the EEH device */
 	pe = edev->pe;
 	edev->pe = NULL;
@@ -457,6 +468,8 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
 		pe = parent;
 	}
 
+	eeh_unlock();
+
 	return 0;
 }
 
@@ -502,7 +515,9 @@ static void *__eeh_pe_state_mark(void *data, void *flag)
  */
 void eeh_pe_state_mark(struct eeh_pe *pe, int state)
 {
+	eeh_lock();
 	eeh_pe_traverse(pe, __eeh_pe_state_mark, &state);
+	eeh_unlock();
 }
 
 /**
@@ -536,7 +551,9 @@ static void *__eeh_pe_state_clear(void *data, void *flag)
  */
 void eeh_pe_state_clear(struct eeh_pe *pe, int state)
 {
+	eeh_lock();
 	eeh_pe_traverse(pe, __eeh_pe_state_clear, &state);
+	eeh_unlock();
 }
 
 /**
@@ -598,6 +615,10 @@ static void *eeh_restore_one_device_bars(void *data, void *flag)
  */
 void eeh_pe_restore_bars(struct eeh_pe *pe)
 {
+	/*
+	 * We needn't take the EEH lock since eeh_pe_dev_traverse()
+	 * will take that.
+	 */
 	eeh_pe_dev_traverse(pe, eeh_restore_one_device_bars, NULL);
 }
 
@@ -617,6 +638,8 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
 	struct eeh_dev *edev;
 	struct pci_dev *pdev;
 
+	eeh_lock();
+
 	if (pe->type & EEH_PE_PHB) {
 		bus = pe->phb->bus;
 	} else if (pe->type & EEH_PE_BUS) {
@@ -626,5 +649,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
 			bus = pdev->bus;
 	}
 
+	eeh_unlock();
+
 	return bus;
 }
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 1/3] ppc/eeh: introduce EEH_PE_INVALID type PE
From: Gavin Shan @ 2012-09-12  5:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan

When EEH error happens on the PE whose PCI devices don't have
attached drivers. In function eeh_handle_event(), the default
value PCI_ERS_RESULT_NONE will be returned after iterating all
drivers of those PCI devices belonging to the PE. Actually, we
don't have installed drivers for the PCI devices. Under the
circumstance, we will remove the corresponding PCI bus of the PE,
including the associated EEH devices and PE instance. However,
we still need the information stored in the PE instance to do PE
reset after that. So it's unsafe to free the PE instance.

The patch introduces EEH_PE_INVALID type PE to address the issue.
When the PCI bus and the corresponding attached EEH devices are
removed, we will mark the PE as EEH_PE_INVALID. At later point,
the PE will be changed to EEH_PE_DEVICE or EEH_PE_BUS when the
corresponding EEH devices are attached again.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h          |    7 ++--
 arch/powerpc/platforms/pseries/eeh_pe.c |   50 ++++++++++++++++++++++++-------
 2 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index 58c5ee6..afeb400 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -45,9 +45,10 @@ struct device_node;
  * in the corresponding PHB. Therefore, the root PEs should be created
  * against existing PHBs in on-to-one fashion.
  */
-#define EEH_PE_PHB	1	/* PHB PE    */
-#define EEH_PE_DEVICE 	2	/* Device PE */
-#define EEH_PE_BUS	3	/* Bus PE    */
+#define EEH_PE_INVALID	(1 << 0)	/* Invalid   */
+#define EEH_PE_PHB	(1 << 1)	/* PHB PE    */
+#define EEH_PE_DEVICE 	(1 << 2)	/* Device PE */
+#define EEH_PE_BUS	(1 << 3)	/* Bus PE    */
 
 #define EEH_PE_ISOLATED		(1 << 0)	/* Isolated PE		*/
 #define EEH_PE_RECOVERING	(1 << 1)	/* Recovering PE	*/
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index 047617e..8f95ffd 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -107,7 +107,7 @@ static struct eeh_pe *eeh_phb_pe_get(struct pci_controller *phb)
 		 * the PE for PHB has been determined when that
 		 * was created.
 		 */
-		if (pe->type == EEH_PE_PHB &&
+		if ((pe->type & EEH_PE_PHB) &&
 		    pe->phb == phb) {
 			eeh_unlock();
 			return pe;
@@ -219,7 +219,7 @@ static void *__eeh_pe_get(void *data, void *flag)
 	struct eeh_dev *edev = (struct eeh_dev *)flag;
 
 	/* Unexpected PHB PE */
-	if (pe->type == EEH_PE_PHB)
+	if (pe->type & EEH_PE_PHB)
 		return NULL;
 
 	/* We prefer PE address */
@@ -314,7 +314,7 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 	 * components.
 	 */
 	pe = eeh_pe_get(edev);
-	if (pe) {
+	if (pe && !(pe->type & EEH_PE_INVALID)) {
 		if (!edev->pe_config_addr) {
 			pr_err("%s: PE with addr 0x%x already exists\n",
 				__func__, edev->config_addr);
@@ -331,6 +331,24 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 			edev->dn->full_name, pe->addr);
 
 		return 0;
+	} else if (pe && (pe->type & EEH_PE_INVALID)) {
+		list_add_tail(&edev->list, &pe->edevs);
+		edev->pe = pe;
+		/*
+		 * We're running to here because of PCI hotplug caused by
+		 * EEH recovery. We need clear EEH_PE_INVALID until the top.
+		 */
+		parent = pe;
+		while (parent) {
+			if (!(parent->type & EEH_PE_INVALID))
+				break;
+			parent->type &= ~EEH_PE_INVALID;
+			parent = parent->parent;
+		}
+		pr_debug("EEH: Add %s to Device PE#%x, Parent PE#%x\n",
+			edev->dn->full_name, pe->addr, pe->parent->addr);
+
+		return 0;
 	}
 
 	/* Create a new EEH PE */
@@ -385,7 +403,8 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
  */
 int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
 {
-	struct eeh_pe *pe, *parent;
+	struct eeh_pe *pe, *parent, *child;
+	int cnt;
 
 	if (!edev->pe) {
 		pr_warning("%s: No PE found for EEH device %s\n",
@@ -406,13 +425,22 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
 	 */
 	while (1) {
 		parent = pe->parent;
-		if (pe->type == EEH_PE_PHB)
+		if (pe->type & EEH_PE_PHB)
 			break;
 
-		if (list_empty(&pe->edevs) &&
-		    list_empty(&pe->child_list)) {
-			list_del(&pe->child);
-			kfree(pe);
+		if (list_empty(&pe->edevs)) {
+			cnt = 0;
+			list_for_each_entry(child, &pe->child_list, child) {
+				if (!(pe->type & EEH_PE_INVALID)) {
+					cnt++;
+					break;
+				}
+			}
+
+			if (!cnt)
+				pe->type |= EEH_PE_INVALID;
+			else
+				break;
 		}
 
 		pe = parent;
@@ -578,9 +606,9 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
 	struct eeh_dev *edev;
 	struct pci_dev *pdev;
 
-	if (pe->type == EEH_PE_PHB) {
+	if (pe->type & EEH_PE_PHB) {
 		bus = pe->phb->bus;
-	} else if (pe->type == EEH_PE_BUS) {
+	} else if (pe->type & EEH_PE_BUS) {
 		edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
 		pdev = eeh_dev_to_pci_dev(edev);
 		if (pdev)
-- 
1.7.5.4

^ permalink raw reply related

* [PATCH 2/3] ppc/eeh: remove EEH PE for normal PCI hotplug
From: Gavin Shan @ 2012-09-12  5:16 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1347426978-6194-1-git-send-email-shangw@linux.vnet.ibm.com>

Function eeh_rmv_from_parent_pe() could be called by the path of
either normal PCI hotplug, or EEH recovery. For the former case,
we need purge the corresponding PE on removal of the associated
PE bus.

The patch tries to cover that by passing more information to function
pcibios_remove_pci_devices() so that we know if the corresponding PE
needs to be purged or be marked as "invalid".

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/eeh.h              |    6 ++--
 arch/powerpc/include/asm/pci-bridge.h       |    1 +
 arch/powerpc/platforms/pseries/eeh.c        |   12 +++++----
 arch/powerpc/platforms/pseries/eeh_driver.c |    8 +++++-
 arch/powerpc/platforms/pseries/eeh_pe.c     |   35 +++++++++++++++++---------
 arch/powerpc/platforms/pseries/pci_dlpar.c  |   32 ++++++++++++++++++------
 6 files changed, 65 insertions(+), 29 deletions(-)

diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
index afeb400..b0ef738 100644
--- a/arch/powerpc/include/asm/eeh.h
+++ b/arch/powerpc/include/asm/eeh.h
@@ -185,7 +185,7 @@ static inline void eeh_unlock(void)
 typedef void *(*eeh_traverse_func)(void *data, void *flag);
 int __devinit eeh_phb_pe_create(struct pci_controller *phb);
 int eeh_add_to_parent_pe(struct eeh_dev *edev);
-int eeh_rmv_from_parent_pe(struct eeh_dev *edev);
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe);
 void *eeh_pe_dev_traverse(struct eeh_pe *root,
 		eeh_traverse_func fn, void *flag);
 void eeh_pe_restore_bars(struct eeh_pe *pe);
@@ -201,7 +201,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev);
 void __init eeh_addr_cache_build(void);
 void eeh_add_device_tree_early(struct device_node *);
 void eeh_add_device_tree_late(struct pci_bus *);
-void eeh_remove_bus_device(struct pci_dev *);
+void eeh_remove_bus_device(struct pci_dev *, int);
 
 /**
  * EEH_POSSIBLE_ERROR() -- test for possible MMIO failure.
@@ -240,7 +240,7 @@ static inline void eeh_add_device_tree_early(struct device_node *dn) { }
 
 static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
 
-static inline void eeh_remove_bus_device(struct pci_dev *dev) { }
+static inline void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe) { }
 
 static inline void eeh_lock(void) { }
 static inline void eeh_unlock(void) { }
diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 973df4d..a059cb9 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -192,6 +192,7 @@ static inline struct eeh_dev *of_node_to_eeh_dev(struct device_node *dn)
 extern struct pci_bus *pcibios_find_pci_bus(struct device_node *dn);
 
 /** Remove all of the PCI devices under this bus */
+extern void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe);
 extern void pcibios_remove_pci_devices(struct pci_bus *bus);
 
 /** Discover new pci devices under this bus, and add them */
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
index 18c168b..43f6ed4 100644
--- a/arch/powerpc/platforms/pseries/eeh.c
+++ b/arch/powerpc/platforms/pseries/eeh.c
@@ -817,6 +817,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
 /**
  * eeh_remove_device - Undo EEH setup for the indicated pci device
  * @dev: pci device to be removed
+ * @purge_pe: remove the PE or not
  *
  * This routine should be called when a device is removed from
  * a running system (e.g. by hotplug or dlpar).  It unregisters
@@ -824,7 +825,7 @@ EXPORT_SYMBOL_GPL(eeh_add_device_tree_late);
  * this device will no longer be detected after this call; thus,
  * i/o errors affecting this slot may leave this device unusable.
  */
-static void eeh_remove_device(struct pci_dev *dev)
+static void eeh_remove_device(struct pci_dev *dev, int purge_pe)
 {
 	struct eeh_dev *edev;
 
@@ -843,7 +844,7 @@ static void eeh_remove_device(struct pci_dev *dev)
 	dev->dev.archdata.edev = NULL;
 	pci_dev_put(dev);
 
-	eeh_rmv_from_parent_pe(edev);
+	eeh_rmv_from_parent_pe(edev, purge_pe);
 	eeh_addr_cache_rmv_dev(dev);
 	eeh_sysfs_remove_device(dev);
 }
@@ -851,21 +852,22 @@ static void eeh_remove_device(struct pci_dev *dev)
 /**
  * eeh_remove_bus_device - Undo EEH setup for the indicated PCI device
  * @dev: PCI device
+ * @purge_pe: remove the corresponding PE or not
  *
  * This routine must be called when a device is removed from the
  * running system through hotplug or dlpar. The corresponding
  * PCI address cache will be removed.
  */
-void eeh_remove_bus_device(struct pci_dev *dev)
+void eeh_remove_bus_device(struct pci_dev *dev, int purge_pe)
 {
 	struct pci_bus *bus = dev->subordinate;
 	struct pci_dev *child, *tmp;
 
-	eeh_remove_device(dev);
+	eeh_remove_device(dev, purge_pe);
 
 	if (bus && dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) {
 		list_for_each_entry_safe(child, tmp, &bus->devices, bus_list)
-			 eeh_remove_bus_device(child);
+			 eeh_remove_bus_device(child, purge_pe);
 	}
 }
 EXPORT_SYMBOL_GPL(eeh_remove_bus_device);
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c
index 8370ce7..37c2cf7 100644
--- a/arch/powerpc/platforms/pseries/eeh_driver.c
+++ b/arch/powerpc/platforms/pseries/eeh_driver.c
@@ -305,8 +305,14 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
 	/* pcibios will clear the counter; save the value */
 	cnt = pe->freeze_count;
 
+	/*
+	 * We don't remove the corresponding PE instances because
+	 * we need the information afterwords. The attached EEH
+	 * devices are expected to be attached soon when calling
+	 * into pcibios_add_pci_devices().
+	 */
 	if (bus)
-		pcibios_remove_pci_devices(bus);
+		__pcibios_remove_pci_devices(bus, 0);
 
 	/* Reset the pci controller. (Asserts RST#; resets config space).
 	 * Reconfigure bridges and devices. Don't try to bring the system
diff --git a/arch/powerpc/platforms/pseries/eeh_pe.c b/arch/powerpc/platforms/pseries/eeh_pe.c
index 8f95ffd..a2646cf 100644
--- a/arch/powerpc/platforms/pseries/eeh_pe.c
+++ b/arch/powerpc/platforms/pseries/eeh_pe.c
@@ -395,13 +395,14 @@ int eeh_add_to_parent_pe(struct eeh_dev *edev)
 /**
  * eeh_rmv_from_parent_pe - Remove one EEH device from the associated PE
  * @edev: EEH device
+ * @purge_pe: remove PE or not
  *
  * The PE hierarchy tree might be changed when doing PCI hotplug.
  * Also, the PCI devices or buses could be removed from the system
  * during EEH recovery. So we have to call the function remove the
  * corresponding PE accordingly if necessary.
  */
-int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
+int eeh_rmv_from_parent_pe(struct eeh_dev *edev, int purge_pe)
 {
 	struct eeh_pe *pe, *parent, *child;
 	int cnt;
@@ -428,19 +429,29 @@ int eeh_rmv_from_parent_pe(struct eeh_dev *edev)
 		if (pe->type & EEH_PE_PHB)
 			break;
 
-		if (list_empty(&pe->edevs)) {
-			cnt = 0;
-			list_for_each_entry(child, &pe->child_list, child) {
-				if (!(pe->type & EEH_PE_INVALID)) {
-					cnt++;
-					break;
-				}
+		if (purge_pe) {
+			if (list_empty(&pe->edevs) &&
+			    list_empty(&pe->child_list)) {
+				list_del(&pe->child);
+				kfree(pe);
+			} else {
+				break;
 			}
+		} else {
+			if (list_empty(&pe->edevs)) {
+				cnt = 0;
+				list_for_each_entry(child, &pe->child_list, child) {
+					if (!(pe->type & EEH_PE_INVALID)) {
+						cnt++;
+						break;
+					}
+				}
 
-			if (!cnt)
-				pe->type |= EEH_PE_INVALID;
-			else
-				break;
+				if (!cnt)
+					pe->type |= EEH_PE_INVALID;
+				else
+					break;
+			}
 		}
 
 		pe = parent;
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 3ccebc8..261a577 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -65,27 +65,43 @@ pcibios_find_pci_bus(struct device_node *dn)
 EXPORT_SYMBOL_GPL(pcibios_find_pci_bus);
 
 /**
- * pcibios_remove_pci_devices - remove all devices under this bus
+ * __pcibios_remove_pci_devices - remove all devices under this bus
+ * @bus: the indicated PCI bus
+ * @purge_pe: destroy the PE on removal of PCI devices
  *
  * Remove all of the PCI devices under this bus both from the
  * linux pci device tree, and from the powerpc EEH address cache.
+ * By default, the corresponding PE will be destroied during the
+ * normal PCI hotplug path. For PCI hotplug during EEH recovery,
+ * the corresponding PE won't be destroied and deallocated.
  */
-void pcibios_remove_pci_devices(struct pci_bus *bus)
+void __pcibios_remove_pci_devices(struct pci_bus *bus, int purge_pe)
 {
- 	struct pci_dev *dev, *tmp;
+	struct pci_dev *dev, *tmp;
 	struct pci_bus *child_bus;
 
 	/* First go down child busses */
 	list_for_each_entry(child_bus, &bus->children, node)
-		pcibios_remove_pci_devices(child_bus);
+		__pcibios_remove_pci_devices(child_bus, purge_pe);
 
 	pr_debug("PCI: Removing devices on bus %04x:%02x\n",
-		 pci_domain_nr(bus),  bus->number);
+		pci_domain_nr(bus),  bus->number);
 	list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) {
 		pr_debug("     * Removing %s...\n", pci_name(dev));
-		eeh_remove_bus_device(dev);
- 		pci_stop_and_remove_bus_device(dev);
- 	}
+		eeh_remove_bus_device(dev, purge_pe);
+		pci_stop_and_remove_bus_device(dev);
+	}
+}
+
+/**
+ * pcibios_remove_pci_devices - remove all devices under this bus
+ *
+ * Remove all of the PCI devices under this bus both from the
+ * linux pci device tree, and from the powerpc EEH address cache.
+ */
+void pcibios_remove_pci_devices(struct pci_bus *bus)
+{
+	__pcibios_remove_pci_devices(bus, 1);
 }
 EXPORT_SYMBOL_GPL(pcibios_remove_pci_devices);
 
-- 
1.7.5.4

^ permalink raw reply related

* Re: [RFC v8 PATCH 00/20] memory-hotplug: hot-remove physical memory
From: Wen Congyang @ 2012-09-12  5:20 UTC (permalink / raw)
  To: Vasilis Liaskovitis
  Cc: linux-s390, linux-ia64, len.brown, linux-acpi, linux-sh, x86,
	linux-kernel, cmetcalf, linux-mm, Yasuaki Ishimatsu, paulus,
	minchan.kim, kosaki.motohiro, rientjes, sparclinux, Andrew Morton,
	linuxppc-dev, cl, liuj97
In-Reply-To: <20120910135213.GA1550@dhcp-192-168-178-175.profitbricks.localdomain>

At 09/10/2012 09:52 PM, Vasilis Liaskovitis Wrote:
> Hi,
> 
> On Mon, Sep 10, 2012 at 10:01:44AM +0800, Wen Congyang wrote:
>> At 09/10/2012 09:46 AM, Yasuaki Ishimatsu Wrote:
>>> Hi Wen,
>>>
>>> 2012/09/01 5:49, Andrew Morton wrote:
>>>> On Tue, 28 Aug 2012 18:00:07 +0800
>>>> wency@cn.fujitsu.com wrote:
>>>>
>>>>> This patch series aims to support physical memory hot-remove.
>>>>
>>>> I doubt if many people have hardware which permits physical memory
>>>> removal?  How would you suggest that people with regular hardware can
>>>> test these chagnes?
>>>
>>> How do you test the patch? As Andrew says, for hot-removing memory,
>>> we need a particular hardware. I think so too. So many people may want
>>> to know how to test the patch.
>>> If we apply following patch to kvm guest, can we hot-remove memory on
>>> kvm guest?
>>>
>>> http://lists.gnu.org/archive/html/qemu-devel/2012-07/msg01389.html
>>
>> Yes, if we apply this patchset, we can test hot-remove memory on kvm guest.
>> But that patchset doesn't implement _PS3, so there is some restriction.
> 
> the following repos contain the patchset above, plus 2 more patches that add
> PS3 support to the dimm devices in qemu/seabios:
> 
> https://github.com/vliaskov/seabios/commits/memhp-v2
> https://github.com/vliaskov/qemu-kvm/commits/memhp-v2
> 
> I have not posted the PS3 patches yet in the qemu list, but will post them
> soon for v3 of the memory hotplug series. If you have issues testing, let me
> know.

Hmm, seabios doesn't support ACPI table SLIT. We can specify node it for dimm
device, so I think we should support SLIT in seabios. Otherwise we may meet
the following kernel messages:
[  325.016769] init_memory_mapping: [mem 0x40000000-0x5fffffff]
[  325.018060]  [mem 0x40000000-0x5fffffff] page 2M
[  325.019168] [ffffea0001000000-ffffea00011fffff] potential offnode page_structs
[  325.024172] [ffffea0001200000-ffffea00013fffff] potential offnode page_structs
[  325.028596]  [ffffea0001400000-ffffea00017fffff] PMD -> [ffff880035000000-ffff8800353fffff] on node 1
[  325.031775] [ffffea0001600000-ffffea00017fffff] potential offnode page_structs

Do you have plan to do it?

Thanks
Wen Congyang

> 
> thanks,
> 
> - Vasilis
> 

^ permalink raw reply

* Re: [RFC v8 PATCH 00/20] memory-hotplug: hot-remove physical memory
From: Minchan Kim @ 2012-09-12  6:17 UTC (permalink / raw)
  To: Jerry
  Cc: linux-s390, linux-ia64, Wen Congyang, linux-acpi, linux-sh,
	len.brown, x86, linux-kernel, cmetcalf, Vasilis Liaskovitis,
	linux-mm, Yasuaki Ishimatsu, paulus, kosaki.motohiro, rientjes,
	sparclinux, Andrew Morton, linuxppc-dev, cl, liuj97
In-Reply-To: <CAAV+Mu4hb0qbW2Ry6w5FAGUM06puDH0v_H-jr584-G9CzJqSGw@mail.gmail.com>

On Tue, Sep 11, 2012 at 01:18:24PM +0800, Jerry wrote:
> Hi Kim,
> 
> Thank you for your kindness. Let me clarify this:
> 
> On ARM architecture, there are 32 bits physical addresses space. However,
> the addresses space is divided into 8 banks normally. Each bank
> disabled/enabled by a chip selector signal. In my platform, bank0 connects
> a DDR chip, and bank1 also connects another DDR chip. And each DDR chip
> whose capability is 512MB is integrated into the main board. So, it could
> not be removed by hand. We can disable/enable each bank by peripheral
> device controller registers.
> 
> When system enter suspend state, if all the pages allocated could be
> migrated to one bank, there are no valid data in the another bank. In this
> time, I could disable the free bank. It isn't necessary to provided power
> to this chip in the suspend state. When system resume, I just need to
> enable it again.
> 

Yes. I already know it and other trials for that a few years ago[1].
A few years ago, I investigated the benefit between power consumption
benefit during suspend VS start-up latency of resume and
power consumption cost of migration(page migration and IO write for
migration) and concluded normally the gain is not big. :)
The situation could be changed these days as workload are changing
but I'm skeptical about that approach, still.

Anyway, it's my private thought so you don't need to care about that.
If you are ready to submit the patchset, please send out.

1. http://lwn.net/Articles/478049/

Thanks.

- 
Kind regards,
Minchan Kim

^ permalink raw reply

* RE: [PATCH 2/3] powerpc/esdhc: add property to disable the CMD23
From: Huang Changming-R66093 @ 2012-09-12  6:18 UTC (permalink / raw)
  To: Chris Ball, Kumar Gala
  Cc: linux-mmc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org list,
	Anton Vorontsov
In-Reply-To: <87liggwa1w.fsf@octavius.laptop.org>



Best Regards
Jerry Huang


> -----Original Message-----
> From: Chris Ball [mailto:cjb@laptop.org]
> Sent: Wednesday, September 12, 2012 4:59 AM
> To: Kumar Gala
> Cc: Huang Changming-R66093; linuxppc-dev@lists.ozlabs.org list; linux-
> mmc@vger.kernel.org; Anton Vorontsov
> Subject: Re: [PATCH 2/3] powerpc/esdhc: add property to disable the CMD23
>=20
> Hi,
>=20
> On Tue, Sep 11 2012, Kumar Gala wrote:
> > thanks for the info.  Do you know what's required on controller side
> > to handle cards that support CMD23?
> >
> > I'm trying to figure out if older controller's on FSL SoCs are missing
> > some feature to allow CMD23 to work (vs Auto-CMD23).
>=20
> It seems plausible that it's just not implemented on these controllers.
> It's a little strange, since the command's been specified for so long and
> we haven't seen any other controllers with problems.  The patch would be
> correct if this is true.
>=20

I didn't find any description about it, but after testing on FSL silicones,=
 I got this result:
Some silicones support this command, and some silicones don't support it, w=
hich will cause I/O error.

^ permalink raw reply

* [PATCH] powerpc: Add an xmon command to dump one or all pacas
From: Michael Ellerman @ 2012-09-12  7:52 UTC (permalink / raw)
  To: linuxppc-dev

This was originally motivated by a desire to see the mapping between
logical and hardware cpu numbers.

But it seemed that it made more sense to just add a command to dump
(most of) the paca.

With no arguments "dp" will dump the paca for all possible cpus. If
there are no possible cpus, like early in boot, it will tell you that.

It also takes an argument, eg. "dp 3" which is the logical cpu number
in hex. This form does not check if the cpu is possible, but displays
the paca regardless, as well as the cpu's state in the possible, present
and online masks.

Sample output, number in brackets is the offset into the struct:

2:mon> dp 3
paca for cpu 0x3 @ c00000000ff20a80:
 possible         = yes
 present          = yes
 online           = yes
 lock_token       = 0x8000            	(0x8)
 paca_index       = 0x3               	(0xa)
 kernel_toc       = 0xc00000000144f990	(0x10)
 kernelbase       = 0xc000000000000000	(0x18)
 kernel_msr       = 0xb000000000001032	(0x20)
 stab_real        = 0x0               	(0x28)
 stab_addr        = 0x0               	(0x30)
 emergency_sp     = 0xc00000003ffe4000	(0x38)
 data_offset      = 0xa40000          	(0x40)
 hw_cpu_id        = 0x9               	(0x50)
 cpu_start        = 0x1               	(0x52)
 kexec_state      = 0x0               	(0x53)
 __current        = 0xc00000007e568680	(0x218)
 kstack           = 0xc00000007e5a3e30	(0x220)
 stab_rr          = 0x1a              	(0x228)
 saved_r1         = 0xc00000007e7cb450	(0x230)
 trap_save        = 0x0               	(0x240)
 soft_enabled     = 0x0               	(0x242)
 irq_happened     = 0x0               	(0x243)
 io_sync          = 0x0               	(0x244)
 irq_work_pending = 0x0               	(0x245)
 nap_state_lost   = 0x0               	(0x246)

Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
 arch/powerpc/xmon/xmon.c |   83 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index eab3492..f090c46 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -202,6 +202,7 @@ Commands:\n\
   df	dump float values\n\
   dd	dump double values\n\
   dl    dump the kernel log buffer\n\
+  dp #  dump paca for cpu # (or all)\n\
   dr	dump stream of raw bytes\n\
   e	print exception information\n\
   f	flush cache\n\
@@ -2008,6 +2009,82 @@ static void xmon_rawdump (unsigned long adrs, long ndump)
 	printf("\n");
 }
 
+static void dump_one_paca(int cpu)
+{
+	struct paca_struct *p;
+
+	if (setjmp(bus_error_jmp) != 0) {
+		printf("*** Error dumping paca for cpu 0x%x!\n", cpu);
+		return;
+	}
+
+	catch_memory_errors = 1;
+	sync();
+
+	p = &paca[cpu];
+
+	printf("paca for cpu 0x%x @ %p:\n", cpu, p);
+
+	printf(" %-*s = %s\n", 16, "possible", cpu_possible(cpu) ? "yes" : "no");
+	printf(" %-*s = %s\n", 16, "present", cpu_present(cpu) ? "yes" : "no");
+	printf(" %-*s = %s\n", 16, "online", cpu_online(cpu) ? "yes" : "no");
+
+#define DUMP(name, format) \
+	printf(" %-*s = %#-*"format"\t(0x%lx)\n", 16, #name, 18, p->name, \
+		(u64)((void *)&(p->name) - (void *)p));
+
+	DUMP(lock_token, "x");
+	DUMP(paca_index, "x");
+	DUMP(kernel_toc, "lx");
+	DUMP(kernelbase, "lx");
+	DUMP(kernel_msr, "lx");
+#ifdef CONFIG_PPC_STD_MMU_64
+	DUMP(stab_real, "lx");
+	DUMP(stab_addr, "lx");
+#endif
+	DUMP(emergency_sp, "p");
+	DUMP(data_offset, "lx");
+	DUMP(hw_cpu_id, "x");
+	DUMP(cpu_start, "x");
+	DUMP(kexec_state, "x");
+	DUMP(__current, "p");
+	DUMP(kstack, "lx");
+	DUMP(stab_rr, "lx");
+	DUMP(saved_r1, "lx");
+	DUMP(trap_save, "x");
+	DUMP(soft_enabled, "x");
+	DUMP(irq_happened, "x");
+	DUMP(io_sync, "x");
+	DUMP(irq_work_pending, "x");
+	DUMP(nap_state_lost, "x");
+
+#undef DUMP
+
+	catch_memory_errors = 0;
+	sync();
+}
+
+static void dump_pacas(void)
+{
+	unsigned long num = ULONG_MAX;
+	int cpu;
+
+	scanhex(&num);
+	if (num != ULONG_MAX) {
+		/* NB we allow showing a non-possible paca here */
+		dump_one_paca(num);
+		return;
+	}
+
+	if (num_possible_cpus() == 0) {
+		printf("No possible cpus, use 'dp #' to dump individual cpus\n");
+		return;
+	}
+
+	for_each_possible_cpu(cpu)
+		dump_one_paca(cpu);
+}
+
 #define isxdigit(c)	(('0' <= (c) && (c) <= '9') \
 			 || ('a' <= (c) && (c) <= 'f') \
 			 || ('A' <= (c) && (c) <= 'F'))
@@ -2017,6 +2094,12 @@ dump(void)
 	int c;
 
 	c = inchar();
+
+	if (c == 'p') {
+		dump_pacas();
+		return;
+	}
+
 	if ((isxdigit(c) && c != 'f' && c != 'd') || c == '\n')
 		termch = c;
 	scanhex((void *)&adrs);
-- 
1.7.9.5

^ permalink raw reply related

* Re: [v3][PATCH 2/3] ppc/kprobe: complete kprobe and migrate exception frame
From: tiejun.chen @ 2012-09-12  8:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1347342718.2603.38.camel@pasglop>

On 09/11/2012 01:51 PM, Benjamin Herrenschmidt wrote:
> On Tue, 2012-09-11 at 10:20 +0800, Tiejun Chen wrote:
>> We can't emulate stwu since that may corrupt current exception stack.
>> So we will have to do real store operation in the exception return code.
>>
>> Firstly we'll allocate a trampoline exception frame below the kprobed
>> function stack and copy the current exception frame to the trampoline.
>> Then we can do this real store operation to implement 'stwu', and reroute
>> the trampoline frame to r1 to complete this exception migration.
>
> Ok, so not quite there yet :-)
>
> See below:
>
>> Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
>> ---
>>   arch/powerpc/kernel/entry_32.S |   45 ++++++++++++++++++++++++++++++++++------
>>   arch/powerpc/kernel/entry_64.S |   32 ++++++++++++++++++++++++++++
>>   2 files changed, 71 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
>> index ead5016..6cfe12f 100644
>> --- a/arch/powerpc/kernel/entry_32.S
>> +++ b/arch/powerpc/kernel/entry_32.S
>> @@ -831,19 +831,54 @@ restore_user:
>>   	bnel-	load_dbcr0
>>   #endif
>>
>> -#ifdef CONFIG_PREEMPT
>>   	b	restore
>>
>>   /* N.B. the only way to get here is from the beq following ret_from_except. */
>>   resume_kernel:
>> +	/* check current_thread_info, _TIF_EMULATE_STACK_STORE */
>> +	CURRENT_THREAD_INFO(r9, r1)
>> +	lwz	r0,TI_FLAGS(r9)
>> +	andis.	r0,r0,_TIF_EMULATE_STACK_STORE@h
>> +	beq+	1f
>
> So you used r0 to load the TI_FLAGS and immediately clobbered it in
> andis. forcing you to re-load them later down. Instead, put them in r8
>
> 	lwz	r8,TI_FLAGS(r9)
> 	andis.	r0,r8,_TIF_*
> 	beq+	*
>
>> +	addi	r8,r1,INT_FRAME_SIZE	/* Get the kprobed function entry */
>
> Then you put your entry in r8 ....

I'll update this for 32b and 64b sections.

>
>> +	lwz	r3,GPR1(r1)
>> +	subi	r3,r3,INT_FRAME_SIZE	/* dst: Allocate a trampoline exception frame */
>> +	mr	r4,r1			/* src:  current exception frame */
>> +	li	r5,INT_FRAME_SIZE	/* size: INT_FRAME_SIZE */
>> +	mr	r1,r3			/* Reroute the trampoline frame to r1 */
>> +	bl	memcpy			/* Copy from the original to the trampoline */
>
> Which you just clobbered... oops :-)
>
> So you need to store that old r1 somewhere fist then retrieve it
> after the memcpy call. That or open-code the memcpy to avoid all
> the clobbering problems.

Maybe we can use copy_and_flush() since looks copy_and_flush() only clobber r0, 
r6 and LR explicitly.

I'll resync these comments for v4.

Tiejun

^ permalink raw reply

* [v4][PATCH 1/4] powerpc/kprobe: introduce a new thread flag
From: Tiejun Chen @ 2012-09-12  8:42 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev

We need to add a new thread flag, TIF_EMULATE_STACK_STORE,
for emulating stack store operation while exiting exception.

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
 arch/powerpc/include/asm/thread_info.h |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/arch/powerpc/include/asm/thread_info.h b/arch/powerpc/include/asm/thread_info.h
index e942203..8ceea14 100644
--- a/arch/powerpc/include/asm/thread_info.h
+++ b/arch/powerpc/include/asm/thread_info.h
@@ -104,6 +104,8 @@ static inline struct thread_info *current_thread_info(void)
 #define TIF_NOTIFY_RESUME	13	/* callback before returning to user */
 #define TIF_UPROBE		14	/* breakpointed or single-stepping */
 #define TIF_SYSCALL_TRACEPOINT	15	/* syscall tracepoint instrumentation */
+#define TIF_EMULATE_STACK_STORE	16	/* Is an instruction emulation
+						for stack store? */
 
 /* as above, but as bit values */
 #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)
@@ -121,6 +123,7 @@ static inline struct thread_info *current_thread_info(void)
 #define _TIF_NOTIFY_RESUME	(1<<TIF_NOTIFY_RESUME)
 #define _TIF_UPROBE		(1<<TIF_UPROBE)
 #define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)
+#define _TIF_EMULATE_STACK_STORE	(1<<TIF_EMULATE_STACK_STORE)
 #define _TIF_SYSCALL_T_OR_A	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
 				 _TIF_SECCOMP | _TIF_SYSCALL_TRACEPOINT)
 
-- 
1.7.9.5

^ permalink raw reply related

* [v4][PATCH 2/4] powerpc/ppc32: make copy_and_flush() as global
From: Tiejun Chen @ 2012-09-12  8:42 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev
In-Reply-To: <1347439325-5563-1-git-send-email-tiejun.chen@windriver.com>

Somewhere we need this simple copy_and_flush().

Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
---
 arch/powerpc/kernel/entry_32.S |   27 +++++++++++++++++++++++++++
 arch/powerpc/kernel/head_32.S  |   26 --------------------------
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index ead5016..1536d2c 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -32,6 +32,7 @@
 #include <asm/unistd.h>
 #include <asm/ftrace.h>
 #include <asm/ptrace.h>
+#include <asm/cache.h>
 
 #undef SHOW_SYSCALLS
 #undef SHOW_SYSCALLS_TASK
@@ -1265,6 +1266,32 @@ ee_restarts:
 	.previous
 
 /*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ */
+_GLOBAL(copy_and_flush)
+	addi	r5,r5,-4
+	addi	r6,r6,-4
+4:	li	r0,L1_CACHE_BYTES/4
+	mtctr	r0
+3:	addi	r6,r6,4			/* copy a cache line */
+	lwzx	r0,r6,r4
+	stwx	r0,r6,r3
+	bdnz	3b
+	dcbst	r6,r3			/* write it to memory */
+	sync
+	icbi	r6,r3			/* flush the icache line */
+	cmplw	0,r6,r5
+	blt	4b
+	sync				/* additional sync needed on g4 */
+	isync
+	addi	r5,r5,4
+	addi	r6,r6,4
+	blr
+
+/*
  * PROM code for specific machines follows.  Put it
  * here so it's easy to add arch-specific sections later.
  * -- Cort
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index dc0488b..14ea361 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -777,32 +777,6 @@ relocate_kernel:
 	bl	copy_and_flush		/* copy the rest */
 	b	turn_on_mmu
 
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- */
-_ENTRY(copy_and_flush)
-	addi	r5,r5,-4
-	addi	r6,r6,-4
-4:	li	r0,L1_CACHE_BYTES/4
-	mtctr	r0
-3:	addi	r6,r6,4			/* copy a cache line */
-	lwzx	r0,r6,r4
-	stwx	r0,r6,r3
-	bdnz	3b
-	dcbst	r6,r3			/* write it to memory */
-	sync
-	icbi	r6,r3			/* flush the icache line */
-	cmplw	0,r6,r5
-	blt	4b
-	sync				/* additional sync needed on g4 */
-	isync
-	addi	r5,r5,4
-	addi	r6,r6,4
-	blr
-
 #ifdef CONFIG_SMP
 	.globl __secondary_start_mpc86xx
 __secondary_start_mpc86xx:
-- 
1.7.9.5

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox