LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 4/5] Convert PowerPC MPC i2c to of_platform_driver from platform_driver
From: Jon Smirl @ 2008-01-02 19:49 UTC (permalink / raw)
  To: Jochen Friedrich; +Cc: Scott Wood, linuxppc-dev
In-Reply-To: <477BE8F8.9030804@scram.de>

On 1/2/08, Jochen Friedrich <jochen@scram.de> wrote:
>
> Should this go into some central file? Else we would have to copy it in any i2c bus driver that supports powerpc.
> This would at least be i2c-cpm and i2c-gpio.

I can change that in the next rev. I'm waiting to see if there are any
more changes.

> IMHO, there should be a node attribute to override i2c_adapter.class. Legacy i2c drivers (in particular v4l and dvb drivers) use this class to decide which adapter to bind to. dbox2 needs I2C_CLASS_TV_DIGITAL (4).

I hadn't paid any attention to i2c_adapter.class. Now that you mention
it I wonder why i2c has it.  It appears to be a holdover from the
older mechanism of searching for devices and it is used as a filter to
reduce the number of device being searched. I would think a new style
driver could just ignore it.

It is probably best to fix it in a successive patch.


-- 
Jon Smirl
jonsmirl@gmail.com

^ permalink raw reply

* [PATCHv2] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Jochen Friedrich @ 2008-01-02 19:52 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Jean Delvare, linuxppc-dev, linux-kernel, Scott Wood

Using the port of 2.4 code from Vitaly Bordug <vitb@kernel.crashing.org>
and the actual algorithm used by the i2c driver of the DBox code on
cvs.tuxboc.org from Tmbinc, Gillem (htoa@gmx.net). Renamed i2c-rpx.c and
i2c-algo-8xx.c to i2c-cpm.c and converted the driver to an
of_platform_driver.

Signed-off-by: Jochen Friedrich <jochen@scram.de>
---
 arch/powerpc/boot/dts/mpc8272ads.dts         |   10 +
 arch/powerpc/boot/dts/mpc866ads.dts          |   10 +
 arch/powerpc/boot/dts/mpc885ads.dts          |   10 +
 arch/powerpc/platforms/8xx/mpc885ads_setup.c |    5 +
 drivers/i2c/busses/Kconfig                   |   10 +
 drivers/i2c/busses/Makefile                  |    1 +
 drivers/i2c/busses/i2c-cpm.c                 |  786 ++++++++++++++++++++++++++
 7 files changed, 832 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/busses/i2c-cpm.c

diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 7285ca1..7273996 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -215,6 +215,16 @@
 				linux,network-index = <1>;
 				fsl,cpm-command = <16200300>;
 			};
+
+			i2c@11860 {
+				compatible = "fsl,mpc8248-i2c",
+					     "fsl,cpm2-i2c",
+					     "fsl,cpm-i2c";
+				reg = <11860 20 8afc 2>;
+				interrupts = <1 8>;
+				interrupt-parent = <&PIC>;
+				fsl,cpm-command = <29600000>;
+			};
 		};
 
 		PIC: interrupt-controller@10c00 {
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index daf9433..80c08bf 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -169,6 +169,16 @@
 				fsl,cpm-command = <0000>;
 				linux,network-index = <1>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc866-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10 3>;
+				interrupt-parent = <&Cpm_pic>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index 8848e63..fd9c9d7 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -213,6 +213,16 @@
 				fsl,cpm-command = <0080>;
 				linux,network-index = <2>;
 			};
+
+			i2c@860 {
+				compatible = "fsl,mpc885-i2c",
+					     "fsl,cpm1-i2c",
+					     "fsl,cpm-i2c";
+				reg = <860 20 3c80 30>;
+				interrupts = <10>;
+				interrupt-parent = <&CPM_PIC>;
+				fsl,cpm-command = <0010>;
+			};
 		};
 	};
 
diff --git a/arch/powerpc/platforms/8xx/mpc885ads_setup.c b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
index 2cf1b6a..4377521 100644
--- a/arch/powerpc/platforms/8xx/mpc885ads_setup.c
+++ b/arch/powerpc/platforms/8xx/mpc885ads_setup.c
@@ -157,6 +157,11 @@ static struct cpm_pin mpc885ads_pins[] = {
 	{CPM_PORTE, 28, CPM_PIN_OUTPUT},
 	{CPM_PORTE, 29, CPM_PIN_OUTPUT},
 #endif
+	/* I2C */
+#ifdef CONFIG_I2C_8XX
+	{CPM_PORTB, 26, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+	{CPM_PORTB, 27, CPM_PIN_INPUT | CPM_PIN_OPENDRAIN},
+#endif
 };
 
 static void __init init_ioports(void)
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index c466c6c..5950172 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -114,6 +114,16 @@ config I2C_BLACKFIN_TWI_CLK_KHZ
 	help
 	  The unit of the TWI clock is kHz.
 
+config I2C_CPM
+	tristate "Freescale CPM1 or CPM2 (MPC8xx/826x)"
+	depends on (CPM1 || CPM2) && I2C && PPC_OF
+	help
+	  This supports the use of the I2C interface on Freescale
+	  processors with CPM1 or CPM2.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called i2c-cpm.
+
 config I2C_DAVINCI
 	tristate "DaVinci I2C driver"
 	depends on ARCH_DAVINCI
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 81d43c2..a395555 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_I2C_AMD8111)	+= i2c-amd8111.o
 obj-$(CONFIG_I2C_AT91)		+= i2c-at91.o
 obj-$(CONFIG_I2C_AU1550)	+= i2c-au1550.o
 obj-$(CONFIG_I2C_BLACKFIN_TWI)	+= i2c-bfin-twi.o
+obj-$(CONFIG_I2C_CPM)		+= i2c-cpm.o
 obj-$(CONFIG_I2C_DAVINCI)	+= i2c-davinci.o
 obj-$(CONFIG_I2C_ELEKTOR)	+= i2c-elektor.o
 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
