Add I2C support for Octeon SOCs.
Subsystems (3)
cover Add I2C support for Octeon SOCs.
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
I will reply with the three patches.
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.
Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.
arch/mips/cavium-octeon/octeon-platform.c | 85 +++++ arch/mips/include/asm/octeon/octeon.h | 5 + drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-octeon.c | 579 +++++++++++++++++++++++++++++ 5 files changed, 680 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-octeon.c
A message that is not in the archive (sent off-list or not yet received): 4B463B1F.6000404-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org
PATCH 1/3 MIPS: Octeon: Add I2C platform driver.
--- arch/mips/cavium-octeon/octeon-platform.c | 72 +++++++++++++++++++++++++++++ arch/mips/include/asm/octeon/octeon.h | 5 ++ 2 files changed, 77 insertions(+), 0 deletions(-)
arch/mips/cavium-octeon/octeon-platform.c +72 -0
@@ -165,6 +165,78 @@ out: }device_initcall (octeon_rng_device_init); + +#define OCTEON_I2C_IO_BASE 0x1180000001000ull +#define OCTEON_I2C_IO_UNIT_OFFSET 0x200 + +static struct octeon_i2c_data octeon_i2c_data[2 ]; + +static int __init octeon_i2c_device_init (void ) +{ +struct platform_device *pd; +int ret =0 ; +int port, num_ports; + +struct resource i2c_resources[] = { + { + .flags =IORESOURCE_MEM , + }, { + .flags =IORESOURCE_IRQ , + } + }; + +if (OCTEON_IS_MODEL (OCTEON_CN56XX ) ||OCTEON_IS_MODEL (OCTEON_CN52XX )) + num_ports =2 ; +else + num_ports =1 ; + +for (port =0 ; port < num_ports; port++) { + octeon_i2c_data[port].sys_freq =octeon_get_clock_rate (); +/*FIXME: should be examined. At the moment is set for 100Khz */ + octeon_i2c_data[port].i2c_freq =100000 ; + + pd =platform_device_alloc ("i2c-octeon" , port); +if (!pd) { + ret = -ENOMEM ; + goto out; + } + + pd->dev.platform_data = octeon_i2c_data + port; + + i2c_resources[0 ].start = +OCTEON_I2C_IO_BASE + (port *OCTEON_I2C_IO_UNIT_OFFSET ); + i2c_resources[0 ].end = i2c_resources[0 ].start +0x20 ; +switch (port) { +case 0 : + i2c_resources[1 ].start =OCTEON_IRQ_TWSI ; + i2c_resources[1 ].end =OCTEON_IRQ_TWSI ; +break ; +case 1 : + i2c_resources[1 ].start =OCTEON_IRQ_TWSI2 ; + i2c_resources[1 ].end =OCTEON_IRQ_TWSI2 ; +break ; +default : +BUG (); + } + + ret =platform_device_add_resources (pd, + i2c_resources, +ARRAY_SIZE (i2c_resources)); +if (ret) + goto fail; + + ret =platform_device_add (pd); +if (ret) + goto fail; + } +return ret; +fail: +platform_device_put (pd); +out: +return ret; +} +device_initcall (octeon_i2c_device_init); +/* Octeon SMI/MDIO interface. */ static int __init octeon_mdiobus_device_init (void ) {
arch/mips/include/asm/octeon/octeon.h +5 -0
@@ -213,6 +213,11 @@ struct octeon_cf_data {int dma_engine;/* -1 for no DMA */ }; +struct octeon_i2c_data { +unsigned int sys_freq; +unsigned int i2c_freq; +}; +extern void octeon_write_lcd (const char *s);extern void octeon_check_cpu_bist (void );extern int octeon_get_boot_uart (void );
Signature · 1 line
1.6.0.6
A message that is not in the archive (sent off-list or not yet received): 1262894061-32613-1-git-send-email-ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org
Re: [PATCH 1/3] MIPS: Octeon: Add I2C platform driver.
Hello.
Quoted 3 lines · David Daney
Signed-off-by David Daney <[email protected]>CC Rade Bozic <[email protected]>
[...]
Quoted 40 lines
arch/mips/cavium-octeon/octeon-platform.c +32
-0@@ -165,6 +165,78 @@ out: }device_initcall (octeon_rng_device_init); + +#define OCTEON_I2C_IO_BASE 0x1180000001000ull +#define OCTEON_I2C_IO_UNIT_OFFSET 0x200 + +static struct octeon_i2c_data octeon_i2c_data[2 ]; + +static int __init octeon_i2c_device_init (void ) +{ +struct platform_device *pd; +int ret =0 ; +int port, num_ports; + +struct resource i2c_resources[] = { + { + .flags =IORESOURCE_MEM , + }, { + .flags =IORESOURCE_IRQ , + } + }; + +if (OCTEON_IS_MODEL (OCTEON_CN56XX ) ||OCTEON_IS_MODEL (OCTEON_CN52XX )) + num_ports =2 ; +else + num_ports =1 ; + +for (port =0 ; port < num_ports; port++) { + octeon_i2c_data[port].sys_freq =octeon_get_clock_rate (); +/*FIXME: should be examined. At the moment is set for 100Khz */ + octeon_i2c_data[port].i2c_freq =100000 ; + + pd =platform_device_alloc ("i2c-octeon" , port); +if (!pd) {
arch/mips/cavium-octeon/octeon-platform.c out: · line 209
Quoted 10 lines
arch/mips/cavium-octeon/octeon-platform.c +9
-0+ ret = -ENOMEM ; + goto out; + } + + pd->dev.platform_data = octeon_i2c_data + port; + + i2c_resources[0 ].start = +OCTEON_I2C_IO_BASE + (port *OCTEON_I2C_IO_UNIT_OFFSET ); + i2c_resources[0 ].end = i2c_resources[0 ].start +0x20 ;
Not 0x1F?
WBR, Sergei
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 1/3] MIPS: Octeon: Add I2C platform driver.
Quoted 53 lines · Sergei Shtylyov
Hello.
Quoted 3 lines · David Daney
Signed-off-by David Daney <[email protected]>CC Rade Bozic <[email protected]>[...]
Quoted 45 lines
arch/mips/cavium-octeon/octeon-platform.c +36
-0@@ -165,6 +165,78 @@ out: }device_initcall (octeon_rng_device_init); + +#define OCTEON_I2C_IO_BASE 0x1180000001000ull +#define OCTEON_I2C_IO_UNIT_OFFSET 0x200 + +static struct octeon_i2c_data octeon_i2c_data[2 ]; + +static int __init octeon_i2c_device_init (void ) +{ +struct platform_device *pd; +int ret =0 ; +int port, num_ports; + +struct resource i2c_resources[] = { + { + .flags =IORESOURCE_MEM , + }, { + .flags =IORESOURCE_IRQ , + } + }; + +if (OCTEON_IS_MODEL (OCTEON_CN56XX ) ||OCTEON_IS_MODEL (OCTEON_CN52XX )) + num_ports =2 ; +else + num_ports =1 ; + +for (port =0 ; port < num_ports; port++) { + octeon_i2c_data[port].sys_freq =octeon_get_clock_rate (); +/*FIXME: should be examined. At the moment is set for 100Khz */ + octeon_i2c_data[port].i2c_freq =100000 ; + + pd =platform_device_alloc ("i2c-octeon" , port); +if (!pd) { + ret = -ENOMEM ; + goto out; + } +
Quoted 9 lines
arch/mips/cavium-octeon/octeon-platform.c out:
Quoted 6 lines
arch/mips/cavium-octeon/octeon-platform.c +5
-0+ pd->dev.platform_data = octeon_i2c_data + port; + + i2c_resources[0 ].start = +OCTEON_I2C_IO_BASE + (port *OCTEON_I2C_IO_UNIT_OFFSET ); + i2c_resources[0 ].end = i2c_resources[0 ].start +0x20 ;Not
0x1F?
You are correct. I will fix it.
David Daney
PATCH 1/3 MIPS: Octeon: Add I2C platform device.
---
This supersedes the original '[PATCH 1/3] MIPS: Octeon: Add I2C platform driver.' and corrects the resource end value as noted by Sergei Shtylyov.
arch/mips/cavium-octeon/octeon-platform.c | 72 +++++++++++++++++++++++++++++ arch/mips/include/asm/octeon/octeon.h | 5 ++ 2 files changed, 77 insertions(+), 0 deletions(-)
arch/mips/cavium-octeon/octeon-platform.c +72 -0
@@ -165,6 +165,78 @@ out: }device_initcall (octeon_rng_device_init); + +#define OCTEON_I2C_IO_BASE 0x1180000001000ull +#define OCTEON_I2C_IO_UNIT_OFFSET 0x200 + +static struct octeon_i2c_data octeon_i2c_data[2 ]; + +static int __init octeon_i2c_device_init (void ) +{ +struct platform_device *pd; +int ret =0 ; +int port, num_ports; + +struct resource i2c_resources[] = { + { + .flags =IORESOURCE_MEM , + }, { + .flags =IORESOURCE_IRQ , + } + }; + +if (OCTEON_IS_MODEL (OCTEON_CN56XX ) ||OCTEON_IS_MODEL (OCTEON_CN52XX )) + num_ports =2 ; +else + num_ports =1 ; + +for (port =0 ; port < num_ports; port++) { + octeon_i2c_data[port].sys_freq =octeon_get_clock_rate (); +/*FIXME: should be examined. At the moment is set for 100Khz */ + octeon_i2c_data[port].i2c_freq =100000 ; + + pd =platform_device_alloc ("i2c-octeon" , port); +if (!pd) { + ret = -ENOMEM ; + goto out; + } + + pd->dev.platform_data = octeon_i2c_data + port; + + i2c_resources[0 ].start = +OCTEON_I2C_IO_BASE + (port *OCTEON_I2C_IO_UNIT_OFFSET ); + i2c_resources[0 ].end = i2c_resources[0 ].start +0x1f ; +switch (port) { +case 0 : + i2c_resources[1 ].start =OCTEON_IRQ_TWSI ; + i2c_resources[1 ].end =OCTEON_IRQ_TWSI ; +break ; +case 1 : + i2c_resources[1 ].start =OCTEON_IRQ_TWSI2 ; + i2c_resources[1 ].end =OCTEON_IRQ_TWSI2 ; +break ; +default : +BUG (); + } + + ret =platform_device_add_resources (pd, + i2c_resources, +ARRAY_SIZE (i2c_resources)); +if (ret) + goto fail; + + ret =platform_device_add (pd); +if (ret) + goto fail; + } +return ret; +fail: +platform_device_put (pd); +out: +return ret; +} +device_initcall (octeon_i2c_device_init); +/* Octeon SMI/MDIO interface. */ static int __init octeon_mdiobus_device_init (void ) {
arch/mips/include/asm/octeon/octeon.h +5 -0
@@ -213,6 +213,11 @@ struct octeon_cf_data {int dma_engine;/* -1 for no DMA */ }; +struct octeon_i2c_data { +unsigned int sys_freq; +unsigned int i2c_freq; +}; +extern void octeon_write_lcd (const char *s);extern void octeon_check_cpu_bist (void );extern int octeon_get_boot_uart (void );
Signature · 1 line
1.6.0.6
PATCH 2/3 I2C: Add driver for Cavium OCTEON I2C ports.
In reply to a message not in the archiveFrom: Rade Bozic <[email protected]>
--- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-octeon.c | 579 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 590 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-octeon.c
drivers/i2c/busses/Kconfig +10 -0
@@ -564,6 +564,16 @@ config I2C_VERSATILE This driver can also be built as a module. If so, the module will be called i2c-versatile. +config I2C_OCTEON + tristate "Cavium OCTEON I2C bus support" + depends on CPU_CAVIUM_OCTEON + help + Say yes if you want to support the I2C serial bus on Cavium + OCTEON SOC. + + This driver can also be built as a module. If so, the module + will be called i2c-octeon. + comment "External I2C/SMBus adapter drivers" config I2C_PARPORT
drivers/i2c/busses/Makefile +1 -0
@@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_STU300) += i2c-stu300.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o +obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o # External I2C/SMBus adapter drivers obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
drivers/i2c/busses/i2c-octeon.c new file +579 -0
579 lines not on this page · raw message
Signature · 1 line
1.6.0.6
A message that is not in the archive (sent off-list or not yet received): 1262894061-32613-2-git-send-email-ddaney-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org
Re: [PATCH 2/3] I2C: Add driver for Cavium OCTEON I2C ports.
Quoted 103 lines · David Daney
From: Rade Bozic <[email protected]>
Signed-off-by Rade Bozic <[email protected]>Signed-off-by David Daney <[email protected]>--- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-octeon.c | 579 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 590 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-octeon.cdrivers/i2c/busses/Kconfig +10
-0@@ -564,6 +564,16 @@ config I2C_VERSATILE This driver can also be built as a module. If so, the module will be called i2c-versatile. +config I2C_OCTEON + tristate "Cavium OCTEON I2C bus support" + depends on CPU_CAVIUM_OCTEON + help + Say yes if you want to support the I2C serial bus on Cavium + OCTEON SOC. + + This driver can also be built as a module. If so, the module + will be called i2c-octeon. + comment "External I2C/SMBus adapter drivers" config I2C_PARPORTdrivers/i2c/busses/Makefile +1
-0@@ -54,6 +54,7 @@ obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_STU300) += i2c-stu300.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o +obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o # External I2C/SMBus adapter drivers obj-$(CONFIG_I2C_PARPORT) += i2c-parport.odrivers/i2c/busses/i2c-octeon.c new file +53
-0@@ -0,0 +1,579 @@ +/* +* (C) Copyright 2009-2010 +* Nokia Siemens Networks, [email protected] +* +* This is a driver for the i2c adapter in Cavium Networks' OCTEON processors. +* +* Release 0.1 +* +* This file is licensed under the terms of the GNU General Public +* License version 2. This program is licensed "as is" without any +* warranty of any kind, whether express or implied. +*/ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/init.h> + +#include <linux/io.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <linux/platform_device.h> + +#include <asm/octeon/octeon.h> + +#define DRV_NAME "i2c-octeon" +#define DRV_VERSION "0.1" + +/* register offsets */ +#define SW_TWSI 0x00 +#define TWSI_INT 0x10 + +/* Controller command patterns */ +#define SW_TWSI_V 0x8000000000000000ull +#define SW_TWSI_EOP_TWSI_DATA 0x0C00000100000000ull +#define SW_TWSI_EOP_TWSI_CTL 0x0C00000200000000ull +#define SW_TWSI_EOP_TWSI_CLKCTL 0x0C00000300000000ull +#define SW_TWSI_EOP_TWSI_STAT 0x0C00000300000000ull +#define SW_TWSI_EOP_TWSI_RST 0x0C00000700000000ull +#define SW_TWSI_OP_TWSI_CLK 0x0800000000000000ull +#define SW_TWSI_R 0x0100000000000000ull + +/* Controller command and status bits */ +#define TWSI_CTL_CE 0x80 +#define TWSI_CTL_ENAB 0x40 +#define TWSI_CTL_STA 0x20 +#define TWSI_CTL_STP 0x10 +#define TWSI_CTL_IFLG 0x08 +#define TWSI_CTL_AAK 0x04 + +/* Some status values */ +#define STAT_START 0x08
drivers/i2c/busses/i2c-octeon.c line 63
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+#define STAT_RSTART 0x10 +#define STAT_TXADDR_ACK 0x18 +#define STAT_TXDATA_ACK 0x28 +#define STAT_RXADDR_ACK 0x40 +#define STAT_RXDATA_ACK 0x50 +#define STAT_IDLE 0xF8 + +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif
this does not fill me with a warm joyous feeling...
drivers/i2c/busses/i2c-octeon.c line 76
Quoted 12 lines
drivers/i2c/busses/i2c-octeon.c new file +12
-0+struct octeon_i2c { +wait_queue_head_t queue; +struct i2c_adapter adap; +int irq; +int twsi_freq; +int sys_freq; +uint8_t twsi_ctl; +resource_size_t twsi_phys; +void __iomem *twsi_base; +resource_size_t regsize; +struct device *dev; +};
kerneldoc or any documentation at-all would be nice.
Quoted 151 lines
drivers/i2c/busses/i2c-octeon.c new file +151
-0+/* Writes need to be flushed by a read. */ +static void octeon_i2c_write_sw (struct octeon_i2c *i2c, +uint64_t eop_reg, +uint8_t data) +{ +uint64_t tmp; + +__raw_writeq (SW_TWSI_V | eop_reg | data, i2c->twsi_base +SW_TWSI ); + tmp =__raw_readq (i2c->twsi_base +SW_TWSI ); +} + +static uint8_t octeon_i2c_read_sw (struct octeon_i2c *i2c,uint64_t eop_reg) +{ +uint64_t tmp; + +__raw_writeq (SW_TWSI_V | eop_reg |SW_TWSI_R , i2c->twsi_base +SW_TWSI ); + tmp =__raw_readq (i2c->twsi_base +SW_TWSI ); + +return __raw_readq (i2c->twsi_base +SW_TWSI ) &0xFF ; +} + +static void octeon_i2c_write_int (struct octeon_i2c *i2c,uint64_t data) +{ +uint64_t tmp; + +__raw_writeq (data, i2c->twsi_base +TWSI_INT ); + tmp =__raw_readq (i2c->twsi_base +TWSI_INT ); +} + +static void octeon_i2c_int_enable (struct octeon_i2c *i2c) +{ +octeon_i2c_write_int (i2c,0x40 ); +} + +static void octeon_i2c_int_disable (struct octeon_i2c *i2c) +{ +octeon_i2c_write_int (i2c,0 ); +} + +/* If there was a reset while a device was driving 0 to bus, +bus is blocked. We toggle it free manually by some clock +cycles and send a stop. */ +static void octeon_i2c_unblock (struct octeon_i2c *i2c) +{ +int i; + +dev_dbg (i2c->dev,"%s\n" , __func__); +for (i =0 ; i <9 ; i++) { +octeon_i2c_write_int (i2c,0x0 ); +udelay (5 ); +octeon_i2c_write_int (i2c,0x200 ); +udelay (5 ); + } +octeon_i2c_write_int (i2c,0x300 ); +udelay (5 ); +octeon_i2c_write_int (i2c,0x100 ); +udelay (5 ); +octeon_i2c_write_int (i2c,0x0 ); +} + +static irqreturn_t octeon_i2c_isr (int irq,void *dev_id) +{ +struct octeon_i2c *i2c = dev_id; + +octeon_i2c_int_disable (i2c); + i2c->twsi_ctl =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_CTL ); +wake_up_interruptible (&i2c->queue); + +return IRQ_HANDLED ; +} + +static int octeon_i2c_wait (struct octeon_i2c *i2c) +{ +unsigned long orig_jiffies = jiffies; +uint8_t ctl; +int result =0 ; + +if (i2c->irq ==NO_IRQ ) { +/* polling */ +do { + ctl =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_CTL ); +if (ctl &TWSI_CTL_IFLG ) +break ; + }while (!time_after (jiffies, + orig_jiffies + i2c->adap.timeout)); + +if (!(ctl &TWSI_CTL_IFLG )) { +dev_dbg (i2c->dev,"%s: timeout\n" , __func__); + result = -ETIMEDOUT ; + } + }else { + i2c->twsi_ctl =0 ; +/* interrupt mode */ +octeon_i2c_int_enable (i2c); + + result =wait_event_interruptible_timeout (i2c->queue, + (i2c->twsi_ctl &TWSI_CTL_IFLG ), + i2c->adap.timeout); + +if (unlikely (result <0 )) { +dev_dbg (i2c->dev,"%s: wait interrupted\n" , __func__); + }else if (unlikely (!(i2c->twsi_ctl &TWSI_CTL_IFLG ))) { +dev_dbg (i2c->dev,"%s: timeout\n" , __func__); + result = -ETIMEDOUT ; + } + } + +return result <0 ? result :0 ; +} + +static int octeon_i2c_start (struct octeon_i2c *i2c) +{ +uint8_t data; +int result; + +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL , +TWSI_CTL_ENAB |TWSI_CTL_STA ); + + result =octeon_i2c_wait (i2c); +if (unlikely (result <0 ) && +octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ) ==STAT_IDLE ) { +/* +* Controller refused to send start flag May be a +* client is holding SDA low - let's try to free it. +*/ +octeon_i2c_unblock (i2c); +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL , +TWSI_CTL_ENAB |TWSI_CTL_STA ); + + result =octeon_i2c_wait (i2c); +if (result <0 ) +return result; + } + + data =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if ((data !=STAT_START ) && (data !=STAT_RSTART )) { +dev_dbg (i2c->dev,"%s: bad status (0x%x)\n" , __func__, data); +return -1 ; + } + +return 0 ; +} + +static int octeon_i2c_stop (struct octeon_i2c *i2c) +{ +unsigned long orig_jiffies = jiffies; +uint8_t data; + +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL , +TWSI_CTL_ENAB |TWSI_CTL_STP ); +
drivers/i2c/busses/i2c-octeon.c line 238
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+/* +* Controller will change to idle, but that does not raise an +* interrupt, so we have to poll. +*/ +do { + data =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if (data ==STAT_IDLE ) +break ; +udelay (1 ); + }while (!time_after (jiffies, orig_jiffies +2 ));
you sure you want to busy wait like this?
Quoted 93 lines
drivers/i2c/busses/i2c-octeon.c new file +93
-0+if (data !=STAT_IDLE ) { +dev_dbg (i2c->dev,"%s: bad status(0x%x)\n" , __func__, data); +return -1 ; + } +return 0 ; +} + +static int octeon_i2c_write (struct octeon_i2c *i2c,int target, +const uint8_t *data,int length) +{ +int i, result; +uint8_t tmp; + + result =octeon_i2c_start (i2c); +if (unlikely (result <0 )) +return result; + +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_DATA , target <<1 ); +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL ,TWSI_CTL_ENAB ); + + result =octeon_i2c_wait (i2c); +if (unlikely (result <0 )) +return result; + +for (i =0 ; i < length; i++) { + tmp =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if ((tmp !=STAT_TXADDR_ACK ) && (tmp !=STAT_TXDATA_ACK )) { +dev_dbg (i2c->dev, +"%s: bad status before write (0x%x)\n" , + __func__, tmp); +return -(int )tmp; + } + +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_DATA , data[i]); +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL ,TWSI_CTL_ENAB ); + + result =octeon_i2c_wait (i2c); +if (unlikely (result <0 )) +return result; + } + +return 0 ; +} + +static int octeon_i2c_read (struct octeon_i2c *i2c,int target, +uint8_t *data,int length) +{ +int i, result; +uint8_t tmp; + +if (length <1 ) +return -EINVAL ; + + result =octeon_i2c_start (i2c); +if (result) +return result; + +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_DATA , (target<<1 ) |1 ); +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL ,TWSI_CTL_ENAB ); + + result =octeon_i2c_wait (i2c); +if (unlikely (result <0 )) +return result; + +for (i =0 ; i < length; i++) { + tmp =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if ((tmp !=STAT_RXDATA_ACK ) && (tmp !=STAT_RXADDR_ACK )) { +dev_dbg (i2c->dev, +"%s: bad status before read (0x%x)\n" , + __func__, tmp); +return -(int )tmp; + } + +if (i+1 < length) +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL , +TWSI_CTL_ENAB |TWSI_CTL_AAK ); +else +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL , +TWSI_CTL_ENAB ); + + result =octeon_i2c_wait (i2c); +if (unlikely (result <0 )) +return result; + + data[i] =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_DATA ); + } +return length; +} + +static int octeon_i2c_xfer (struct i2c_adapter *adap, +struct i2c_msg *msgs, +int num) +{
drivers/i2c/busses/i2c-octeon.c line 342
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+struct i2c_msg *pmsg; +int i; +int ret =0 ; +struct octeon_i2c *i2c =i2c_get_adapdata (adap); + +for (i =0 ; ret >=0 && i < num; i++) { + pmsg = &msgs[i]; + dev_dbg(i2c->dev, + "%s: Doing %s %d byte(s) to/from 0x%02x - " + "%d of %d messages\n",
i'd rather not see text lines broken over like this, it is one case where >80 character lines are allowed. You could always shorten it by removing the "to/from" and having "%d/%d msgs" at the end and possible removing the "Doing" as well.
Quoted 115 lines
drivers/i2c/busses/i2c-octeon.c new file +115
-0+ __func__, + pmsg->flags &I2C_M_RD ?"read" :"write" , + pmsg->len, pmsg->addr, i + 1, num); +if (pmsg->flags &I2C_M_RD ) + ret =octeon_i2c_read (i2c, pmsg->addr, pmsg->buf, + pmsg->len); +else + ret =octeon_i2c_write (i2c, pmsg->addr, pmsg->buf, + pmsg->len); + } +octeon_i2c_stop (i2c); + +return (ret <0 ) ? ret : num; +} + +static u32 octeon_i2c_functionality (struct i2c_adapter *adap) +{ +return I2C_FUNC_I2C |I2C_FUNC_SMBUS_EMUL ; +} + +static const struct i2c_algorithm octeon_i2c_algo = { + .master_xfer = octeon_i2c_xfer, + .functionality = octeon_i2c_functionality, +}; + +static struct i2c_adapter octeon_i2c_ops = { + .owner =THIS_MODULE , + .name ="OCTEON adapter" , + .algo = &octeon_i2c_algo, + .timeout =2 , +}; + +static int __init octeon_i2c_setclock (struct octeon_i2c *i2c) +{ +int tclk, thp_base, inc, thp_idx, mdiv_idx, ndiv_idx, foscl, diff; +int thp =0x18 , mdiv =2 , ndiv =0 , delta_hz =1000000 ; + +for (ndiv_idx =0 ; ndiv_idx <8 && delta_hz !=0 ; ndiv_idx++) { +/* +* An mdiv value of less than 2 seems to not work well +* with ds1337 RTCs, so we constrain it to larger +* values. +*/ +for (mdiv_idx =15 ; mdiv_idx >=2 && delta_hz !=0 ; mdiv_idx--) { +/* +* For given ndiv and mdiv values check the +* two closest thp values. +*/ + tclk = i2c->twsi_freq * (mdiv_idx +1 ) *10 ; + tclk *= (1 << ndiv_idx); + thp_base = (i2c->sys_freq / (tclk *2 )) -1 ; +for (inc =0 ; inc <=1 ; inc++) { + thp_idx = thp_base + inc; +if (thp_idx <5 || thp_idx >0xff ) +continue ; + + foscl = i2c->sys_freq / (2 * (thp_idx +1 )); + foscl = foscl / (1 << ndiv_idx); + foscl = foscl / (mdiv_idx +1 ) /10 ; + diff =abs (foscl - i2c->twsi_freq); +if (diff < delta_hz) { + delta_hz = diff; + thp = thp_idx; + mdiv = mdiv_idx; + ndiv = ndiv_idx; + } + } + } + } +octeon_i2c_write_sw (i2c,SW_TWSI_OP_TWSI_CLK , thp); +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CLKCTL , (mdiv <<3 ) | ndiv); + +return 0 ; +} + +static int __init octeon_i2c_initlowlevel (struct octeon_i2c *i2c) +{ +uint8_t status; +int tries; + +/* disable high level controller, enable bus access */ +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_CTL ,TWSI_CTL_ENAB ); + +/* reset controller */ +octeon_i2c_write_sw (i2c,SW_TWSI_EOP_TWSI_RST ,0 ); + +for (tries =10 ; tries; tries--) { +udelay (1 ); + status =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if (status ==STAT_IDLE ) +return 0 ; + } +dev_dbg (i2c->dev,"%s: TWSI_RST failed! (0x%x)\n" , __func__, status); +return -1 ; +} + +static int __init octeon_i2c_probe (struct platform_device *pdev) +{ +int irq, result =0 ; +struct octeon_i2c *i2c; +struct octeon_i2c_data *i2c_data; +struct resource *res_mem; + + i2c =kzalloc (sizeof (*i2c),GFP_KERNEL ); +if (!i2c) { +printk (KERN_ERR "%s i2c-cavium - kzalloc failed\n" , __func__); +return -ENOMEM ; + } + i2c->dev = &pdev->dev; + i2c_data = pdev->dev.platform_data; + + res_mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + irq =platform_get_irq (pdev,0 ); + +if (res_mem ==NULL ) {
drivers/i2c/busses/i2c-octeon.c line 467
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+dev_dbg (i2c->dev,"%s: found no memory resource\n" , __func__); +kfree (i2c); +return -ENODEV ; + } + +if (i2c_data ==NULL ) { +dev_dbg (i2c->dev,"%s: no I2C frequence data\n" , __func__); +kfree (i2c); +return -ENODEV ; + }
returning -ENODEV isn't a good idea, the device layer won't print an error on seeing -ENODEV as it thinks this is a probe for a device that was never there.
Quoted 7 lines
drivers/i2c/busses/i2c-octeon.c new file +7
-0+ i2c->twsi_phys = res_mem->start; + i2c->regsize =resource_size (res_mem); + i2c->twsi_freq = i2c_data->i2c_freq; + i2c->sys_freq = i2c_data->sys_freq; + +if (!request_mem_region (i2c->twsi_phys, i2c->regsize, res_mem->name)) { + dev_dbg(i2c->dev,
drivers/i2c/busses/i2c-octeon.c line 485
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+"%s i2c-cavium - request_mem_region failed\n" , + __func__); + goto fail_region; + } + i2c->twsi_base =ioremap (i2c->twsi_phys, i2c->regsize); + +init_waitqueue_head (&i2c->queue); + + i2c->irq = irq; +if (i2c->irq !=NO_IRQ ) {
platform_get_irq() returns a negative error cdoe if no irq is found, so you need to do (irq < 0) here otherwise it'll never trip. Should also mean yo ucan get rid of NO_IRQ define above.
Quoted 45 lines
drivers/i2c/busses/i2c-octeon.c new file +45
-0+/* i2c->irq = NO_IRQ implies polling */ + result =request_irq (i2c->irq, octeon_i2c_isr,0 ,DRV_NAME , i2c); +if (result <0 ) { +dev_dbg (i2c->dev, +"%s: - failed to attach interrupt\n" , + __func__); + goto fail_irq; + } + } + + result =octeon_i2c_initlowlevel (i2c); +if (result) { +dev_dbg (i2c->dev,"%s: init low level failed\n" , __func__); + goto fail_add; + } + + result =octeon_i2c_setclock (i2c); +if (result) { +dev_dbg (i2c->dev,"%s: clock init failed\n" , __func__); + goto fail_add; + } + + i2c->adap = octeon_i2c_ops; + i2c->adap.dev.parent = &pdev->dev; + i2c->adap.nr = pdev->id >=0 ? pdev->id :0 ; +i2c_set_adapdata (&i2c->adap, i2c); +platform_set_drvdata (pdev, i2c); + + result =i2c_add_numbered_adapter (&i2c->adap); +if (result <0 ) { +dev_dbg (i2c->dev,"%s: failed to add adapter\n" , __func__); + goto fail_add; + } +return result; + +fail_add: +platform_set_drvdata (pdev,NULL ); +if (i2c->irq !=NO_IRQ ) +free_irq (i2c->irq, i2c); +fail_irq: +iounmap (i2c->twsi_base); +release_mem_region (i2c->twsi_phys, i2c->regsize); +fail_region: +kfree (i2c); +return result;
drivers/i2c/busses/i2c-octeon.c line 540
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+}; + +static int __exit octeon_i2c_remove(struct platform_device *pdev) +{ +struct octeon_i2c *i2c =platform_get_drvdata (pdev); + +i2c_del_adapter (&i2c->adap); +platform_set_drvdata (pdev,NULL ); +if (i2c->irq !=NO_IRQ ) +free_irq (i2c->irq, i2c);
see above comment on NO_IRQ
drivers/i2c/busses/i2c-octeon.c line 549
Quoted 9 lines
drivers/i2c/busses/i2c-octeon.c new file +9
-0+iounmap (i2c->twsi_base); +release_mem_region (i2c->twsi_phys, i2c->regsize); +kfree (i2c); +return 0 ; +}; + +static struct platform_driver octeon_i2c_driver = { + .probe = octeon_i2c_probe, + .remove =__exit_p (octeon_i2c_remove),
__devexit_p() here, probably should change __exit to __devexit on the remove function.
Quoted 4 lines
drivers/i2c/busses/i2c-octeon.c new file +4
-0+ .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + },
drivers/i2c/busses/i2c-octeon.c line 563
Quoted 10 lines
drivers/i2c/busses/i2c-octeon.c new file +10
-0+}; + +static int __init octeon_i2c_init (void ) +{ +int rv; + + rv =platform_driver_register (&octeon_i2c_driver); +printk (KERN_INFO "driver %s is loaded\n" ,DRV_NAME ); +return rv; +}
I'd rather not see 'driver loaded' messages if possible.
drivers/i2c/busses/i2c-octeon.c line 569
Quoted 5 lines
drivers/i2c/busses/i2c-octeon.c new file +5
-0+static void __exit octeon_i2c_exit(void) +{ +platform_driver_unregister (&octeon_i2c_driver); +printk (KERN_INFO "driver %s unloaded\n" ,DRV_NAME ); +}
I'd say this is even less useful that the one in the init code.
Quoted 8 lines
drivers/i2c/busses/i2c-octeon.c new file +8
-0+MODULE_AUTHOR ("Michael Lawnick <[email protected]>" ); +MODULE_DESCRIPTION ("I2C-Bus adapter for Cavium OCTEON processors" ); +MODULE_LICENSE ("GPL" ); +MODULE_VERSION (DRV_VERSION ); +MODULE_ALIAS ("platform:" DRV_NAME ); + +module_init (octeon_i2c_init); +module_exit (octeon_i2c_exit);
Signature · 3 lines
Ben ([email protected], http://www.fluff.org/) 'a smiley only costs 4 bytes'
A message that is not in the archive (sent off-list or not yet received): [email protected]
Re: [PATCH 2/3] I2C: Add driver for Cavium OCTEON I2C ports.
Hi,
this is the author.
Ben Dooks said the following:
Quoted 1 line · David Daney
<snip>
Quoted 5 lines
drivers/i2c/busses/i2c-octeon.c line 63
Quoted 3 lines
drivers/i2c/busses/i2c-octeon.c new file +3
-0+#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif this does not fill me with a warm joyous feeling...
see near end of reply.
Quoted 15 lines
drivers/i2c/busses/i2c-octeon.c line 76
Quoted 13 lines
drivers/i2c/busses/i2c-octeon.c new file +12
-0+struct octeon_i2c { +wait_queue_head_t queue; +struct i2c_adapter adap; +int irq; +int twsi_freq; +int sys_freq; +uint8_t twsi_ctl; +resource_size_t twsi_phys; +void __iomem *twsi_base; +resource_size_t regsize; +struct device *dev; +};kerneldoc or any documentation at-all would be nice.
This is driver private data, used within this file only. Usage should be rather obvious?!
<snip>
Quoted 9 lines
drivers/i2c/busses/i2c-octeon.c line 238
Quoted 6 lines
drivers/i2c/busses/i2c-octeon.c new file +6
-0+do { + data =octeon_i2c_read_sw (i2c,SW_TWSI_EOP_TWSI_STAT ); +if (data ==STAT_IDLE ) +break ; +udelay (1 ); + }while (!time_after (jiffies, orig_jiffies +2 ));you sure you want to busy wait like this?
Hmm, yes?
Its a busy wait of typically 10us, but not guaranteed. Timeout is 1 to 2 jiffies.
Any other suggestion?
<snip>
Quoted 12 lines
Quoted 12 lines
drivers/i2c/busses/i2c-octeon.c new file +12
-0+ i2c_data = pdev->dev.platform_data; + + res_mem =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + irq =platform_get_irq (pdev,0 ); + +if (res_mem ==NULL ) { +dev_dbg (i2c->dev,"%s: found no memory resource\n" , __func__); +kfree (i2c); +return -ENODEV ; + } + +if (i2c_data ==NULL ) {
Quoted 9 lines
drivers/i2c/busses/i2c-octeon.c line 467
Quoted 4 lines
drivers/i2c/busses/i2c-octeon.c new file +4
-0+dev_dbg (i2c->dev,"%s: no I2C frequence data\n" , __func__); +kfree (i2c); +return -ENODEV ; + }returning
-ENODEVisn't a good idea, the device layer won't print an error on seeing-ENODEVas it thinks this is a probe for a device that was never there.
ACK, couldn't find something really appropriate. Will change to EINVAL.
<snip>
Quoted 13 lines
Quoted 13 lines
drivers/i2c/busses/i2c-octeon.c new file +13
-0+ i2c->twsi_phys = res_mem->start; + i2c->regsize =resource_size (res_mem); + i2c->twsi_freq = i2c_data->i2c_freq; + i2c->sys_freq = i2c_data->sys_freq; + +if (!request_mem_region (i2c->twsi_phys, i2c->regsize, res_mem->name)) { +dev_dbg (i2c->dev, +"%s i2c-cavium - request_mem_region failed\n" , + __func__); + goto fail_region; + } + i2c->twsi_base =ioremap (i2c->twsi_phys, i2c->regsize); +
Quoted 8 lines
drivers/i2c/busses/i2c-octeon.c line 485
Quoted 4 lines
drivers/i2c/busses/i2c-octeon.c new file +4
-0+init_waitqueue_head (&i2c->queue); + + i2c->irq = irq; +if (i2c->irq !=NO_IRQ ) {
platform_get_irq()returns a negative error cdoe if no irq is found, so you need to do (irq < 0) here otherwise it'll never trip. Should also mean yo ucan get rid ofNO_IRQdefine above.
NO_IRQ is thought of as polling.
The code assumes that request_irq() denies irq < 0 After reviewing kernel code I think this should not be assumed. I will have to contemplate about this.
<snip>
Quoted 5 lines
drivers/i2c/busses/i2c-octeon.c line 549
Quoted 3 lines
drivers/i2c/busses/i2c-octeon.c new file +3
-0+static struct platform_driver octeon_i2c_driver = { + .probe = octeon_i2c_probe, + .remove =__exit_p (octeon_i2c_remove),
__devexit_p()here, probably should change__exitto__devexiton the remove function.
I thought I had read something about abuse of __devexit (to be used only for hotplugable devices), but I can't find it anymore.
I'll change.
Currently I'm unsure about using __devinit for probe().
It will be called twice (2 devices), but I can't absolutely tell that second call will be in system initialization phase.
Your 2 Cents?
Quoted 8 lines
Quoted 8 lines
drivers/i2c/busses/i2c-octeon.c new file +8
-0+ .driver = { + .owner = THIS_MODULE, + .name = DRV_NAME, + }, +}; + +static int __init octeon_i2c_init (void ) +{
Quoted 8 lines
drivers/i2c/busses/i2c-octeon.c line 563
Quoted 6 lines
drivers/i2c/busses/i2c-octeon.c new file +6
-0+int rv; + + rv =platform_driver_register (&octeon_i2c_driver); +printk (KERN_INFO "driver %s is loaded\n" ,DRV_NAME ); +return rv; +}I'd rather not see 'driver loaded' messages if possible.
Whats about adjusting your message filter? ;-)
Would KERN_DEBUG be more appropriate?
We love such messages in our projects. You can filter for the 'loaded phrases and have an fast overview this way.
Signature · 2 lines
Kind Regards, Michael
Re: [PATCH 2/3] I2C: Add driver for Cavium OCTEON I2C ports.
In reply to a message not in the archiveQuoted 11 lines · Ben Dooks
Quoted 10 lines · David Daney
From: Rade Bozic <[email protected]>
Signed-off-by Rade Bozic <[email protected]>Signed-off-by David Daney <[email protected]>--- drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-octeon.c | 579 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 590 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-octeon.c
[...]
Quoted 7 lines
drivers/i2c/busses/i2c-octeon.c line 63
Quoted 4 lines
drivers/i2c/busses/i2c-octeon.c new file +4
-0+ +#ifndef NO_IRQ +#define NO_IRQ (-1) +#endif this does not fill me with a warm joyous feeling...
Indeed.
[ many other helpful comments deleted for brevity.]
We will improve the driver and resubmit.
Thanks for looking at it.
David Daney
RE: [PATCH 2/3] I2C: Add driver for Cavium OCTEON I2C ports.
In reply to Ben DooksHello David,
Yesterday Ben Dooks wrote a email with some new issues ( Message-ID: <[email protected]>).
New changes:
1. Some return values was Changed
2. Changed __exit_p to __devexit_p and __exit into __devexit
3. New handling of NO_IRQ
In the appendix is a new I2C patch.
Maybe we can put the patch also in the Kernel.
Regards
Rade
--->
drivers/i2c/busses/i2c-octeon.c +22 -13
@@ -10,7 +10,6 @@* License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ -#include <linux/kernel.h> #include <linux/module.h> #include <linux/sched.h>
@@ -352,7 +351,7 @@ static int octeon_i2c_xfer(struct i2c_ad }octeon_i2c_stop (i2c); -return (ret <0 ) ? ret : num; +return (ret <0 ) ?EIO : num; }static u32 octeon_i2c_functionality (struct i2c_adapter *adap)
@@ -457,13 +456,13 @@ static int __init octeon_i2c_probe(strucif (res_mem ==NULL ) {dev_dbg (i2c->dev,"%s: found no memory resource\n" , __func__);kfree (i2c); -return -ENODEV ; +return -EINVAL ; }if (i2c_data ==NULL ) {dev_dbg (i2c->dev,"%s: no I2C frequence data\n" , __func__);kfree (i2c); -return -ENODEV ; +return -EINVAL ; } i2c->twsi_phys = res_mem->start;
@@ -475,6 +474,7 @@ static int __init octeon_i2c_probe(strucdev_dbg (i2c->dev,"%s i2c-cavium - request_mem_region failed\n" , __func__); + result = -ENOMEM ; goto fail_region; } i2c->twsi_base =ioremap (i2c->twsi_phys, i2c->regsize);
@@ -482,27 +482,37 @@ static int __init octeon_i2c_probe(strucinit_waitqueue_head (&i2c->queue); i2c->irq = irq; + +/* i2c->irq == NO_IRQ implies polling */ if (i2c->irq !=NO_IRQ ) { -/* i2c->irq = NO_IRQ implies polling */ - result =request_irq (i2c->irq, octeon_i2c_isr,0 ,DRV_NAME , i2c); -if (result <0 ) { +if (i2c->irq <0 ) {dev_dbg (i2c->dev, -"%s: - failed to attach interrupt\n" , +"%s: - bad interrupt number\n" , __func__); + result = -EINVAL ; goto fail_irq; + }else { + result =request_irq (i2c->irq, octeon_i2c_isr,0 , +DRV_NAME , i2c); +if (result <0 ) { +dev_dbg (i2c->dev, +"%s: - failed to attach interrupt\n" , + __func__); + goto fail_irq; + } } } result =octeon_i2c_initlowlevel (i2c);if (result) {dev_dbg (i2c->dev,"%s: init low level failed\n" , __func__); - goto fail_add; + goto fail_add; } result =octeon_i2c_setclock (i2c);if (result) {dev_dbg (i2c->dev,"%s: clock init failed\n" , __func__); - goto fail_add; + goto fail_add; } i2c->adap = octeon_i2c_ops;
@@ -530,7 +540,7 @@ fail_region:return result; }; -static int __exit octeon_i2c_remove(struct platform_device *pdev) +static int __devexit octeon_i2c_remove(struct platform_device *pdev) {struct octeon_i2c *i2c =platform_get_drvdata (pdev);
@@ -546,7 +556,7 @@ static int __exit octeon_i2c_remove(strustatic struct platform_driver octeon_i2c_driver = { .probe = octeon_i2c_probe, - .remove =__exit_p (octeon_i2c_remove), + .remove =__devexit_p (octeon_i2c_remove), .driver = { .owner =THIS_MODULE , .name =DRV_NAME ,
@@ -576,4 +586,3 @@ MODULE_ALIAS("platform:" DRV_NAME);module_init (octeon_i2c_init);module_exit (octeon_i2c_exit); -
PATCH 3/3 MIPS: Octeon: Register some devices on the I2C bus.
In reply to a message not in the archive--- arch/mips/cavium-octeon/octeon-platform.c | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
arch/mips/cavium-octeon/octeon-platform.c +13 -0
@@ -10,6 +10,7 @@#include <linux/delay.h> #include <linux/init.h> #include <linux/irq.h> +#include <linux/i2c.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h>
@@ -165,6 +166,18 @@ out: }device_initcall (octeon_rng_device_init); +static struct i2c_board_info __initdata octeon_i2c_devices[] = { + { +I2C_BOARD_INFO ("ds1337" ,0x68 ), + }, +}; + +static int __init octeon_i2c_devices_init (void ) +{ +return i2c_register_board_info (0 , octeon_i2c_devices, +ARRAY_SIZE (octeon_i2c_devices)); +} +arch_initcall (octeon_i2c_devices_init);#define OCTEON_I2C_IO_BASE 0x1180000001000ull#define OCTEON_I2C_IO_UNIT_OFFSET 0x200
Signature · 1 line
1.6.0.6
Bah... I forgot to include Rade Bozic on the original message. Now included.
Quoted 26 lines · David Daney
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
I will reply with the three patches.
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.arch/mips/cavium-octeon/octeon-platform.c | 85 +++++ arch/mips/include/asm/octeon/octeon.h | 5 + drivers/i2c/busses/Kconfig | 10 + drivers/i2c/busses/Makefile | 1 + drivers/i2c/busses/i2c-octeon.c | 579 +++++++++++++++++++++++++++++ 5 files changed, 680 insertions(+), 0 deletions(-) create mode 100644 drivers/i2c/busses/i2c-octeon.c
A message that is not in the archive (sent off-list or not yet received): 4B463C71.3080005-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org
Quoted 8 lines · David Daney
Quoted 7 lines · David Daney
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
Quoted 8 lines
Quoted 8 lines
I will reply with the three patches.
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.
Do you want to merge this series through the MIPS tree?
Ralf
A message that is not in the archive (sent off-list or not yet received): 20100111144416.GA23157-6z/[email protected]
Quoted 12 lines · Ralf Baechle
Quoted 10 lines · David Daney
Quoted 9 lines · David Daney
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
I will reply with the three patches.
Quoted 9 lines
Quoted 6 lines
Quoted 6 lines
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.Do you want to merge this series through the MIPS tree?
Two of the patches touch only arch/mips/cavium-octeon, so it might make sense. But the I2C maintainers may have other desires, so I would defer to them.
David Daney
A message that is not in the archive (sent off-list or not yet received): 4B4B5CD3.4040204-M3mlKVOIwJVv6pq1l3V1OdBPR1lH4CV8@public.gmane.org
Quoted 17 lines · David Daney
Quoted 16 lines · Ralf Baechle
Quoted 14 lines · David Daney
Quoted 13 lines · David Daney
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
I will reply with the three patches.
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
Quoted 2 lines
Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.Do you want to merge this series through the MIPS tree?
Two of the patches touch only
arch/mips/cavium-octeon, so it might make sense. But the I2C maintainers may have other desires, so I would defer to them.
I won't take care of them, so I have no objection if the go through the MIPS tree. For a platform-specific driver I think it makes a lot of sense.
Signature · 1 line
Jean Delvare
Methinks this goes to I2C...
//Markus
Quoted 24 lines · David Daney
Quoted 11 lines · Ralf Baechle
Quoted 10 lines · David Daney
Quoted 9 lines · David Daney
This patch set adds I2C driver support for Cavium Networks' Octeon processor family. The Octeon is a multi-core MIPS64 based SOC.
The first patch adds platform devices for the I2C devices. The second patch is the main driver. Finally the third patch registers some devices so we have something to control with the fancy new driver.
I will reply with the three patches.
Quoted 7 lines
Quoted 6 lines
Quoted 6 lines
David Daney (2):
MIPS: Octeon: Add I2C platform driver.
MIPS: Octeon: Register some devices on the I2C bus.Rade Bozic (1):
I2C: Add driver for Cavium OCTEON I2C ports.Do you want to merge this series through the MIPS tree?
Two of the patches touch only
arch/mips/cavium-octeon, so it might make sense. But the I2C maintainers may have other desires, so I would defer to them.David Daney
A message that is not in the archive (sent off-list or not yet received): F5F1F5D1-6057-49CF-A5B3-A921E1C0EEEB-SamgB31n2u5IcsJQ0EH25Q@public.gmane.org
Quoted 1 line · Markus Gothe
Methinks this goes to I2C...
But given that you are not maintaining any part of the kernel, what you think on this matter doesn't have much value, methinks. You do not seriously intend to tell maintainers how they should work together, do you?
Signature · 1 line
Jean Delvare