* Re: Add support for the currituck 476 platform from IBM (v2)
From: Tony Breeds @ 2011-12-01 7:43 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Josh Boyer; +Cc: LinuxPPC-dev
In-Reply-To: <1322725164-4391-1-git-send-email-tony@bakeyournoodle.com>
[-- Attachment #1: Type: text/plain, Size: 1462 bytes --]
On Thu, Dec 01, 2011 at 06:39:16PM +1100, Tony Breeds wrote:
> Patches 1 to 3
> Modify the 44x PCI code to work with 476fpe/currituck.
> Patch 4
> Is an old patch by Christoph Egger that fell through the cracks somehow.
> Patches 5 and 6
> Modify the bootwrapper to handle 476fpe/currituck
> Patch 7
> The SoC support.
> Patch 8
> The currituck board support.
Sorry I forgot the diffstat
arch/powerpc/boot/Makefile | 5 +-
arch/powerpc/boot/dcr.h | 6 +
arch/powerpc/boot/div64.S | 52 ++++++
arch/powerpc/boot/dts/currituck.dts | 237 ++++++++++++++++++++++++++
arch/powerpc/boot/treeboot-currituck.c | 119 +++++++++++++
arch/powerpc/boot/wrapper | 3 +
arch/powerpc/configs/44x/currituck_defconfig | 110 ++++++++++++
arch/powerpc/include/asm/reg.h | 1 +
arch/powerpc/kernel/cputable.c | 14 ++
arch/powerpc/kernel/head_44x.S | 2 +
arch/powerpc/mm/44x_mmu.c | 4 -
arch/powerpc/platforms/44x/Kconfig | 14 ++
arch/powerpc/platforms/44x/Makefile | 1 +
arch/powerpc/platforms/44x/currituck.c | 204 ++++++++++++++++++++++
arch/powerpc/sysdev/ppc4xx_pci.c | 85 +++++++++-
arch/powerpc/sysdev/ppc4xx_pci.h | 7 +
16 files changed, 851 insertions(+), 13 deletions(-)
Yours Tony
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply
* [PATCH net-next v6 4/4] powerpc: tqm8548/tqm8xx: add and update CAN device nodes
From: Wolfgang Grandegger @ 2011-12-01 9:41 UTC (permalink / raw)
To: netdev; +Cc: devicetree-discuss, linux-can, linuxppc-dev, socketcan-users
In-Reply-To: <1322732481-2255-1-git-send-email-wg@grandegger.com>
This patch enables or updates support for the CC770 and AN82527
CAN controller on the TQM8548 and TQM8xx boards.
CC: devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
---
arch/powerpc/boot/dts/tqm8548-bigflash.dts | 19 ++++++++++++++-----
arch/powerpc/boot/dts/tqm8548.dts | 19 ++++++++++++++-----
arch/powerpc/boot/dts/tqm8xx.dts | 25 +++++++++++++++++++++++++
3 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/boot/dts/tqm8548-bigflash.dts b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
index 9452c3c..d918752 100644
--- a/arch/powerpc/boot/dts/tqm8548-bigflash.dts
+++ b/arch/powerpc/boot/dts/tqm8548-bigflash.dts
@@ -352,7 +352,7 @@
ranges = <
0 0x0 0xfc000000 0x04000000 // NOR FLASH bank 1
1 0x0 0xf8000000 0x08000000 // NOR FLASH bank 0
- 2 0x0 0xa3000000 0x00008000 // CAN (2 x i82527)
+ 2 0x0 0xa3000000 0x00008000 // CAN (2 x CC770)
3 0x0 0xa3010000 0x00008000 // NAND FLASH
>;
@@ -393,18 +393,27 @@
};
/* Note: CAN support needs be enabled in U-Boot */
- can0@2,0 {
- compatible = "intel,82527"; // Bosch CC770
+ can@2,0 {
+ compatible = "bosch,cc770"; // Bosch CC770
reg = <2 0x0 0x100>;
interrupts = <4 1>;
interrupt-parent = <&mpic>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
+ bosch,clock-out-frequency = <16000000>;
};
- can1@2,100 {
- compatible = "intel,82527"; // Bosch CC770
+ can@2,100 {
+ compatible = "bosch,cc770"; // Bosch CC770
reg = <2 0x100 0x100>;
interrupts = <4 1>;
interrupt-parent = <&mpic>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
};
/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8548.dts b/arch/powerpc/boot/dts/tqm8548.dts
index 619776f..988d887 100644
--- a/arch/powerpc/boot/dts/tqm8548.dts
+++ b/arch/powerpc/boot/dts/tqm8548.dts
@@ -352,7 +352,7 @@
ranges = <
0 0x0 0xfc000000 0x04000000 // NOR FLASH bank 1
1 0x0 0xf8000000 0x08000000 // NOR FLASH bank 0
- 2 0x0 0xe3000000 0x00008000 // CAN (2 x i82527)
+ 2 0x0 0xe3000000 0x00008000 // CAN (2 x CC770)
3 0x0 0xe3010000 0x00008000 // NAND FLASH
>;
@@ -393,18 +393,27 @@
};
/* Note: CAN support needs be enabled in U-Boot */
- can0@2,0 {
- compatible = "intel,82527"; // Bosch CC770
+ can@2,0 {
+ compatible = "bosch,cc770"; // Bosch CC770
reg = <2 0x0 0x100>;
interrupts = <4 1>;
interrupt-parent = <&mpic>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
+ bosch,clock-out-frequency = <16000000>;
};
- can1@2,100 {
- compatible = "intel,82527"; // Bosch CC770
+ can@2,100 {
+ compatible = "bosch,cc770"; // Bosch CC770
reg = <2 0x100 0x100>;
interrupts = <4 1>;
interrupt-parent = <&mpic>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
};
/* Note: NAND support needs to be enabled in U-Boot */
diff --git a/arch/powerpc/boot/dts/tqm8xx.dts b/arch/powerpc/boot/dts/tqm8xx.dts
index f6da7ec..c3dba25 100644
--- a/arch/powerpc/boot/dts/tqm8xx.dts
+++ b/arch/powerpc/boot/dts/tqm8xx.dts
@@ -57,6 +57,7 @@
ranges = <
0x0 0x0 0x40000000 0x800000
+ 0x3 0x0 0xc0000000 0x200
>;
flash@0,0 {
@@ -67,6 +68,30 @@
bank-width = <4>;
device-width = <2>;
};
+
+ /* Note: CAN support needs be enabled in U-Boot */
+ can@3,0 {
+ compatible = "intc,82527";
+ reg = <3 0x0 0x80>;
+ interrupts = <8 1>;
+ interrupt-parent = <&PIC>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
+ bosch,clock-out-frequency = <16000000>;
+ };
+
+ can@3,100 {
+ compatible = "intc,82527";
+ reg = <3 0x100 0x80>;
+ interrupts = <8 1>;
+ interrupt-parent = <&PIC>;
+ bosch,external-clock-frequency = <16000000>;
+ bosch,disconnect-rx1-input;
+ bosch,disconnect-tx1-output;
+ bosch,iso-low-speed-mux;
+ };
};
soc@fff00000 {
--
1.7.4.1
^ permalink raw reply related
* [PATCH net-next v6 3/4] can: cc770: add platform bus driver for the CC770 and AN82527
From: Wolfgang Grandegger @ 2011-12-01 9:41 UTC (permalink / raw)
To: netdev; +Cc: Devicetree-discuss, linux-can, linuxppc-dev, socketcan-users
In-Reply-To: <1322732481-2255-1-git-send-email-wg@grandegger.com>
This driver works with both, static platform data and device tree
bindings. It has been tested on a TQM855L board with two AN82527
CAN controllers on the local bus.
CC: Devicetree-discuss@lists.ozlabs.org
CC: linuxppc-dev@ozlabs.org
CC: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
.../devicetree/bindings/net/can/cc770.txt | 53 ++++
drivers/net/can/cc770/Kconfig | 7 +
drivers/net/can/cc770/Makefile | 1 +
drivers/net/can/cc770/cc770_platform.c | 272 ++++++++++++++++++++
4 files changed, 333 insertions(+), 0 deletions(-)
create mode 100644 Documentation/devicetree/bindings/net/can/cc770.txt
create mode 100644 drivers/net/can/cc770/cc770_platform.c
diff --git a/Documentation/devicetree/bindings/net/can/cc770.txt b/Documentation/devicetree/bindings/net/can/cc770.txt
new file mode 100644
index 0000000..77027bf
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/can/cc770.txt
@@ -0,0 +1,53 @@
+Memory mapped Bosch CC770 and Intel AN82527 CAN controller
+
+Note: The CC770 is a CAN controller from Bosch, which is 100%
+compatible with the old AN82527 from Intel, but with "bugs" being fixed.
+
+Required properties:
+
+- compatible : should be "bosch,cc770" for the CC770 and "intc,82527"
+ for the AN82527.
+
+- reg : should specify the chip select, address offset and size required
+ to map the registers of the controller. The size is usually 0x80.
+
+- interrupts : property with a value describing the interrupt source
+ (number and sensitivity) required for the controller.
+
+Optional properties:
+
+- bosch,external-clock-frequency : frequency of the external oscillator
+ clock in Hz. Note that the internal clock frequency used by the
+ controller is half of that value. If not specified, a default
+ value of 16000000 (16 MHz) is used.
+
+- bosch,clock-out-frequency : slock frequency in Hz on the CLKOUT pin.
+ If not specified or if the specified value is 0, the CLKOUT pin
+ will be disabled.
+
+- bosch,slew-rate : slew rate of the CLKOUT signal. If not specified,
+ a resonable value will be calculated.
+
+- bosch,disconnect-rx0-input : see data sheet.
+
+- bosch,disconnect-rx1-input : see data sheet.
+
+- bosch,disconnect-tx1-output : see data sheet.
+
+- bosch,polarity-dominant : see data sheet.
+
+- bosch,divide-memory-clock : see data sheet.
+
+- bosch,iso-low-speed-mux : see data sheet.
+
+For further information, please have a look to the CC770 or AN82527.
+
+Examples:
+
+can@3,100 {
+ compatible = "bosch,cc770";
+ reg = <3 0x100 0x80>;
+ interrupts = <2 0>;
+ interrupt-parent = <&mpic>;
+ bosch,external-clock-frequency = <16000000>;
+};
diff --git a/drivers/net/can/cc770/Kconfig b/drivers/net/can/cc770/Kconfig
index 28e4d48..22c07a8 100644
--- a/drivers/net/can/cc770/Kconfig
+++ b/drivers/net/can/cc770/Kconfig
@@ -11,4 +11,11 @@ config CAN_CC770_ISA
connected to the ISA bus using I/O port, memory mapped or
indirect access.
+config CAN_CC770_PLATFORM
+ tristate "Generic Platform Bus based CC770 driver"
+ ---help---
+ This driver adds support for the CC770 and AN82527 chips
+ connected to the "platform bus" (Linux abstraction for directly
+ to the processor attached devices).
+
endif
diff --git a/drivers/net/can/cc770/Makefile b/drivers/net/can/cc770/Makefile
index 872ecff..9fb8321 100644
--- a/drivers/net/can/cc770/Makefile
+++ b/drivers/net/can/cc770/Makefile
@@ -4,5 +4,6 @@
obj-$(CONFIG_CAN_CC770) += cc770.o
obj-$(CONFIG_CAN_CC770_ISA) += cc770_isa.o
+obj-$(CONFIG_CAN_CC770_PLATFORM) += cc770_platform.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/cc770/cc770_platform.c b/drivers/net/can/cc770/cc770_platform.c
new file mode 100644
index 0000000..53115ee
--- /dev/null
+++ b/drivers/net/can/cc770/cc770_platform.c
@@ -0,0 +1,272 @@
+/*
+ * Driver for CC770 and AN82527 CAN controllers on the platform bus
+ *
+ * Copyright (C) 2009, 2011 Wolfgang Grandegger <wg@grandegger.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the version 2 of the GNU General Public License
+ * as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * If platform data are used you should have similar definitions
+ * in your board-specific code:
+ *
+ * static struct cc770_platform_data myboard_cc770_pdata = {
+ * .osc_freq = 16000000,
+ * .cir = 0x41,
+ * .cor = 0x20,
+ * .bcr = 0x40,
+ * };
+ *
+ * Please see include/linux/can/platform/cc770.h for description of
+ * above fields.
+ *
+ * If the device tree is used, you need a CAN node definition in your
+ * DTS file similar to:
+ *
+ * can@3,100 {
+ * compatible = "bosch,cc770";
+ * reg = <3 0x100 0x80>;
+ * interrupts = <2 0>;
+ * interrupt-parent = <&mpic>;
+ * bosch,external-clock-frequency = <16000000>;
+ * };
+ *
+ * See "Documentation/devicetree/bindings/net/can/cc770.txt" for further
+ * information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/can.h>
+#include <linux/can/dev.h>
+#include <linux/can/platform/cc770.h>
+
+#include "cc770.h"
+
+#define DRV_NAME "cc770_platform"
+
+MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>");
+MODULE_DESCRIPTION("Socket-CAN driver for CC770 on the platform bus");
+MODULE_LICENSE("GPL v2");
+
+#define CC770_PLATFORM_CAN_CLOCK 16000000
+
+static u8 cc770_platform_read_reg(const struct cc770_priv *priv, int reg)
+{
+ return ioread8(priv->reg_base + reg);
+}
+
+static void cc770_platform_write_reg(const struct cc770_priv *priv, int reg,
+ u8 val)
+{
+ iowrite8(val, priv->reg_base + reg);
+}
+
+static int __devinit cc770_get_of_node_data(struct platform_device *pdev,
+ struct cc770_priv *priv)
+{
+ struct device_node *np = pdev->dev.of_node;
+ const u32 *prop;
+ int prop_size;
+ u32 clkext;
+
+ prop = of_get_property(np, "bosch,external-clock-frequency",
+ &prop_size);
+ if (prop && (prop_size == sizeof(u32)))
+ clkext = *prop;
+ else
+ clkext = CC770_PLATFORM_CAN_CLOCK; /* default */
+ priv->can.clock.freq = clkext;
+
+ /* The system clock may not exceed 10 MHz */
+ if (priv->can.clock.freq > 10000000) {
+ priv->cpu_interface |= CPUIF_DSC;
+ priv->can.clock.freq /= 2;
+ }
+
+ /* The memory clock may not exceed 8 MHz */
+ if (priv->can.clock.freq > 8000000)
+ priv->cpu_interface |= CPUIF_DMC;
+
+ if (of_get_property(np, "bosch,divide-memory-clock", NULL))
+ priv->cpu_interface |= CPUIF_DMC;
+ if (of_get_property(np, "bosch,iso-low-speed-mux", NULL))
+ priv->cpu_interface |= CPUIF_MUX;
+
+ if (!of_get_property(np, "bosch,no-comperator-bypass", NULL))
+ priv->bus_config |= BUSCFG_CBY;
+ if (of_get_property(np, "bosch,disconnect-rx0-input", NULL))
+ priv->bus_config |= BUSCFG_DR0;
+ if (of_get_property(np, "bosch,disconnect-rx1-input", NULL))
+ priv->bus_config |= BUSCFG_DR1;
+ if (of_get_property(np, "bosch,disconnect-tx1-output", NULL))
+ priv->bus_config |= BUSCFG_DT1;
+ if (of_get_property(np, "bosch,polarity-dominant", NULL))
+ priv->bus_config |= BUSCFG_POL;
+
+ prop = of_get_property(np, "bosch,clock-out-frequency", &prop_size);
+ if (prop && (prop_size == sizeof(u32)) && *prop > 0) {
+ u32 cdv = clkext / *prop;
+ int slew;
+
+ if (cdv > 0 && cdv < 16) {
+ priv->cpu_interface |= CPUIF_CEN;
+ priv->clkout |= (cdv - 1) & CLKOUT_CD_MASK;
+
+ prop = of_get_property(np, "bosch,slew-rate",
+ &prop_size);
+ if (prop && (prop_size == sizeof(u32))) {
+ slew = *prop;
+ } else {
+ /* Determine default slew rate */
+ slew = (CLKOUT_SL_MASK >>
+ CLKOUT_SL_SHIFT) -
+ ((cdv * clkext - 1) / 8000000);
+ if (slew < 0)
+ slew = 0;
+ }
+ priv->clkout |= (slew << CLKOUT_SL_SHIFT) &
+ CLKOUT_SL_MASK;
+ } else {
+ dev_dbg(&pdev->dev, "invalid clock-out-frequency\n");
+ }
+ }
+
+ return 0;
+}
+
+static int __devinit cc770_get_platform_data(struct platform_device *pdev,
+ struct cc770_priv *priv)
+{
+
+ struct cc770_platform_data *pdata = pdev->dev.platform_data;
+
+ priv->can.clock.freq = pdata->osc_freq;
+ if (priv->cpu_interface | CPUIF_DSC)
+ priv->can.clock.freq /= 2;
+ priv->clkout = pdata->cor;
+ priv->bus_config = pdata->bcr;
+ priv->cpu_interface = pdata->cir;
+
+ return 0;
+}
+
+static int __devinit cc770_platform_probe(struct platform_device *pdev)
+{
+ struct net_device *dev;
+ struct cc770_priv *priv;
+ struct resource *mem;
+ resource_size_t mem_size;
+ void __iomem *base;
+ int err, irq;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!mem || irq <= 0)
+ return -ENODEV;
+
+ mem_size = resource_size(mem);
+ if (!request_mem_region(mem->start, mem_size, pdev->name))
+ return -EBUSY;
+
+ base = ioremap(mem->start, mem_size);
+ if (!base) {
+ err = -ENOMEM;
+ goto exit_release_mem;
+ }
+
+ dev = alloc_cc770dev(0);
+ if (!dev) {
+ err = -ENOMEM;
+ goto exit_unmap_mem;
+ }
+
+ dev->irq = irq;
+ priv = netdev_priv(dev);
+ priv->read_reg = cc770_platform_read_reg;
+ priv->write_reg = cc770_platform_write_reg;
+ priv->irq_flags = IRQF_SHARED;
+ priv->reg_base = base;
+
+ if (pdev->dev.of_node)
+ err = cc770_get_of_node_data(pdev, priv);
+ else if (pdev->dev.platform_data)
+ err = cc770_get_platform_data(pdev, priv);
+ else
+ err = -ENODEV;
+ if (err)
+ goto exit_free_cc770;
+
+ dev_dbg(&pdev->dev,
+ "reg_base=0x%p irq=%d clock=%d cpu_interface=0x%02x "
+ "bus_config=0x%02x clkout=0x%02x\n",
+ priv->reg_base, dev->irq, priv->can.clock.freq,
+ priv->cpu_interface, priv->bus_config, priv->clkout);
+
+ dev_set_drvdata(&pdev->dev, dev);
+ SET_NETDEV_DEV(dev, &pdev->dev);
+
+ err = register_cc770dev(dev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "couldn't register CC700 device (err=%d)\n", err);
+ goto exit_free_cc770;
+ }
+
+ return 0;
+
+exit_free_cc770:
+ free_cc770dev(dev);
+exit_unmap_mem:
+ iounmap(base);
+exit_release_mem:
+ release_mem_region(mem->start, mem_size);
+
+ return err;
+}
+
+static int __devexit cc770_platform_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = dev_get_drvdata(&pdev->dev);
+ struct cc770_priv *priv = netdev_priv(dev);
+ struct resource *mem;
+
+ unregister_cc770dev(dev);
+ iounmap(priv->reg_base);
+ free_cc770dev(dev);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+
+ return 0;
+}
+
+static struct of_device_id __devinitdata cc770_platform_table[] = {
+ {.compatible = "bosch,cc770"}, /* CC770 from Bosch */
+ {.compatible = "intc,82527"}, /* AN82527 from Intel CP */
+ {},
+};
+
+static struct platform_driver cc770_platform_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = cc770_platform_table,
+ },
+ .probe = cc770_platform_probe,
+ .remove = __devexit_p(cc770_platform_remove),
+};
+
+module_platform_driver(cc770_platform_driver);
--
1.7.4.1
^ permalink raw reply related
* Different behaviour when using "nosmp" parameter on SMP and UP
From: Jean-Michel Hautbois @ 2011-12-01 9:57 UTC (permalink / raw)
To: linux-kernel; +Cc: linuxppc-dev
Hi,
I have a P2020 CPU (powerpc) and I compiled it with two different defconfigs.
The first one is a SMP, 2 cores, launched with the "nosmp" kernel
parameter, the other one is an UP kernel.
My driver behaviour is not the same whether launching one or the
other. It is hard to explain more precisely, as it deals only with
ioctl which only does ioread32/iowrite32 on a PCIe device.
But I can tell that it never works the same way when UP (not working
correctly), or SMP "nosmp" (working) or even SMP (not working).
AFAIK, the "nosmp" parameter should tell the kernel to act the same is
if it is an UP kernel, and it disables IO APIC, which is not an issue
in my case.
Can you think about anything that would explain it, or would help me
debugging it ?
Thanks in advance for your help.
Regards,
JM
^ permalink raw reply
* Re: [PATCH 1/2] [hw-breakpoint] Use generic hw-breakpoint interfaces for new PPC ptrace flags
From: K.Prasad @ 2011-12-01 10:20 UTC (permalink / raw)
To: linuxppc-dev, David Gibson
Cc: linuxppc-dev, Thiago Jung Bauermann, Edjunior Barbosa Machado
In-Reply-To: <20111128031111.GC3508@truffala.fritz.box>
On Mon, Nov 28, 2011 at 02:11:11PM +1100, David Gibson wrote:
> [snip]
> On Wed, Oct 12, 2011 at 11:09:48PM +0530, K.Prasad wrote:
> > > > + if (bp) {
> > > > + attr = bp->attr;
> > > > + attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
> > > > + arch_bp_generic_fields(dabr &
> > > > + (DABR_DATA_WRITE | DABR_DATA_READ),
> > > > + &attr.bp_type);
> > > > + attr.bp_len = len;
> > >
> > > If gdb is using the new breakpoint interface, surely it should just
> > > use it, rather than doing this bit frobbing as in the old SET_DABR
> > > call.
> > >
> >
> > I understand that you wanted to avoid this duplication of effort in terms
> > of encoding and decoding the breakpoint type from
> > PPC_BREAKPOINT_TRIGGER_READ to DABR_DATA_READ to HW_BREAKPOINT_R.
> >
> > However HW_BREAKPOINT_R is a generic definition used across
> > architectures, DABR_DATA_READ is used in the !CONFIG_HAVE_HW_BREAKPOINT
> > case while PPC_BREAKPOINT_TRIGGER_READ is used in
> > CONFIG_PPC_ADV_DEBUG_REGS case.
> >
> > While we could define PPC_BREAKPOINT_TRIGGER_READ and DABR_DATA_READ to
> > the same value it may not result in any code savings (since the bit
> > translation is done for !CONFIG_HAVE_HW_BREAKPOINT case anyway). So, I
> > think it is best left the way it is.
>
> That's not what I'm suggesting. What I'm saying is that ig userspace
> is using the new generic interface, then it should just set the
> bp_type field, and it should not use the DABR_DATA_{READ,WRITE} bits.
> The DABR_DATA bits should *only* be processed in the legacy interface,
> never in the generic interface.
>
The DABR_DATA_{READ,WRITE} bits are neither set by the user, nor
expected by the hw-breakpoint interface. It is an intermediate code used
to re-use the arch_bp_generic_fields function. We could convert directly
from PPC_BREAKPOINT_TRIGGER_READ to HW_BREAKPOINT_R (using a switch-case)
but that may not result in any code savings.
DABR_DATA_{READ,WRITE} is indeed legacy and cannot be set by user-space
for a PPC_PTRACE_SETHWDEBUG + CONFIG_HAVE_HW_BREAKPOINT combination.
[snipped]
> > diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
> > index f4a5499..f2a7a39 100644
> > --- a/Documentation/powerpc/ptrace.txt
> > +++ b/Documentation/powerpc/ptrace.txt
> > @@ -127,6 +127,22 @@ Some examples of using the structure to:
> > p.addr2 = (uint64_t) end_range;
> > p.condition_value = 0;
> >
> > +- set a watchpoint in server processors (BookS)
> > +
> > + p.version = 1;
> > + p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
> > + p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
> > + or
> > + p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
> > +
> > + p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
> > + p.addr = (uint64_t) begin_range;
>
> You should probably document the alignment constraint on the address
> here, too.
>
Alignment constraints will be learnt by the user-space during runtime.
We provide that as part of 'struct ppc_debug_info' in
'data_bp_alignment' field.
While the alignment is always 8-bytes for BookS, I think userspace
should be left to learn it through PTRACE_PPC_GETHWDEBUGINFO.
> > + /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
> > + * addr2 - addr <= 8 Bytes.
> > + */
> > + p.addr2 = (uint64_t) end_range;
> > + p.condition_value = 0;
> > +
> > 3. PTRACE_DELHWDEBUG
> >
> > Takes an integer which identifies an existing breakpoint or watchpoint
> > diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
> > index 05b7dd2..be5dc57 100644
> > --- a/arch/powerpc/kernel/ptrace.c
> > +++ b/arch/powerpc/kernel/ptrace.c
> > @@ -1339,6 +1339,12 @@ static int set_dac_range(struct task_struct *child,
> > static long ppc_set_hwdebug(struct task_struct *child,
> > struct ppc_hw_breakpoint *bp_info)
> > {
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > + int ret, len = 0;
> > + struct thread_struct *thread = &(child->thread);
> > + struct perf_event *bp;
> > + struct perf_event_attr attr;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> > #ifndef CONFIG_PPC_ADV_DEBUG_REGS
> > unsigned long dabr;
> > #endif
> > @@ -1382,13 +1388,9 @@ static long ppc_set_hwdebug(struct task_struct *child,
> > */
> > if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
> > (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
> > - bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
> > bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
> > return -EINVAL;
> >
> > - if (child->thread.dabr)
> > - return -ENOSPC;
> > -
> > if ((unsigned long)bp_info->addr >= TASK_SIZE)
> > return -EIO;
> >
> > @@ -1398,15 +1400,75 @@ static long ppc_set_hwdebug(struct task_struct *child,
> > dabr |= DABR_DATA_READ;
> > if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
> > dabr |= DABR_DATA_WRITE;
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > + if (ptrace_get_breakpoints(child) < 0)
> > + return -ESRCH;
> >
> > - child->thread.dabr = dabr;
> > + /*
> > + * Check if the request is for 'range' breakpoints. We can
> > + * support it if range < 8 bytes.
> > + */
> > + if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
> > + len = bp_info->addr2 - bp_info->addr;
> > + } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
> > + ptrace_put_breakpoints(child);
> > + return -EINVAL;
>
> You are overindented here.
I must have been confused!...Even scripts/checkpath.pl didn't throw an error
at this line. Will correct it.
> > + }
> > + bp = thread->ptrace_bps[0];
> > + if (bp) {
> > + attr = bp->attr;
> > + attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
> > + arch_bp_generic_fields(dabr &
> > + (DABR_DATA_WRITE | DABR_DATA_READ),
> > + &attr.bp_type);
>
> You still have this code which has no business in the generic
> interface path.
Same explanation as above. If I have to avoid the call to
arch_bp_generic_fields() then, it should be replaced with
switch(bp_info->trigger_type) {
case PPC_BREAKPOINT_TRIGGER_READ:
attr.bp_type = HW_BREAKPOINT_R;
case PPC_BREAKPOINT_TRIGGER_WRITE:
attr.bp_type = HW_BREAKPOINT_W;
case PPC_BREAKPOINT_TRIGGER_RW:
attr.bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
}
All these additional lines for no extra benefit (or I haven't
still understood your comments fully).
> > + attr.bp_len = len;
> > + ret = modify_user_hw_breakpoint(bp, &attr);
> > + if (ret) {
> > + ptrace_put_breakpoints(child);
> > + return ret;
> > + }
>
> If a bp already exists, you're modifying it. I thought the semantics
> of the new interface meant that you shoul return ENOSPC in this case,
> and a DEL would be necessary before adding another breakpoint.
>
I'm not too sure what would be the desired behaviour for this interface,
either way is fine with me. I'd like to hear from the GDB folks (copied
in this email) to know what would please them.
> > + thread->ptrace_bps[0] = bp;
> > + ptrace_put_breakpoints(child);
> > + thread->dabr = dabr;
> > + return 0;
> > + }
> > +
> > + /* Create a new breakpoint request if one doesn't exist already */
> > + hw_breakpoint_init(&attr);
> > + attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
> > + attr.bp_len = len;
> > + arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
> > + &attr.bp_type);
> > +
> > + thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
> > + ptrace_triggered, NULL, child);
> > + if (IS_ERR(bp)) {
> > + thread->ptrace_bps[0] = NULL;
> > + ptrace_put_breakpoints(child);
> > + return PTR_ERR(bp);
> > + }
> >
> > + ptrace_put_breakpoints(child);
> > + return 1;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> > +
> > + if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
> > + return -EINVAL;
> > +
> > + if (child->thread.dabr)
> > + return -ENOSPC;
> > +
> > + child->thread.dabr = dabr;
> > return 1;
> > #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
> > }
> >
> > static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
> > {
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > + struct thread_struct *thread = &(child->thread);
> > + struct perf_event *bp;
> > +#endif /* CONFIG_HAVE_HW_BREAKPOINT */
> > #ifdef CONFIG_PPC_ADV_DEBUG_REGS
> > int rc;
> >
> > @@ -1426,10 +1488,24 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
> > #else
> > if (data != 1)
> > return -EINVAL;
> > +
> > +#ifdef CONFIG_HAVE_HW_BREAKPOINT
> > + if (ptrace_get_breakpoints(child) < 0)
> > + return -ESRCH;
> > +
> > + bp = thread->ptrace_bps[0];
> > + if (bp) {
> > + unregister_hw_breakpoint(bp);
> > + thread->ptrace_bps[0] = NULL;
> > + }
> > + ptrace_put_breakpoints(child);
> > + return 0;
>
> Shouldn't DEL return an error if there is no existing bp.
>
Same comment as above. We'd like to know what behaviour would help the
GDB use this interface better as there's no right or wrong way here.
Thanks again for your patient review. I will post the modified patch
after hearing comments from all.
Thanks.
K.Prasad
^ permalink raw reply
* Re: [BUG?]3.0-rc4+ftrace+kprobe: set kprobe at instruction 'stwu' lead to system crash/freeze
From: tiejun.chen @ 2011-12-01 10:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Jim Keniston, Anton Blanchard, linux-kernel, Steven Rostedt,
Yong Zhang, paulus, yrl.pp-manager.tt, Masami Hiramatsu,
linuxppc-dev
In-Reply-To: <1322686809.29041.10.camel@pasglop>
Benjamin Herrenschmidt wrote:
> On Wed, 2011-11-30 at 19:06 +0800, tiejun.chen wrote:
>
>>> - Copy the exception frame we're about to unwind to just -below- the
>>> new r1 value we want to write to. Then perform the write, and change
>>> r1 to point to that copy of the frame.
>>>
>>> - Branch to restore: which will unwind everything from that copy of
>>> the frame, and eventually set r1 to GPR(1) in the copy which contains
>>> the new value of r1.
>> We still can't restore this there.
>
> Yes, we can since we have copied the pt_regs down to -below- where we
> are going to write to. That's the whole trick. We copy the pt_regs
> somewhere "safe" and restore from there.
>
>> I mean we have to do that real restore here. So I'm really not sure if its a
>> good way to add such a codes including check TIF/copy-get new r1/restore
>> operation here since this is so deep for the exception return code.
>
> No. Re-read my explanation.
>
> In the do_work case (so when things are still easy), we copy the pt_regs
> of the return frame to a safe place (right below where we want to write
> to typically), and change r1 to point to this "new" frame which we use
> to restore from. Then we do the store which is now safe and go to an
> unmodified "restore" exit path.
Do you mean we should push the original pt_regs (or that whole exception stack)
downwards the location the new r1 point? Then its safe to perform this real
emulated stw instruction. At last we will reroute r1 to that copied exception
frame to restore as normal. Right?
Here I suppose so, I implement this for PPC32 based on the above understanding.
I take a validation for kprobing do_fork()/show_interrupts(), now looks fine.
Tomorrow I will go PPC64, and hope its fine as well.
If everything is good I'll send these patches to linuxppc-dev next week.
Cheers
Tiejun
>
>>> This is the less intrusive approach and should work just fine, it's also
>>> more robust than anything I've been able to think of and the approach
>>> would work for 32 and 64-bit similarily.
>>>
>>> (***) Above comment about a bug: If you look at entry_64.S version of
>>> ret_from_except_lite you'll notice that in the !preempt case, after
>>> we've checked MSR_PR we test for any TIF flag in _TIF_USER_WORK_MASK to
>>> decide whether to go to do_work or not. However, in the preempt case, we
>>> do a convoluted trick to test SIGPENDING only if PR was set and always
>>> test NEED_RESCHED ... but we forget to test any other bit of
>>> _TIF_USER_WORK_MASK !!! So that means that with preempt, we completely
>>> fail to test for things like single step, syscall tracing, etc...
>>>
>> This is another problem we should address.
>>
>>> I think this should be fixed at the same time, by simplifying the code
>>> by doing:
>>>
>>> - Test PR. If set, go to test_work_user, else continue (or the other
>>> way around and call it test_work_kernel)
>>>
>>> - In test_work_user, always test for _TIF_USER_WORK_MASK to decide to
>>> go to do_work, maybe call it do_user_work
>>>
>>> - In test_work_kernel, test for _TIF_KERNEL_WORK_MASK which is set to
>>> our new flag along with NEED_RESCHED if preempt is enabled and branch to
>>> do_kernel_work.
>>>
>>> do_user_work is basically the same as today's user_work
>>>
>>> do_kernel_work is basically the same as today preempt block with added
>>> code to handle the new flag as described above.
>>>
>>> Is anybody volunteering for fixing that ? I don't have the bandwidth
>> I always use one specific kprobe stack to fix this for BOOKE and work well in my
>> local tree :) Do you remember my v3 patch? I think its possible to extend this
>> for all PPC variants.
>>
>> Anyway, I'd like to be this volunteer with our last solution.
>
> So the second problem I exposed, for which you just volunteered
> (hint :-) is an orthogonal issue not related to kprobe or stacks which
> happen to be something I discovered yesterday while looking at the code.
>
> As for the solution to the emulation problem, re-read my explanation.
> The whole trick is that we can avoid a separate stack (which I really
> want to avoid) and we can avoid touching the low level restore code
> path.
>
> Cheers,
> Ben.
^ permalink raw reply
* Re: ppc4xx simple vs SoC's
From: Josh Boyer @ 2011-12-01 11:44 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev
In-Reply-To: <1322717953.3729.18.camel@pasglop>
On Thu, Dec 1, 2011 at 12:39 AM, Benjamin Herrenschmidt
<benh@kernel.crashing.org> wrote:
> Hi Josh !
>
> I was helping Tony with some of the Currituck stuff when I noticed an
> oddity...
>
> So we have various "SoC" config symbols such as 440EP, 460SX, etc...
> that in turn select various bits & pieces that enable support for that
> SoC (such as EMAC4 support or FPU support). Those only act as "enables"
> for compiling of the code, there is still going to be a runtime check of
> course.
>
> Those SoC config symbols are not user selectable, they are meant to be
> themselves select'ed by the board Kconfig entries.
Yep, and they are.
> However, the entry for ppc44x_simple doesn't select any of these,
> meaning for example, AFAIK, that you don't get EMAC4 etc... I'm
> surprised things work at all !
>
> What am I missing ?
CONFIG_PPC44x_SIMPLE is selected by the board Kconfig values, which
also select all of the SoC Kconfig options they need as well.
ppc44x_simple started as a way to basically avoid duplicating a bunch
of board.c files, but it's still "driven" from the board options.
So hopefully that explains how things are working today. The question
now is whether you would like something different?
josh
^ permalink raw reply
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Kumar Gala @ 2011-12-01 14:03 UTC (permalink / raw)
To: Jean-Michel Hautbois; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <CAL8zT=juU_PC92R4za31R8Lmur0PrFwog1m1fk+PEarW_0C6ng@mail.gmail.com>
On Dec 1, 2011, at 3:57 AM, Jean-Michel Hautbois wrote:
> Hi,
>=20
> I have a P2020 CPU (powerpc) and I compiled it with two different =
defconfigs.
> The first one is a SMP, 2 cores, launched with the "nosmp" kernel
> parameter, the other one is an UP kernel.
>=20
> My driver behaviour is not the same whether launching one or the
> other. It is hard to explain more precisely, as it deals only with
> ioctl which only does ioread32/iowrite32 on a PCIe device.
> But I can tell that it never works the same way when UP (not working
> correctly), or SMP "nosmp" (working) or even SMP (not working).
>=20
> AFAIK, the "nosmp" parameter should tell the kernel to act the same is
> if it is an UP kernel, and it disables IO APIC, which is not an issue
> in my case.
>=20
> Can you think about anything that would explain it, or would help me
> debugging it ?
This is a bit odd, hard to say w/o more details on what exactly your =
code is trying to do and wait the failure is.
The larger differences between SMP & UP build would be setting of memory =
attribute for cache coherency. In UP case we don't set it.
Between SMP 'nosmp' and SMP 'on' cases you seem like you're hitting some =
locking condition.
Guessing your running into a timing & locking issue that you're getting =
lucky on the SMP 'nosmp' case such that it just happens to work.
- k=
^ permalink raw reply
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Jean-Michel Hautbois @ 2011-12-01 15:04 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <D70E8CC4-9FA3-4DC9-B623-02F32EFBFE0F@kernel.crashing.org>
2011/12/1 Kumar Gala <galak@kernel.crashing.org>:
>
> On Dec 1, 2011, at 3:57 AM, Jean-Michel Hautbois wrote:
>
>> Hi,
>>
>> I have a P2020 CPU (powerpc) and I compiled it with two different defcon=
figs.
>> The first one is a SMP, 2 cores, launched with the "nosmp" kernel
>> parameter, the other one is an UP kernel.
>>
>> My driver behaviour is not the same whether launching one or the
>> other. It is hard to explain more precisely, as it deals only with
>> ioctl which only does ioread32/iowrite32 on a PCIe device.
>> But I can tell that it never works the same way when UP (not working
>> correctly), or SMP "nosmp" (working) or even SMP (not working).
>>
>> AFAIK, the "nosmp" parameter should tell the kernel to act the same is
>> if it is an UP kernel, and it disables IO APIC, which is not an issue
>> in my case.
>>
>> Can you think about anything that would explain it, or would help me
>> debugging it ?
>
> This is a bit odd, hard to say w/o more details on what exactly your code=
is trying to do and wait the failure is.
I understand that it is difficult to give more details, but the driver
is not mine, and I can't give all the code associated.
> The larger differences between SMP & UP build would be setting of memory =
attribute for cache coherency. =C2=A0In UP case we don't set it.
>
> Between SMP 'nosmp' and SMP 'on' cases you seem like you're hitting some =
locking condition.
>
> Guessing your running into a timing & locking issue that you're getting l=
ucky on the SMP 'nosmp' case such that it just happens to work.
Any idea on how to debug this ? I am using a 2.6.35 kernel.
Thanks,
JM
^ permalink raw reply
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Tabi Timur-B04825 @ 2011-12-01 15:56 UTC (permalink / raw)
To: Jean-Michel Hautbois; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <CAL8zT=gGfBYsLcsKobJPhfhEhNeLcrYMoWh2kv0odT0n0wnZgQ@mail.gmail.com>
On Thu, Dec 1, 2011 at 9:04 AM, Jean-Michel Hautbois
<jhautbois@gmail.com> wrote:
>
> Any idea on how to debug this ? I am using a 2.6.35 kernel.
There are a ton of Kconfig options for debugging various locking bugs.
Try turning them on.
--=20
Timur Tabi
Linux kernel developer at Freescale=
^ permalink raw reply
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Jean-Michel Hautbois @ 2011-12-01 16:14 UTC (permalink / raw)
To: Tabi Timur-B04825; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <CAOZdJXVq_g=GAJLRsHZ+290cAJfpOx0LX3sBL3T5i0CaG+xh9Q@mail.gmail.com>
2011/12/1 Tabi Timur-B04825 <B04825@freescale.com>:
> On Thu, Dec 1, 2011 at 9:04 AM, Jean-Michel Hautbois
> <jhautbois@gmail.com> wrote:
>>
>> Any idea on how to debug this ? I am using a 2.6.35 kernel.
>
> There are a ton of Kconfig options for debugging various locking bugs.
> =C2=A0Try turning them on.
>
And when I do that, it works, even in SMP... :).
JM
^ permalink raw reply
* [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 17:33 UTC (permalink / raw)
To: kumar.gala, grant.likely, linuxppc-dev
An I2C device tree node can contain a 'cell-index' property that can be
used to enumerate the I2C devices. If such a property exists, use it
to specify the I2C adapter number.
This feature is necessary for the Freescale PowerPC audio drivers (e.g.
on the P1022DS). The "machine driver" needs to know the adapter number
for each I2C adapter, but it only has access to the device tree.
Previously, the I2C nodes always appeared in cell-index order, so the
dynamic numbering coincided with the cell-index property. With commit
ab827d97 ("powerpc/85xx: Rework P1022DS device tree"), the I2C nodes are
unintentionally reversed in the device tree, and so the machine driver
guesses the wrong I2C adapter number.
Signed-off-by: Timur Tabi <timur@freescale.com>
---
drivers/i2c/busses/i2c-mpc.c | 14 +++++++++++++-
1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 107397a..8551c34 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -632,7 +632,19 @@ static int __devinit fsl_i2c_probe(struct platform_device *op)
i2c->adap.dev.parent = &op->dev;
i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
- result = i2c_add_adapter(&i2c->adap);
+ /*
+ * If the I2C node has a "cell-index" property, use it to enumerate
+ * the I2C adapter.
+ */
+ prop = of_get_property(i2c->adap.dev.of_node, "cell-index", &plen);
+ if (prop && plen == sizeof(u32)) {
+ dev_dbg(i2c->dev, "using cell-index property %u", *prop);
+ i2c->adap.nr = *prop;
+ result = i2c_add_numbered_adapter(&i2c->adap);
+ } else {
+ result = i2c_add_adapter(&i2c->adap);
+ }
+
if (result < 0) {
dev_err(i2c->dev, "failed to add adapter\n");
goto fail_add;
--
1.7.3.4
^ permalink raw reply related
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Jean-Michel Hautbois @ 2011-12-01 17:52 UTC (permalink / raw)
To: Tabi Timur-B04825; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <CAL8zT=hK2rDDC7s+SkvCA=C5LjVX+5oRQmP+KQet2mkFEnaKKw@mail.gmail.com>
2011/12/1 Jean-Michel Hautbois <jhautbois@gmail.com>:
> 2011/12/1 Tabi Timur-B04825 <B04825@freescale.com>:
>> On Thu, Dec 1, 2011 at 9:04 AM, Jean-Michel Hautbois
>> <jhautbois@gmail.com> wrote:
>>>
>>> Any idea on how to debug this ? I am using a 2.6.35 kernel.
>>
>> There are a ton of Kconfig options for debugging various locking bugs.
>> =C2=A0Try turning them on.
>>
All Kconfig options do not help me with cache coherency problems, though.
Or, I didn't find any option related.
Any idea ?
JM
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Scott Wood @ 2011-12-01 18:41 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <1322760781-31226-1-git-send-email-timur@freescale.com>
On 12/01/2011 11:33 AM, Timur Tabi wrote:
> An I2C device tree node can contain a 'cell-index' property that can be
> used to enumerate the I2C devices. If such a property exists, use it
> to specify the I2C adapter number.
Didn't we decide a long time ago that this was a bad idea?
> This feature is necessary for the Freescale PowerPC audio drivers (e.g.
> on the P1022DS). The "machine driver" needs to know the adapter number
> for each I2C adapter, but it only has access to the device tree.
> Previously, the I2C nodes always appeared in cell-index order, so the
> dynamic numbering coincided with the cell-index property. With commit
> ab827d97 ("powerpc/85xx: Rework P1022DS device tree"), the I2C nodes are
> unintentionally reversed in the device tree, and so the machine driver
> guesses the wrong I2C adapter number.
What specifically do you need this number for? What does it represent?
-Scott
^ permalink raw reply
* [PATCH 6/8 v2] powerpc/ps3: Fix PS3 repository build warnings
From: Geoff Levand @ 2011-12-01 18:58 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: cbe-oss-dev, linuxppc-dev, Geert Uytterhoeven
In-Reply-To: <CAMuHMdUjOXLskrRXYYO1Esd75W4Z=WS3srT0+qFF66DfLeQQmA@mail.gmail.com>
Fix some PS3 repository.c build warnings when DEBUG is
defined. Also change most pr_debug calls to pr_devel calls.
Fixes warnings like these:
format '%lx' expects type 'long unsigned int', but argument 7 has type 'u64'
Signed-off-by: Geoff Levand <geoff@infradead.org>
---
Hi Ben,
I rebased my for-powerpc branch to include this update.
-Geoff
v2: - Format u64 is using the "ll" length modifier (thanks Geert).
- Convert pr_debug to pr_devel.
arch/powerpc/platforms/ps3/repository.c | 135 ++++++++++++++++---------------
1 files changed, 68 insertions(+), 67 deletions(-)
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
index cb68729..7bdfea3 100644
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -44,7 +44,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line)
s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
s[i] = 0;
- pr_debug("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s);
+ pr_devel("%s:%d: %s%016llx : %s\n", func, line, hdr, n, s);
#endif
}
@@ -53,7 +53,7 @@ static void _dump_field(const char *hdr, u64 n, const char *func, int line)
static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
u64 n4, const char *func, int line)
{
- pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
+ pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
_dump_field("n1: ", n1, func, line);
_dump_field("n2: ", n2, func, line);
_dump_field("n3: ", n3, func, line);
@@ -65,13 +65,13 @@ static void _dump_node_name(unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
u64 v1, u64 v2, const char *func, int line)
{
- pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
+ pr_devel("%s:%d: lpar: %u\n", func, line, lpar_id);
_dump_field("n1: ", n1, func, line);
_dump_field("n2: ", n2, func, line);
_dump_field("n3: ", n3, func, line);
_dump_field("n4: ", n4, func, line);
- pr_debug("%s:%d: v1: %016llx\n", func, line, v1);
- pr_debug("%s:%d: v2: %016llx\n", func, line, v2);
+ pr_devel("%s:%d: v1: %016llx\n", func, line, v1);
+ pr_devel("%s:%d: v2: %016llx\n", func, line, v2);
}
/**
@@ -135,7 +135,7 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
&v2);
if (result) {
- pr_debug("%s:%d: lv1_read_repository_node failed: %s\n",
+ pr_warn("%s:%d: lv1_read_repository_node failed: %s\n",
__func__, __LINE__, ps3_result(result));
dump_node_name(lpar_id, n1, n2, n3, n4);
return -ENOENT;
@@ -149,10 +149,10 @@ static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
*_v2 = v2;
if (v1 && !_v1)
- pr_debug("%s:%d: warning: discarding non-zero v1: %016llx\n",
+ pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n",
__func__, __LINE__, v1);
if (v2 && !_v2)
- pr_debug("%s:%d: warning: discarding non-zero v2: %016llx\n",
+ pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n",
__func__, __LINE__, v2);
return 0;
@@ -323,16 +323,16 @@ int ps3_repository_find_device(struct ps3_repository_device *repo)
result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
if (result) {
- pr_debug("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
+ pr_devel("%s:%d read_bus_num_dev failed\n", __func__, __LINE__);
return result;
}
- pr_debug("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n",
+ pr_devel("%s:%d: bus_type %u, bus_index %u, bus_id %llu, num_dev %u\n",
__func__, __LINE__, tmp.bus_type, tmp.bus_index, tmp.bus_id,
num_dev);
if (tmp.dev_index >= num_dev) {
- pr_debug("%s:%d: no device found\n", __func__, __LINE__);
+ pr_devel("%s:%d: no device found\n", __func__, __LINE__);
return -ENODEV;
}
@@ -340,7 +340,7 @@ int ps3_repository_find_device(struct ps3_repository_device *repo)
&tmp.dev_type);
if (result) {
- pr_debug("%s:%d read_dev_type failed\n", __func__, __LINE__);
+ pr_devel("%s:%d read_dev_type failed\n", __func__, __LINE__);
return result;
}
@@ -348,12 +348,12 @@ int ps3_repository_find_device(struct ps3_repository_device *repo)
&tmp.dev_id);
if (result) {
- pr_debug("%s:%d ps3_repository_read_dev_id failed\n", __func__,
+ pr_devel("%s:%d ps3_repository_read_dev_id failed\n", __func__,
__LINE__);
return result;
}
- pr_debug("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n",
+ pr_devel("%s:%d: found: dev_type %u, dev_index %u, dev_id %llu\n",
__func__, __LINE__, tmp.dev_type, tmp.dev_index, tmp.dev_id);
*repo = tmp;
@@ -367,14 +367,14 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
struct ps3_repository_device tmp;
unsigned int num_dev;
- pr_debug(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__,
+ pr_devel(" -> %s:%u: find device by id %llu:%llu\n", __func__, __LINE__,
bus_id, dev_id);
for (tmp.bus_index = 0; tmp.bus_index < 10; tmp.bus_index++) {
result = ps3_repository_read_bus_id(tmp.bus_index,
&tmp.bus_id);
if (result) {
- pr_debug("%s:%u read_bus_id(%u) failed\n", __func__,
+ pr_devel("%s:%u read_bus_id(%u) failed\n", __func__,
__LINE__, tmp.bus_index);
return result;
}
@@ -382,23 +382,23 @@ int ps3_repository_find_device_by_id(struct ps3_repository_device *repo,
if (tmp.bus_id == bus_id)
goto found_bus;
- pr_debug("%s:%u: skip, bus_id %llu\n", __func__, __LINE__,
+ pr_devel("%s:%u: skip, bus_id %llu\n", __func__, __LINE__,
tmp.bus_id);
}
- pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
+ pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
return result;
found_bus:
result = ps3_repository_read_bus_type(tmp.bus_index, &tmp.bus_type);
if (result) {
- pr_debug("%s:%u read_bus_type(%u) failed\n", __func__,
+ pr_devel("%s:%u read_bus_type(%u) failed\n", __func__,
__LINE__, tmp.bus_index);
return result;
}
result = ps3_repository_read_bus_num_dev(tmp.bus_index, &num_dev);
if (result) {
- pr_debug("%s:%u read_bus_num_dev failed\n", __func__,
+ pr_devel("%s:%u read_bus_num_dev failed\n", __func__,
__LINE__);
return result;
}
@@ -408,7 +408,7 @@ found_bus:
tmp.dev_index,
&tmp.dev_id);
if (result) {
- pr_debug("%s:%u read_dev_id(%u:%u) failed\n", __func__,
+ pr_devel("%s:%u read_dev_id(%u:%u) failed\n", __func__,
__LINE__, tmp.bus_index, tmp.dev_index);
return result;
}
@@ -416,21 +416,21 @@ found_bus:
if (tmp.dev_id == dev_id)
goto found_dev;
- pr_debug("%s:%u: skip, dev_id %llu\n", __func__, __LINE__,
+ pr_devel("%s:%u: skip, dev_id %llu\n", __func__, __LINE__,
tmp.dev_id);
}
- pr_debug(" <- %s:%u: dev not found\n", __func__, __LINE__);
+ pr_devel(" <- %s:%u: dev not found\n", __func__, __LINE__);
return result;
found_dev:
result = ps3_repository_read_dev_type(tmp.bus_index, tmp.dev_index,
&tmp.dev_type);
if (result) {
- pr_debug("%s:%u read_dev_type failed\n", __func__, __LINE__);
+ pr_devel("%s:%u read_dev_type failed\n", __func__, __LINE__);
return result;
}
- pr_debug(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n",
+ pr_devel(" <- %s:%u: found: type (%u:%u) index (%u:%u) id (%llu:%llu)\n",
__func__, __LINE__, tmp.bus_type, tmp.dev_type, tmp.bus_index,
tmp.dev_index, tmp.bus_id, tmp.dev_id);
*repo = tmp;
@@ -443,18 +443,18 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
int result = 0;
struct ps3_repository_device repo;
- pr_debug(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
+ pr_devel(" -> %s:%d: find bus_type %u\n", __func__, __LINE__, bus_type);
repo.bus_type = bus_type;
result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);
if (result) {
- pr_debug(" <- %s:%u: bus not found\n", __func__, __LINE__);
+ pr_devel(" <- %s:%u: bus not found\n", __func__, __LINE__);
return result;
}
result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);
if (result) {
- pr_debug("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
+ pr_devel("%s:%d read_bus_id(%u) failed\n", __func__, __LINE__,
repo.bus_index);
return result;
}
@@ -469,13 +469,13 @@ int __devinit ps3_repository_find_devices(enum ps3_bus_type bus_type,
result = callback(&repo);
if (result) {
- pr_debug("%s:%d: abort at callback\n", __func__,
+ pr_devel("%s:%d: abort at callback\n", __func__,
__LINE__);
break;
}
}
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ pr_devel(" <- %s:%d\n", __func__, __LINE__);
return result;
}
@@ -489,7 +489,7 @@ int ps3_repository_find_bus(enum ps3_bus_type bus_type, unsigned int from,
for (i = from; i < 10; i++) {
error = ps3_repository_read_bus_type(i, &type);
if (error) {
- pr_debug("%s:%d read_bus_type failed\n",
+ pr_devel("%s:%d read_bus_type failed\n",
__func__, __LINE__);
*bus_index = UINT_MAX;
return error;
@@ -509,7 +509,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
int result = 0;
unsigned int res_index;
- pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
+ pr_devel("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
*interrupt_id = UINT_MAX;
@@ -521,7 +521,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
repo->dev_index, res_index, &t, &id);
if (result) {
- pr_debug("%s:%d read_dev_intr failed\n",
+ pr_devel("%s:%d read_dev_intr failed\n",
__func__, __LINE__);
return result;
}
@@ -535,7 +535,7 @@ int ps3_repository_find_interrupt(const struct ps3_repository_device *repo,
if (res_index == 10)
return -ENODEV;
- pr_debug("%s:%d: found intr_type %u at res_index %u\n",
+ pr_devel("%s:%d: found intr_type %u at res_index %u\n",
__func__, __LINE__, intr_type, res_index);
return result;
@@ -547,7 +547,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo,
int result = 0;
unsigned int res_index;
- pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
+ pr_devel("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
*bus_addr = *len = 0;
@@ -560,7 +560,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo,
repo->dev_index, res_index, &t, &a, &l);
if (result) {
- pr_debug("%s:%d read_dev_reg failed\n",
+ pr_devel("%s:%d read_dev_reg failed\n",
__func__, __LINE__);
return result;
}
@@ -575,7 +575,7 @@ int ps3_repository_find_reg(const struct ps3_repository_device *repo,
if (res_index == 10)
return -ENODEV;
- pr_debug("%s:%d: found reg_type %u at res_index %u\n",
+ pr_devel("%s:%d: found reg_type %u at res_index %u\n",
__func__, __LINE__, reg_type, res_index);
return result;
@@ -1009,7 +1009,7 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
int result = 0;
unsigned int res_index;
- pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
+ pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
for (res_index = 0; res_index < 10; res_index++) {
@@ -1021,13 +1021,13 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
if (result) {
if (result != LV1_NO_ENTRY)
- pr_debug("%s:%d ps3_repository_read_dev_intr"
+ pr_devel("%s:%d ps3_repository_read_dev_intr"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
break;
}
- pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
+ pr_devel("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
__func__, __LINE__, repo->bus_index, repo->dev_index,
intr_type, interrupt_id);
}
@@ -1042,18 +1042,18 @@ int ps3_repository_dump_resource_info(const struct ps3_repository_device *repo)
if (result) {
if (result != LV1_NO_ENTRY)
- pr_debug("%s:%d ps3_repository_read_dev_reg"
+ pr_devel("%s:%d ps3_repository_read_dev_reg"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
break;
}
- pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
+ pr_devel("%s:%d (%u:%u) reg_type %u, bus_addr %llxh, len %llxh\n",
__func__, __LINE__, repo->bus_index, repo->dev_index,
reg_type, bus_addr, len);
}
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ pr_devel(" <- %s:%d\n", __func__, __LINE__);
return result;
}
@@ -1063,22 +1063,22 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo)
unsigned int num_regions, region_index;
u64 port, blk_size, num_blocks;
- pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
+ pr_devel(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
result = ps3_repository_read_stor_dev_info(repo->bus_index,
repo->dev_index, &port, &blk_size, &num_blocks, &num_regions);
if (result) {
- pr_debug("%s:%d ps3_repository_read_stor_dev_info"
+ pr_devel("%s:%d ps3_repository_read_stor_dev_info"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
goto out;
}
- pr_debug("%s:%d (%u:%u): port %lu, blk_size %lu, num_blocks "
- "%lu, num_regions %u\n",
- __func__, __LINE__, repo->bus_index, repo->dev_index, port,
- blk_size, num_blocks, num_regions);
+ pr_devel("%s:%d (%u:%u): port %llu, blk_size %llu, num_blocks "
+ "%llu, num_regions %u\n",
+ __func__, __LINE__, repo->bus_index, repo->dev_index,
+ port, blk_size, num_blocks, num_regions);
for (region_index = 0; region_index < num_regions; region_index++) {
unsigned int region_id;
@@ -1088,19 +1088,20 @@ static int dump_stor_dev_info(struct ps3_repository_device *repo)
repo->dev_index, region_index, ®ion_id,
®ion_start, ®ion_size);
if (result) {
- pr_debug("%s:%d ps3_repository_read_stor_dev_region"
+ pr_devel("%s:%d ps3_repository_read_stor_dev_region"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
break;
}
- pr_debug("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
+ pr_devel("%s:%d (%u:%u) region_id %u, start %lxh, size %lxh\n",
__func__, __LINE__, repo->bus_index, repo->dev_index,
- region_id, region_start, region_size);
+ region_id, (unsigned long)region_start,
+ (unsigned long)region_size);
}
out:
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ pr_devel(" <- %s:%d\n", __func__, __LINE__);
return result;
}
@@ -1109,7 +1110,7 @@ static int dump_device_info(struct ps3_repository_device *repo,
{
int result = 0;
- pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
+ pr_devel(" -> %s:%d: bus_%u\n", __func__, __LINE__, repo->bus_index);
for (repo->dev_index = 0; repo->dev_index < num_dev;
repo->dev_index++) {
@@ -1118,7 +1119,7 @@ static int dump_device_info(struct ps3_repository_device *repo,
repo->dev_index, &repo->dev_type);
if (result) {
- pr_debug("%s:%d ps3_repository_read_dev_type"
+ pr_devel("%s:%d ps3_repository_read_dev_type"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
break;
@@ -1128,15 +1129,15 @@ static int dump_device_info(struct ps3_repository_device *repo,
repo->dev_index, &repo->dev_id);
if (result) {
- pr_debug("%s:%d ps3_repository_read_dev_id"
+ pr_devel("%s:%d ps3_repository_read_dev_id"
" (%u:%u) failed\n", __func__, __LINE__,
repo->bus_index, repo->dev_index);
continue;
}
- pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__,
+ pr_devel("%s:%d (%u:%u): dev_type %u, dev_id %lu\n", __func__,
__LINE__, repo->bus_index, repo->dev_index,
- repo->dev_type, repo->dev_id);
+ repo->dev_type, (unsigned long)repo->dev_id);
ps3_repository_dump_resource_info(repo);
@@ -1144,7 +1145,7 @@ static int dump_device_info(struct ps3_repository_device *repo,
dump_stor_dev_info(repo);
}
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ pr_devel(" <- %s:%d\n", __func__, __LINE__);
return result;
}
@@ -1153,7 +1154,7 @@ int ps3_repository_dump_bus_info(void)
int result = 0;
struct ps3_repository_device repo;
- pr_debug(" -> %s:%d\n", __func__, __LINE__);
+ pr_devel(" -> %s:%d\n", __func__, __LINE__);
memset(&repo, 0, sizeof(repo));
@@ -1164,7 +1165,7 @@ int ps3_repository_dump_bus_info(void)
&repo.bus_type);
if (result) {
- pr_debug("%s:%d read_bus_type(%u) failed\n",
+ pr_devel("%s:%d read_bus_type(%u) failed\n",
__func__, __LINE__, repo.bus_index);
break;
}
@@ -1173,32 +1174,32 @@ int ps3_repository_dump_bus_info(void)
&repo.bus_id);
if (result) {
- pr_debug("%s:%d read_bus_id(%u) failed\n",
+ pr_devel("%s:%d read_bus_id(%u) failed\n",
__func__, __LINE__, repo.bus_index);
continue;
}
if (repo.bus_index != repo.bus_id)
- pr_debug("%s:%d bus_index != bus_id\n",
+ pr_devel("%s:%d bus_index != bus_id\n",
__func__, __LINE__);
result = ps3_repository_read_bus_num_dev(repo.bus_index,
&num_dev);
if (result) {
- pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
+ pr_devel("%s:%d read_bus_num_dev(%u) failed\n",
__func__, __LINE__, repo.bus_index);
continue;
}
- pr_debug("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
+ pr_devel("%s:%d bus_%u: bus_type %u, bus_id %lu, num_dev %u\n",
__func__, __LINE__, repo.bus_index, repo.bus_type,
- repo.bus_id, num_dev);
+ (unsigned long)repo.bus_id, num_dev);
dump_device_info(&repo, num_dev);
}
- pr_debug(" <- %s:%d\n", __func__, __LINE__);
+ pr_devel(" <- %s:%d\n", __func__, __LINE__);
return result;
}
--
1.7.0.4
^ permalink raw reply related
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Kumar Gala @ 2011-12-01 19:35 UTC (permalink / raw)
To: Jean-Michel Hautbois; +Cc: linuxppc-dev, Tabi Timur-B04825, linux-kernel
In-Reply-To: <CAL8zT=jgZS2=t0SadUXXshabKPsxHJe_frkfOw5XyF88k3jR=g@mail.gmail.com>
On Dec 1, 2011, at 11:52 AM, Jean-Michel Hautbois wrote:
> 2011/12/1 Jean-Michel Hautbois <jhautbois@gmail.com>:
>> 2011/12/1 Tabi Timur-B04825 <B04825@freescale.com>:
>>> On Thu, Dec 1, 2011 at 9:04 AM, Jean-Michel Hautbois
>>> <jhautbois@gmail.com> wrote:
>>>>
>>>> Any idea on how to debug this ? I am using a 2.6.35 kernel.
>>>
>>> There are a ton of Kconfig options for debugging various locking bugs.
>>> Try turning them on.
>>>
>
> All Kconfig options do not help me with cache coherency problems, though.
> Or, I didn't find any option related.
> Any idea ?
>
> JM
Nope, if you can't describe the code in any more detail we can't help.
- k
^ permalink raw reply
* Re: Different behaviour when using "nosmp" parameter on SMP and UP
From: Jean-Michel Hautbois @ 2011-12-01 20:09 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev, Tabi Timur-B04825, linux-kernel
In-Reply-To: <40F38A2B-48A0-4A8C-B45D-579865F135CC@kernel.crashing.org>
2011/12/1 Kumar Gala <galak@kernel.crashing.org>:
>
> On Dec 1, 2011, at 11:52 AM, Jean-Michel Hautbois wrote:
>
>> 2011/12/1 Jean-Michel Hautbois <jhautbois@gmail.com>:
>>> 2011/12/1 Tabi Timur-B04825 <B04825@freescale.com>:
>>>> On Thu, Dec 1, 2011 at 9:04 AM, Jean-Michel Hautbois
>>>> <jhautbois@gmail.com> wrote:
>>>>>
>>>>> Any idea on how to debug this ? I am using a 2.6.35 kernel.
>>>>
>>>> There are a ton of Kconfig options for debugging various locking bugs.
>>>> =C2=A0Try turning them on.
>>>>
>>
>> All Kconfig options do not help me with cache coherency problems, though=
.
>> Or, I didn't find any option related.
>> Any idea ?
>>
>> JM
>
> Nope, if you can't describe the code in any more detail we can't help.
>
Here is what I can tell, I hope this will help you.
I have a userland process, which reads and writes data to a character
device thanks to ioctl.
Reads and Writes are performed with this scheme :
Lock Access -> ioctl -> down_interruptible(semaphore)
Read (or Write) -> ioctl -> ioread32
Unlock Access -> ioctl -> up(semaphore)
It reads (or writes) 4 bytes by 4 bytes, in a loop in the process
which will eventually get several bytes from the PCIe device.
The read (write) ioctl is really simple (and in fact, may be rewritten) :
- kmalloc a structure, then copy_from_user
- ioread32 using adress and offset from the structure copied previously
- copy_to_user and free the structure.
The userland process is currently doing a loop in order to read or
writes with a 4bytes step.
I am neither the writer of the driver nor the userland process, this
is why I can't give you the code.
Here is what I would do, at least :
1/ rewrite the read/write part of the ioctl in order to user a per_cpu
structure and not a "dynamically allocated at each call" structure
2/ rewrite the userland part in order to ask the driver for n bytes,
leaving the loop on ioread32/iowrite32 inside the ioctl
Thanks for your help.
JM
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 20:54 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7CA64.2080503@freescale.com>
Scott Wood wrote:
> On 12/01/2011 11:33 AM, Timur Tabi wrote:
>> An I2C device tree node can contain a 'cell-index' property that can be
>> used to enumerate the I2C devices. If such a property exists, use it
>> to specify the I2C adapter number.
>
> Didn't we decide a long time ago that this was a bad idea?
I don't see what's wrong with it.
>> This feature is necessary for the Freescale PowerPC audio drivers (e.g.
>> on the P1022DS). The "machine driver" needs to know the adapter number
>> for each I2C adapter, but it only has access to the device tree.
>> Previously, the I2C nodes always appeared in cell-index order, so the
>> dynamic numbering coincided with the cell-index property. With commit
>> ab827d97 ("powerpc/85xx: Rework P1022DS device tree"), the I2C nodes are
>> unintentionally reversed in the device tree, and so the machine driver
>> guesses the wrong I2C adapter number.
>
> What specifically do you need this number for? What does it represent?
Well, I thought the above paragraph explained it pretty well.
Audio drivers come in sets of four -- machine, ssi, dma, and codec. The machine driver needs to know which ssi is connected to which codec and which DMA channel(s) it needs to use. So I extract all this information from the device tree.
The individual drivers, however, register only with their own subsystem. So the codec driver, for example, doesn't know anything about device trees -- it just registers as an i2c driver. That means that the machine driver has to guess what name the codec driver will use when it registers. In this case, that's the i2c device name, which include the I2C adapter number (adap->nr). That means that given a device tree node, I need to know what the actual bus number is.
An alternative approach is to create a function like this:
struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
I could then just use adap->nr directly.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Scott Wood @ 2011-12-01 21:29 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7E975.6090704@freescale.com>
On 12/01/2011 02:54 PM, Timur Tabi wrote:
> Scott Wood wrote:
>> On 12/01/2011 11:33 AM, Timur Tabi wrote:
>>> An I2C device tree node can contain a 'cell-index' property that can be
>>> used to enumerate the I2C devices. If such a property exists, use it
>>> to specify the I2C adapter number.
>>
>> Didn't we decide a long time ago that this was a bad idea?
>
> I don't see what's wrong with it.
Obviously, since you're suggesting doing it. :-P
Did you search for the old discussions?
How is this going to interact with other i2c buses (e.g. on a board
FPGA) that might have a conflicting static numbering scheme? Have you
ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
device) can happen before the static SoC i2c buses are added?
Global numberspaces of this sort are usually the wrong answer. Look at
the mess it made with IRQ numbers, and the gymnastics we go through to
virtualize it.
>>> This feature is necessary for the Freescale PowerPC audio drivers (e.g.
>>> on the P1022DS). The "machine driver" needs to know the adapter number
>>> for each I2C adapter, but it only has access to the device tree.
>>> Previously, the I2C nodes always appeared in cell-index order, so the
>>> dynamic numbering coincided with the cell-index property. With commit
>>> ab827d97 ("powerpc/85xx: Rework P1022DS device tree"), the I2C nodes are
>>> unintentionally reversed in the device tree, and so the machine driver
>>> guesses the wrong I2C adapter number.
>>
>> What specifically do you need this number for? What does it represent?
>
> Well, I thought the above paragraph explained it pretty well.
All you said was "needs to know the adapter number", nothing about why.
> Audio drivers come in sets of four -- machine, ssi, dma, and codec.
> The machine driver needs to know which ssi is connected to which
> codec and which DMA channel(s) it needs to use. So I extract all
> this information from the device tree.
>
> The individual drivers, however, register only with their own
> subsystem. So the codec driver, for example, doesn't know anything
> about device trees -- it just registers as an i2c driver. That means
> that the machine driver has to guess what name the codec driver will
> use when it registers. In this case, that's the i2c device name,
> which include the I2C adapter number (adap->nr). That means that
> given a device tree node, I need to know what the actual bus number
> is.
>
> An alternative approach is to create a function like this:
>
> struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
>
> I could then just use adap->nr directly.
If there isn't a way to get a "struct device" from "struct device_node",
we should add it. From that you should be able to look up the sysfs
name -- no need to mess around with adap->nr as an intermediary.
-Scott
^ permalink raw reply
* Re: [BUG?]3.0-rc4+ftrace+kprobe: set kprobe at instruction 'stwu' lead to system crash/freeze
From: Benjamin Herrenschmidt @ 2011-12-01 21:37 UTC (permalink / raw)
To: tiejun.chen
Cc: Jim Keniston, Anton Blanchard, linux-kernel, Steven Rostedt,
Yong Zhang, paulus, yrl.pp-manager.tt, Masami Hiramatsu,
linuxppc-dev
In-Reply-To: <4ED75A9A.1030100@windriver.com>
On Thu, 2011-12-01 at 18:44 +0800, tiejun.chen wrote:
> Do you mean we should push the original pt_regs (or that whole exception stack)
> downwards the location the new r1 point? Then its safe to perform this real
> emulated stw instruction. At last we will reroute r1 to that copied exception
> frame to restore as normal. Right?
Right. That way we don't have to modify the (sensitive) restore path, we
only hook around the do_work branch which is a lot easier and less
risky.
> Here I suppose so, I implement this for PPC32 based on the above understanding.
> I take a validation for kprobing do_fork()/show_interrupts(), now looks fine.
> Tomorrow I will go PPC64, and hope its fine as well.
>
> If everything is good I'll send these patches to linuxppc-dev next week.
Excellent, thanks !
Cheers,
Ben.
^ permalink raw reply
* Re: ppc4xx simple vs SoC's
From: Benjamin Herrenschmidt @ 2011-12-01 21:39 UTC (permalink / raw)
To: Josh Boyer; +Cc: linuxppc-dev
In-Reply-To: <CA+5PVA5xaCa8Tv3MMr1WzQAuLit9KenMoezOKB7ENQSt=fOSOg@mail.gmail.com>
On Thu, 2011-12-01 at 06:44 -0500, Josh Boyer wrote:
> > However, the entry for ppc44x_simple doesn't select any of these,
> > meaning for example, AFAIK, that you don't get EMAC4 etc... I'm
> > surprised things work at all !
> >
> > What am I missing ?
>
> CONFIG_PPC44x_SIMPLE is selected by the board Kconfig values, which
> also select all of the SoC Kconfig options they need as well.
> ppc44x_simple started as a way to basically avoid duplicating a bunch
> of board.c files, but it's still "driven" from the board options.
>
> So hopefully that explains how things are working today. The question
> now is whether you would like something different?
Ok, just getting my head around that stuff, I haven't really looked
since you and Grant I believe came up with the scheme :-) (Was wondering
what to do for currituck, but for now we'll keep it a separate board, at
least until I can decide how to deal with the interrupt quirk).
I just hadn't realized that while we had ppc4xx_simple, we still had
board Kconfig's to enable it.
Cheers,
Ben.
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 21:46 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F1AE.70806@freescale.com>
Scott Wood wrote:
> How is this going to interact with other i2c buses (e.g. on a board
> FPGA) that might have a conflicting static numbering scheme? Have you
> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
> device) can happen before the static SoC i2c buses are added?
Hmm.... You have a point there.
>> An alternative approach is to create a function like this:
>>
>> struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
>>
>> I could then just use adap->nr directly.
>
> If there isn't a way to get a "struct device" from "struct device_node",
> we should add it.
How do I do that? Scan all the struct devices until I find one where dev->of_node == np? That seems really inefficient.
--
Timur Tabi
Linux kernel developer at Freescale
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Scott Wood @ 2011-12-01 21:52 UTC (permalink / raw)
To: Timur Tabi; +Cc: linuxppc-dev, kumar.gala
In-Reply-To: <4ED7F5AA.2040909@freescale.com>
On 12/01/2011 03:46 PM, Timur Tabi wrote:
> Scott Wood wrote:
>
>> How is this going to interact with other i2c buses (e.g. on a board
>> FPGA) that might have a conflicting static numbering scheme? Have you
>> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
>> device) can happen before the static SoC i2c buses are added?
>
> Hmm.... You have a point there.
>
>>> An alternative approach is to create a function like this:
>>>
>>> struct i2c_adapter *i2c_adapter_from_node(struct device_node *np);
>>>
>>> I could then just use adap->nr directly.
>>
>> If there isn't a way to get a "struct device" from "struct device_node",
>> we should add it.
>
> How do I do that? Scan all the struct devices until I find one where dev->of_node == np? That seems really inefficient.
Ideally we would have a field in struct device_node that points to
struct device.
-Scott
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Grant Likely @ 2011-12-01 21:55 UTC (permalink / raw)
To: Scott Wood; +Cc: linuxppc-dev, kumar.gala, Timur Tabi
In-Reply-To: <4ED7F72F.7050405@freescale.com>
On Thu, Dec 1, 2011 at 2:52 PM, Scott Wood <scottwood@freescale.com> wrote:
> On 12/01/2011 03:46 PM, Timur Tabi wrote:
>> Scott Wood wrote:
>>
>>> How is this going to interact with other i2c buses (e.g. on a board
>>> FPGA) that might have a conflicting static numbering scheme? =A0Have yo=
u
>>> ensured that no dynamic bus registrations (e.g. an i2c bus on a PCI
>>> device) can happen before the static SoC i2c buses are added?
>>
>> Hmm.... You have a point there.
>>
>>>> An alternative approach is to create a function like this:
>>>>
>>>> =A0 =A0 struct i2c_adapter *i2c_adapter_from_node(struct device_node *=
np);
>>>>
>>>> I could then just use adap->nr directly.
>>>
>>> If there isn't a way to get a "struct device" from "struct device_node"=
,
>>> we should add it.
>>
>> How do I do that? =A0Scan all the struct devices until I find one where =
dev->of_node =3D=3D np? =A0That seems really inefficient.
>
> Ideally we would have a field in struct device_node that points to
> struct device.
No. There are cases where multiple devices may reference the same node.
It is better to walk the list of i2c adapters and look for one that
has the matching node pointer. It really isn't an expensive operation
to do it that way.
g.
^ permalink raw reply
* Re: [PATCH] i2c-mpc: use the cell-index property to enumerate the I2C adapters
From: Timur Tabi @ 2011-12-01 21:59 UTC (permalink / raw)
To: Grant Likely; +Cc: Scott Wood, linuxppc-dev, kumar.gala
In-Reply-To: <CACxGe6sZgG5q6NKgsGaWLyTzWHXNGqHke9nQMyqzw0audS3=tw@mail.gmail.com>
Grant Likely wrote:
> It is better to walk the list of i2c adapters and look for one that
> has the matching node pointer. It really isn't an expensive operation
> to do it that way.
That's what I was thinking. I can't figure out how to walk the list, though. i2c_get_adapter() takes an adapter number, but I don't think this is going to work:
unsigned int i = 0;
struct i2c_adapter adap = i2c_get_adapter(0);
while (adap) {
if (adap->nr == nr)
break;
adap = i2c_get_adapter(++i);
}
--
Timur Tabi
Linux kernel developer at Freescale
^ 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