new file mode 100644
index 0000000..f5371c6
--- /dev/null
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -0,0 +1,786 @@
+/*
+ * Freescale CPM1/CPM2 I2C interface.
+ * Copyright (c) 1999 Dan Malek (dmalek@jlc.net).
+ *
+ * moved into proper i2c interface;
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * RPX lite specific parts of the i2c interface
+ * Update:  There actually isn't anything RPXLite-specific about this module.
+ * This should work for most any CPM board.  The console messages have been
+ * changed to eliminate RPXLite references.
+ *
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * moved into proper i2c interface; separated out platform specific
+ * parts into i2c-8xx.c
+ * Brad Parker (brad@heeltoe.com)
+ *
+ * Parts from dbox2_i2c.c (cvs.tuxbox.org)
+ * (C) 2000-2001 Tmbinc, Gillem (htoa@gmx.net)
+ *
+ * (C) 2007 Montavista Software, Inc.
+ * Vitaly Bordug <vitb@kernel.crashing.org>
+ *
+ * Converted to of_platform_device. Renamed to i2c-cpm.c.
+ * (C) 2007 Jochen Friedrich <jochen@scram.de>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/stddef.h>
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/time.h>
+#include <linux/dma-mapping.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <sysdev/fsl_soc.h>
+#include <asm/cpm.h>
+
+/* Try to define this if you have an older CPU (earlier than rev D4) */
+/* However, better use a GPIO based bitbang driver in this case :/   */
+#undef	I2C_CHIP_ERRATA
+
+#define CPM_MAX_READ    513
+#define CPM_MAXBD       4
+
+#define CPM_CR_INIT_TRX		(0x00)
+#define CPM_CR_CLOSE_RXBD	(0x07)
+
+#define I2C_EB			(0x10) /* Big endian mode */
+
+/* I2C parameter RAM. */
+struct i2c_ram {
+	ushort  rbase;		/* Rx Buffer descriptor base address */
+	ushort  tbase;		/* Tx Buffer descriptor base address */
+	u_char  rfcr;		/* Rx function code */
+	u_char  tfcr;		/* Tx function code */
+	ushort  mrblr;		/* Max receive buffer length */
+	uint    rstate;		/* Internal */
+	uint    rdp;		/* Internal */
+	ushort  rbptr;		/* Rx Buffer descriptor pointer */
+	ushort  rbc;		/* Internal */
+	uint    rxtmp;		/* Internal */
+	uint    tstate;		/* Internal */
+	uint    tdp;		/* Internal */
+	ushort  tbptr;		/* Tx Buffer descriptor pointer */
+	ushort  tbc;		/* Internal */
+	uint    txtmp;		/* Internal */
+	char    res1[4];	/* Reserved */
+	ushort  rpbase;		/* Relocation pointer */
+	char    res2[2];	/* Reserved */
+};
+
+/* I2C Registers */
+struct i2c_reg {
+	u8	i2mod;
+	u8	res1[3];
+	u8	i2add;
+	u8	res2[3];
+	u8	i2brg;
+	u8	res3[3];
+	u8	i2com;
+	u8	res4[3];
+	u8	i2cer;
+	u8	res5[3];
+	u8	i2cmr;
+};
+
+struct cpm_i2c {
+	char *base;
+	struct of_device *ofdev;
+	struct i2c_adapter adap;
+	uint dp_addr;
+	int version; /* CPM1=1, CPM2=2 */
+	int irq;
+	int cp_command;
+	struct i2c_reg __iomem *i2c_reg;
+	struct i2c_ram __iomem *i2c_ram;
+	u16 i2c_addr;
+	wait_queue_head_t i2c_wait;
+	struct mutex i2c_mutex; /* Protects I2C CPM */
+	u_char *txbuf[CPM_MAXBD];
+	u_char *rxbuf[CPM_MAXBD];
+	u32 txdma[CPM_MAXBD];
+	u32 rxdma[CPM_MAXBD];
+};
+
+static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
+{
+	struct i2c_adapter *adap;
+	struct cpm_i2c *cpm;
+	struct i2c_reg __iomem *i2c_reg;
+	int i;
+
+	adap = (struct i2c_adapter *) dev_id;
+	cpm = i2c_get_adapdata(adap);
+	i2c_reg = cpm->i2c_reg;
+
+	/* Clear interrupt.
+	 */
+	i = in_8(&i2c_reg->i2cer);
+	out_8(&i2c_reg->i2cer, i);
+
+	dev_dbg(&adap->dev, "Interrupt: %x\n", i);
+
+	/* Get 'me going again.
+	 */
+	wake_up_interruptible(&cpm->i2c_wait);
+
+	return i ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static void cpm_reset_i2c_params(struct cpm_i2c *cpm)
+{
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+
+	/* Set up the IIC parameters in the parameter ram.
+	 */
+	out_be16(&i2c_ram->tbase, cpm->dp_addr);
+	out_be16(&i2c_ram->rbase, cpm->dp_addr + sizeof(cbd_t) * CPM_MAXBD);
+
+	out_8(&i2c_ram->tfcr, I2C_EB);
+	out_8(&i2c_ram->rfcr, I2C_EB);
+
+	out_be16(&i2c_ram->mrblr, CPM_MAX_READ);
+
+	out_be32(&i2c_ram->rstate, 0);
+	out_be32(&i2c_ram->rdp, 0);
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->rbc, 0);
+	out_be32(&i2c_ram->rxtmp, 0);
+	out_be32(&i2c_ram->tstate, 0);
+	out_be32(&i2c_ram->tdp, 0);
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+	out_be16(&i2c_ram->tbc, 0);
+	out_be32(&i2c_ram->txtmp, 0);
+}
+
+static void cpm_i2c_force_close(struct i2c_adapter *adap)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+
+	dev_dbg(&adap->dev, "cpm_i2c_force_close()\n");
+
+	cpm_command(cpm->cp_command, CPM_CR_CLOSE_RXBD);
+
+	out_8(&i2c_reg->i2cmr, 0x00);	/* Disable all interrupts */
+	out_8(&i2c_reg->i2cer, 0xff);
+}
+
+static void cpm_i2c_parse_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int num, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char addr;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i, dscan;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	/* This chip can't do zero length writes. However, the i2c core uses
+	   them to scan for devices. The best we can do is to convert them
+	   into 1 byte reads */
+
+	dscan = ((pmsg->len == 0) && (num == 1));
+
+	addr = pmsg->addr << 1;
+	if ((pmsg->flags & I2C_M_RD) || dscan)
+		addr |= 1;
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((ulong) rb + 1) & ~1);
+
+	if ((pmsg->flags & I2C_M_RD) || dscan) {
+		/* To read, we need an empty buffer of the proper length.
+		 * All that is used is the first byte for address, the remainder
+		 * is just used for timing (and doesn't really have to exist).
+		 */
+		tb[0] = addr;		/* Device address byte w/rw flag */
+
+		dev_dbg(&adap->dev, "cpm_i2c_read(abyte=0x%x)\n", addr);
+
+		if (dscan)
+			tbdf[tx].cbd_datlen = 2;
+		else
+			tbdf[tx].cbd_datlen = pmsg->len + 1;
+
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		rbdf[rx].cbd_datlen = 0;
+		rbdf[rx].cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
+
+		if (rx + 1 == CPM_MAXBD)
+			tbdf[rx].cbd_sc |= BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY;
+	} else {
+		tb[0] = addr;		/* Device address byte w/rw flag */
+		for (i = 0; i < pmsg->len; i++)
+			tb[i+1] = pmsg->buf[i];
+
+		dev_dbg(&adap->dev, "cpm_iic_write(abyte=0x%x)\n", addr);
+
+		tbdf[tx].cbd_datlen = pmsg->len + 1;
+		tbdf[tx].cbd_sc = 0;
+
+		if (!(pmsg->flags & I2C_M_NOSTART))
+			tbdf[tx].cbd_sc |= BD_I2C_START;
+
+		if (tx + 1 == num)
+			tbdf[tx].cbd_sc |= BD_SC_LAST | BD_SC_WRAP;
+
+		eieio();
+		tbdf[tx].cbd_sc |= BD_SC_READY | BD_SC_INTRPT;
+
+		dev_dbg(&adap->dev, "tx sc %d %04x\n",
+			tx, tbdf[tx].cbd_sc);
+	}
+}
+
+static int cpm_i2c_check_message(struct i2c_adapter *adap,
+	struct i2c_msg *pmsg, int tx, int rx)
+{
+	cbd_t *tbdf, *rbdf;
+	u_char *tb;
+	u_char *rb;
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	int i;
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tb = cpm->txbuf[tx];
+	rb = cpm->rxbuf[rx];
+
+	/* Align read buffer */
+	rb = (u_char *) (((uint) rb + 1) & ~1);
+
+	if (pmsg->flags & I2C_M_RD) {
+		dev_dbg(&adap->dev, "rx sc %04x, rx sc %04x\n",
+			tbdf[tx].cbd_sc, rbdf[rx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC read; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_EMPTY) {
+			dev_dbg(&adap->dev,
+				"IIC read; complete but rbuf empty\n");
+			return -EREMOTEIO;
+		}
+		if (rbdf[rx].cbd_sc & BD_SC_OV) {
+			dev_dbg(&adap->dev, "IIC read; Overrun\n");
+			return -EREMOTEIO;
+		}
+		for (i = 0; i < pmsg->len; i++)
+			pmsg->buf[i] = rb[i];
+	} else {
+		dev_dbg(&adap->dev, "tx sc %d %04x\n", tx, tbdf[tx].cbd_sc);
+
+		if (tbdf[tx].cbd_sc & BD_SC_NAK) {
+			dev_dbg(&adap->dev, "IIC write; No ack\n");
+
+			if (pmsg->flags & I2C_M_IGNORE_NAK)
+				return 0;
+			else
+				return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_UN) {
+			dev_dbg(&adap->dev, "IIC write; Underrun\n");
+			return -EIO;
+		}
+		if (tbdf[tx].cbd_sc & BD_SC_CL) {
+			dev_dbg(&adap->dev, "IIC write; Collision\n");
+			return -EIO;
+		}
+	}
+	return 0;
+}
+
+static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
+{
+	struct cpm_i2c *cpm = i2c_get_adapdata(adap);
+	struct i2c_reg __iomem *i2c_reg = cpm->i2c_reg;
+	struct i2c_ram __iomem *i2c_ram = cpm->i2c_ram;
+	struct i2c_msg *pmsg, *rmsg;
+	int ret, i;
+	int tptr;
+	int rptr;
+	cbd_t *tbdf, *rbdf;
+
+	if (num > CPM_MAXBD)
+		return -EINVAL;
+
+	/* Check if we have any oversized READ requests */
+	for (i = 0; i < num; i++) {
+		pmsg = &msgs[i];
+		if (pmsg->len >= CPM_MAX_READ)
+			return -EINVAL;
+	}
+
+	mutex_lock(&cpm->i2c_mutex);
+
+	/* Reset to use first buffer */
+	out_be16(&i2c_ram->rbptr, in_be16(&i2c_ram->rbase));
+	out_be16(&i2c_ram->tbptr, in_be16(&i2c_ram->tbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&i2c_ram->rbase));
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		pmsg = &msgs[tptr];
+		dev_dbg(&adap->dev, "i2c-algo-cpm.o: " "R: %d T: %d\n",
+			rptr, tptr);
+
+		cpm_i2c_parse_message(adap, pmsg, num, tptr, rptr);
+		if (pmsg->flags & I2C_M_RD)
+			rptr++;
+		tptr++;
+	}
+	/* Start transfer now */
+	/* Chip bug, set enable here */
+	out_8(&i2c_reg->i2cmr, 0x13);	/* Enable RX/TX/Error interupts */
+	out_8(&i2c_reg->i2cer, 0xff);	/* Clear interrupt status */
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | 1);	/* Enable */
+	/* Begin transmission */
+	out_8(&i2c_reg->i2com, in_8(&i2c_reg->i2com) | 0x80);
+
+	tptr = 0;
+	rptr = 0;
+
+	while (tptr < num) {
+		/* Check for outstanding messages */
+		dev_dbg(&adap->dev, "test ready.\n");
+		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
+			dev_dbg(&adap->dev, "ready.\n");
+			rmsg = &msgs[tptr];
+			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
+			tptr++;
+			if (rmsg->flags & I2C_M_RD)
+				rptr++;
+			if (ret) {
+				cpm_i2c_force_close(adap);
+				mutex_unlock(&cpm->i2c_mutex);
+				return ret;
+			}
+		} else {
+			dev_dbg(&adap->dev, "not ready.\n");
+			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
+				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
+			if (ret == 0) {
+				cpm_i2c_force_close(adap);
+				dev_dbg(&adap->dev, "I2C read: timeout!\n");
+				mutex_unlock(&cpm->i2c_mutex);
+				return -EREMOTEIO;
+			}
+		}
+	}
+#ifdef I2C_CHIP_ERRATA
+	/* Chip errata, clear enable. This is not needed on rev D4 CPUs.
+	   Disabling I2C too early may cause too short stop condition */
+	udelay(4);
+	out_8(&i2c_reg->i2mod, in_8(&i2c_reg->i2mod) | ~1);
+#endif
+	mutex_unlock(&cpm->i2c_mutex);
+	return (num);
+}
+
+static u32 cpm_i2c_func(struct i2c_adapter *adap)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+/* -----exported algorithm data: -------------------------------------	*/
+
+static struct i2c_algorithm cpm_i2c_algo = {
+	.master_xfer = cpm_i2c_xfer,
+	.functionality = cpm_i2c_func,
+};
+
+static const struct i2c_adapter cpm_ops = {
+	.owner		= THIS_MODULE,
+	.name		= "i2c-cpm",
+	.id		= I2C_HW_MPC8XX_EPON,
+	.algo		= &cpm_i2c_algo,
+	.class		= I2C_CLASS_HWMON,
+};
+
+static int cpm_i2c_setup(struct cpm_i2c *cpm)
+{
+	struct of_device *ofdev = cpm->ofdev;
+	const u32 *data;
+	int len, ret, i;
+	void __iomem *i2c_base;
+	cbd_t *tbdf, *rbdf;
+	unsigned char brg;
+
+	pr_debug("i2c-cpm: cpm_i2c_setup()\n");
+
+	init_waitqueue_head(&cpm->i2c_wait);
+	mutex_init(&cpm->i2c_mutex);
+
+	cpm->irq = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (cpm->irq == NO_IRQ)
+		return -EINVAL;
+
+	/* Install interrupt handler.
+	 */
+	ret = request_irq(cpm->irq, cpm_i2c_interrupt, 0, "cpm_i2c",
+			  &cpm->adap);
+	if (ret)
+		goto out_irq;
+
+	/* IIC parameter RAM */
+	i2c_base = of_iomap(ofdev->node, 1);
+	if (i2c_base == NULL) {
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	if (of_device_is_compatible(ofdev->node, "fsl,cpm1-i2c")) {
+
+		/* Check for and use a microcode relocation patch. */
+		cpm->i2c_ram = i2c_base;
+		cpm->i2c_addr = in_be16(&cpm->i2c_ram->rpbase);
+
+		/* Maybe should use cpm_muram_alloc instead of hardcoding
+		 * this in micropatch.c */
+		if (cpm->i2c_addr) {
+			cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+			iounmap(i2c_base);
+		}
+
+		cpm->version = 1;
+
+	} else if (of_device_is_compatible(ofdev->node, "fsl,cpm2-i2c")) {
+		cpm->i2c_addr = cpm_muram_alloc(sizeof(struct i2c_ram), 64);
+		cpm->i2c_ram = cpm_muram_addr(cpm->i2c_addr);
+		out_be16(i2c_base, cpm->i2c_addr);
+		iounmap(i2c_base);
+
+		cpm->version = 2;
+
+	} else {
+		iounmap(i2c_base);
+		ret = -EINVAL;
+		goto out_irq;
+	}
+
+	/* I2C control/status registers */
+	cpm->i2c_reg = of_iomap(ofdev->node, 0);
+	if (cpm->i2c_reg == NULL) {
+		ret = -EINVAL;
+		goto out_ram;
+	}
+
+	data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+	if (!data || len != 4) {
+		ret = -EINVAL;
+		goto out_reg;
+	}
+	cpm->cp_command = *data;
+
+	/* Allocate space for CPM_MAXBD transmit and receive buffer
+	 * descriptors in the DP ram.
+	 */
+	cpm->dp_addr = cpm_muram_alloc(sizeof(cbd_t) * 2 * CPM_MAXBD, 8);
+	if (!cpm->dp_addr) {
+		ret = -ENOMEM;
+		goto out_reg;
+	}
+
+	/* Initialize Tx/Rx parameters. */
+
+	cpm_reset_i2c_params(cpm);
+
+	pr_debug("i2c-cpm: i2c_ram %x, dp_addr 0x%x\n", (uint) cpm->i2c_ram,
+		cpm->dp_addr);
+	pr_debug("i2c-cpm: tbase %d, rbase %d\n",
+		in_be16(&cpm->i2c_ram->tbase), in_be16(&cpm->i2c_ram->rbase));
+
+	tbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->tbase));
+	rbdf = (cbd_t *) cpm_muram_addr(in_be16(&cpm->i2c_ram->rbase));
+
+	/* Allocate TX and RX buffers */
+
+	for (i = 0; i < CPM_MAXBD; i++) {
+		cpm->rxbuf[i] = dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+		if (!cpm->rxbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		rbdf[i].cbd_bufaddr = ((cpm->rxdma[i] + 1) & ~1);
+		cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
+			NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+		if (!cpm->txbuf[i]) {
+			ret = -ENOMEM;
+			goto out_muram;
+		}
+		tbdf[i].cbd_bufaddr = cpm->txdma[i];
+	}
+
+	cpm_command(cpm->cp_command, CPM_CR_INIT_TRX);
+
+	/* Select an invalid address. Just make sure we don't use loopback mode
+	 */
+	out_8(&cpm->i2c_reg->i2add, 0xfe);
+
+	/* Make clock run at 60 kHz. */
+
+	brg = get_brgfreq() / (32 * 2 * 60000) - 3;
+	out_8(&cpm->i2c_reg->i2brg, brg);
+
+	out_8(&cpm->i2c_reg->i2mod, 0x00);
+	out_8(&cpm->i2c_reg->i2com, 0x01);	/* Master mode */
+
+	/* Disable interrupts. */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	return 0;
+
+out_muram:
+	for (i = 0; i < CPM_MAXBD; i++) {
+		if (cpm->rxbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->rxbuf[i], cpm->rxdma[i]);
+		if (cpm->txbuf[i])
+			dma_free_coherent(NULL, CPM_MAX_READ + 1,
+				cpm->txbuf[i], cpm->txdma[i]);
+	}
+	cpm_muram_free(cpm->dp_addr);
+out_reg:
+	iounmap(cpm->i2c_reg);
+out_ram:
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+out_irq:
+	free_irq(cpm->irq, &cpm->adap);
+	return ret;
+}
+
+static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
+{
+	int i;
+
+	/* Shut down I2C. */
+	out_8(&cpm->i2c_reg->i2mod, in_8(&cpm->i2c_reg->i2mod) | ~1);
+
+	/* Disable interrupts */
+	out_8(&cpm->i2c_reg->i2cmr, 0);
+	out_8(&cpm->i2c_reg->i2cer, 0xff);
+
+	free_irq(cpm->irq, &cpm->adap);
+
+	/* Free all memory */
+	for (i = 0; i < CPM_MAXBD; i++) {
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->rxbuf[i], cpm->rxdma[i]);
+		dma_free_coherent(NULL, CPM_MAX_READ + 1,
+			cpm->txbuf[i], cpm->txdma[i]);
+	}
+
+	cpm_muram_free(cpm->dp_addr);
+	iounmap(cpm->i2c_reg);
+
+	if ((cpm->version == 1) && (!cpm->i2c_addr))
+		iounmap(cpm->i2c_ram);
+	if (cpm->version == 2)
+		cpm_muram_free(cpm->i2c_addr);
+
+	return;
+}
+
+static void of_register_i2c_devices(struct i2c_adapter *adap,
+				    struct device_node *adap_node)
+{
+	struct device_node *node = NULL;
+
+	while ((node = of_get_next_child(adap_node, node))) {
+		struct i2c_board_info info;
+		const u32 *addr;
+		const char *compatible;
+		int len;
+
+		addr = of_get_property(node, "reg", &len);
+		if (!addr || len < sizeof(int) || *addr > (1 << 10) - 1) {
+			printk(KERN_ERR "i2c-cpm.c: invalid entry, "
+			       "missing reg attribute\n");
+			continue;
+		}
+
+		info.irq = irq_of_parse_and_map(node, 0);
+		if (info.irq == NO_IRQ)
+			info.irq = -1;
+
+		compatible = of_get_property(node, "compatible", &len);
+		if (!compatible) {
+			printk(KERN_ERR "i2c-cpm.c: invalid entry, "
+			       "missing compatible attribute\n");
+			continue;
+		}
+
+		/* need full alias i2c:NOF,vendor,device */
+		strcpy(info.driver_name, I2C_OF_MODULE_PREFIX);
+		strncat(info.driver_name, compatible, sizeof(info.driver_name));
+		request_module(info.driver_name);
+
+		/* need module alias OF,vendor,device */
+		strcpy(info.driver_name, OF_I2C_PREFIX);
+		strncat(info.driver_name, compatible, sizeof(info.driver_name));
+
+		info.type[0] = '\0';
+		info.platform_data = NULL;
+		info.addr = *addr;
+
+		if (!i2c_new_device(adap, &info)) {
+			printk(KERN_ERR "i2c-cpm.c: Failed to load driver for "
+			       "%s\n", info.driver_name);
+			continue;
+		}
+	}
+}
+
+static int cpm_i2c_probe(struct of_device *ofdev,
+			 const struct of_device_id *match)
+{
+	int result;
+	struct cpm_i2c *cpm;
+
+	cpm = kzalloc(sizeof(struct cpm_i2c), GFP_KERNEL);
+	if (!cpm)
+		return -ENOMEM;
+
+	cpm->ofdev = ofdev;
+
+	dev_set_drvdata(&ofdev->dev, cpm);
+
+	cpm->adap = cpm_ops;
+	i2c_set_adapdata(&cpm->adap, cpm);
+	cpm->adap.dev.parent = &ofdev->dev;
+
+	result = cpm_i2c_setup(cpm);
+	if (result) {
+		printk(KERN_ERR "i2c-cpm: Unable to init hardware\n");
+		goto out;
+	}
+
+	/* register new adapter to i2c module... */
+
+	result = i2c_add_adapter(&cpm->adap);
+	if (result < 0) {
+		printk(KERN_ERR "i2c-cpm: Unable to register with I2C\n");
+		goto out2;
+	}
+
+	pr_debug("i2c-cpm: hw routines for %s registered.\n", cpm->adap.name);
+
+	of_register_i2c_devices(&cpm->adap, ofdev->node);
+
+	return 0;
+out2:
+	cpm_i2c_shutdown(cpm);
+out:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return result;
+}
+
+static int cpm_i2c_remove(struct of_device *ofdev)
+{
+	struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);
+
+	i2c_del_adapter(&cpm->adap);
+
+	cpm_i2c_shutdown(cpm);
+
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(cpm);
+
+	return 0;
+}
+
+static struct of_device_id cpm_i2c_match[] = {
+	{
+		.compatible = "fsl,cpm-i2c",
+	},
+	{},
+};
+
+MODULE_DEVICE_TABLE(of, cpm_i2c_match);
+
+static struct of_platform_driver cpm_i2c_driver = {
+	.match_table	= cpm_i2c_match,
+	.probe		= cpm_i2c_probe,
+	.remove		= __devexit_p(cpm_i2c_remove),
+	.driver		= {
+		.name	= "fsl-i2c-cpm",
+		.owner	= THIS_MODULE,
+	}
+};
+
+static int __init cpm_i2c_init(void)
+{
+	return of_register_platform_driver(&cpm_i2c_driver);
+}
+
+static void __exit cpm_i2c_exit(void)
+{
+	of_unregister_platform_driver(&cpm_i2c_driver);
+}
+
+module_init(cpm_i2c_init);
+module_exit(cpm_i2c_exit);
+
+MODULE_AUTHOR("Dan Malek <dmalek@jlc.net>");
+MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
+MODULE_LICENSE("GPL");
-- 
1.5.3.7

