Re: [i2c] [PATCH V10] I2C driver for IMX

2008-07-23 Thread Ben Dooks
On Fri, Jul 18, 2008 at 09:56:45AM +0300, Darius wrote:
 Description:

 Implementation of I2C Adapter/Algorithm Driver
 for I2C Bus integrated in Freescale's i.MXL and i.MX1 processors

 Changes from V9 version:

 - platform_driver_register replaced by platform_driver_probe because I2C is 
 non-hotpluggable device
 - Patch divided into two separate patches for I2C driver and for board 
 support for I2C device
 - In I2C wait functions dummy cycles replaced by calling shedule();
 - Fixed coding style errors

 This driver is not yet compatible with upcomming Clock API for i.MX.
 I'll implement this after 2.6.27-rc1 release.

 Signed-off-by: Darius Augulis [EMAIL PROTECTED]
 ---

ok, clean up the description and i'll try and include it before
the end of the merge window.

 Index: linux-2.6.26/drivers/i2c/busses/i2c-imx.c
 ===
 --- /dev/null
 +++ linux-2.6.26/drivers/i2c/busses/i2c-imx.c
 @@ -0,0 +1,617 @@
 +/*
 + *   Copyright (C) 2002 Motorola GSG-China
 + *
 + *   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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
 + *   USA.
 + *
 + * Author:
 + *   Darius Augulis, Teltonika Inc.
 + *
 + * Desc.:
 + *   Implementation of I2C Adapter/Algorithm Driver
 + *   for I2C Bus integrated in i.MXL, i.MX1
 + *
 + *   module parameters:
 + *   - clkfreq:
 + *   Sets the desired clock rate
 + *   The default value is 10
 + *   Max value is 40
 + *
 + *   Derived from Motorola GSG China I2C example driver
 + *
 + *   Copyright (C) 2005 Torsten Koschorrek koschorrek at synertronixx.de
 + *   Portions:
 + *   Copyright (C) 2005 Matthias Blaschke blaschke at synertronixx.de
 + *   Copyright (C) 2007 RightHand Technologies, Inc. 
 adyeratrighthandtech.com
 + *   Copyright (C) 2008 Darius Augulis darius.augulis at teltonika.lt
 + *
 + */
 +
 +/** Includes 
 ***
 +***/
 +
 +#include linux/init.h
 +#include linux/kernel.h
 +#include linux/module.h
 +#include linux/errno.h
 +#include linux/interrupt.h
 +#include linux/delay.h
 +#include linux/i2c.h
 +#include linux/io.h
 +#include linux/sched.h
 +#include linux/platform_device.h
 +#include asm/arch/irqs.h
 +#include asm/arch/hardware.h
 +#include asm/arch/imx-regs.h
 +
 +/** Defines 
 
 +***/
 +
 +/* This will be the driver name the kernel reports */
 +#define DRIVER_NAME imx-i2c
 +
 +/* Default values of module parameters */
 +#define IMX_I2C_BIT_RATE 10  /* 100kHz */
 +
 +/* Timeouts */
 +#define I2C_IMX_TIME_BUSY2000/* loop count */
 +#define I2C_IMX_TIME_ACK 2000/* loop count */
 +#define I2C_IMX_TIME_TRX 5   /* seconds */
 +
 +/* IMX I2C registers */
 +#define IMX_I2C_IADR 0x00/* i2c slave address */
 +#define IMX_I2C_IFDR 0x04/* i2c frequency divider */
 +#define IMX_I2C_I2CR 0x08/* i2c control */
 +#define IMX_I2C_I2SR 0x0C/* i2c status */
 +#define IMX_I2C_I2DR 0x10/* i2c transfer data */
 +
 +/* Bits of IMX I2C registers */
 +#define I2SR_RXAK0x01
 +#define I2SR_IIF 0x02
 +#define I2SR_SRW 0x04
 +#define I2SR_IAL 0x10
 +#define I2SR_IBB 0x20
 +#define I2SR_IAAS0x40
 +#define I2SR_ICF 0x80
 +#define I2CR_RSTA0x04
 +#define I2CR_TXAK0x08
 +#define I2CR_MTX 0x10
 +#define I2CR_MSTA0x20
 +#define I2CR_IIEN0x40
 +#define I2CR_IEN 0x80
 +
 +/** Variables 
 **
 +***/
 +
 +static unsigned int clkfreq = IMX_I2C_BIT_RATE;
 +static unsigned int disable_delay;   /* Dummy delay */
 +
 +/*
 + * sorted list of clock divider, register value pairs
 + * taken from table 26-5, p.26-9, Freescale i.MX
 + * Integrated Portable System Processor Reference Manual
 + * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007
 + *
 + * Duplicated divider values removed from list
 + */
 +
 +static u16 __initdata i2c_imx_clk_divider [50] [2] = {
 + { 22,   0x20 }, { 24,   

[i2c] [PATCH V11] I2C driver for IMX

2008-07-23 Thread Darius

Description:

Implementation of I2C Adapter/Algorithm Driver
for I2C Bus integrated in Freescale's i.MXL and i.MX1 processors

Changes from V10 version:

- adapter class changed to I2C_CLASS_ALL
- changes regarding new IMX Clock API

Signed-off-by: Darius Augulis [EMAIL PROTECTED]
---
Index: linux-2.6.26-git7/drivers/i2c/busses/i2c-imx.c
===
--- /dev/null
+++ linux-2.6.26-git7/drivers/i2c/busses/i2c-imx.c
@@ -0,0 +1,623 @@
+/*
+ * Copyright (C) 2002 Motorola GSG-China
+ *
+ * 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
+ * USA.
+ *
+ * Author:
+ * Darius Augulis, Teltonika Inc.
+ *
+ * Desc.:
+ * Implementation of I2C Adapter/Algorithm Driver
+ * for I2C Bus integrated in i.MXL, i.MX1
+ *
+ * module parameters:
+ * - clkfreq:
+ * Sets the desired clock rate
+ * The default value is 10
+ * Max value is 40
+ *
+ * Derived from Motorola GSG China I2C example driver
+ *
+ * Copyright (C) 2005 Torsten Koschorrek koschorrek at synertronixx.de
+ * Portions:
+ * Copyright (C) 2005 Matthias Blaschke blaschke at synertronixx.de
+ * Copyright (C) 2007 RightHand Technologies, Inc. 
adyeratrighthandtech.com
+ * Copyright (C) 2008 Darius Augulis darius.augulis at teltonika.lt
+ *
+ */
+
+/** Includes 
***
+***/
+
+#include linux/init.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/errno.h
+#include linux/interrupt.h
+#include linux/delay.h
+#include linux/i2c.h
+#include linux/io.h
+#include linux/sched.h
+#include linux/platform_device.h
+#include linux/clk.h
+#include asm/arch/irqs.h
+#include asm/arch/hardware.h
+#include asm/arch/imx-regs.h
+
+/** Defines 

+***/
+
+/* This will be the driver name the kernel reports */
+#define DRIVER_NAME imx-i2c
+
+/* Default values of module parameters */
+#define IMX_I2C_BIT_RATE   10  /* 100kHz */
+
+/* Timeouts */
+#define I2C_IMX_TIME_BUSY  2000/* loop count */
+#define I2C_IMX_TIME_ACK   2000/* loop count */
+#define I2C_IMX_TIME_TRX   5   /* seconds */
+
+/* IMX I2C registers */
+#define IMX_I2C_IADR   0x00/* i2c slave address */
+#define IMX_I2C_IFDR   0x04/* i2c frequency divider */
+#define IMX_I2C_I2CR   0x08/* i2c control */
+#define IMX_I2C_I2SR   0x0C/* i2c status */
+#define IMX_I2C_I2DR   0x10/* i2c transfer data */
+
+/* Bits of IMX I2C registers */
+#define I2SR_RXAK  0x01
+#define I2SR_IIF   0x02
+#define I2SR_SRW   0x04
+#define I2SR_IAL   0x10
+#define I2SR_IBB   0x20
+#define I2SR_IAAS  0x40
+#define I2SR_ICF   0x80
+#define I2CR_RSTA  0x04
+#define I2CR_TXAK  0x08
+#define I2CR_MTX   0x10
+#define I2CR_MSTA  0x20
+#define I2CR_IIEN  0x40
+#define I2CR_IEN   0x80
+
+/** Variables 
**
+***/
+
+static unsigned int clkfreq = IMX_I2C_BIT_RATE;
+static unsigned int disable_delay; /* Dummy delay */
+
+/*
+ * sorted list of clock divider, register value pairs
+ * taken from table 26-5, p.26-9, Freescale i.MX
+ * Integrated Portable System Processor Reference Manual
+ * Document Number: MC9328MXLRM, Rev. 5.1, 06/2007
+ *
+ * Duplicated divider values removed from list
+ */
+
+static u16 __initdata i2c_imx_clk_divider [50] [2] = {
+   { 22,   0x20 }, { 24,   0x21 }, { 26,   0x22 }, { 28,   0x23 },
+   { 30,   0x00 }, { 32,   0x24 }, { 36,   0x25 }, { 40,   0x26 },
+   { 42,   0x03 }, { 44,   0x27 }, { 48,   0x28 }, { 52,   0x05 },
+   { 56,   0x29 }, { 60,   0x06 }, { 64,   0x2A }, { 72,   0x2B },
+   { 80,   0x2C }, { 88,   0x09 }, { 96,   0x2D }, { 104,  0x0A },
+   { 112,  0x2E }, { 128,  0x2F }, { 144,  0x0C }, { 160,  0x30 },
+   { 192,  0x31 }, { 224,  0x32 }, { 240,  0x0F }, { 256,  0x33 },
+  

Re: [i2c] N800 problems with MMC, LM8323 on current linux-omap git head

2008-07-23 Thread Riku Voipio
On Tue, Jul 22, 2008 at 09:20:46AM -0500, Felipe Balbi wrote:
 On Tue, 22 Jul 2008 14:43:14 +0100, Ben Dooks [EMAIL PROTECTED] wrote:
  Split them into a common and then machine specfic structures, you are
  allowed to register more than one board per bus.

 Good to know :-)

Indeed - compared to my previous version, this one makes the boardfile
even smaller:

   textdata bss dec hex filename
   23621552   43918 f4e old/arch/arm/mach-omap2/board-n800.o
   23541456   43814 ee6 new/arch/arm/mach-omap2/board-n800.o


 Riku, could you update your patch then ?

tested and attached.

 but it anyways doesn't annul the need of a better error handling
 in lm8323. I think both patches will need to be applied :-)

true. 

-- 
rm -rf only sounds scary if you don't have backups
From 1e9d7271505e85c99fe9b46653569ff6216e07b3 Mon Sep 17 00:00:00 2001
From: Riku Voipio [EMAIL PROTECTED]
Date: Tue, 22 Jul 2008 12:29:31 +0300
Subject: [PATCH] Separate i2c_board_info for n800 and n810

n800 and n810 have different peripherals on the second i2c bus
(tea5761 on n800 and lm8323 on n810). Split the i2c_board_info to
common and hw specific to avoid probing nonexistent devices.

Signed-off-by: Riku Voipio [EMAIL PROTECTED]
---
 arch/arm/mach-omap2/board-n800.c |   36 ++--
 1 files changed, 22 insertions(+), 14 deletions(-)

diff --git a/arch/arm/mach-omap2/board-n800.c b/arch/arm/mach-omap2/board-n800.c
index ae85c2c..e156dbd 100644
--- a/arch/arm/mach-omap2/board-n800.c
+++ b/arch/arm/mach-omap2/board-n800.c
@@ -642,30 +642,31 @@ static struct i2c_board_info __initdata 
n800_i2c_board_info_1[] = {
 
 extern struct tcm825x_platform_data n800_tcm825x_platform_data;
 
-static struct i2c_board_info __initdata_or_module n800_i2c_board_info_2[] = {
-#if defined (CONFIG_VIDEO_TCM825X) || defined (CONFIG_VIDEO_TCM825X_MODULE)
+static struct i2c_board_info __initdata_or_module n8x0_i2c_board_info_2[] = {
{
I2C_BOARD_INFO(TCM825X_NAME, TCM825X_I2C_ADDR),
.platform_data = n800_tcm825x_platform_data,
},
-#endif
-#if defined(CONFIG_RADIO_TEA5761) || defined(CONFIG_RADIO_TEA5761_MODULE)
{
-   I2C_BOARD_INFO(tea5761, 0x10),
+   I2C_BOARD_INFO(tsl2563, 0x29),
},
-#endif
-#ifdef CONFIG_MACH_NOKIA_N810
{
-   I2C_BOARD_INFO(lm8323, 0x45),
-   .irq= OMAP_GPIO_IRQ(109),
-   .platform_data  = lm8323_pdata,
+   I2C_BOARD_INFO(lp5521, 0x32),
},
-#endif
+};
+
+
+static struct i2c_board_info __initdata_or_module n800_i2c_board_info_2[] = {
{
-   I2C_BOARD_INFO(tsl2563, 0x29),
+   I2C_BOARD_INFO(tea5761, 0x10),
},
+};
+
+static struct i2c_board_info __initdata_or_module n810_i2c_board_info_2[] = {
{
-   I2C_BOARD_INFO(lp5521, 0x32),
+   I2C_BOARD_INFO(lm8323, 0x45),
+   .irq= OMAP_GPIO_IRQ(109),
+   .platform_data  = lm8323_pdata,
},
 };
 
@@ -690,8 +691,15 @@ void __init nokia_n800_common_init(void)
omap_serial_init();
omap_register_i2c_bus(1, 400, n800_i2c_board_info_1,
  ARRAY_SIZE(n800_i2c_board_info_1));
-   omap_register_i2c_bus(2, 400, n800_i2c_board_info_2,
+   omap_register_i2c_bus(2, 400, n8x0_i2c_board_info_2,
  ARRAY_SIZE(n800_i2c_board_info_2));
+   if (machine_is_nokia_n800())
+   i2c_register_board_info(2, n800_i2c_board_info_2,
+   ARRAY_SIZE(n800_i2c_board_info_2));
+   if (machine_is_nokia_n810())
+   i2c_register_board_info(2, n810_i2c_board_info_2,
+   ARRAY_SIZE(n810_i2c_board_info_2));
+   
mipid_dev_init();
blizzard_dev_init();
 }
-- 
1.5.5.4

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c

Re: [i2c] N800 problems with MMC, LM8323 on current linux-omap git head

2008-07-23 Thread Felipe Balbi


On Wed, 23 Jul 2008 12:38:49 +0300, Riku Voipio [EMAIL PROTECTED] wrote:
 Indeed - compared to my previous version, this one makes the boardfile
 even smaller:
 
textdata bss dec hex filename
23621552   43918 f4e
 old/arch/arm/mach-omap2/board-n800.o
23541456   43814 ee6
 new/arch/arm/mach-omap2/board-n800.o

Cool :-)

Acked-by: Felipe Balbi [EMAIL PROTECTED]

-- 
Best Regards,

Felipe Balbi
http://blog.felipebalbi.com
[EMAIL PROTECTED]


___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


Re: [i2c] [lm-sensors] [PATCH] hwmon: (max6650) Convert to a new-style i2c driver

2008-07-23 Thread Hans J. Koch
On Wed, Jul 16, 2008 at 10:52:42PM +0200, Hans de Goede wrote:
 Jean Delvare wrote:
  The new-style max6650 driver implements the optional detect() callback
  to cover the use cases of the legacy driver.
  
  Signed-off-by: Jean Delvare [EMAIL PROTECTED]
  Cc: Hans J. Koch [EMAIL PROTECTED]
 
 Looks good,

Yep.

 
 Acked-by: Hans de Goede [EMAIL PROTECTED]

Acked-by: Hans J. Koch [EMAIL PROTECTED]

 
 Regards,
 
 Hans
 
 
 
  ---
   drivers/hwmon/max6650.c |  102 
  +--
   1 file changed, 47 insertions(+), 55 deletions(-)
  
  --- linux-2.6.26-rc9.orig/drivers/hwmon/max6650.c   2008-07-12 
  09:20:29.0 +0200
  +++ linux-2.6.26-rc9/drivers/hwmon/max6650.c2008-07-12 
  10:27:13.0 +0200
  @@ -104,22 +104,34 @@ I2C_CLIENT_INSMOD_1(max6650);
   
   #define DIV_FROM_REG(reg) (1  (reg  7))
   
  -static int max6650_attach_adapter(struct i2c_adapter *adapter);
  -static int max6650_detect(struct i2c_adapter *adapter, int address, int 
  kind);
  +static int max6650_probe(struct i2c_client *client,
  +const struct i2c_device_id *id);
  +static int max6650_detect(struct i2c_client *client, int kind,
  + struct i2c_board_info *info);
   static int max6650_init_client(struct i2c_client *client);
  -static int max6650_detach_client(struct i2c_client *client);
  +static int max6650_remove(struct i2c_client *client);
   static struct max6650_data *max6650_update_device(struct device *dev);
   
   /*
* Driver data (common to all clients)
*/
   
  +static const struct i2c_device_id max6650_id[] = {
  +   { max6650, max6650 },
  +   { }
  +};
  +MODULE_DEVICE_TABLE(i2c, max6650_id);
  +
   static struct i2c_driver max6650_driver = {
  +   .class  = I2C_CLASS_HWMON,
  .driver = {
  .name   = max6650,
  },
  -   .attach_adapter = max6650_attach_adapter,
  -   .detach_client  = max6650_detach_client,
  +   .probe  = max6650_probe,
  +   .remove = max6650_remove,
  +   .id_table   = max6650_id,
  +   .detect = max6650_detect,
  +   .address_data   = addr_data,
   };
   
   /*
  @@ -128,7 +140,6 @@ static struct i2c_driver max6650_driver 
   
   struct max6650_data
   {
  -   struct i2c_client client;
  struct device *hwmon_dev;
  struct mutex update_lock;
  char valid; /* zero until following fields are valid */
  @@ -437,47 +448,21 @@ static struct attribute_group max6650_at
* Real code
*/
   
  -static int max6650_attach_adapter(struct i2c_adapter *adapter)
  +/* Return 0 if detection is successful, -ENODEV otherwise */
  +static int max6650_detect(struct i2c_client *client, int kind,
  + struct i2c_board_info *info)
   {
  -   if (!(adapter-class  I2C_CLASS_HWMON)) {
  -   dev_dbg(adapter-dev,
  -   FATAL: max6650_attach_adapter class HWMON not set\n);
  -   return 0;
  -   }
  -
  -   return i2c_probe(adapter, addr_data, max6650_detect);
  -}
  -
  -/*
  - * The following function does more than just detection. If detection
  - * succeeds, it also registers the new chip.
  - */
  -
  -static int max6650_detect(struct i2c_adapter *adapter, int address, int 
  kind)
  -{
  -   struct i2c_client *client;
  -   struct max6650_data *data;
  -   int err = -ENODEV;
  +   struct i2c_adapter *adapter = client-adapter;
  +   int address = client-addr;
   
  dev_dbg(adapter-dev, max6650_detect called, kind = %d\n, kind);
   
  if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
  dev_dbg(adapter-dev, max6650: I2C bus doesn't support 
  byte read mode, skipping.\n);
  -   return 0;
  -   }
  -
  -   if (!(data = kzalloc(sizeof(struct max6650_data), GFP_KERNEL))) {
  -   dev_err(adapter-dev, max6650: out of memory.\n);
  -   return -ENOMEM;
  +   return -ENODEV;
  }
   
  -   client = data-client;
  -   i2c_set_clientdata(client, data);
  -   client-addr = address;
  -   client-adapter = adapter;
  -   client-driver = max6650_driver;
  -
  /*
   * Now we do the remaining detection. A negative kind means that
   * the driver was loaded with no force parameter (default), so we
  @@ -501,28 +486,40 @@ static int max6650_detect(struct i2c_ada
  ||(i2c_smbus_read_byte_data(client, MAX6650_REG_COUNT)  0xFC))) {
  dev_dbg(adapter-dev,
  max6650: detection failed at 0x%02x.\n, address);
  -   goto err_free;
  +   return -ENODEV;
  }
   
  dev_info(adapter-dev, max6650: chip found at 0x%02x.\n, address);
   
  -   strlcpy(client-name, max6650, I2C_NAME_SIZE);
  -   mutex_init(data-update_lock);
  +   strlcpy(info-type, max6650, I2C_NAME_SIZE);
   
  -   if ((err = i2c_attach_client(client))) {
  -   dev_err(adapter-dev, max6650: failed to attach client.\n);
  -   goto err_free;
  +   return 0;
  +}
  +
  

[i2c] [PATCH 03/03] i2c-i801: Fix minor style issues

2008-07-23 Thread Ivo Manca

This patch fixes minor style issues warned about by checkPatch

Signed-off-by: Ivo Manca [EMAIL PROTECTED]
---

[PATCH 00/03] i2c-i801: Add basic interrupt support


--- __new   2008-07-23 10:51:28.0 +0200
+++ _new2008-07-23 10:53:06.0 +0200
@@ -381,9 +381,8 @@ static int i801_block_transaction_byte_b
do {
msleep(1);
temp = inb_p(SMBHSTSTS);
-   }
-   while ((!(temp  SMBHSTSTS_BYTE_DONE))
-   (timeout++  MAX_TIMEOUT));
+   } while ((!(temp  SMBHSTSTS_BYTE_DONE))
+ (timeout++  MAX_TIMEOUT));
 
/* If the SMBus is still busy, we give up */
if (timeout = MAX_TIMEOUT) {
@@ -502,7 +501,7 @@ static int i801_block_transaction(union 
 }
 
 /* Return -1 on error. */
-static s32 i801_access(struct i2c_adapter * adap, u16 addr,
+static s32 i801_access(struct i2c_adapter *adap, u16 addr,
   unsigned short flags, char read_write, u8 command,
   int size, union i2c_smbus_data * data)
 {
@@ -574,7 +573,7 @@ static s32 i801_access(struct i2c_adapte
else
outb_p(inb_p(SMBAUXCTL)  (~SMBAUXCTL_CRC), SMBAUXCTL);
 
-   if(block)
+   if (block)
ret = i801_block_transaction(data, read_write, size, hwpec);
else
ret = i801_transaction(xact | ENABLE_INT9);
@@ -586,9 +585,9 @@ static s32 i801_access(struct i2c_adapte
outb_p(inb_p(SMBAUXCTL)  ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B),
   SMBAUXCTL);
 
-   if(block)
+   if (block)
return ret;
-   if(ret)
+   if (ret)
return -1;
if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
return 0;
___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c

[i2c] class_for_each_device() oops

2008-07-23 Thread David Brownell
I happened across this ... it looks like the root cause
is that an i2c driver (smbus_alert) gets registered
before the class (i2c_adapter) being iterated.

(This used the latest version of the patch adding SMBus
alert support to I2C.  It's not mainline, although it's
been posted a few times.)


Now, obviously a trivial fix is to change that init order,
and just accept that there's now an init dependency which
didn't exist before.  But on the other hand I don't think
that it's reasonable to oops there; it's needless, and in
fact it never oopsed before!  

In this case adding 

if (!class-p)
return -EINVAL;

at the top of class_for_each_device() would prevent such
oopses from ever happening.

- Dave



=== insmod i2c-core
BUG: unable to handle kernel NULL pointer dereference at 00e4
IP: [c03381ef] mutex_lock_nested+0x65/0x23c
*pde =  
Oops:  [#1] PREEMPT 
Modules linked in: i2c_core(+) loop forcedeth ehci_hcd ohci_hcd

Pid: 2599, comm: insmod Not tainted (2.6.26-dev #40)
EIP: 0060:[c03381ef] EFLAGS: 00010002 CPU: 0
EIP is at mutex_lock_nested+0x65/0x23c
EAX: 0b92 EBX: f8a7ba80 ECX:  EDX: c03381ef
ESI: 00b0 EDI: 0246 EBP: f65a3e80 ESP: f65a3e48
 DS: 007b ES: 007b FS:  GS: 0033 SS: 0068
Process insmod (pid: 2599, ti=f65a2000 task=f64eba00 task.ti=f65a2000)
Stack: c025bf42  f65a3e80 f8a7ba20 f65a3e60 f64eba00 f65a3ea0 c03383be 
   f8a77226  f8a7ba58 f8a7ba80  f8a7bb00 f65a3e9c c025bf42 
   f8a7ba80 ffea f8a7ba80  f8a60e40 f65a3eb0 f8a77242 f8a789c1 
Call Trace:
 [c025bf42] ? class_for_each_device+0x2d/0xad
 [c03383be] ? mutex_lock_nested+0x234/0x23c
 [f8a77226] ? i2c_register_driver+0x65/0x95 [i2c_core]
 [c025bf42] ? class_for_each_device+0x2d/0xad
 [f8a77242] ? i2c_register_driver+0x81/0x95 [i2c_core]
 [f8a789c1] ? __attach_adapter+0x0/0x25 [i2c_core]
 [f881a023] ? i2c_init+0x23/0x76 [i2c_core]
 [c013ab8d] ? sys_init_module+0x1270/0x13eb
 [c0131e69] ? trace_hardirqs_off+0xb/0xd
 [c025b263] ? bus_register+0x0/0x1d0
 [c0102b81] ? sysenter_past_esp+0x6a/0xa5
 ===
Code: 74 21 e8 95 35 ec ff 85 c0 74 18 83 3d 20 23 7b c0 00 75 0f ba 86 00 00 
00 b8 c7 a9 3d c0 e8 87 0a de ff 9c 5f fa e8 6f 9c df ff 39 76 34 8d 46 04 c7 
46 04 00 00 00 00 89 45 d4 74 21 e8 5a 35 
EIP: [c03381ef] mutex_lock_nested+0x65/0x23c SS:ESP 0068:f65a3e48
---[ end trace c3a87e2e592c29fc ]---

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


Re: [i2c] class_for_each_device() oops

2008-07-23 Thread Greg KH
On Wed, Jul 23, 2008 at 04:06:47PM -0700, David Brownell wrote:
 I happened across this ... it looks like the root cause
 is that an i2c driver (smbus_alert) gets registered
 before the class (i2c_adapter) being iterated.
 
 (This used the latest version of the patch adding SMBus
 alert support to I2C.  It's not mainline, although it's
 been posted a few times.)
 
 
 Now, obviously a trivial fix is to change that init order,
 and just accept that there's now an init dependency which
 didn't exist before.  But on the other hand I don't think
 that it's reasonable to oops there; it's needless, and in
 fact it never oopsed before!  
 
 In this case adding 
 
   if (!class-p)
   return -EINVAL;
 
 at the top of class_for_each_device() would prevent such
 oopses from ever happening.

Makes sense, care to send a real patch for this?

thanks,

greg k-h

___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c


Re: [i2c] class_for_each_device() oops

2008-07-23 Thread David Brownell
On Wednesday 23 July 2008, Greg KH wrote:
  In this case adding 
  
    if (!class-p)
    return -EINVAL;
  
  at the top of class_for_each_device() would prevent such
  oopses from ever happening.
 
 Makes sense, care to send a real patch for this?

Here you go ... I noticed another place with the same
type of oops-affinity, and fixed that too.

= CUT HERE
From: David Brownell [EMAIL PROTECTED]

Anti-oops medicine for the class iterators ... the oops was
observed when a class was implicitly referenced before it
was initialized.

Signed-off-by: David Brownell [EMAIL PROTECTED]
---
 drivers/base/class.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/base/class.c  2008-07-22 15:27:52.0 -0700
+++ b/drivers/base/class.c  2008-07-23 16:39:58.0 -0700
@@ -292,7 +292,7 @@ int class_for_each_device(struct class *
struct device *dev;
int error = 0;
 
-   if (!class)
+   if (!class || !class-p)
return -EINVAL;
mutex_lock(class-p-class_mutex);
list_for_each_entry(dev, class-p-class_devices, node) {
@@ -341,7 +341,7 @@ struct device *class_find_device(struct 
struct device *dev;
int found = 0;
 
-   if (!class)
+   if (!class || !class-p)
return NULL;
 
mutex_lock(class-p-class_mutex);


___
i2c mailing list
i2c@lm-sensors.org
http://lists.lm-sensors.org/mailman/listinfo/i2c