Marvell mv64xxx i2c driver
PATCH 1/1 Marvell mv64xxx i2c driver
Greg, Philip,
Marvell makes a line of host bridge for PPC and MIPS systems. On those bridges is an i2c controller. This patch adds the driver for that i2c controller.
Please let me know if you see any problems with this patch.
Also, if you're not the correct person(s), please point me to who is.
Thanks,
Mark
--
drivers/i2c/busses/Kconfig +10 -0
@@ -476,4 +476,14 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + endmenu
drivers/i2c/busses/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
drivers/i2c/busses/i2c-mv64xxx.c new file +550 -0
550 lines not on this page · raw message
drivers/i2c/busses/i2c-mv64xxx.h new file +99 -0
99 lines not on this page · raw message
include/linux/i2c-id.h +4 -0
@@ -200,6 +200,7 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +#define I2C_ALGO_MV64XXX 0x170000/* Marvell mv64xxx i2c ctlr */ #define I2C_ALGO_EXP 0x800000/* experimental */
@@ -304,5 +305,8 @@/* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00#endif /* LINUX_I2C_ID_H */
include/linux/mv643xx.h +11 -6
@@ -977,12 +977,9 @@/* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020/****************************************/ /* GPP Interface Registers */
@@ -1083,6 +1080,14 @@u8 brg_can_tune;u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { +u32 freq_m; +u32 freq_n; +u32 timeout;/* In milliseconds */ +u32 retries; };#endif /* __ASM_MV64340_H */
Hi Mark,
Quoted 5 lines
Marvell makes a line of host bridge for PPC and MIPS systems. On those bridges is an i2c controller. This patch adds the driver for that i2c controller.
Please let me know if you see any problems with this patch.
I do not feel qualified for a full review of this code. However, I noticed the following minor issues:
drivers/i2c/busses/Kconfig line 481
Quoted 3 lines
drivers/i2c/busses/Kconfig +3
-0+config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60
&& EXPERIMENTAL?
include/linux/i2c-id.h line 203
Quoted 8 lines
diff -Nru
a/include/linux/i2c-id.hb/include/linux/i2c-id.hinclude/linux/i2c-id.h +1
-0@@ -200,6 +200,7 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +#define I2C_ALGO_MV64XXX 0x170000/* Marvell mv64xxx i2c ctlr */
0x170000 is reserved within the legacy i2c project for an USB algorithm, and 0x180000 for virtual busses. Could you please use 0x190000 instead, so as to avoid future collisions?
include/linux/i2c-id.h
Quoted 9 lines
include/linux/i2c-id.h +3
-6-#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020
You have a tab instead of space before MV64XXX_I2C_CTLR_NAME, it seems. Also, you want to align the numerical values using only tabs, no space.
Thanks,
Signature · 2 lines
Jean Delvare http://khali.linux-fr.org/
Quoted 8 lines · Jean Delvare
Review
Quoted 5 lines
(quoted diff) +3
-0+config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60&& EXPERIMENTAL?
Done.
Quoted 8 lines
Quoted 3 lines
+#define
I2C_ALGO_MV64XXX0x170000/* Marvell mv64xxx i2c ctlr */
0x170000is reserved within the legacy i2c project for an USB algorithm, and0x180000for virtual busses. Could you please use0x190000instead, so as to avoid future collisions?
Done.
Quoted 11 lines
(quoted diff) +3
-0+#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020You have a tab instead of space before
MV64XXX_I2C_CTLR_NAME, it seems. Also, you want to align the numerical values using only tabs, no space.
Actually, I did use tabs but what was already there used spaces. So the patch won't mess up the alignment, I changed mine to spaces too.
The attached patch is a complete replacement for the one posted earlier.
drivers/i2c/busses/Kconfig +10 -0
@@ -476,4 +476,14 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + endmenu
drivers/i2c/busses/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
drivers/i2c/busses/i2c-mv64xxx.c new file +550 -0
550 lines not on this page · raw message
drivers/i2c/busses/i2c-mv64xxx.h new file +99 -0
99 lines not on this page · raw message
include/linux/i2c-id.h +6 -0
@@ -200,6 +200,9 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ #define I2C_ALGO_EXP 0x800000/* experimental */
@@ -304,5 +307,8 @@/* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00#endif /* LINUX_I2C_ID_H */
include/linux/mv643xx.h +11 -6
@@ -977,12 +977,9 @@/* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020/****************************************/ /* GPP Interface Registers */
@@ -1083,6 +1080,14 @@u8 brg_can_tune;u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { +u32 freq_m; +u32 freq_n; +u32 timeout;/* In milliseconds */ +u32 retries; };#endif /* __ASM_MV64340_H */
Quoted 5 lines · Mark A. Greer
drivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/init.h>
drivers/i2c/busses/i2c-mv64xxx.c line 28
Quoted 10 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +10
-0+#include <linux/pci.h> +#include <linux/wait.h> +#include <linux/spinlock.h> +#include <asm/io.h> +#include <asm/ocp.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/mv643xx.h> +#include "i2c-mv64xxx.h"
Please put <asm/ after <linux/
drivers/i2c/busses/i2c-mv64xxx.c line 41
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+static inline void +mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status) +{ +pr_debug ("mv64xxx_i2c_fsm: ENTER--state: %d, status: 0x%x\n" , + drv_data->state, status);
You have a lot of pr_debug and other printk() for stuff in this driver. Please use dev_dbg(), dev_err() and friends instead. That way you get a consistant message, that points to the exact device that is causing the message.
drivers/i2c/busses/i2c-mv64xxx.c line 257
Quoted 3 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +3
-0+static inline void +mv64xxx_i2c_prepare_for_io (struct mv64xxx_i2c_data *drv_data, +struct i2c_msg *msg)
You have some big inline functions here. Should they really be inline? We aren't really worried about speed here, right? Size is probably a bigger issue.
drivers/i2c/busses/i2c-mv64xxx.h
Quoted 3 lines
diff -Nru
a/drivers/i2c/busses/i2c-mv64xxx.hb/drivers/i2c/busses/i2c-mv64xxx.hdrivers/i2c/busses/i2c-mv64xxx.h new file +0
-0
Is this header file really needed? Does any other file other than this single driver ever include it? If not, please just put it into the driver itself.
thanks,
greg k-h
Quoted 2 lines · Greg KH
Please put <asm/ after <linux/
Done.
Quoted 5 lines
You have a lot of
pr_debugand otherprintk()for stuff in this driver. Please usedev_dbg(),dev_err()and friends instead. That way you get a consistant message, that points to the exact device that is causing the message.
Cool. Done.
Quoted 4 lines
You have some big inline functions here. Should they really be inline? We aren't really worried about speed here, right? Size is probably a bigger issue.
No, no, and done.
Quoted 6 lines
Is this header file really needed? Does any other file other than this single driver ever include it? If not, please just put it into the driver itself.
No, no, and done.
Included is an *incremental* patch that I hope addresses your concerns.
Thanks Greg.
Mark
--
drivers/i2c/busses/i2c-mv64xxx.c +98 -34
@@ -11,21 +11,94 @@* is licensed "as is" without any warranty of any kind, whether express * or implied. */ -#include <linux/config.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/sched.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/wait.h> #include <linux/spinlock.h> -#include <asm/io.h> -#include <asm/ocp.h> #include <linux/i2c.h> #include <linux/interrupt.h> -#include <linux/delay.h> #include <linux/mv643xx.h> -#include "i2c-mv64xxx.h" +#include <asm/io.h> + +/* Register defines */ +#define MV64XXX_I2C_REG_SLAVE_ADDR 0x00 +#define MV64XXX_I2C_REG_DATA 0x04 +#define MV64XXX_I2C_REG_CONTROL 0x08 +#define MV64XXX_I2C_REG_STATUS 0x0c +#define MV64XXX_I2C_REG_BAUD 0x0c +#define MV64XXX_I2C_REG_EXT_SLAVE_ADDR 0x10 +#define MV64XXX_I2C_REG_SOFT_RESET 0x1c + +#define MV64XXX_I2C_REG_CONTROL_ACK 0x00000004 +#define MV64XXX_I2C_REG_CONTROL_IFLG 0x00000008 +#define MV64XXX_I2C_REG_CONTROL_STOP 0x00000010 +#define MV64XXX_I2C_REG_CONTROL_START 0x00000020 +#define MV64XXX_I2C_REG_CONTROL_TWSIEN 0x00000040 +#define MV64XXX_I2C_REG_CONTROL_INTEN 0x00000080 + +/* Ctlr status values */ +#define MV64XXX_I2C_STATUS_BUS_ERR 0x00 +#define MV64XXX_I2C_STATUS_MAST_START 0x08 +#define MV64XXX_I2C_STATUS_MAST_REPEAT_START 0x10 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_ACK 0x18 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_NO_ACK 0x20 +#define MV64XXX_I2C_STATUS_MAST_WR_ACK 0x28 +#define MV64XXX_I2C_STATUS_MAST_WR_NO_ACK 0x30 +#define MV64XXX_I2C_STATUS_MAST_LOST_ARB 0x38 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_ACK 0x40 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_NO_ACK 0x48 +#define MV64XXX_I2C_STATUS_MAST_RD_DATA_ACK 0x50 +#define MV64XXX_I2C_STATUS_MAST_RD_DATA_NO_ACK 0x58 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_ACK 0xd0 +#define MV64XXX_I2C_STATUS_MAST_WR_ADDR_2_NO_ACK 0xd8 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_ACK 0xe0 +#define MV64XXX_I2C_STATUS_MAST_RD_ADDR_2_NO_ACK 0xe8 +#define MV64XXX_I2C_STATUS_NO_STATUS 0xf8 + +/* Driver states */ +enum { +MV64XXX_I2C_STATE_INVALID , +MV64XXX_I2C_STATE_IDLE , +MV64XXX_I2C_STATE_WAITING_FOR_START_COND , +MV64XXX_I2C_STATE_WAITING_FOR_ADDR_1_ACK , +MV64XXX_I2C_STATE_WAITING_FOR_ADDR_2_ACK , +MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_ACK , +MV64XXX_I2C_STATE_WAITING_FOR_SLAVE_DATA , +MV64XXX_I2C_STATE_ABORTING , +}; + +/* Driver actions */ +enum { +MV64XXX_I2C_ACTION_INVALID , +MV64XXX_I2C_ACTION_CONTINUE , +MV64XXX_I2C_ACTION_SEND_START , +MV64XXX_I2C_ACTION_SEND_ADDR_1 , +MV64XXX_I2C_ACTION_SEND_ADDR_2 , +MV64XXX_I2C_ACTION_SEND_DATA , +MV64XXX_I2C_ACTION_RCV_DATA , +MV64XXX_I2C_ACTION_RCV_DATA_STOP , +MV64XXX_I2C_ACTION_SEND_STOP , +}; + +struct mv64xxx_i2c_data { +int irq; +uint state; +uint action; +u32 cntl_bits; +void *reg_base; +ulong reg_base_p; +u32 addr1; +u32 addr2; +uint bytes_left; +uint byte_posn; +uint block; +int rc; +u32 freq_m; +u32 freq_n; +wait_queue_head_t waitq; +spinlock_t lock; +struct i2c_msg *msg; +struct i2c_adapter adapter; +};/* *****************************************************************************
@@ -34,12 +107,9 @@* ***************************************************************************** */ -static inline void +static void mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status) { -pr_debug ("mv64xxx_i2c_fsm: ENTER--state: %d, status: 0x%x\n" , - drv_data->state, status); -/* * If state is idle, then this is likely the remnants of an old * operation that driver has given up on or the user has killed.
@@ -48,14 +118,12 @@if (drv_data->state ==MV64XXX_I2C_STATE_IDLE ) { drv_data->action =MV64XXX_I2C_ACTION_SEND_STOP ; drv_data->state =MV64XXX_I2C_STATE_IDLE ; -pr_debug ("mv64xxx_i2c_fsm: EXIT--Entered when in IDLE state\n" );return ; }if (drv_data->state ==MV64XXX_I2C_STATE_ABORTING ) { drv_data->action =MV64XXX_I2C_ACTION_SEND_STOP ; drv_data->state =MV64XXX_I2C_STATE_IDLE ; -pr_debug ("mv64xxx_i2c_fsm: EXIT--Aborting\n" );return ; }
@@ -135,27 +203,22 @@break ;default : -printk (KERN_ERR "mv64xxx_i2c_fsm: Ctlr Error -- " -"state: 0x%x, status: 0x%x\n" , drv_data->state, status); -printk (KERN_INFO "addr: 0x%x, flags: 0x%x\n" , - drv_data->msg->addr, drv_data->msg->flags); +dev_err (&drv_data->adapter.dev, +"mv64xxx_i2c_fsm: Ctlr Error -- state: 0x%x, " +"status: 0x%x, addr: 0x%x, flags: 0x%x\n" , + drv_data->state, status, drv_data->msg->addr, + drv_data->msg->flags); drv_data->action =MV64XXX_I2C_ACTION_SEND_STOP ; drv_data->state =MV64XXX_I2C_STATE_IDLE ; drv_data->rc = -EIO ; } -pr_debug ("mv64xxx_i2c_fsm: EXIT--action: %d, state: %d, rc: 0x%x\n" , - drv_data->action, drv_data->state, drv_data->rc);return ; }static void mv64xxx_i2c_do_action (struct mv64xxx_i2c_data *drv_data) { -pr_debug ("mv64xxx_i2c_do_action: ENTER--action: %d, state: %d, " -"cntl: 0x%x\n" , drv_data->action, drv_data->state, - drv_data->cntl_bits); -switch (drv_data->action) {case MV64XXX_I2C_ACTION_CONTINUE : writel(drv_data->cntl_bits,
@@ -207,7 +270,8 @@case MV64XXX_I2C_ACTION_INVALID :default : -printk (KERN_ERR "mv64xxx_i2c_do_action: Invalid action: %d\n" , +dev_err (&drv_data->adapter.dev, +"mv64xxx_i2c_do_action: Invalid action: %d\n" , drv_data->action); drv_data->rc = -EIO ;/* FALLTHRU */
@@ -220,7 +284,6 @@break ; } -pr_debug ("mv64xxx_i2c_do_action: EXIT\n" );return ; }
@@ -252,7 +315,7 @@* ***************************************************************************** */ -static inline void +static void mv64xxx_i2c_prepare_for_io (struct mv64xxx_i2c_data *drv_data,struct i2c_msg *msg) {
@@ -283,7 +346,7 @@return ; } -static inline void +static void mv64xxx_i2c_wait_for_completion (struct mv64xxx_i2c_data *drv_data) {long flags, time_left;
@@ -312,7 +375,8 @@if (!time_left <=0 ) { drv_data->state =MV64XXX_I2C_STATE_IDLE ; -printk (KERN_WARNING "mv64xxx: I2C bus locked\n" ); +dev_err (&drv_data->adapter.dev, +"mv64xxx: I2C bus locked\n" ); } }else
@@ -321,7 +385,7 @@return ; } -static inline int +static int mv64xxx_i2c_execute_msg (struct mv64xxx_i2c_data *drv_data,struct i2c_msg *msg) {long flags;
@@ -484,7 +548,7 @@if (request_irq (drv_data->irq, mv64xxx_i2c_intr,0 ,MV64XXX_I2C_CTLR_NAME , drv_data)) { -printk (KERN_ERR "mv64xxx: Can't register intr handler " +dev_err (dev,"mv64xxx: Can't register intr handler " "irq: %d\\n" , drv_data->irq);mv64xxx_i2c_unmap_regs (drv_data);
@@ -492,8 +556,8 @@return -EINVAL ; }else if ((rc =i2c_add_adapter (&drv_data->adapter)) !=0 ) { -printk (KERN_WARNING "mv64xxx: Can't add i2c adapter " -"rc: %d\n" , -rc); +dev_err (dev,"mv64xxx: Can't add i2c adapter, rc: %d\n" , + -rc);free_irq (drv_data->irq, drv_data);mv64xxx_i2c_unmap_regs (drv_data);kfree (drv_data);
drivers/i2c/busses/i2c-mv64xxx.h deleted +0 -99
99 lines not on this page · raw message
Quoted 2 lines · Jean Delvare
Hi Mark,
Thanks for the commenting, Jean.
Quoted 4 lines
<snip>
Quoted 8 lines
drivers/i2c/busses/Kconfig line 481
Quoted 5 lines
drivers/i2c/busses/Kconfig +3
-0+config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60&& EXPERIMENTAL?
Yes, I guess that's the correct thing to do. I'll add that.
Quoted 5 lines
Quoted 5 lines
diff -Nru
a/include/linux/i2c-id.hb/include/linux/i2c-id.hinclude/linux/i2c-id.h +0
-0@@ -200,6 +200,7 @@
Quoted 10 lines
include/linux/i2c-id.h line 206
Quoted 5 lines
include/linux/i2c-id.h +1
-0#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +#define I2C_ALGO_MV64XXX 0x170000/* Marvell mv64xxx i2c ctlr */
0x170000is reserved within the legacy i2c project for an USB algorithm, and0x180000for virtual busses. Could you please use0x190000instead, so as to avoid future collisions?
Absolutely. I was unaware of the other uses.
Quoted 13 lines
include/linux/i2c-id.h
Quoted 8 lines
include/linux/i2c-id.h +3
-1-#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020You have a tab instead of space before
MV64XXX_I2C_CTLR_NAME, it seems. Also, you want to align the numerical values using only tabs, no space.
Oops. I'll fix that too and repost later today.
Mark
drivers/i2c/busses/i2c-mv64xxx.c line 38
Quoted 2 lines · Mark A. Greer
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+static inline void +mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status)
This is a much too big of a function to be "inline". Please change it. Same for your other inline functions, that's not really needed, right?
drivers/i2c/busses/i2c-mv64xxx.c line 41
Quoted 3 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +3
-0+{ +pr_debug ("mv64xxx_i2c_fsm: ENTER--state: %d, status: 0x%x\n" , + drv_data->state, status);
Please use the dev_* calls instead. It gives you an accurate description of the specific device that emits the messages. Also use it for all of the printk() calls in the driver too.
thanks,
greg k-h
Quoted 23 lines · Greg KH
drivers/i2c/busses/i2c-mv64xxx.c line 38
Quoted 4 lines · Mark A. Greer
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+static inline void +mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status)This is a much too big of a function to be "inline". Please change it. Same for your other inline functions, that's not really needed, right?
drivers/i2c/busses/i2c-mv64xxx.c line 41
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +3
-0+{ +pr_debug ("mv64xxx_i2c_fsm: ENTER--state: %d, status: 0x%x\n" , + drv_data->state, status);Please use the dev_* calls instead. It gives you an accurate description of the specific device that emits the messages. Also use it for all of the
printk()calls in the driver too.
Quoted 4 lines
thanks,
greg k-h
Certainly. I already posted this [incremental] patch based on your previous comments, http://www.ussg.iu.edu/hypermail/linux/kernel/0501.3/0941.html. Is that better?
Mark
Quoted 27 lines · Mark A. Greer
Quoted 25 lines · Greg KH
drivers/i2c/busses/i2c-mv64xxx.c line 38
Quoted 4 lines · Mark A. Greer
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+static inline void +mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status)This is a much too big of a function to be "inline". Please change it. Same for your other inline functions, that's not really needed, right?
drivers/i2c/busses/i2c-mv64xxx.c line 41
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +3
-0+{ +pr_debug ("mv64xxx_i2c_fsm: ENTER--state: %d, status: 0x%x\n" , + drv_data->state, status);Please use the dev_* calls instead. It gives you an accurate description of the specific device that emits the messages. Also use it for all of the
printk()calls in the driver too.thanks,
Quoted 7 lines
Quoted 2 lines
greg k-h
Certainly. I already posted this [incremental] patch based on your previous comments,
http://www.ussg.iu.edu/hypermail/linux/kernel/0501.3/0941.html. Is that better?
How about a whole new patch that I could apply? That would be better :)
thanks,
greg k-h
Quoted 3 lines · Greg KH
How about a whole new patch that I could apply? That would be better :)
Oops, sorry. :)
drivers/i2c/busses/Kconfig +10 -0
@@ -476,4 +476,14 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + endmenu
drivers/i2c/busses/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
drivers/i2c/busses/i2c-mv64xxx.c new file +614 -0
614 lines not on this page · raw message
include/linux/i2c-id.h +6 -0
@@ -200,6 +200,9 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ #define I2C_ALGO_EXP 0x800000/* experimental */
@@ -305,5 +308,8 @@/* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00#endif /* LINUX_I2C_ID_H */
include/linux/mv643xx.h +11 -6
@@ -977,12 +977,9 @@/* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020/****************************************/ /* GPP Interface Registers */
@@ -1083,6 +1080,14 @@u8 brg_can_tune;u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { +u32 freq_m; +u32 freq_n; +u32 timeout;/* In milliseconds */ +u32 retries; };#endif /* __ASM_MV64340_H */
PATCH 1/1 Marvell mv64xxx i2c driver
In reply to Mark A. Greerdrivers/i2c/busses/i2c-mv64xxx.c
Quoted 5 lines · Mark A. Greer
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+struct mv64xxx_i2c_data { +void *reg_base;
ioremap() returns "void __iomem *".
drivers/i2c/busses/i2c-mv64xxx.c line 437
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+static void __devexit +mv64xxx_i2c_unmap_regs (struct mv64xxx_i2c_data *drv_data) +{ +if (!drv_data->reg_base) { +iounmap (drv_data->reg_base);
A typo? You're unmapping known to be invalid address.
drivers/i2c/busses/i2c-mv64xxx.c line 442
Quoted 1 line
drivers/i2c/busses/i2c-mv64xxx.c new file +1
-0+ drv_data->reg_base =0 ;
Use NULL because drv_data->reg_base is a pointer.
drivers/i2c/busses/i2c-mv64xxx.c
Quoted 7 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+}; +static int __devinit +mv64xxx_i2c_probe (struct device *dev) +{ +if ((pd->id =0 ) && pdata) {
Rewrite this as:
if ((pd->id != 0) || !pdata) return -ENODEV;
and save one level of indentation below.
drivers/i2c/busses/i2c-mv64xxx.c line 466
Quoted 9 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +9
-0+ drv_data =kmalloc (sizeof (struct mv64xxx_i2c_data ),GFP_KERNEL ); +if (!drv_data) +return -ENOMEM ; +memset (drv_data,0 ,sizeof (struct mv64xxx_i2c_data )); + +if (mv64xxx_i2c_map_regs (pd, drv_data)) { +kfree (drv_data); +return -ENODEV ; + }
[snip non-branching stuff]
drivers/i2c/busses/i2c-mv64xxx.c line 488
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+if (request_irq (drv_data->irq, mv64xxx_i2c_intr,0 , +MV64XXX_I2C_CTLR_NAME , drv_data)) { + +dev_err (dev,"mv64xxx: Can't register intr handler " +"irq: %d\\n" , drv_data->irq);
"\n".
drivers/i2c/busses/i2c-mv64xxx.c line 501
Quoted 13 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +13
-0+ +mv64xxx_i2c_unmap_regs (drv_data); +kfree (drv_data); +return -EINVAL ; + } +else if ((rc =i2c_add_adapter (&drv_data->adapter)) !=0 ) { +dev_err (dev,"mv64xxx: Can't add i2c adapter, rc: %d\n" , + -rc); +free_irq (drv_data->irq, drv_data); +mv64xxx_i2c_unmap_regs (drv_data); +kfree (drv_data); +return rc; + }
[snip]
drivers/i2c/busses/i2c-mv64xxx.c line 60
Quoted 3 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+ } +}
Use centralized exiting and goto's. Something like:
if (mv64xxx_i2c_map_regs(pd, drv_data)) {
rc = -ENODEV;
goto exit_free;
}
if (request_irq) {
rc = -EINVAL;
dev_err
goto exit_unmap_regs
}
if (rc = i2c_add_adapter) {
dev_err
goto exit_free_irq
}
mv64xxx_i2c_hw_init
return 0;
exit_free_irq:
free_irq
exit_unmap_regs:
mv64xxx_i2c_unmap_regs
exit_free:
kfree
return rc;
AlexeyP. S.: struct mv64xxx_i2c_data revisited...
drivers/i2c/busses/i2c-mv64xxx.c
Quoted 2 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+uint state; +ulong reg_base_p;
Silly request, but... Maybe this should be changed to plain old "unsigned int" and "unsigned long". Please. I just don't understand why people use "uint", "u_int", "uInt", "UINT", "uINT", "uint_t" which are always typedef'ed to "unsigned int".
Quoted 9 lines · Alexey Dobriyan
P. S.: struct
mv64xxx_i2c_datarevisited...drivers/i2c/busses/i2c-mv64xxx.h line 84
Quoted 2 lines
drivers/i2c/busses/i2c-mv64xxx.h new file +2
-0+uint state; +ulong reg_base_p;Silly request, but... Maybe this should be changed to plain old "unsigned int" and "unsigned long". Please. I just don't understand why people use "uint", "
u_int", "uInt", "UINT", "uINT", "uint_t" which are always typedef'ed to "unsigned int".
Not a silly request at all. Please use the u32, u64 and so on values instead. That way we know what you mean, and it's portable.
thanks,
greg k-h
Quoted 11 lines · Alexey Dobriyan
Review
Quoted 4 lines · Mark A. Greer
(quoted diff) +2
-0+struct mv64xxx_i2c_data { + void *reg_base;
ioremap()returns "void__iomem*".
Okay.
Quoted 12 lines
Review
Quoted 9 lines
(quoted diff) +5
-0+static void __devexit +mv64xxx_i2c_unmap_regs(struct mv64xxx_i2c_data *drv_data) +{ + if (!drv_data->reg_base) { + iounmap(drv_data->reg_base);A typo? You're unmapping known to be invalid address.
Yes, a typo. Good catch.
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +1
-0+ drv_data->reg_base = 0;Use NULL because
drv_data->reg_baseis a pointer.
Done.
Quoted 8 lines
Review
Quoted 5 lines
(quoted diff) +1
-0+ if ((pd->id == 0) && pdata) {Rewrite this as:
Quoted 5 lines
if ((pd->id != 0) || !pdata) return -ENODEV;and save one level of indentation below.
Done.
Quoted 3 lines
<snip of
xxx_probemodifications>
Done.
Quoted 7 lines
Alexey
P. S.: struct
mv64xxx_i2c_datarevisited...
Quoted 12 lines
Review
Quoted 4 lines
(quoted diff) +2
-0+ uint state; + ulong reg_base_p;Silly request, but... Maybe this should be changed to plain old "unsigned int" and "unsigned long". Please. I just don't understand why people use "uint", "
u_int", "uInt", "UINT", "uINT", "uint_t" which are always typedef'ed to "unsigned int".
Thanks Alexey & Greg. How's this (a complete replacement for previous patch)?
--
drivers/i2c/busses/Kconfig +10 -0
@@ -476,4 +476,14 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + endmenu
drivers/i2c/busses/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
drivers/i2c/busses/i2c-mv64xxx.c new file +615 -0
615 lines not on this page · raw message
include/linux/i2c-id.h +6 -0
@@ -200,6 +200,9 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ #define I2C_ALGO_EXP 0x800000/* experimental */
@@ -305,5 +308,8 @@/* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00#endif /* LINUX_I2C_ID_H */
include/linux/mv643xx.h +11 -6
@@ -977,12 +977,9 @@/* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020/****************************************/ /* GPP Interface Registers */
@@ -1083,6 +1080,14 @@u8 brg_can_tune;u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { +u32 freq_m; +u32 freq_n; +u32 timeout;/* In milliseconds */ +u32 retries; };#endif /* __ASM_MV64340_H */
PATCH 1/1 Marvell mv64xxx i2c driver
In reply to Mark A. Greerdrivers/i2c/busses/Kconfig line 484
Quoted 7 lines · Mark A. Greer
How's this (a complete replacement for previous patch)?
drivers/i2c/busses/Kconfig +2
-0+ If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges
Dot at the end. Should have noticed it earlier...
drivers/i2c/busses/i2c-mv64xxx.c
Quoted 11 lines
drivers/i2c/busses/Kconfig +1
-0+ This driver can also be built as a module. If so, the moduledrivers/i2c/busses/i2c-mv64xxx.c new file +5
-0+static void +mv64xxx_i2c_fsm (struct mv64xxx_i2c_data *drv_data,u32 status) + if (drv_data->state = MV64XXX_I2C_STATE_IDLE) { + drv_data->action =MV64XXX_I2C_ACTION_SEND_STOP ; + drv_data->state =MV64XXX_I2C_STATE_IDLE ;
drv_data->state is already MV64XXX_I2C_STATE_IDLE. Gcc will probably optimize this line away, but...
drivers/i2c/busses/i2c-mv64xxx.c
Quoted 2 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+ } +else {
It should be "} else {" according to CodingStyle.
drivers/i2c/busses/i2c-mv64xxx.c line 239
Quoted 7 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +6
-0+static int +mv64xxx_i2c_intr (int irq,void *dev_id,struct pt_regs *regs) + while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) & +MV64XXX_I2C_REG_CONTROL_IFLG ) { + status =readl (drv_data->reg_base +MV64XXX_I2C_REG_STATUS ); +mv64xxx_i2c_fsm (drv_data, status);
It can set drv_data->rc to -ENODEV or -EIO. In both cases ->action goes to MV64XXX_I2C_ACTION_SEND_STOP and mv64xxx_i2c_do_action() will writel() something. Is it correct to _not_ check ->rc here? If it isn't then would it be better to make all functions that set it return -E___ instead and drop struct mv64xxx_i2c_data.rc altogether?
drivers/i2c/busses/i2c-mv64xxx.c line 313
Quoted 10 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +8
-0+mv64xxx_i2c_do_action (drv_data); +static void +mv64xxx_i2c_wait_for_completion (struct mv64xxx_i2c_data *drv_data) + time_left =wait_event_timeout (drv_data->waitq, + !drv_data->block, +msecs_to_jiffies (drv_data->adapter.timeout)); + +if (!time_left <=0 ) {
Confusing. You meant "if (time_left)" or "if (time_left > 0)"?
drivers/i2c/busses/i2c-mv64xxx.c line 386
Quoted 7 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +6
-0+ drv_data->state =MV64XXX_I2C_STATE_IDLE ; +dev_err (&drv_data->adapter.dev, +"mv64xxx: I2C bus locked\n" ); + } +static struct i2c_algorithm mv64xxx_i2c_algo = { + .name =MV64XXX_I2C_CTLR_NAME "algorithm" ,
MV64XXX_I2C_CTLR_NAME doesn't end with space. " algorithm" here.
drivers/i2c/busses/i2c-mv64xxx.c line 469
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +4
-0+static int __devinit +mv64xxx_i2c_probe(struct device *dev) + strncpy(drv_data->adapter.name, MV64XXX_I2C_CTLR_NAME "adapter", + I2C_NAME_SIZE);
And " adapter" there.
drivers/i2c/busses/i2c-mv64xxx.c
Quoted 2 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +2
-0+dev_err (dev,"mv64xxx: Can't register intr handler " +"irq: %d\\n" , drv_data->irq);
You snipped s# \\n # \n # suggestion in my previous email. ;-)
include/linux/mv643xx.h line 980
Quoted 4 lines
include/linux/mv643xx.h +1
-0+#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c"
Alexey
Hi, Alexey.
--
Quoted 17 lines · Alexey Dobriyan
Quoted 10 lines · Mark A. Greer
How's this (a complete replacement for previous patch)?
drivers/i2c/busses/Kconfig +0
-0
Quoted 7 lines
drivers/i2c/busses/Kconfig
Quoted 4 lines
drivers/i2c/busses/Kconfig +2
-0+ If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridgesDot at the end. Should have noticed it earlier...
Gahh, I noticed that too a while back. I thought I'd fixed it... Done.
Quoted 11 lines
drivers/i2c/busses/Kconfig
Quoted 7 lines
drivers/i2c/busses/Kconfig +3
-0+ if (drv_data->state == MV64XXX_I2C_STATE_IDLE) { + drv_data->action = MV64XXX_I2C_ACTION_SEND_STOP; + drv_data->state = MV64XXX_I2C_STATE_IDLE;
drv_data->stateis alreadyMV64XXX_I2C_STATE_IDLE. Gcc will probably optimize this line away, but...
Done away with.
Quoted 9 lines
drivers/i2c/busses/Kconfig
Quoted 6 lines
drivers/i2c/busses/Kconfig +2
-0+ } + else {It should be "} else {" according to CodingStyle.
Done.
Quoted 9 lines
Quoted 6 lines
drivers/i2c/busses/Kconfig +2
-0+static int +mv64xxx_i2c_intr(int irq, void *dev_id, struct pt_regs *regs)
Quoted 11 lines
drivers/i2c/busses/Kconfig
Quoted 6 lines
drivers/i2c/busses/Kconfig +4
-0+ while (readl(drv_data->reg_base + MV64XXX_I2C_REG_CONTROL) & + MV64XXX_I2C_REG_CONTROL_IFLG) { + status = readl(drv_data->reg_base + MV64XXX_I2C_REG_STATUS); + mv64xxx_i2c_fsm(drv_data, status);It can set
drv_data->rcto-ENODEVor-EIO. In both cases ->action goes toMV64XXX_I2C_ACTION_SEND_STOPandmv64xxx_i2c_do_action()willwritel()something. Is it correct to _not_ check ->rc here?
I think so. It still needs to go into do_action even when rc != 0 (in which case it'll do a STOP condition).
Quoted 4 lines
If it isn't then would it be
better to make all functions that set it return -E___ instead and drop struct mv64xxx_i2c_data.rc altogether?
I may not be understanding what you mean but I think I need something like mv64xxx_i2c_data.rc or a plain old global to hang onto the return code. I need that so when the wait_event_interruptible_timeout() returns, that thread can find out what happened while it was blocked. This is what I mean:
- calling thread enters i2c_xfer
- eventually the initial i2c action is executed and the thread blocks in wait_event_interruptible_timeout()
- other processes run
- several interrupts happen, last one causing an error which is stored in mv64xxx_i2c_data.rc
- do_action issues a stop on the i2c bus
- thread is unblocked and now has to dig out the rc from mv64xxx_i2c_data.rc
Or am I not understanding what you mean?
Quoted 7 lines
(quoted diff) +2
-0+ + if (!time_left <= 0) {Confusing. You meant "if (
time_left)" or "if (time_left> 0)"?
No, I'm blind. I meant "if (time_left <=0)". Should be fixed now. Good catch.
Quoted 9 lines
drivers/i2c/busses/Kconfig
Quoted 6 lines
drivers/i2c/busses/Kconfig +2
-0+static struct i2c_algorithm mv64xxx_i2c_algo = { + .name = MV64XXX_I2C_CTLR_NAME "algorithm",
MV64XXX_I2C_CTLR_NAMEdoesn't end with space. " algorithm" here.
Space added.
Quoted 9 lines
drivers/i2c/busses/Kconfig
Quoted 6 lines
drivers/i2c/busses/Kconfig +2
-0+ dev_err(dev, "mv64xxx: Can't register intr handler " + "irq: %d\\n", drv_data->irq);You snipped s# \\n # \n # suggestion in my previous email. ;-)
Ah, got it this time. :)
This patch is a replacement patch that should address your concerns except maybe the mv64xxx_i2c_data.rc one.
--
drivers/i2c/busses/Kconfig +10 -0
@@ -476,4 +476,14 @@ This driver can also be built as a module. If so, the module will be called i2c-pca-isa. +config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on I2C && MV64X60 && EXPERIMENTAL + help + If you say yes to this option, support will be included for the + built-in I2C interface on the Marvell 64xxx line of host bridges. + + This driver can also be built as a module. If so, the module + will be called i2c-mv64xxx. + endmenu
drivers/i2c/busses/Makefile +1 -0
@@ -20,6 +20,7 @@ obj-$(CONFIG_I2C_IXP4XX) += i2c-ixp4xx.o obj-$(CONFIG_I2C_KEYWEST) += i2c-keywest.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o +obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_NFORCE2) += i2c-nforce2.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT_LIGHT) += i2c-parport-light.o
drivers/i2c/busses/i2c-mv64xxx.c new file +606 -0
606 lines not on this page · raw message
include/linux/i2c-id.h +6 -0
@@ -200,6 +200,9 @@#define I2C_ALGO_SIBYTE 0x150000/* Broadcom SiByte SOCs */ #define I2C_ALGO_SGI 0x160000/* SGI algorithm */ +/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ #define I2C_ALGO_EXP 0x800000/* experimental */
@@ -305,5 +308,8 @@/* --- MCP107 adapter */ #define I2C_HW_MPC107 0x00 + +/* --- Marvell mv64xxx i2c adapter */ +#define I2C_HW_MV64XXX 0x00#endif /* LINUX_I2C_ID_H */
include/linux/mv643xx.h +11 -6
@@ -977,12 +977,9 @@/* I2C Registers */ /****************************************/ -#define MV64340_I2C_SLAVE_ADDR 0xc000 -#define MV64340_I2C_EXTENDED_SLAVE_ADDR 0xc010 -#define MV64340_I2C_DATA 0xc004 -#define MV64340_I2C_CONTROL 0xc008 -#define MV64340_I2C_STATUS_BAUDE_RATE 0xc00C -#define MV64340_I2C_SOFT_RESET 0xc01c +#define MV64XXX_I2C_CTLR_NAME "mv64xxx i2c" +#define MV64XXX_I2C_OFFSET 0xc000 +#define MV64XXX_I2C_REG_BLOCK_SIZE 0x0020/****************************************/ /* GPP Interface Registers */
@@ -1083,6 +1080,14 @@u8 brg_can_tune;u8 brg_clk_src; u32 brg_clk_freq; +}; + +/* i2c Platform Device, Driver Data */ +struct mv64xxx_i2c_pdata { +u32 freq_m; +u32 freq_n; +u32 timeout;/* In milliseconds */ +u32 retries; };#endif /* __ASM_MV64340_H */
Quoted 8 lines · Mark A. Greer
Quoted 5 lines
drivers/i2c/busses/i2c-mv64xxx.c line 300
Quoted 1 line
drivers/i2c/busses/i2c-mv64xxx.c new file +1
-0+mv64xxx_i2c_fsm (drv_data, status);It can set
drv_data->rcto-ENODEVor-EIO. In both cases ->action goes toMV64XXX_I2C_ACTION_SEND_STOPandmv64xxx_i2c_do_action()willwritel()something. Is it correct to _not_ check ->rc here?I think so. It still needs to go into
do_actioneven when rc != 0 (in which case it'll do a STOP condition).
Ok. Thanks for the explanation. Agree, ->rc should be left as is.
include/linux/i2c-id.h line 205
Quoted 9 lines
This patch is a replacement patch that should address your concerns except maybe the mv64xxx_i2c_data.rc one.
include/linux/i2c-id.h +3
-0+/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */
While I searched for typos and you're fixing them, au1550 owned 0x170000. 2.6.11-rc3 says:
#define I2C_ALGO_AU1550 0x170000 /* Au1550 PSC algorithm */
So, I'd remove first two comments.
Oh, and the last note: current sparse and gcc 4 don't produce any warnings.
Alexey
Quoted 12 lines · Alexey Dobriyan
Quoted 8 lines · Mark A. Greer
Quoted 8 lines
drivers/i2c/busses/i2c-mv64xxx.c line 300
Quoted 3 lines
drivers/i2c/busses/i2c-mv64xxx.c new file +1
-0+mv64xxx_i2c_fsm (drv_data, status);It can set
drv_data->rcto-ENODEVor-EIO. In both cases ->action goes toMV64XXX_I2C_ACTION_SEND_STOPandmv64xxx_i2c_do_action()willwritel()something. Is it correct to _not_ check ->rc here?
Quoted 6 lines
Quoted 3 lines
I think so. It still needs to go into
do_actioneven when rc != 0 (in which case it'll do a STOP condition).Ok. Thanks for the explanation. Agree, ->rc should be left as is.
Okay.
Quoted 18 lines
Quoted 6 lines
include/linux/i2c-id.h line 205
Quoted 8 lines
include/linux/i2c-id.h +3
-0+/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ While I searched for typos and you're fixing them, au1550 owned
0x170000. 2.6.11-rc3 says:
Quoted 4 lines
#define I2C_ALGO_AU1550 0x170000 /* Au1550 PSC algorithm */So, I'd remove first two comments.
I added the comments b/c of this email from Jean Delvare, http://www.uwsg.iu.edu/hypermail/linux/kernel/0501.3/0977.html. The relevant part being:
"0x170000 is reserved within the legacy i2c project for an USB algorithm, and 0x180000 for virtual busses. Could you please use 0x190000 instead, so as to avoid future collisions?"
It looks like I2C_ALGO_AU1550 was just added so my guess is Jean is correct and I2C_ALGO_AU1550 should be made 0x1a0000 (or I move mine back one). Would someone confirm that 0x170000 is used by legacy i2c stuffs? I don't really know where to look. If so, I can easily make a patch moving it back.
Quoted 3 lines
Oh, and the last note: current sparse and gcc 4 don't produce any warnings.
Cool!
Mark
Hi Mark, Alexey,
Quoted 19 lines
Quoted 10 lines
include/linux/i2c-id.h line 205
Quoted 3 lines
include/linux/i2c-id.h +3
-0+/* 0x170000 - USB */ +/* 0x180000 - Virtual buses */ +#define I2C_ALGO_MV64XXX 0x190000/* Marvell mv64xxx i2c ctlr */ While I searched for typos and you're fixing them, au1550 owned
0x170000. 2.6.11-rc3 says:#define I2C_ALGO_AU1550 0x170000 /* Au1550 PSC algorithm */So, I'd remove first two comments.
I added the comments b/c of this email from Jean Delvare,
http://www.uwsg.iu.edu/hypermail/linux/kernel/0501.3/0977.html. The relevant part being:"
0x170000is reserved within the legacy i2c project for an USB algorithm, and0x180000for virtual busses. Could you please use0x190000instead, so as to avoid future collisions?"
Quoted 5 lines
It looks like
I2C_ALGO_AU1550was just added so my guess is Jean is correct andI2C_ALGO_AU1550should be made0x1a0000(or I move mine back one). Would someone confirm that0x170000is used by legacy i2c stuffs? I don't really know where to look. If so, I can easily make a patch moving it back.
I am as surprised as you are to see this here. I2C_ALGO_AU1550 should really be made a different value. There is also a problem with I2C_ALGO_PCA and I2C_ALGO_SIBYTE having the same value, which was already reported to Greg some days ago if memory serves. I think I will send a patch against 2.6.10-rc3 to Linus this evening, which fixes the broken algo IDs. That way Mark can keep the algorithm ID he is using right now, and each algorithm will get its own, unique ID, as should be.
You can see the i2c-id.h list from the legacy i2c project here:
http://www2.lm-sensors.nu/~lm78/cvs/i2c/kernel/i2c-id.h
I am indeed trying to keep it in sync with the one in Linux 2.6 (and with the one in Linux 2.4 at times), in the hope it'll avoid confusion and increase portability.
Thanks,
--
Jean Delvare
Hi all,
Quoting myself:
Quoted 8 lines
I am as surprised as you are to see this here.
I2C_ALGO_AU1550should really be made a different value. There is also a problem withI2C_ALGO_PCAandI2C_ALGO_SIBYTEhaving the same value, which was already reported to Greg some days ago if memory serves. I think I will send a patch against 2.6.10-rc3 to Linus this evening, which fixes the broken algo IDs. That way Mark can keep the algorithm ID he is using right now, and each algorithm will get its own, unique ID, as should be.
I've changed my mind since. There isn't anything critical here and pushing random patches to Linus right before he releases 2.6.11 wouldn't have been particularly subtle. So I instead sent a patch to Greg, as can be seen here:
http://archives.andrew.net.au/lm-sensors/msg29405.html
So Mark, providing Greg accepts this patch, you can assume that I2C_ALGO_MV64XXX is already properly defined in Greg's tree (where your own patch will end up) so you don't need to add it yourself. You will still have to define I2C_HW_MV64XXX though.
Thanks,
Signature · 1 line
Jean Delvare