^ permalink raw reply related

* Re: [PATCH 1/5] [POWERPC] powermac: Use machine_*_initcall() hooks in platform code
From: Benjamin Herrenschmidt @ 2008-01-02 20:20 UTC (permalink / raw)
  To: Grant Likely; +Cc: olof, linuxppc-dev
In-Reply-To: <20080102191424.24178.41726.stgit@trillian.secretlab.ca>


On Wed, 2008-01-02 at 12:14 -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

Ack.

> 
>  arch/powerpc/platforms/powermac/low_i2c.c    |    7 ++-----
>  arch/powerpc/platforms/powermac/pfunc_base.c |    3 +--
>  arch/powerpc/platforms/powermac/pic.c        |    3 +--
>  arch/powerpc/platforms/powermac/setup.c      |   12 ++----------
>  4 files changed, 6 insertions(+), 19 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c
> index da2007e..9c9299c 100644
> --- a/arch/powerpc/platforms/powermac/low_i2c.c
> +++ b/arch/powerpc/platforms/powermac/low_i2c.c
> @@ -1462,9 +1462,6 @@ int __init pmac_i2c_init(void)
>  		return 0;
>  	i2c_inited = 1;
>  
> -	if (!machine_is(powermac))
> -		return 0;
> -
>  	/* Probe keywest-i2c busses */
>  	kw_i2c_probe();
>  
> @@ -1483,7 +1480,7 @@ int __init pmac_i2c_init(void)
>  
>  	return 0;
>  }
> -arch_initcall(pmac_i2c_init);
> +machine_arch_initcall(powermac, pmac_i2c_init);
>  
>  /* Since pmac_i2c_init can be called too early for the platform device
>   * registration, we need to do it at a later time. In our case, subsys
> @@ -1515,4 +1512,4 @@ static int __init pmac_i2c_create_platform_devices(void)
>  
>  	return 0;
>  }
> -subsys_initcall(pmac_i2c_create_platform_devices);
> +machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices);
> diff --git a/arch/powerpc/platforms/powermac/pfunc_base.c b/arch/powerpc/platforms/powermac/pfunc_base.c
> index 45d54b9..db20de5 100644
> --- a/arch/powerpc/platforms/powermac/pfunc_base.c
> +++ b/arch/powerpc/platforms/powermac/pfunc_base.c
> @@ -363,8 +363,7 @@ int __init pmac_pfunc_base_install(void)
>  
>  	return 0;
>  }
> -
> -arch_initcall(pmac_pfunc_base_install);
> +machine_arch_initcall(powermac, pmac_pfunc_base_install);
>  
>  #ifdef CONFIG_PM
>  
> diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
> index 999f5e1..cd72164 100644
> --- a/arch/powerpc/platforms/powermac/pic.c
> +++ b/arch/powerpc/platforms/powermac/pic.c
> @@ -690,6 +690,5 @@ static int __init init_pmacpic_sysfs(void)
>  	sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
>  	return 0;
>  }
> -
> -subsys_initcall(init_pmacpic_sysfs);
> +machine_subsys_initcall(powermac, init_pmacpic_sysfs);
>  
> diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
> index adad4e9..36ff1b6 100644
> --- a/arch/powerpc/platforms/powermac/setup.c
> +++ b/arch/powerpc/platforms/powermac/setup.c
> @@ -397,17 +397,13 @@ static int initializing = 1;
>  
>  static int pmac_late_init(void)
>  {
> -	if (!machine_is(powermac))
> -		return -ENODEV;
> -
>  	initializing = 0;
>  	/* this is udbg (which is __init) and we can later use it during
>  	 * cpu hotplug (in smp_core99_kick_cpu) */
>  	ppc_md.progress = NULL;
>  	return 0;
>  }
> -
> -late_initcall(pmac_late_init);
> +machine_late_initcall(powermac, pmac_late_init);
>  
>  /*
>   * This is __init_refok because we check for "initializing" before
> @@ -534,9 +530,6 @@ static int __init pmac_declare_of_platform_devices(void)
>  	if (machine_is(chrp))
>  		return -1;
>  
> -	if (!machine_is(powermac))
> -		return 0;
> -
>  	np = of_find_node_by_name(NULL, "valkyrie");
>  	if (np)
>  		of_platform_device_create(np, "valkyrie", NULL);
> @@ -551,8 +544,7 @@ static int __init pmac_declare_of_platform_devices(void)
>  
>  	return 0;
>  }
> -
> -device_initcall(pmac_declare_of_platform_devices);
> +machine_device_initcall(powermac, pmac_declare_of_platform_devices);
>  
>  /*
>   * Called very early, MMU is off, device-tree isn't unflattened

^ permalink raw reply

* Re: [PATCH 3/5] [POWERPC] pasemi: Use machine_*_initcall() hooks in platform code
From: Olof Johansson @ 2008-01-02 20:30 UTC (permalink / raw)
  To: Grant Likely; +Cc: linuxppc-dev
In-Reply-To: <20080102191441.24178.42988.stgit@trillian.secretlab.ca>

On Wed, Jan 02, 2008 at 12:32:28PM -0700, Grant Likely wrote:
> From: Grant Likely <grant.likely@secretlab.ca>
> 
> Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> 
>  arch/powerpc/platforms/pasemi/idle.c  |    5 +----
>  arch/powerpc/platforms/pasemi/setup.c |   10 ++--------
>  2 files changed, 3 insertions(+), 12 deletions(-)

Applied to for-2.6.25.

Thanks,

-Olof

^ permalink raw reply

* Re: [PATCH/RFC] powerpc: DBox2 Board Support
From: Jochen Friedrich @ 2008-01-02 20:29 UTC (permalink / raw)
  To: Scott Wood; +Cc: linuxppc-dev
In-Reply-To: <20080102180655.GB4398@loki.buserror.net>

Hi Scott,

> These unit addresses look wrong.

I know. These have (hopefully) been fixed in v3.

> What does dbox2-config mean?

I used it to search for the vendor info byte in the flash. It has been moved to the boot wrapper in v3.
Later this should all be moved to u-boot, IMHO.

>> +			ovpartition@20000 {
>> +				label = "Flash without bootloader";
>> +				reg = <20000 7e0000>;
>> +			};
>> +			ovpartition@0 {
>> +				label = "Complete Flash";
>> +				reg = <0 800000>;
>> +				read-only;
>> +			};
> 
> What is "ovpartition"?

Overlay partition. Is there a better way to specify this?

>> +			// Port D is LCD exclusive. Don't export as GPIO
>> +			CPM1_PIO: pio@970 {
>> +				compatible = "fsl,cpm1-pario";
>> +				reg = <970 180>;
>> +				num-ports = <3>;
>> +				#gpio-cells = <2>;
>> +			};
> 
> Why are we doing things differently just because all of the pins on this
> port happen to be directed to one device?  If it's because the Linux GPIO
> API sucks, then either fix the API, or work around the suckage in software,
> not the device tree.
> 
>> +			lcd@970 {
>> +				reg = <970 10>;
>> +				compatible = "samsung,ks0713";
>> +			};
> 
> So some driver that matches on samsung,ks0713 has to know the details of the
> mpc8xx GPIO registers?

The GPIO API only has an accessor for 1bit I/O. The LCD, however has for 1bit
control lines and an 8bit port. The GPIO API currently is unable to handle this.

>> +			i2c@860 {
>> +				compatible = "fsl,mpc823-i2c",
>> +					     "fsl,cpm1-i2c",
>> +					     "fsl,cpm-i2c";
>> +				reg = <860 20 3c80 30>;
>> +				interrupts = <10 3>;
>> +				interrupt-parent = <&CPM_PIC>;
>> +				fsl,cpm-command = <0010>;
>> +			};
> 
> Should have #address-cells and #size-cells.

In the meantime, i use the i2c patches from Jon Smirl and have added
these parameters.

> 
>> +enum dbox2_mid dbox2_get_mid(void)
>> +{
>> +	return dbox2_manuf_id;
>> +}
>> +EXPORT_SYMBOL_GPL(dbox2_get_mid);
> 
> Honestly, you're claiming derived-work status by calling a function that
> returns an integer, that was read directly from hardware?

Nope. It was a big fat hint not to use this value :). It has been moved to the
device tree in the mean time.

> I'd use separate device trees (I only did this kind of thing in mpc885ads
> because it's dip-switchable), but whatever...

I don't really like having to use different images on different DBoxes. It's
already too much to have two images (there are two different flash layouts).
People tend to brick their box by flashing the wrong image.

>> --- a/include/asm-powerpc/mpc8xx.h
>> +++ b/include/asm-powerpc/mpc8xx.h
>> @@ -23,6 +23,10 @@
>> #include <platforms/8xx/mpc885ads.h>
>> #endif
>>
>> +#if defined(CONFIG_DBOX2)
>> +#include <platforms/8xx/dbox2.h>
>> +#endif
> 
> This shouldn't be needed.

Already gone in v3.

> What happens if a device sits on two different gpio-parents?

On the dbox2, there are even stranger devices. One is using iomaped address spaces, GPIO and an i2c control interface.
Another one uses GPIO and an i2c control interface. For now, they appear twice in the device tree (once under i2c and 
once under localbus or pio). Is there a better way to do this?

localbus@8000000 {
	cam@3,0 {
		compatible = "betaresearch,dbox2-cam";
		reg = <3 0 20000 6 0 20000>;
		interrupts = <6 2>;
		interrupt-parent = <&PIC>;
		gpios = <1 1c 1 1d 1 1e 1 1f>;
		gpio-parent = <&CPM1_PIO>;
	};
};
soc@ff000000 {
	cpm@9c0 {
		CPM1_PIO: pio@950 {
			fp@0,0 {
				compatible = "betaresearch,dbox2-fp";
				interrupts = <4 2>;
				interrupt-parent = <&PIC>;
				gpios = <0 e>;
				gpio-parent = <&CPM1_PIO>;
			};
		};
		i2c@860 {
			fp@30 {
				compatible = "betaresearch,dbox2-fp";
				reg = <30>;
			};
			cam@37 {
				compatible = "betaresearch,dbox2-cam";
				reg = <37>;
			};			
		};
	};
};

Thanks,
Jochen

^ permalink raw reply

* [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 21:08 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102191030.GA11217@uranus.ravnborg.org>

This patch should go in immediately after:

	commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
	Author: Roland McGrath <roland@redhat.com>

	    compat_binfmt_elf

Thanks,
Roland

---
[PATCH] compat_binfmt_elf Kconfig

This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
just added.  Each arch that wants to use this file needs to add a
"select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.

Signed-off-by: Roland McGrath <roland@redhat.com>
---
 fs/Kconfig.binfmt |    4 ++++
 fs/Makefile       |    1 +
 2 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index d4fc609..0000000 100644  
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -23,6 +23,10 @@ config BINFMT_ELF
 	  ld.so (check the file <file:Documentation/Changes> for location and
 	  latest version).
 
+config COMPAT_BINFMT_ELF
+	bool
+	depends on COMPAT && MMU
+
 config BINFMT_ELF_FDPIC
 	bool "Kernel support for FDPIC ELF binaries"
 	default y
diff --git a/fs/Makefile b/fs/Makefile
index 500cf15..0000000 100644  
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC)	+= binfmt_misc
 obj-y				+= binfmt_script.o
 
 obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
+obj-$(CONFIG_COMPAT_BINFMT_ELF)	+= compat_binfmt_elf.o
 obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
 obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
 obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o

^ permalink raw reply related

* [PATCH -mm] x86 compat_binfmt_elf, Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 21:12 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>

This patch replaces the earlier patch by the same title already in x86/mm:

	commit a9014d2dfcb253fb3ce5f4e3318849f743b85427
	Author: Roland McGrath <roland@redhat.com>

	    x86 compat_binfmt_elf

It requires the new patch I just posted, titled "compat_binfmt_elf Kconfig".


Thanks,
Roland
---
x86 compat_binfmt_elf

This switches x86-64's 32-bit ELF support to use the shared
fs/compat_binfmt_elf.c code instead of our own ia32_binfmt.c.

Signed-off-by: Roland McGrath <roland@redhat.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 arch/x86/Kconfig             |    1 +
 arch/x86/ia32/Makefile       |    3 +-
 arch/x86/vdso/vdso32-setup.c |   33 ++++++++++++++++
 include/asm-x86/elf.h        |   88 ++++++++++++++++++++++++++++++-----------
 4 files changed, 99 insertions(+), 26 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 66d38bf..0000000 100644  
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1546,6 +1546,7 @@ source "fs/Kconfig.binfmt"
 config IA32_EMULATION
 	bool "IA32 Emulation"
 	depends on X86_64
+	select COMPAT_BINFMT_ELF
 	help
 	  Include code to run 32-bit programs under a 64-bit kernel. You should
 	  likely turn this on, unless you're 100% sure that you don't have any
diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index 93a6fda..0000000 100644  
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -2,8 +2,7 @@
 # Makefile for the ia32 kernel emulation subsystem.
 #
 
-obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o \
-	ia32_binfmt.o
+obj-$(CONFIG_IA32_EMULATION) := ia32entry.o sys_ia32.o ia32_signal.o
 
 sysv-$(CONFIG_SYSVIPC) := ipc32.o
 obj-$(CONFIG_IA32_EMULATION) += $(sysv-y)
diff --git a/arch/x86/vdso/vdso32-setup.c b/arch/x86/vdso/vdso32-setup.c
index e0feb66..0000000 100644  
--- a/arch/x86/vdso/vdso32-setup.c
+++ b/arch/x86/vdso/vdso32-setup.c
@@ -377,6 +377,39 @@ int arch_setup_additional_pages(struct l
 
 __initcall(sysenter_setup);
 
+#ifdef CONFIG_SYSCTL
+/* Register vsyscall32 into the ABI table */
+#include <linux/sysctl.h>
+
+static ctl_table abi_table2[] = {
+	{
+		.procname	= "vsyscall32",
+		.data		= &sysctl_vsyscall32,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec
+	},
+	{}
+};
+
+static ctl_table abi_root_table2[] = {
+	{
+		.ctl_name = CTL_ABI,
+		.procname = "abi",
+		.mode = 0555,
+		.child = abi_table2
+	},
+	{}
+};
+
+static __init int ia32_binfmt_init(void)
+{
+	register_sysctl_table(abi_root_table2);
+	return 0;
+}
+__initcall(ia32_binfmt_init);
+#endif
+
 #else  /* CONFIG_X86_32 */
 
 const char *arch_vma_name(struct vm_area_struct *vma)
diff --git a/include/asm-x86/elf.h b/include/asm-x86/elf.h
index d6bf742..0000000 100644  
--- a/include/asm-x86/elf.h
+++ b/include/asm-x86/elf.h
@@ -73,6 +73,9 @@ typedef struct user_fxsr_struct elf_fpxr
 #endif
 
 #ifdef __KERNEL__
+#include <asm/vdso.h>
+
+extern unsigned int vdso_enabled;
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
@@ -84,7 +87,6 @@ typedef struct user_fxsr_struct elf_fpxr
 #include <asm/processor.h>
 #include <asm/system.h>		/* for savesegment */
 #include <asm/desc.h>
-#include <asm/vdso.h>
 
 #define elf_check_arch(x)	elf_check_arch_ia32(x)
 
@@ -106,7 +108,6 @@ typedef struct user_fxsr_struct elf_fpxr
 
 #define ELF_PLATFORM	(utsname()->machine)
 #define set_personality_64bit()	do { } while (0)
-extern unsigned int vdso_enabled;
 
 #else /* CONFIG_X86_32 */
 
@@ -118,29 +119,57 @@ extern unsigned int vdso_enabled;
 #define elf_check_arch(x) \
 	((x)->e_machine == EM_X86_64)
 
+#define compat_elf_check_arch(x)	elf_check_arch_ia32(x)
+
+static inline void start_ia32_thread(struct pt_regs *regs, u32 ip, u32 sp)
+{
+	asm volatile("movl %0,%%fs" :: "r" (0));
+	asm volatile("movl %0,%%es; movl %0,%%ds" : : "r" (__USER32_DS));
+	load_gs_index(0);
+	regs->ip = ip;
+	regs->sp = sp;
+	regs->flags = X86_EFLAGS_IF;
+	regs->cs = __USER32_CS;
+	regs->ss = __USER32_DS;
+}
+
+static inline void elf_common_init(struct thread_struct *t,
+				   struct pt_regs *regs, const u16 ds)
+{
+	regs->ax = regs->bx = regs->cx = regs->dx = 0;
+	regs->si = regs->di = regs->bp = 0;
+	regs->r8 = regs->r9 = regs->r10 = regs->r11 = 0;
+	regs->r12 = regs->r13 = regs->r14 = regs->r15 = 0;
+	t->fs = t->gs = 0;
+	t->fsindex = t->gsindex = 0;
+	t->ds = t->es = ds;
+}
+
 #define ELF_PLAT_INIT(_r, load_addr)	do {		  \
-	struct task_struct *cur = current;		  \
-	(_r)->bx = 0; (_r)->cx = 0; (_r)->dx = 0;	  \
-	(_r)->si = 0; (_r)->di = 0; (_r)->bp = 0;	  \
-	(_r)->ax = 0;					  \
-	(_r)->r8 = 0;					  \
-	(_r)->r9 = 0;					  \
-	(_r)->r10 = 0;					  \
-	(_r)->r11 = 0;					  \
-	(_r)->r12 = 0;					  \
-	(_r)->r13 = 0;					  \
-	(_r)->r14 = 0;					  \
-	(_r)->r15 = 0;					  \
-	cur->thread.fs = 0; cur->thread.gs = 0;		  \
-	cur->thread.fsindex = 0; cur->thread.gsindex = 0; \
-	cur->thread.ds = 0; cur->thread.es = 0;		  \
+	elf_common_init(&current->thread, _r, 0);	  \
 	clear_thread_flag(TIF_IA32);			  \
 } while (0)
 
+#define	COMPAT_ELF_PLAT_INIT(regs, load_addr)	\
+	elf_common_init(&current->thread, regs, __USER_DS)
+#define	compat_start_thread(regs, ip, sp)	do {		\
+		start_ia32_thread(regs, ip, sp);		\
+		set_fs(USER_DS);				\
+	} while (0)
+#define COMPAT_SET_PERSONALITY(ex, ibcs2)	do {		\
+		if (test_thread_flag(TIF_IA32))			\
+			clear_thread_flag(TIF_ABI_PENDING);	\
+		else						\
+			set_thread_flag(TIF_ABI_PENDING);	\
+		current->personality |= force_personality32;	\
+	} while (0)
+#define COMPAT_ELF_PLATFORM			("i686")
+
 /* I'm not sure if we can use '-' here */
 #define ELF_PLATFORM       ("x86_64")
 extern void set_personality_64bit(void);
-extern int vdso_enabled;
+extern unsigned int sysctl_vsyscall32;
+extern int force_personality32;
 
 #endif /* !CONFIG_X86_32 */
 
@@ -179,17 +208,19 @@ extern int vdso_enabled;
 
 struct task_struct;
 
+#define	ARCH_DLINFO_IA32(vdso_enabled) \
+do if (vdso_enabled) {							\
+		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
+		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
+} while (0)
+
 #ifdef CONFIG_X86_32
 
 #define VDSO_HIGH_BASE		(__fix_to_virt(FIX_VDSO))
 
-/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
+#define ARCH_DLINFO		ARCH_DLINFO_IA32(vdso_enabled)
 
-#define ARCH_DLINFO \
-do if (vdso_enabled) {							\
-		NEW_AUX_ENT(AT_SYSINFO,	VDSO_ENTRY);			\
-		NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_CURRENT_BASE);	\
-} while (0)
+/* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
 
 #else /* CONFIG_X86_32 */
 
@@ -203,6 +234,12 @@ do if (vdso_enabled) {						\
 	NEW_AUX_ENT(AT_SYSINFO_EHDR,(unsigned long)current->mm->context.vdso);\
 } while (0)
 
+#define AT_SYSINFO		32
+
+#define COMPAT_ARCH_DLINFO	ARCH_DLINFO_IA32(sysctl_vsyscall32)
+
+#define COMPAT_ELF_ET_DYN_BASE	(TASK_UNMAPPED_BASE + 0x1000000)
+
 #endif /* !CONFIG_X86_32 */
 
 #define VDSO_CURRENT_BASE	((unsigned long)current->mm->context.vdso)
@@ -216,6 +253,9 @@ struct linux_binprm;
 extern int arch_setup_additional_pages(struct linux_binprm *bprm,
 				       int executable_stack);
 
+extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
+#define compat_arch_setup_additional_pages	syscall32_setup_pages
+
 extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 #define arch_randomize_brk arch_randomize_brk
 

^ permalink raw reply related

* [PATCH -mm] powerpc compat_binfmt_elf
From: Roland McGrath @ 2008-01-02 21:17 UTC (permalink / raw)
  To: Paul Mackerras
  Cc: linux-arch, linuxppc-dev, Ingo Molnar, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>

This replaces my earlier patch of the same title, posted with:

	Subject: [PATCH -mm 18/43] powerpc compat_binfmt_elf
	Date: Thu, 20 Dec 2007 03:58:16 -0800 (PST)

This requires all the powerpc patches in that series from late December and
also requires the new patch I just posted, titled "compat_binfmt_elf Kconfig".


Thanks,
Roland
---
powerpc compat_binfmt_elf

This switches the CONFIG_PPC64 support for 32-bit ELF to use the generic
fs/compat_binfmt_elf.c implementation instead of our own binfmt_elf32.c.
Since so much is the same between 32/64, there is only one macro we have to
define to make the generic support work out of the box.

Signed-off-by: Roland McGrath <roland@redhat.com>
---
 arch/powerpc/Kconfig               |    1 +
 arch/powerpc/kernel/Makefile       |    2 +-
 arch/powerpc/kernel/binfmt_elf32.c |   69 ------------------------------------
 include/asm-powerpc/elf.h          |    1 +
 4 files changed, 3 insertions(+), 70 deletions(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index c17a194..0000000 100644  
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -92,6 +92,7 @@ config EARLY_PRINTK
 config COMPAT
 	bool
 	default y if PPC64
+	select COMPAT_BINFMT_ELF
 
 config SYSVIPC_COMPAT
 	bool
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index ca51f0c..0000000 100644  
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -15,7 +15,7 @@ obj-y				:= semaphore.o cputable.o ptrac
 				   init_task.o process.o systbl.o idle.o \
 				   signal.o
 obj-y				+= vdso32/
-obj-$(CONFIG_PPC64)		+= setup_64.o binfmt_elf32.o sys_ppc32.o \
+obj-$(CONFIG_PPC64)		+= setup_64.o sys_ppc32.o \
 				   signal_64.o ptrace32.o \
 				   paca.o cpu_setup_ppc970.o \
 				   cpu_setup_pa6t.o \
diff --git a/arch/powerpc/kernel/binfmt_elf32.c b/arch/powerpc/kernel/binfmt_elf32.c
deleted file mode 100644
index 1d45d77... .  
--- a/arch/powerpc/kernel/binfmt_elf32.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * binfmt_elf32.c: Support 32-bit PPC ELF binaries on Power3 and followons.
- * based on the SPARC64 version.
- * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller	(davem@redhat.com)
- * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek	(jj@ultra.linux.cz)
- *
- * Copyright (C) 2000,2001 Ken Aaker (kdaaker@rchland.vnet.ibm.com), IBM Corp
- * Copyright (C) 2001 Anton Blanchard (anton@au.ibm.com), IBM
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-
-#include <asm/processor.h>
-#include <linux/module.h>
-#include <linux/compat.h>
-#include <linux/elfcore-compat.h>
-
-#undef	ELF_ARCH
-#undef	ELF_CLASS
-#define ELF_CLASS	ELFCLASS32
-#define ELF_ARCH	EM_PPC
-
-#undef	elfhdr
-#undef	elf_phdr
-#undef	elf_note
-#undef	elf_addr_t
-#define elfhdr		elf32_hdr
-#define elf_phdr	elf32_phdr
-#define elf_note	elf32_note
-#define elf_addr_t	Elf32_Off
-
-#define elf_prstatus	compat_elf_prstatus
-#define elf_prpsinfo	compat_elf_prpsinfo
-
-#define elf_core_copy_regs compat_elf_core_copy_regs
-static inline void compat_elf_core_copy_regs(compat_elf_gregset_t *elf_regs,
-					     struct pt_regs *regs)
-{
-	PPC_ELF_CORE_COPY_REGS((*elf_regs), regs);
-}
-
-#define elf_core_copy_task_regs compat_elf_core_copy_task_regs
-static int compat_elf_core_copy_task_regs(struct task_struct *tsk,
-					  compat_elf_gregset_t *elf_regs)
-{
-	struct pt_regs *regs = tsk->thread.regs;
-	if (regs)
-		compat_elf_core_copy_regs(elf_regs, regs);
-	return 1;
-}
-
-#include <linux/time.h>
-
-#undef cputime_to_timeval
-#define cputime_to_timeval cputime_to_compat_timeval
-static __inline__ void
-cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
-{
-	unsigned long jiffies = cputime_to_jiffies(cputime);
-	value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
-	value->tv_sec = jiffies / HZ;
-}
-
-#define init_elf_binfmt init_elf32_binfmt
-
-#include "../../../fs/binfmt_elf.c"
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 6bd07ef..0000000 100644  
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -165,6 +165,7 @@ typedef elf_vrreg_t elf_vrregset_t32[ELF
  * This is used to ensure we don't load something for the wrong architecture.
  */
 #define elf_check_arch(x) ((x)->e_machine == ELF_ARCH)
+#define compat_elf_check_arch(x)	((x)->e_machine == EM_PPC)
 
 #define USE_ELF_CORE_DUMP
 #define ELF_EXEC_PAGESIZE	PAGE_SIZE

^ permalink raw reply related

* Re: [PATCH/RFC] powerpc: DBox2 Board Support
From: Scott Wood @ 2008-01-02 21:22 UTC (permalink / raw)
  To: Jochen Friedrich; +Cc: linuxppc-dev
In-Reply-To: <477BF446.9070401@scram.de>

Jochen Friedrich wrote:
>>> +            ovpartition@20000 {
>>> +                label = "Flash without bootloader";
>>> +                reg = <20000 7e0000>;
>>> +            };
>>> +            ovpartition@0 {
>>> +                label = "Complete Flash";
>>> +                reg = <0 800000>;
>>> +                read-only;
>>> +            };
>>
>> What is "ovpartition"?
> 
> Overlay partition. Is there a better way to specify this?

Not sure... what will the mtd code do with this?

>>> +            lcd@970 {
>>> +                reg = <970 10>;
>>> +                compatible = "samsung,ks0713";
>>> +            };
>>
>> So some driver that matches on samsung,ks0713 has to know the details 
>> of the
>> mpc8xx GPIO registers?
> 
> The GPIO API only has an accessor for 1bit I/O. The LCD, however has for 
> 1bit
> control lines and an 8bit port. The GPIO API currently is unable to 
> handle this.

Right, but we shouldn't weird up the device tree because of Linux's 
weaknesses.  Ideally, the GPIO API should support wider I/O; in the 
meantime, there should be something in the board file that tells the 
ks0713 driver what to do.

>> I'd use separate device trees (I only did this kind of thing in mpc885ads
>> because it's dip-switchable), but whatever...
> 
> I don't really like having to use different images on different DBoxes. 
> It's
> already too much to have two images (there are two different flash 
> layouts).
> People tend to brick their box by flashing the wrong image.

Fair enough.

> localbus@8000000 {
>     cam@3,0 {
>         compatible = "betaresearch,dbox2-cam";
>         reg = <3 0 20000 6 0 20000>;
>         interrupts = <6 2>;
>         interrupt-parent = <&PIC>;
>         gpios = <1 1c 1 1d 1 1e 1 1f>;
>         gpio-parent = <&CPM1_PIO>;
>     };
> };
> soc@ff000000 {
>     cpm@9c0 {
>         CPM1_PIO: pio@950 {
>             fp@0,0 {
>                 compatible = "betaresearch,dbox2-fp";
>                 interrupts = <4 2>;
>                 interrupt-parent = <&PIC>;
>                 gpios = <0 e>;
>                 gpio-parent = <&CPM1_PIO>;
>             };
>         };
>         i2c@860 {
>             fp@30 {
>                 compatible = "betaresearch,dbox2-fp";
>                 reg = <30>;
>             };
>             cam@37 {
>                 compatible = "betaresearch,dbox2-cam";
>                 reg = <37>;
>             };           
>         };
>     };
> };

I'd make the compatible name specific to the interface (e.g. 
"betaresearch,dbox2-cam-mmio", "betaresearch,dbox2-fp-i2c"), use reg 
rather than gpios/gpio-parent, and use phandle linkage between the 
different inteferfaces of a device.  But yes, multiple nodes is the 
sanest way to do it.

-Scott

^ permalink raw reply

* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Sam Ravnborg @ 2008-01-02 21:53 UTC (permalink / raw)
  To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>

On Wed, Jan 02, 2008 at 01:08:31PM -0800, Roland McGrath wrote:
> This patch should go in immediately after:
> 
> 	commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> 	Author: Roland McGrath <roland@redhat.com>
> 
> 	    compat_binfmt_elf
> 
> Thanks,
> Roland
> 
> ---
> [PATCH] compat_binfmt_elf Kconfig
> 
> This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
> just added.  Each arch that wants to use this file needs to add a
> "select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.
> 
> Signed-off-by: Roland McGrath <roland@redhat.com>
> ---
>  fs/Kconfig.binfmt |    4 ++++
>  fs/Makefile       |    1 +
>  2 files changed, 5 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index d4fc609..0000000 100644  
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -23,6 +23,10 @@ config BINFMT_ELF
>  	  ld.so (check the file <file:Documentation/Changes> for location and
>  	  latest version).
>  
> +config COMPAT_BINFMT_ELF
> +	bool
> +	depends on COMPAT && MMU
> +
>  config BINFMT_ELF_FDPIC
>  	bool "Kernel support for FDPIC ELF binaries"
>  	default y
> diff --git a/fs/Makefile b/fs/Makefile
> index 500cf15..0000000 100644  
> --- a/fs/Makefile
> +++ b/fs/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC)	+= binfmt_misc
>  obj-y				+= binfmt_script.o
>  
>  obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
> +obj-$(CONFIG_COMPAT_BINFMT_ELF)	+= compat_binfmt_elf.o
>  obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
>  obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
>  obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o

You totally missed the point of having selectable features noted
by a config symbol named "HAVE_*".
When you see such a "HAVE_*" you know it is supposed to be selected
and thus you need to be much more careful about the dependencies.

And my patch was purely a cooked up example btw and not at all tested.
Should have been clear about that.

	Sam

^ permalink raw reply

* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Ingo Molnar @ 2008-01-02 21:57 UTC (permalink / raw)
  To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102210831.9F80426F9A0@magilla.localdomain>


* Roland McGrath <roland@redhat.com> wrote:

> This patch should go in immediately after:
> 
> 	commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> 	Author: Roland McGrath <roland@redhat.com>
> 
> 	    compat_binfmt_elf
> 
> Thanks,
> Roland
> 
> ---
> [PATCH] compat_binfmt_elf Kconfig

thanks, applied.

	Ingo

^ permalink raw reply

* Re: [PATCH -mm] x86 compat_binfmt_elf
From: Ingo Molnar @ 2008-01-02 21:58 UTC (permalink / raw)
  To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Sam Ravnborg, linux-kernel
In-Reply-To: <20080102211243.D7CFA26F9A0@magilla.localdomain>


* Roland McGrath <roland@redhat.com> wrote:

> This patch replaces the earlier patch by the same title already in 
> x86/mm:
> 
> 	commit a9014d2dfcb253fb3ce5f4e3318849f743b85427
> 	Author: Roland McGrath <roland@redhat.com>
> 
> 	    x86 compat_binfmt_elf
> 
> It requires the new patch I just posted, titled "compat_binfmt_elf 
> Kconfig".

thanks, applied.

	Ingo

^ permalink raw reply

* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Sam Ravnborg @ 2008-01-02 21:59 UTC (permalink / raw)
  To: Roland McGrath; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102215311.GA12558@uranus.ravnborg.org>

On Wed, Jan 02, 2008 at 10:53:11PM +0100, Sam Ravnborg wrote:
> On Wed, Jan 02, 2008 at 01:08:31PM -0800, Roland McGrath wrote:
> > This patch should go in immediately after:
> > 
> > 	commit 5e45efc63e33ee2bae9ff4d500b53d3bf86d2b48
> > 	Author: Roland McGrath <roland@redhat.com>
> > 
> > 	    compat_binfmt_elf
> > 
> > Thanks,
> > Roland
> > 
> > ---
> > [PATCH] compat_binfmt_elf Kconfig
> > 
> > This adds Kconfig and Makefile bits to build fs/compat_binfmt_elf.c,
> > just added.  Each arch that wants to use this file needs to add a
> > "select COMPAT_BINFMT_ELF" line in its Kconfig bits that enable COMPAT.
> > 
> > Signed-off-by: Roland McGrath <roland@redhat.com>
> > ---
> >  fs/Kconfig.binfmt |    4 ++++
> >  fs/Makefile       |    1 +
> >  2 files changed, 5 insertions(+), 0 deletions(-)
> > 
> > diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> > index d4fc609..0000000 100644  
> > --- a/fs/Kconfig.binfmt
> > +++ b/fs/Kconfig.binfmt
> > @@ -23,6 +23,10 @@ config BINFMT_ELF
> >  	  ld.so (check the file <file:Documentation/Changes> for location and
> >  	  latest version).
> >  
> > +config COMPAT_BINFMT_ELF
> > +	bool
> > +	depends on COMPAT && MMU
> > +
> >  config BINFMT_ELF_FDPIC
> >  	bool "Kernel support for FDPIC ELF binaries"
> >  	default y
> > diff --git a/fs/Makefile b/fs/Makefile
> > index 500cf15..0000000 100644  
> > --- a/fs/Makefile
> > +++ b/fs/Makefile
> > @@ -39,6 +39,7 @@ obj-$(CONFIG_BINFMT_MISC)	+= binfmt_misc
> >  obj-y				+= binfmt_script.o
> >  
> >  obj-$(CONFIG_BINFMT_ELF)	+= binfmt_elf.o
> > +obj-$(CONFIG_COMPAT_BINFMT_ELF)	+= compat_binfmt_elf.o
> >  obj-$(CONFIG_BINFMT_ELF_FDPIC)	+= binfmt_elf_fdpic.o
> >  obj-$(CONFIG_BINFMT_SOM)	+= binfmt_som.o
> >  obj-$(CONFIG_BINFMT_FLAT)	+= binfmt_flat.o
> 
> You totally missed the point of having selectable features noted
> by a config symbol named "HAVE_*".
> When you see such a "HAVE_*" you know it is supposed to be selected
> and thus you need to be much more careful about the dependencies.
> 
> And my patch was purely a cooked up example btw and not at all tested.
> Should have been clear about that.
My comment refer to a private mail - but I saw this hit lkml so a bit out
of context.

	Sam

^ permalink raw reply

* Re: [PATCH -mm] compat_binfmt_elf Kconfig
From: Roland McGrath @ 2008-01-02 22:12 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-arch, linuxppc-dev, Ingo Molnar, linux-kernel
In-Reply-To: <20080102215311.GA12558@uranus.ravnborg.org>

I have no opinions about the config symbol names.  Among the existing
precedents for internal/descriptionless symbols I find more not using the
HAVE_ prefix than those using it.  The patch versions I've sent now work
fine, fix the parallel build problem people were seeing, and AFAICT follow
the style of what's already in common use.  At this point, I think it would
be easiest just to keep them and have you send symbol-renaming patches
for any and all symbols of this sort that concern you as separate cleanups.


Thanks,
Roland

^ permalink raw reply

* Re: [PATCH v4 02/13] [POWERPC] Add 'fsl, lpb' bus type for MPC5200 LocalPlus Bus
From: Grant Likely @ 2008-01-02 23:37 UTC (permalink / raw)
  To: Marian Balakowicz; +Cc: linuxppc-dev
In-Reply-To: <20071109171149.16289.88635.stgit@hekate.izotz.org>

On 11/9/07, Marian Balakowicz <m8@semihalf.com> wrote:
> Define MPC52xx specific device id list, add new
> 'fsl,lpb' compatible id for LocalPlus Bus.

I'll pick this up, but I'm going to drop the .compatible="soc" line.
(I'd like to drop the device_type="soc" line also, but that requires a
bit more thought first).

Cheers,
g.

>
> Signed-off-by: Marian Balakowicz <m8@semihalf.com>
> Acked-by: David Gibson <david@gibson.dropbear.id.au>
> ---
>
>  arch/powerpc/platforms/52xx/mpc52xx_common.c |    9 ++++++++-
>  1 files changed, 8 insertions(+), 1 deletions(-)
>
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> index 9850685..2df97c5 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -124,11 +124,18 @@ mpc5200_setup_xlb_arbiter(void)
>         iounmap(xlb);
>  }
>
> +static struct of_device_id mpc52xx_ids[] = {
> +       { .type = "soc", },
> +       { .compatible = "soc", },
> +       { .compatible = "fsl,lpb", },
> +       {},
> +};
> +
>  void __init
>  mpc52xx_declare_of_platform_devices(void)
>  {
>         /* Find every child of the SOC node and add it to of_platform */
> -       if (of_platform_bus_probe(NULL, NULL, NULL))
> +       if (of_platform_bus_probe(NULL, mpc52xx_ids, NULL))
>                 printk(KERN_ERR __FILE__ ": "
>                         "Error while probing of_platform bus\n");
>  }
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>


-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
grant.likely@secretlab.ca
(403) 399-0195

^ permalink raw reply

* Re: [PATCHv2] i2c: adds support for i2c bus on Frescale CPM1/CPM2 controllers
From: Stephen Rothwell @ 2008-01-02 23:41 UTC (permalink / raw)
  To: Jochen Friedrich; +Cc: Jean Delvare, linuxppc-dev, Scott Wood, linux-kernel
In-Reply-To: <477BEB60.4070703@scram.de>

[-- Attachment #1: Type: text/plain, Size: 2439 bytes --]

Hi Jochen,

Just a few trivial things.

On Wed, 02 Jan 2008 20:52:00 +0100 Jochen Friedrich <jochen@scram.de> wrote:
>
> +++ b/drivers/i2c/busses/i2c-cpm.c
> +
> +static irqreturn_t cpm_i2c_interrupt(int irq, void *dev_id)
> +{
> +	struct i2c_adapter *adap;
> +	struct cpm_i2c *cpm;
> +	struct i2c_reg __iomem *i2c_reg;
> +	int i;
> +
> +	adap = (struct i2c_adapter *) dev_id;

This cast is unnecessary. In fact, you could just pass dev_id to the
following call to i2c_get_adapdata() and eliminate adap completely.

> +	/* Get 'me going again.
> +	 */

For short comments, just make them one line.  Similarly later as well.

> +	/* This chip can't do zero length writes. However, the i2c core uses
> +	   them to scan for devices. The best we can do is to convert them
> +	   into 1 byte reads */

For multiline comments, we normally do
/*
 * blah ...
 * more blah
 */

> +static int cpm_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
> +{
> +
> +	while (tptr < num) {
> +		/* Check for outstanding messages */
> +		dev_dbg(&adap->dev, "test ready.\n");
> +		if (!(tbdf[tptr].cbd_sc & BD_SC_READY)) {
> +			dev_dbg(&adap->dev, "ready.\n");
> +			rmsg = &msgs[tptr];
> +			ret = cpm_i2c_check_message(adap, rmsg, tptr, rptr);
> +			tptr++;
> +			if (rmsg->flags & I2C_M_RD)
> +				rptr++;
> +			if (ret) {
> +				cpm_i2c_force_close(adap);
> +				mutex_unlock(&cpm->i2c_mutex);
> +				return ret;
> +			}
> +		} else {
> +			dev_dbg(&adap->dev, "not ready.\n");
> +			ret = wait_event_interruptible_timeout(cpm->i2c_wait,
> +				!(tbdf[tptr].cbd_sc & BD_SC_READY), 1 * HZ);
> +			if (ret == 0) {
> +				cpm_i2c_force_close(adap);
> +				dev_dbg(&adap->dev, "I2C read: timeout!\n");
> +				mutex_unlock(&cpm->i2c_mutex);
> +				return -EREMOTEIO;
> +			}

You might want to consolidate the two error paths above using gotos to an
error return section below.

> +static void of_register_i2c_devices(struct i2c_adapter *adap,
> +				    struct device_node *adap_node)
> +{
> +	struct device_node *node = NULL;
> +
> +	while ((node = of_get_next_child(adap_node, node))) {

Use
	for_each_child_of_node(adap_node, node) {
instead and you don't need to initialise "node" above.

> +static struct of_device_id cpm_i2c_match[] = {

const?

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* [PATCH] powerpc: #address-cells & #size-cells properties not inherited
From: Mark A. Greer @ 2008-01-03  0:07 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: David Gibson

From: Mark A. Greer <mgreer@mvista.com>

Fix error in booting-without-of.txt that indicates that a node can inherit
its #address-cells and #size-cells definitions from its parent's parent.
This is not correct and the latest dtc enforces it.

Signed-off-by: Mark A. Greer <mgreer@mvista.com>
---
 Documentation/powerpc/booting-without-of.txt |    8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index ee0209a..58db5ea 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -671,10 +671,10 @@ device or bus to be described by the device tree.
 
 In general, the format of an address for a device is defined by the
 parent bus type, based on the #address-cells and #size-cells
-property. In the absence of such a property, the parent's parent
-values are used, etc... The kernel requires the root node to have
-those properties defining addresses format for devices directly mapped
-on the processor bus.
+properties.  Note that the parent's parent definitions of #address-cells
+and #size-cells are not inhereted so every node with children must specify
+them.  The kernel requires the root node to have those properties defining
+addresses format for devices directly mapped on the processor bus.
 
 Those 2 properties define 'cells' for representing an address and a
 size. A "cell" is a 32-bit number. For example, if both contain 2

^ permalink raw reply related

* Re: [PATCH] powerpc: #address-cells & #size-cells properties not inherited
From: Josh Boyer @ 2008-01-03  1:46 UTC (permalink / raw)
  To: Mark A. Greer; +Cc: linuxppc-dev, David Gibson
In-Reply-To: <20080103000750.GA22035@mag.az.mvista.com>

On Wed, 2 Jan 2008 17:07:50 -0700
"Mark A. Greer" <mgreer@mvista.com> wrote:

> From: Mark A. Greer <mgreer@mvista.com>
> 
> Fix error in booting-without-of.txt that indicates that a node can inherit
> its #address-cells and #size-cells definitions from its parent's parent.
> This is not correct and the latest dtc enforces it.

I'm lazy so I haven't checked myself, but by "latest dtc" does that
mean the DTC that's in the kernel now?

Things are going to be fun when we start saying generic things like
"latest DTC".  And when upstream DTC gets new features or enforcements,
we'll have to have all the in-kernel DTS files patched up when that
version of DTC gets merged in-kernel.  Just something to keep in mind
as we move along.

josh

^ permalink raw reply

* Re: [patch] powerpc systbl.h broken
From: Stephen Rothwell @ 2008-01-03  2:16 UTC (permalink / raw)
  To: Clifford Wolf; +Cc: linuxppc-dev, lkml, stable
In-Reply-To: <20080102141127.GA11870@clifford.at>

Hi Clifford,

Thanks for the report.

PowerPC problems should be reported to linuxppc-dev@ozlabs.org.

This has been fixed in the current (approaching 2.6.24) kernel.  It
should be fixed in 2.6.23.xx, so I have cc'd this to
stable@vger.kernel.org (and linuxppc-dev, of course).

(Also, please post patches inline, don't attach them.  And you need to
reply to this with a Signed-off-by: line.)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
------------------------------------------------------------------------
From:	Clifford Wolf <clifford@clifford.at>

Hi,

In current 2.6.23 (I have checked 2.6.23.12 and 2.6.23.9) the end of
include/asm-powerpc/systbl.h reads:

--snip--
SYSCALL_SPU(getcpu)
COMPAT_SYS(epoll_pwait)
COMPAT_SYS_SPU(utimensat)
COMPAT_SYS(fallocate)
COMPAT_SYS_SPU(signalfd)
COMPAT_SYS_SPU(timerfd)
SYSCALL_SPU(eventfd)
COMPAT_SYS_SPU(sync_file_range2)
--snap--

This obviously does not match the definitions in asm-powerpc/unistd.h:

--snip--
#define __NR_getcpu		302
#define __NR_epoll_pwait	303
#define __NR_utimensat		304
#define __NR_signalfd		305
#define __NR_timerfd		306
#define __NR_eventfd		307
#define __NR_sync_file_range2	308
#define __NR_fallocate		309
--snap--

which breaks the system calls 305 to 309 inclusive.

--- linux-2.6.23.12/include/asm-powerpc/systbl.h.orig	2008-01-02 15:09:04.000000000 +0100
+++ linux-2.6.23.12/include/asm-powerpc/systbl.h	2008-01-02 15:09:29.000000000 +0100
@@ -308,8 +308,8 @@
 SYSCALL_SPU(getcpu)
 COMPAT_SYS(epoll_pwait)
 COMPAT_SYS_SPU(utimensat)
-COMPAT_SYS(fallocate)
 COMPAT_SYS_SPU(signalfd)
 COMPAT_SYS_SPU(timerfd)
 SYSCALL_SPU(eventfd)
 COMPAT_SYS_SPU(sync_file_range2)
+COMPAT_SYS(fallocate)

^ permalink raw reply

* Re: [patch] powerpc systbl.h broken
From: Stephen Rothwell @ 2008-01-03  2:54 UTC (permalink / raw)
  To: Clifford Wolf; +Cc: linuxppc-dev, lkml, stable
In-Reply-To: <20080103131624.5a3e98e8.sfr@canb.auug.org.au>

[-- Attachment #1: Type: text/plain, Size: 464 bytes --]

On Thu, 3 Jan 2008 13:16:24 +1100 Stephen Rothwell <sfr@canb.auug.org.au> wrote:
>
> This has been fixed in the current (approaching 2.6.24) kernel.  It
> should be fixed in 2.6.23.xx, so I have cc'd this to
> stable@vger.kernel.org (and linuxppc-dev, of course).

Should have been stable@kernel.org. (where I have sent another copy of
the email)

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply

* RE: File system problem
From: Jean-Samuel Chenard @ 2008-01-03  3:32 UTC (permalink / raw)
  To: linuxppc-embedded, kernelppc

> Date: Wed, 2 Jan 2008 19:50:13 +0100
> From: "mojtaba"
> I am trying to boot a root file system build by buildroot. But I got this
> error" init has generated signal 11 but has no handler for it".
>
> My kernel version is 2.6.24-rc3
> My target system is PPC 405 (XILINX VIRTEX II pro) I am using the 26-12-2=
007
> snapshot of buildroot.
[ ... ]
> Warning: unable to open an initial console.
> init has generated signal 11 but has no handler for it Kernel panic - not

Hi Mojtaba,

I got a similar error on my ML-310 when I tried a new root filesystem.
 As far as I recall, I needed to make sure that two entries existed in
/dev, namely:

crw-------    1 root     root       5,   1 Jan  1 05:18 console
crw-rw----    1 root     root       1,   3 Dec 10  2007 null

I think that you are missing /dev/console and then init cannot run
since it has nowhere to put its standard output.

You can make those by mounting your CF card on your development host
and (as root) make the nodes:

# mknod -m 660 /dev/console c 5 1
# mknod -m 660 /dev/null c 1 3

In my case, I use the UartLite (ttyUL0) serial port driver, but I'm
pretty sure this is going to fix the problem you are observing.

Regards,

Jean-Samuel
--=20
Ph.D. candidate
Integrated Microsystems Laboratory
McGill University, Montr=E9al, QC, CANADA
Web Page: http://chaos.ece.mcgill.ca

^ permalink raw reply

* [PATCH] [POWERPC] arch/powerpc/kernel: use for_each_child_of_node
From: Stephen Rothwell @ 2008-01-03  4:13 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev


Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 arch/powerpc/kernel/ibmebus.c     |    2 +-
 arch/powerpc/kernel/of_platform.c |    4 ++--
 arch/powerpc/kernel/pci_32.c      |    4 ++--
 arch/powerpc/kernel/pci_64.c      |    4 ++--
 arch/powerpc/kernel/rtas_pci.c    |    5 +----
 5 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index caae49f..1844359 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -171,7 +171,7 @@ static int ibmebus_create_devices(const struct of_device_id *matches)
 
 	root = of_find_node_by_path("/");
 
-	for (child = NULL; (child = of_get_next_child(root, child)); ) {
+	for_each_child_of_node(root, child) {
 		if (!of_match_node(matches, child))
 			continue;
 
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
index de36e23..7a60191 100644
--- a/arch/powerpc/kernel/of_platform.c
+++ b/arch/powerpc/kernel/of_platform.c
@@ -108,7 +108,7 @@ static int of_platform_bus_create(const struct device_node *bus,
 	struct of_device *dev;
 	int rc = 0;
 
-	for (child = NULL; (child = of_get_next_child(bus, child)); ) {
+	for_each_child_of_node(bus, child) {
 		pr_debug("   create child: %s\n", child->full_name);
 		dev = of_platform_device_create(child, NULL, parent);
 		if (dev == NULL)
@@ -170,7 +170,7 @@ int of_platform_bus_probe(struct device_node *root,
 		rc = of_platform_bus_create(root, matches, &dev->dev);
 		goto bail;
 	}
-	for (child = NULL; (child = of_get_next_child(root, child)); ) {
+	for_each_child_of_node(root, child) {
 		if (!of_match_node(matches, child))
 			continue;
 
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 47dc754..14e300f 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -276,11 +276,11 @@ scan_OF_pci_childs(struct device_node *parent, pci_OF_scan_iterator filter, void
 static struct device_node *scan_OF_for_pci_dev(struct device_node *parent,
 					       unsigned int devfn)
 {
-	struct device_node *np = NULL;
+	struct device_node *np;
 	const u32 *reg;
 	unsigned int psize;
 
-	while ((np = of_get_next_child(parent, np)) != NULL) {
+	for_each_child_of_node(parent, np) {
 		reg = of_get_property(np, "reg", &psize);
 		if (reg == NULL || psize < 4)
 			continue;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 5949bba..1930f39 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -227,7 +227,7 @@ EXPORT_SYMBOL(of_create_pci_dev);
 void __devinit of_scan_bus(struct device_node *node,
 			   struct pci_bus *bus)
 {
-	struct device_node *child = NULL;
+	struct device_node *child;
 	const u32 *reg;
 	int reglen, devfn;
 	struct pci_dev *dev;
@@ -235,7 +235,7 @@ void __devinit of_scan_bus(struct device_node *node,
 	DBG("of_scan_bus(%s) bus no %d... \n", node->full_name, bus->number);
 
 	/* Scan direct children */
-	while ((child = of_get_next_child(node, child)) != NULL) {
+	for_each_child_of_node(node, child) {
 		DBG("  * %s\n", child->full_name);
 		reg = of_get_property(child, "reg", &reglen);
 		if (reg == NULL || reglen < 20)
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index 99aaae3..433a0a0 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -280,10 +280,7 @@ void __init find_and_init_phbs(void)
 	struct pci_controller *phb;
 	struct device_node *root = of_find_node_by_path("/");
 
-	for (node = of_get_next_child(root, NULL);
-	     node != NULL;
-	     node = of_get_next_child(root, node)) {
-
+	for_each_child_of_node(root, node) {
 		if (node->type == NULL || (strcmp(node->type, "pci") != 0 &&
 					   strcmp(node->type, "pciex") != 0))
 			continue;
-- 
1.5.3.7

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* [PATCH] [POWERPC] therm_windtunnel: eliminate some build warnings
From: Stephen Rothwell @ 2008-01-03  4:15 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev, samuel

We don't care if the device_create_file calls fail, the driver will work
just as well without them, so just issue a runtime warning.

drivers/macintosh/therm_windtunnel.c: In function 'setup_hardware':
drivers/macintosh/therm_windtunnel.c:268: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_windtunnel.c:269: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 drivers/macintosh/therm_windtunnel.c |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 3722402..63ef1f6 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -223,6 +223,7 @@ static void
 setup_hardware( void )
 {
 	int val;
+	int err;
 
 	/* save registers (if we unload the module) */
 	x.r0 = read_reg( x.fan, 0x00, 1 );
@@ -265,8 +266,11 @@ setup_hardware( void )
 	x.upind = -1;
 	/* tune_fan( fan_up_table[x.upind].fan_setting ); */
 
-	device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
-	device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
+	err = device_create_file( &x.of_dev->dev, &dev_attr_cpu_temperature );
+	err |= device_create_file( &x.of_dev->dev, &dev_attr_case_temperature );
+	if (err)
+		printk(KERN_WARNING
+			"Failed to create temperature attribute file(s).\n");
 }
 
 static void
-- 
1.5.3.7

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* [PATCH] [POWERPC] therm_adt746x: eliminate some build warnings
From: Stephen Rothwell @ 2008-01-03  4:17 UTC (permalink / raw)
  To: paulus; +Cc: ppc-dev

We don't care if the device_create_file calls fail, the driver will work
just as well without them, so just issue a runtime warning.

drivers/macintosh/therm_adt746x.c: In function 'thermostat_init':
drivers/macintosh/therm_adt746x.c:615: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:616: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:617: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:618: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:619: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:620: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:621: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:622: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:623: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result
drivers/macintosh/therm_adt746x.c:625: warning: ignoring return value of 'device_create_file', declared with attribute warn_unused_result

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
---
 drivers/macintosh/therm_adt746x.c |   24 ++++++++++++++----------
 1 files changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 276945d..54f4942 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -553,6 +553,7 @@ thermostat_init(void)
 	struct device_node* np;
 	const u32 *prop;
 	int i = 0, offset = 0;
+	int err;
 	
 	np = of_find_node_by_name(NULL, "fan");
 	if (!np)
@@ -612,17 +613,20 @@ thermostat_init(void)
 		return -ENODEV;
 	}
 	
-	device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
-	device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
-	device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
-	device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
-	device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
-	device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
-	device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
-	device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
-	device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
+	err = device_create_file(&of_dev->dev, &dev_attr_sensor1_temperature);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_temperature);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_limit);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_limit);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_location);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_location);
+	err |= device_create_file(&of_dev->dev, &dev_attr_limit_adjust);
+	err |= device_create_file(&of_dev->dev, &dev_attr_specified_fan_speed);
+	err |= device_create_file(&of_dev->dev, &dev_attr_sensor1_fan_speed);
 	if(therm_type == ADT7460)
-		device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
+		err |= device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
+	if (err)
+		printk(KERN_WARNING
+			"Failed to create tempertaure attribute file(s).\n");
 
 #ifndef CONFIG_I2C_POWERMAC
 	request_module("i2c-powermac");
-- 
1.5.3.7

-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au
http://www.canb.auug.org.au/~sfr/

^ permalink raw reply related

* Re: How to creat a .config file for a driver and How to use it in adevice driver?????
From: Misbah khan @ 2008-01-03  4:40 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <477BCE30.8010306@pikatech.com>


Ya i got your point ...the way you told is the very generic way of doing this
but what i need is this :-

Like your any .config if you edit your configuration and restart your
default configuration changes ....The merit of this technique is that i need
not compile the driver with every default config change ....

---Misbah <><

Sean MacLennan-2 wrote:
> 
> Misbah khan wrote:
>> Hi all ...
>>
>> i am writing a device driver in which the default configuration for LCD
>> display i need to keep it in a .config file so that as the system boots
>> it
>> take the value from this file and does the initial configuration in the
>> init
>> of the driver. If user changes the .config file content in the next boot
>> the
>> LCD driver should take the new default configuration 
>>
>> There will also be a run time config which could be changed at the rum
>> time
>> but will not change the default configuration.
>>
>>
>> i am writing a LCD driver for PPC arch i need to know that how should i
>> creat a .config file and How should i use it my device driver. ??????
>>
>> If you had an exprience in this regard please do share with me ...
>>
>> ----Misbah <><
>>   
> You don't. The safe way is to have sane defaults in the driver. Then 
> write a user mode app that reads the config file and configures the 
> driver properly, probably through ioctls.
> 
> Cheers,
>     Sean
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
> 
> 

-- 
View this message in context: http://www.nabble.com/How-to-creat-a-.config-file-for-a-driver-and-How-to-use-it-in-a-device-driver------tp14576412p14591612.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

^ permalink raw reply


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