[PATCH] i2c: omap: Remove the OMAP_I2C_FLAG_RESET_REGS_POSTIDLE flag
The OMAP_I2C_FLAG_RESET_REGS_POSTIDLE is not used anymore in the i2c driver. Remove the flag. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Has dependency on the below patch http://git.pengutronix.de/?p=wsa/linux.git;a=commitdiff;h=554c96744afd169886bd6fc2736fb0d9aaf634e8 arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |3 +-- arch/arm/mach-omap2/omap_hwmod_44xx_data.c |3 +-- drivers/i2c/busses/i2c-omap.c |3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 943222c4..3dd9e69 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | - OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod omap3xxx_i2c1_hwmod = { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0b1249e..1afab5f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1527,8 +1527,7 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 872444a..d3b853b 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1034,8 +1034,7 @@ static const struct i2c_algorithm omap_i2c_algo = { #ifdef CONFIG_OF static struct omap_i2c_bus_platform_data omap3_pdata = { .rev = OMAP_I2C_IP_VERSION_1, - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_i2c_bus_platform_data omap4_pdata = { -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] i2c: omap: Remove the OMAP_I2C_FLAG_RESET_REGS_POSTIDLE flag
The OMAP_I2C_FLAG_RESET_REGS_POSTIDLE is not used anymore in the i2c driver. Remove the flag. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Has dependency on the below patch http://git.pengutronix.de/?p=wsa/linux.git;a=commitdiff;h=554c96744afd169886bd6fc2736fb0d9aaf634e8 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |3 +-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +++-- arch/arm/mach-omap2/omap_hwmod_44xx_data.c |3 +-- drivers/i2c/busses/i2c-omap.c |3 +-- include/linux/i2c-omap.h |1 - 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 59d5c1c..c9a186b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1103,8 +1103,7 @@ static struct omap_hwmod_class i2c_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 943222c4..36270bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | - OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod omap3xxx_i2c1_hwmod = { @@ -817,8 +816,7 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { /* I2C2 */ static struct omap_i2c_dev_attr i2c2_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod omap3xxx_i2c2_hwmod = { @@ -843,8 +841,7 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { /* I2C3 */ static struct omap_i2c_dev_attr i2c3_dev_attr = { .fifo_depth = 64, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d028..eb40dbc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1526,8 +1526,7 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fabcbe1..815a401 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1038,8 +1038,7 @@ static const struct i2c_algorithm omap_i2c_algo = { #ifdef CONFIG_OF static struct omap_i2c_bus_platform_data omap3_pdata = { .rev = OMAP_I2C_IP_VERSION_1, - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_i2c_bus_platform_data omap4_pdata = { diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 1b25c04..babe0cf 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -20,7 +20,6 @@ #define OMAP_I2C_FLAG_NO_FIFO BIT(0) #define OMAP_I2C_FLAG_SIMPLE_CLOCK BIT(1) #define OMAP_I2C_FLAG_16BIT_DATA_REG BIT(2) -#define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3) #define OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLKBIT(5) #define OMAP_I2C_FLAG_FORCE_19200_INT_CLK BIT(6) /* how the CPU address bus must be translated for I2C unit access */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] i2c: omap: Remove the OMAP_I2C_FLAG_RESET_REGS_POSTIDLE flag
The OMAP_I2C_FLAG_RESET_REGS_POSTIDLE is not used anymore in the i2c driver. Remove the flag. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Has dependency on the below patch http://git.pengutronix.de/?p=wsa/linux.git;a=commitdiff;h=554c96744afd169886bd6fc2736fb0d9aaf634e8 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |3 +-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +++-- arch/arm/mach-omap2/omap_hwmod_44xx_data.c |3 +-- drivers/i2c/busses/i2c-omap.c |3 +-- include/linux/i2c-omap.h |1 - 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 59d5c1c..c9a186b 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1103,8 +1103,7 @@ static struct omap_hwmod_class i2c_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 943222c4..36270bb 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | - OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod omap3xxx_i2c1_hwmod = { @@ -817,8 +816,7 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { /* I2C2 */ static struct omap_i2c_dev_attr i2c2_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod omap3xxx_i2c2_hwmod = { @@ -843,8 +841,7 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { /* I2C3 */ static struct omap_i2c_dev_attr i2c3_dev_attr = { .fifo_depth = 64, /* bytes */ - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = { diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 652d028..eb40dbc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1526,8 +1526,7 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, }; /* i2c1 */ diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fabcbe1..815a401 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1038,8 +1038,7 @@ static const struct i2c_algorithm omap_i2c_algo = { #ifdef CONFIG_OF static struct omap_i2c_bus_platform_data omap3_pdata = { .rev = OMAP_I2C_IP_VERSION_1, - .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | -OMAP_I2C_FLAG_BUS_SHIFT_2, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2, }; static struct omap_i2c_bus_platform_data omap4_pdata = { diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 1b25c04..babe0cf 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -20,7 +20,6 @@ #define OMAP_I2C_FLAG_NO_FIFO BIT(0) #define OMAP_I2C_FLAG_SIMPLE_CLOCK BIT(1) #define OMAP_I2C_FLAG_16BIT_DATA_REG BIT(2) -#define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3) #define OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLKBIT(5) #define OMAP_I2C_FLAG_FORCE_19200_INT_CLK BIT(6) /* how the CPU address bus must be translated for I2C unit access */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Input: omap4-keypad: Remove the OMAP4_KBD_SYSCONFIG and OMAP4_KBD_SYSSTATUS
The macros OMAP4_KBD_SYSSTATUS and OMAP4_KBD_SYSSTATUS are not used so remove them. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/input/keyboard/omap4-keypad.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/input/keyboard/omap4-keypad.c b/drivers/input/keyboard/omap4-keypad.c index c05f98c..d2b72b7 100644 --- a/drivers/input/keyboard/omap4-keypad.c +++ b/drivers/input/keyboard/omap4-keypad.c @@ -36,8 +36,6 @@ /* OMAP4 registers */ #define OMAP4_KBD_REVISION 0x00 -#define OMAP4_KBD_SYSCONFIG0x10 -#define OMAP4_KBD_SYSSTATUS0x14 #define OMAP4_KBD_IRQSTATUS0x18 #define OMAP4_KBD_IRQENABLE0x1C #define OMAP4_KBD_WAKEUPENABLE 0x20 -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RFC] i2c: omap: Remove the OMAP_I2C_IP_VERSION_*
The OMAP_I2C_IP_VERSION_1 and OMAP_I2C_IP_VERSION_2 was needed as on VER2 we were not reading all the 32-bits. Since now that we read the hi register we do not need the OMAP_I2C_IP_VERSION_*. Delete the same. The custom reset is also changed to detect VER2 based on the scheme. Also move some of the common defines to i2c-omap.h to avoid duplication. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- arch/arm/mach-omap2/i2c.c | 16 +++- arch/arm/mach-omap2/omap_hwmod_2420_data.c |1 - arch/arm/mach-omap2/omap_hwmod_2430_data.c |1 - arch/arm/mach-omap2/omap_hwmod_33xx_data.c |1 - arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |1 - arch/arm/mach-omap2/omap_hwmod_44xx_data.c |1 - arch/arm/plat-omap/i2c.c |3 --- drivers/i2c/busses/i2c-omap.c |5 - include/linux/i2c-omap.h | 16 9 files changed, 11 insertions(+), 34 deletions(-) diff --git a/arch/arm/mach-omap2/i2c.c b/arch/arm/mach-omap2/i2c.c index fc57e67..6532bc1 100644 --- a/arch/arm/mach-omap2/i2c.c +++ b/arch/arm/mach-omap2/i2c.c @@ -63,18 +63,16 @@ void __init omap2_i2c_mux_pins(int bus_id) int omap_i2c_reset(struct omap_hwmod *oh) { u32 v; - u16 i2c_con; + u16 i2c_con, scheme; int c = 0; - if (oh-class-rev == OMAP_I2C_IP_VERSION_2) { - i2c_con = OMAP4_I2C_CON_OFFSET; - } else if (oh-class-rev == OMAP_I2C_IP_VERSION_1) { + i2c_con = OMAP4_I2C_CON_OFFSET; + v = omap_hwmod_read(oh, 0x4); + + scheme = OMAP_I2C_SCHEME(v); + + if (scheme == OMAP_I2C_SCHEME_0) i2c_con = OMAP2_I2C_CON_OFFSET; - } else { - WARN(1, Cannot reset I2C block %s: unsupported revision\n, -oh-name); - return -EINVAL; - } /* Disable I2C */ v = omap_hwmod_read(oh, i2c_con); diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b5db600..51251a9 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -91,7 +91,6 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { static struct omap_hwmod_class i2c_class = { .name = i2c, .sysc = i2c_sysc, - .rev= OMAP_I2C_IP_VERSION_1, .reset = omap_i2c_reset, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index b79ccf6..260b3d1 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -70,7 +70,6 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { static struct omap_hwmod_class i2c_class = { .name = i2c, .sysc = i2c_sysc, - .rev= OMAP_I2C_IP_VERSION_1, .reset = omap_i2c_reset, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index c9a186b..ce1f68e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1098,7 +1098,6 @@ static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = { static struct omap_hwmod_class i2c_class = { .name = i2c, .sysc = am33xx_i2c_sysc, - .rev= OMAP_I2C_IP_VERSION_2, .reset = omap_i2c_reset, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 36270bb..5c1c8e2 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -612,7 +612,6 @@ static struct omap_hwmod am35xx_uart4_hwmod = { static struct omap_hwmod_class i2c_class = { .name = i2c, .sysc = i2c_sysc, - .rev= OMAP_I2C_IP_VERSION_1, .reset = omap_i2c_reset, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index eb40dbc..d6ef477 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -1521,7 +1521,6 @@ static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { .name = i2c, .sysc = omap44xx_i2c_sysc, - .rev= OMAP_I2C_IP_VERSION_2, .reset = omap_i2c_reset, }; diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 6013831..d02d4b6 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -108,9 +108,6 @@ static inline int omap1_i2c_add_bus(int bus_id) res[1].start = OMAP1_INT_I2C; pdata = i2c_pdata[bus_id - 1]; - /* all OMAP1 have IP version 1 register set */ - pdata-rev = OMAP_I2C_IP_VERSION_1; - /* all OMAP1 I2C are implemented like this */ pdata-flags = OMAP_I2C_FLAG_NO_FIFO
[PATCH] spi: omap2-mcspi: Fix the redifine warning
Fix the below warning drivers/spi/spi-omap2-mcspi.c:336:34: warning: symbol 'tx' shadows an earlier one drivers/spi/spi-omap2-mcspi.c:327:12: originally declared here So delete the u8 tx as it is assigned and not used(resigned afterwards). Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 251f6d0..c3dcfb3 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -323,14 +323,11 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - const u8* tx; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; count = xfer-len; - tx = xfer-tx_buf; - if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3] i2c: omap: Move the remove constraint
Currently we just queue the transfer and release the qos constraints, however we do not wait for the transfer to complete to release the constraint. Move the remove constraint after the bus busy as we are sure that the transfers are completed by then. Acked-by: Jean Pihet j-pi...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v2: rebase to the for-next branch v3: Fix a typo drivers/i2c/busses/i2c-omap.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 482c63d..fabcbe1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -654,13 +654,14 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev-set_mpu_wkup_lat != NULL) - dev-set_mpu_wkup_lat(dev-dev, -1); - if (r == 0) r = num; omap_i2c_wait_for_bb(dev); + + if (dev-set_mpu_wkup_lat != NULL) + dev-set_mpu_wkup_lat(dev-dev, -1); + out: pm_runtime_mark_last_busy(dev-dev); pm_runtime_put_autosuspend(dev-dev); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2] i2c: omap: Move the remove constraint
Currently we just queue the transfer and release the qos constraints, however we donot wait for the transfer to complete to release the constraint. Move the remove constraint after the bus busy as we are sure that the transfers are completed by then. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v2: rebase to the for-next branch drivers/i2c/busses/i2c-omap.c |7 --- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 482c63d..fabcbe1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -654,13 +654,14 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev-set_mpu_wkup_lat != NULL) - dev-set_mpu_wkup_lat(dev-dev, -1); - if (r == 0) r = num; omap_i2c_wait_for_bb(dev); + + if (dev-set_mpu_wkup_lat != NULL) + dev-set_mpu_wkup_lat(dev-dev, -1); + out: pm_runtime_mark_last_busy(dev-dev); pm_runtime_put_autosuspend(dev-dev); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] spi: omap2-mcspi: Reorder the wait_for_completion for tx
The commit d7b4394e[Cleanup the omap2_mcspi_txrx_dma function] changed the wait_for_completion order. Move the wait so that the rx doesnot wait for the tx to complete. Reported-and-tested-by: Sørensen, Stefan soren...@polycom.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 39 +++ 1 files changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bcfd062..251f6d0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -323,18 +323,13 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - u8 * rx; const u8* tx; - void __iomem*chstat_reg; - struct omap2_mcspi_cs *cs = spi-controller_state; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; count = xfer-len; - rx = xfer-rx_buf; tx = xfer-tx_buf; - chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; @@ -359,19 +354,6 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, dma_async_issue_pending(mcspi_dma-dma_tx); omap2_mcspi_set_dma_req(spi, 0, 1); - wait_for_completion(mcspi_dma-dma_tx_completion); - dma_unmap_single(mcspi-dev, xfer-tx_dma, count, -DMA_TO_DEVICE); - - /* for TX_ONLY mode, be sure all words have shifted out */ - if (rx == NULL) { - if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_TXS) 0) - dev_err(spi-dev, TXS timed out\n); - else if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_EOT) 0) - dev_err(spi-dev, EOT timed out\n); - } } static unsigned @@ -492,6 +474,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) struct dma_slave_config cfg; enum dma_slave_buswidth width; unsigned es; + void __iomem*chstat_reg; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; @@ -526,8 +509,24 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) omap2_mcspi_tx_dma(spi, xfer, cfg); if (rx != NULL) - return omap2_mcspi_rx_dma(spi, xfer, cfg, es); - + count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); + + if (tx != NULL) { + chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; + wait_for_completion(mcspi_dma-dma_tx_completion); + dma_unmap_single(mcspi-dev, xfer-tx_dma, xfer-len, +DMA_TO_DEVICE); + + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) 0) + dev_err(spi-dev, TXS timed out\n); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) 0) + dev_err(spi-dev, EOT timed out\n); + } + } return count; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] spi: omap2-mcspi: Reorder the wait_for_completion for tx
The commit d7b4394e[Cleanup the omap2_mcspi_txrx_dma function] changed the wait_for_completion order. Move the wait so that the rx doesnot wait for the tx to complete. Reported-and-tested-by: Sørensen, Stefan soren...@polycom.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 39 +++ 1 files changed, 19 insertions(+), 20 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bcfd062..251f6d0 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -323,18 +323,13 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - u8 * rx; const u8* tx; - void __iomem*chstat_reg; - struct omap2_mcspi_cs *cs = spi-controller_state; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; count = xfer-len; - rx = xfer-rx_buf; tx = xfer-tx_buf; - chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; @@ -359,19 +354,6 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, dma_async_issue_pending(mcspi_dma-dma_tx); omap2_mcspi_set_dma_req(spi, 0, 1); - wait_for_completion(mcspi_dma-dma_tx_completion); - dma_unmap_single(mcspi-dev, xfer-tx_dma, count, -DMA_TO_DEVICE); - - /* for TX_ONLY mode, be sure all words have shifted out */ - if (rx == NULL) { - if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_TXS) 0) - dev_err(spi-dev, TXS timed out\n); - else if (mcspi_wait_for_reg_bit(chstat_reg, - OMAP2_MCSPI_CHSTAT_EOT) 0) - dev_err(spi-dev, EOT timed out\n); - } } static unsigned @@ -492,6 +474,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) struct dma_slave_config cfg; enum dma_slave_buswidth width; unsigned es; + void __iomem*chstat_reg; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; @@ -526,8 +509,24 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) omap2_mcspi_tx_dma(spi, xfer, cfg); if (rx != NULL) - return omap2_mcspi_rx_dma(spi, xfer, cfg, es); - + count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); + + if (tx != NULL) { + chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; + wait_for_completion(mcspi_dma-dma_tx_completion); + dma_unmap_single(mcspi-dev, xfer-tx_dma, xfer-len, +DMA_TO_DEVICE); + + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) 0) + dev_err(spi-dev, TXS timed out\n); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) 0) + dev_err(spi-dev, EOT timed out\n); + } + } return count; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] i2c: omap: Move the remove constraint
Currently we just queue the transfer and release the qos constraints, however we donot wait for the transfer to complete to release the constraint. Move the remove constraint after the bus busy as we are sure that the transfers are completed by then. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 94ff685..8b079d7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -655,13 +655,13 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) break; } - if (dev-latency) - pm_qos_remove_request(dev-pm_qos_request); - if (r == 0) r = num; omap_i2c_wait_for_bb(dev); + + if (dev-latency) + pm_qos_remove_request(dev-pm_qos_request); out: pm_runtime_mark_last_busy(dev-dev); pm_runtime_put_autosuspend(dev-dev); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 2/8] i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207
The errata i207 is enabled for 2430 and 3xxx. Use the revision check to enable the erratum instead. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5c6f538..737d843 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1166,7 +1166,8 @@ omap_i2c_probe(struct platform_device *pdev) dev-errata = 0; - if (dev-flags OMAP_I2C_FLAG_APPLY_ERRATA_I207) + if (dev-rev = OMAP_I2C_REV_ON_2430 + dev-rev OMAP_I2C_REV_ON_4430_PLUS) dev-errata |= I2C_OMAP_ERRATA_I207; if (dev-rev = OMAP_I2C_REV_ON_3430_3530) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 0/7] i2c: omap: updates
Does the followiing - Make the revision a 32- bit consisting of rev_lo amd rev_hi each of 16 bits. - Also use the revision register for the erratum i207. - Refactor the i2c_omap_init code. Adds a patch to remove the hardcoding sysc register. Instead read register ,reset and then writeback the read value. Also more cleanup is possible will check on that subsequently. Previous discussions can be found http://www.spinics.net/lists/linux-omap/msg81265.html Tested on OMAP4430sdp ,4460 ,omap3630 ,3430 and omap2430. For omap2 testing the below patch was used [PATCH] ARM: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_VFPv3 set Also for using the pm testing below patches are used. arm: sched: stop sched_clock() during suspend ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod The following changes since commit 3d70f8c617a436c7146ecb81df2265b4626dfe89: Linux 3.7-rc4 (2012-11-04 11:07:39 -0800) are available in the git repository at: git://gitorious.org/linus-tree/linus-tree.git i2c_omap/for_3.8 Shubhrajyoti D (8): i2c: omap: Fix the revision register read i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207 i2c: omap: remove the dtrev ARM: i2c: omap: Remove the i207 errata flag i2c: omap: re-factor omap_i2c_init function i2c: omap: make reset a seperate function i2c: omap: Restore i2c context always i2c: omap: cleanup the sysc write arch/arm/mach-omap2/omap_hwmod_2430_data.c |3 +- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +- drivers/i2c/busses/i2c-omap.c | 202 include/linux/i2c-omap.h |1 - 4 files changed, 118 insertions(+), 97 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 8/8] i2c: omap: cleanup the sysc write
Currently after the reset the sysc is written with hardcoded values. The patch reads the sysc register and writes back the same value after reset. - Some unnecessary rev checks can be optimised. - Also due to whatever reason the hwmod flags are changed we will not reset the values. - In some of the cases the minor values of the 2430 register is different(0x37) in that case the autoidle setting may be missed. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 20 +--- 1 files changed, 5 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 25f1564..a09acdc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -302,7 +302,11 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) static int omap_i2c_reset(struct omap_i2c_dev *dev) { unsigned long timeout; + u16 sysc; + if (dev-rev = OMAP_I2C_OMAP1_REV_2) { + sysc = omap_i2c_read_reg(dev, OMAP_I2C_SYSC_REG); + /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, omap_i2c_read_reg(dev, OMAP_I2C_CON_REG) @@ -324,22 +328,8 @@ static int omap_i2c_reset(struct omap_i2c_dev *dev) } /* SYSC register is cleared by the reset; rewrite it */ - if (dev-rev == OMAP_I2C_REV_ON_2430) { - - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, - SYSC_AUTOIDLE_MASK); + omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, sysc); - } else if (dev-rev = OMAP_I2C_REV_ON_3430_3530) { - dev-syscstate = SYSC_AUTOIDLE_MASK; - dev-syscstate |= SYSC_ENAWAKEUP_MASK; - dev-syscstate |= (SYSC_IDLEMODE_SMART - __ffs(SYSC_SIDLEMODE_MASK)); - dev-syscstate |= (SYSC_CLOCKACTIVITY_FCLK - __ffs(SYSC_CLOCKACTIVITY_MASK)); - - omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, - dev-syscstate); - } } return 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 7/8] i2c: omap: Restore i2c context always
Currently the restore is done based on the flag OMAP_I2C_FLAG_RESET_REGS_POSTIDLE. This helps the following - The driver is always capable of restoring regardless of the off mode support being there or not. - While testing omap2430 it is found that in case of certain error paths (timeout) a reset is done. However the restore never happens as it is dependent on the POSTIDLE flag. The other option would be to call a restore in the reset case. As there are only a few registers to be restored the penalty in the idle case should not be much. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Todo: the flag could be deleted if the patch is accepted. drivers/i2c/busses/i2c-omap.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7393017..25f1564 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1316,8 +1316,7 @@ static int omap_i2c_runtime_resume(struct device *dev) if (!_dev-regs) return 0; - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) - __omap_i2c_init(_dev); + __omap_i2c_init(_dev); return 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 6/8] i2c: omap: make reset a seperate function
Implement reset as a separate function. This will enable us to make sure that we don't do the calculation again on every transfer. Also at probe the reset is not added as the hwmod is doing that for us. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- todo: reprodue the errors and optimise the reset if possible drivers/i2c/busses/i2c-omap.c | 39 --- 1 files changed, 24 insertions(+), 15 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 393bb22..7393017 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -299,15 +299,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); } -static int omap_i2c_init(struct omap_i2c_dev *dev) +static int omap_i2c_reset(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0; - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; - unsigned long fclk_rate = 1200; unsigned long timeout; - unsigned long internal_clk = 0; - struct clk *fclk; - if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -345,14 +339,27 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_SYSC_REG, dev-syscstate); - /* -* Enabling all wakup sources to stop I2C freezing on -* WFI instruction. -* REVISIT: Some wkup sources might not be needed. -*/ - dev-westate = OMAP_I2C_WE_ALL; } } + return 0; +} + +static int omap_i2c_init(struct omap_i2c_dev *dev) +{ + u16 psc = 0, scll = 0, sclh = 0; + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; + unsigned long fclk_rate = 1200; + unsigned long internal_clk = 0; + struct clk *fclk; + + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) { + /* +* Enabling all wakup sources to stop I2C freezing on +* WFI instruction. +* REVISIT: Some wkup sources might not be needed. +*/ + dev-westate = OMAP_I2C_WE_ALL; + } if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -592,7 +599,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev-buf_len = 0; if (timeout == 0) { dev_err(dev-dev, controller timed out\n); - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); return -ETIMEDOUT; } @@ -602,7 +610,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, /* We have an error */ if (dev-cmd_err (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); return -EIO; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 4/8] ARM: i2c: omap: Remove the i207 errata flag
The commit [i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207] uses the revision id instead of the flag. So the flag can be safely removed. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- arch/arm/mach-omap2/omap_hwmod_2430_data.c |3 +-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +++-- drivers/i2c/busses/i2c-omap.c |3 +-- include/linux/i2c-omap.h |1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index c455e41..b79ccf6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -76,8 +76,7 @@ static struct omap_hwmod_class i2c_class = { static struct omap_i2c_dev_attr i2c_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | - OMAP_I2C_FLAG_BUS_SHIFT_2 | + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 | OMAP_I2C_FLAG_FORCE_19200_INT_CLK, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index f67b7ee..943222c4 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; @@ -818,8 +817,7 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { /* I2C2 */ static struct omap_i2c_dev_attr i2c2_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; @@ -845,8 +843,7 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { /* I2C3 */ static struct omap_i2c_dev_attr i2c3_dev_attr = { .fifo_depth = 64, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5f0c06c..88358d8 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1029,8 +1029,7 @@ static const struct i2c_algorithm omap_i2c_algo = { #ifdef CONFIG_OF static struct omap_i2c_bus_platform_data omap3_pdata = { .rev = OMAP_I2C_IP_VERSION_1, - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index df804ba..5c88187 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -21,7 +21,6 @@ #define OMAP_I2C_FLAG_SIMPLE_CLOCK BIT(1) #define OMAP_I2C_FLAG_16BIT_DATA_REG BIT(2) #define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3) -#define OMAP_I2C_FLAG_APPLY_ERRATA_I207BIT(4) #define OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLKBIT(5) #define OMAP_I2C_FLAG_FORCE_19200_INT_CLK BIT(6) /* how the CPU address bus must be translated for I2C unit access */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv3 1/8] i2c: omap: Fix the revision register read
The revision register on OMAP4 is a 16-bit lo and a 16-bit hi. Currently the driver reads only the lower 8-bits. Fix the same by preventing the truncating of the rev register for OMAP4. Also use the scheme bit ie bit-14 of the hi register to know if it is OMAP_I2C_IP_VERSION_2. On platforms previous to OMAP4 the offset 0x04 is IE register whose bit-14 reset value is 0, the code uses the same to its advantage. Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done to fetch the revision register. The dev-regs is populated after reading the rev_hi. A NULL check has been added in the resume handler to prevent the access before the setting of the regs. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v3: Fix the comments. drivers/i2c/busses/i2c-omap.c | 61 - 1 files changed, 48 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eae..5c6f538 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -49,9 +49,10 @@ #define OMAP_I2C_OMAP1_REV_2 0x20 /* I2C controller revisions present on specific hardware */ -#define OMAP_I2C_REV_ON_2430 0x36 -#define OMAP_I2C_REV_ON_3430_3530 0x3C -#define OMAP_I2C_REV_ON_3630_4430 0x40 +#define OMAP_I2C_REV_ON_2430 0x0036 +#define OMAP_I2C_REV_ON_3430_3530 0x003C +#define OMAP_I2C_REV_ON_3630 0x0040 +#define OMAP_I2C_REV_ON_4430_PLUS 0x5042 /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -202,7 +203,7 @@ struct omap_i2c_dev { * fifo_size==0 implies no fifo * if set, should be trsh+1 */ - u8 rev; + u32 rev; unsignedb_hw:1; /* bad h/w fixes */ unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - if (dev-rev OMAP_I2C_REV_ON_3630_4430) + if (dev-rev OMAP_I2C_REV_ON_3630) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ @@ -1052,6 +1053,16 @@ static const struct of_device_id omap_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, omap_i2c_of_match); #endif +#define OMAP_I2C_SCHEME(rev) ((rev 0xc000) 14) + +#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev 4) +#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev 0xf) + +#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev 0x0700) 7) +#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev 0x1f) +#define OMAP_I2C_SCHEME_0 0 +#define OMAP_I2C_SCHEME_1 1 + static int __devinit omap_i2c_probe(struct platform_device *pdev) { @@ -1064,6 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev) const struct of_device_id *match; int irq; int r; + u32 rev; + u16 minor, major; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1117,11 +1130,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-reg_shift = (dev-flags OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) 3; - if (dev-dtrev == OMAP_I2C_IP_VERSION_2) - dev-regs = (u8 *)reg_map_ip_v2; - else - dev-regs = (u8 *)reg_map_ip_v1; - pm_runtime_enable(dev-dev); pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(dev-dev); @@ -1130,7 +1138,31 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + /* +* Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2. +* On omap1/3/2 Offset 4 is IE Reg the bit [15:14] is 0 at reset. +* Also since the omap_i2c_read_reg uses reg_map_ip_* a +* raw_readw is done. +*/ + rev = __raw_readw(dev-base + 0x04); + + switch (OMAP_I2C_SCHEME(rev)) { + case OMAP_I2C_SCHEME_0: + dev-regs = (u8 *)reg_map_ip_v1; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG); + minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + break; + case OMAP_I2C_SCHEME_1: + /* FALLTHROUGH */ + default: + dev-regs = (u8 *)reg_map_ip_v2; + rev = (rev 16) | + omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO
[PATCHv3 5/8] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Reviewed-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 75 +++-- 1 files changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 88358d8..393bb22 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -275,9 +274,34 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) (i2c_dev-regs[reg] i2c_dev-reg_shift)); } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -327,11 +351,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -416,28 +437,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1297,23 +1307,8 @@ static int omap_i2c_runtime_resume(struct device *dev) if (!_dev-regs) return 0; - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - } - - /* -* Don't write to this register if the IE state is 0 as it can -* cause deadlock
[PATCHv3 3/8] i2c: omap: remove the dtrev
The dtrev is used only for the comments. Remove the same and use the scheme instead to know if it is version2. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v3: remove the scheme from the commments. todo: remove the dtrev from hwmod etc. drivers/i2c/busses/i2c-omap.c | 12 +--- 1 files changed, 5 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 737d843..5f0c06c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -191,7 +191,6 @@ struct omap_i2c_dev { u32 latency;/* maximum MPU wkup latency */ struct pm_qos_request pm_qos_request; u32 speed; /* Speed of bus in kHz */ - u32 dtrev; /* extra revision from DT */ u32 flags; u16 cmd_err; u8 *buf; @@ -1076,7 +1075,7 @@ omap_i2c_probe(struct platform_device *pdev) int irq; int r; u32 rev; - u16 minor, major; + u16 minor, major, scheme; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1108,7 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev) u32 freq = 10; /* default to 10 Hz */ pdata = match-data; - dev-dtrev = pdata-rev; dev-flags = pdata-flags; of_property_read_u32(node, clock-frequency, freq); @@ -1117,7 +1115,6 @@ omap_i2c_probe(struct platform_device *pdev) } else if (pdata != NULL) { dev-speed = pdata-clkrate; dev-flags = pdata-flags; - dev-dtrev = pdata-rev; } dev-dev = pdev-dev; @@ -1146,7 +1143,8 @@ omap_i2c_probe(struct platform_device *pdev) */ rev = __raw_readw(dev-base + 0x04); - switch (OMAP_I2C_SCHEME(rev)) { + scheme = OMAP_I2C_SCHEME(rev); + switch (scheme) { case OMAP_I2C_SCHEME_0: dev-regs = (u8 *)reg_map_ip_v1; dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG); @@ -1230,8 +1228,8 @@ omap_i2c_probe(struct platform_device *pdev) goto err_unuse_clocks; } - dev_info(dev-dev, bus %d rev%d.%d.%d at %d kHz\n, adap-nr, -dev-dtrev, major, minor, dev-speed); + dev_info(dev-dev, bus %d rev%d.%d at %d kHz\n, adap-nr, +major, minor, dev-speed); of_i2c_register_devices(adap); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 7/7] i2c: omap: Restore i2c context always
Currently the restore is done based on the flag OMAP_I2C_FLAG_RESET_REGS_POSTIDLE. This helps the following - The driver is always capable of restoring regardless of the off mode support being there or not. - While testing omap2430 it is found that in case of certain error paths (timeout) a reset is done. However the restore never happens as it is dependent on the POSTIDLE flag. The other option would be to call a restore in the reset case. As there are only a few registers to be restored the penalty in the idle case should not be much. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Todo: the flag could be deleted if the patch is accepted. drivers/i2c/busses/i2c-omap.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 70d43b7..f66c5ab 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1314,8 +1314,7 @@ static int omap_i2c_runtime_resume(struct device *dev) if (!_dev-regs) return 0; - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) - __omap_i2c_init(_dev); + __omap_i2c_init(_dev); return 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 0/7] i2c: omap: updates
Does the followiing - Make the revision a 32- bit consisting of rev_lo amd rev_hi each of 16 bits. - Also use the revision register for the erratum i207. - Refactor the i2c_omap_init code. Also more cleanup is possible will check on that subsequently. Tested on OMAP4430sdp ,4460 ,omap3630 ,3430 and omap2430. For omap2 testing the below patch was used [PATCH] ARM: vfp: fix save and restore when running on pre-VFPv3 and CONFIG_VFPv3 set Also for using the pm testing below patches are used. arm: sched: stop sched_clock() during suspend ARM: OMAP: hwmod: wait for sysreset complete after enabling hwmod Also available through git://gitorious.org/linus-tree/linus-tree.git i2c_omap/for_3.8 Shubhrajyoti D (7): i2c: omap: Fix the revision register read i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207 i2c: omap: remove the dtrev ARM: i2c: omap: Remove the i207 errata flag i2c: omap: re-factor omap_i2c_init function i2c: omap: make reset a seperate function i2c: omap: Restore i2c context always arch/arm/mach-omap2/omap_hwmod_2430_data.c |3 +- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +- drivers/i2c/busses/i2c-omap.c | 166 +--- include/linux/i2c-omap.h |1 - 4 files changed, 104 insertions(+), 75 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 5/7] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 75 +++-- 1 files changed, 35 insertions(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 8a54efc..a87c20a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -275,9 +274,34 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) (i2c_dev-regs[reg] i2c_dev-reg_shift)); } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -327,11 +351,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -416,28 +437,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_ARDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1297,23 +1307,8 @@ static int omap_i2c_runtime_resume(struct device *dev) if (!_dev-regs) return 0; - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - } - - /* -* Don't write to this register if the IE state is 0 as it can -* cause deadlock. -*/ - if (_dev-iestate
[PATCHv2 4/7] ARM: i2c: omap: Remove the i207 errata flag
The commit [i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207] uses the revision id instead of the flag. So the flag can be safely removed. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- arch/arm/mach-omap2/omap_hwmod_2430_data.c |3 +-- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c |9 +++-- drivers/i2c/busses/i2c-omap.c |3 +-- include/linux/i2c-omap.h |1 - 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index c455e41..b79ccf6 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -76,8 +76,7 @@ static struct omap_hwmod_class i2c_class = { static struct omap_i2c_dev_attr i2c_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | - OMAP_I2C_FLAG_BUS_SHIFT_2 | + .flags = OMAP_I2C_FLAG_BUS_SHIFT_2 | OMAP_I2C_FLAG_FORCE_19200_INT_CLK, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index f67b7ee..943222c4 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -791,8 +791,7 @@ static struct omap_hwmod omap3xxx_dss_venc_hwmod = { /* I2C1 */ static struct omap_i2c_dev_attr i2c1_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | - OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; @@ -818,8 +817,7 @@ static struct omap_hwmod omap3xxx_i2c1_hwmod = { /* I2C2 */ static struct omap_i2c_dev_attr i2c2_dev_attr = { .fifo_depth = 8, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; @@ -845,8 +843,7 @@ static struct omap_hwmod omap3xxx_i2c2_hwmod = { /* I2C3 */ static struct omap_i2c_dev_attr i2c3_dev_attr = { .fifo_depth = 64, /* bytes */ - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index b62cd9d..8a54efc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1029,8 +1029,7 @@ static const struct i2c_algorithm omap_i2c_algo = { #ifdef CONFIG_OF static struct omap_i2c_bus_platform_data omap3_pdata = { .rev = OMAP_I2C_IP_VERSION_1, - .flags = OMAP_I2C_FLAG_APPLY_ERRATA_I207 | -OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | + .flags = OMAP_I2C_FLAG_RESET_REGS_POSTIDLE | OMAP_I2C_FLAG_BUS_SHIFT_2, }; diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index df804ba..5c88187 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -21,7 +21,6 @@ #define OMAP_I2C_FLAG_SIMPLE_CLOCK BIT(1) #define OMAP_I2C_FLAG_16BIT_DATA_REG BIT(2) #define OMAP_I2C_FLAG_RESET_REGS_POSTIDLE BIT(3) -#define OMAP_I2C_FLAG_APPLY_ERRATA_I207BIT(4) #define OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLKBIT(5) #define OMAP_I2C_FLAG_FORCE_19200_INT_CLK BIT(6) /* how the CPU address bus must be translated for I2C unit access */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 1/7] i2c: omap: Fix the revision register read
The revision register on OMAP4 is a 16-bit lo and a 16-bit hi. Currently the driver reads only the lower 8-bits. Fix the same by preventing the truncating of the rev register for OMAP4. Also use the scheme bit ie bit-14 of the hi register to know if it is OMAP_I2C_IP_VERSION_2. On platforms previous to OMAP4 the offset 0x04 is IE register whose bit-14 reset value is 0, the code uses the same to its advantage. Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done to fetch the revision register. The dev-regs is populated after reading the rev_hi. A NULL check has been added in the resume handler to prevent the access before the setting of the regs. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 61 - 1 files changed, 48 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eae..72fce6d 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -49,9 +49,10 @@ #define OMAP_I2C_OMAP1_REV_2 0x20 /* I2C controller revisions present on specific hardware */ -#define OMAP_I2C_REV_ON_2430 0x36 -#define OMAP_I2C_REV_ON_3430_3530 0x3C -#define OMAP_I2C_REV_ON_3630_4430 0x40 +#define OMAP_I2C_REV_ON_2430 0x0036 +#define OMAP_I2C_REV_ON_3430_3530 0x003C +#define OMAP_I2C_REV_ON_3630 0x0040 +#define OMAP_I2C_REV_ON_4430_PLUS 0x5042 /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -202,7 +203,7 @@ struct omap_i2c_dev { * fifo_size==0 implies no fifo * if set, should be trsh+1 */ - u8 rev; + u32 rev; unsignedb_hw:1; /* bad h/w fixes */ unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - if (dev-rev OMAP_I2C_REV_ON_3630_4430) + if (dev-rev OMAP_I2C_REV_ON_3630) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ @@ -1052,6 +1053,16 @@ static const struct of_device_id omap_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, omap_i2c_of_match); #endif +#define OMAP_I2C_SCHEME(rev) ((rev 0xc000) 14) + +#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev 4) +#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev 0xf) + +#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev 0x0700) 7) +#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev 0x1f) +#define OMAP_I2C_SCHEME_0 0 +#define OMAP_I2C_SCHEME_1 1 + static int __devinit omap_i2c_probe(struct platform_device *pdev) { @@ -1064,6 +1075,8 @@ omap_i2c_probe(struct platform_device *pdev) const struct of_device_id *match; int irq; int r; + u32 rev; + u16 minor, major; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1117,11 +1130,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-reg_shift = (dev-flags OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) 3; - if (dev-dtrev == OMAP_I2C_IP_VERSION_2) - dev-regs = (u8 *)reg_map_ip_v2; - else - dev-regs = (u8 *)reg_map_ip_v1; - pm_runtime_enable(dev-dev); pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(dev-dev); @@ -1130,7 +1138,31 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + /* +* Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2. +* On omap3 Offset 4 is IE Reg the bit [15:14] is XDR_IE which is 0 +* at reset. Also since the omap_i2c_read_reg uses reg_map_ip_* a +* raw_readw is done. +*/ + rev = __raw_readw(dev-base + 0x04); + + switch (OMAP_I2C_SCHEME(rev)) { + case OMAP_I2C_SCHEME_0: + dev-regs = (u8 *)reg_map_ip_v1; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + break; + case OMAP_I2C_SCHEME_1: + /* FALLTHROUGH */ + default: + dev-regs = (u8 *)reg_map_ip_v2; + rev = (rev 16) | + omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO
[PATCHv2 2/7] i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207
The errata i207 is enabled for 2430 and 3xxx. Use the revision check to enable the erratum instead. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 72fce6d..e009985 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1166,7 +1166,8 @@ omap_i2c_probe(struct platform_device *pdev) dev-errata = 0; - if (dev-flags OMAP_I2C_FLAG_APPLY_ERRATA_I207) + if (dev-rev = OMAP_I2C_REV_ON_2430 + dev-rev OMAP_I2C_REV_ON_4430_PLUS) dev-errata |= I2C_OMAP_ERRATA_I207; if (dev-rev = OMAP_I2C_REV_ON_3430_3530) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 6/7] i2c: omap: make reset a seperate function
Implement reset as a separate function. This will enable us to make sure that we don't do the calculation again on every transfer. Also at probe the reset is not added as the hwmod is doing that for us. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- todo: reprodue the errors and optimise the reset if possible. drivers/i2c/busses/i2c-omap.c | 25 - 1 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index a87c20a..70d43b7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -299,15 +299,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); } -static int omap_i2c_init(struct omap_i2c_dev *dev) +static int omap_i2c_reset(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0; - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; - unsigned long fclk_rate = 1200; unsigned long timeout; - unsigned long internal_clk = 0; - struct clk *fclk; - if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -353,6 +347,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev-westate = OMAP_I2C_WE_ALL; } } + return 0; +} + +static int omap_i2c_init(struct omap_i2c_dev *dev) +{ + u16 psc = 0, scll = 0, sclh = 0; + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; + unsigned long fclk_rate = 1200; + unsigned long internal_clk = 0; + struct clk *fclk; + if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -592,7 +597,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, dev-buf_len = 0; if (timeout == 0) { dev_err(dev-dev, controller timed out\n); - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); return -ETIMEDOUT; } @@ -602,7 +608,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, /* We have an error */ if (dev-cmd_err (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); return -EIO; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 3/7] i2c: omap: remove the dtrev
The dtrev is used only for the comments. Remove the same and use the scheme instead to know if it is version2. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 10 -- 1 files changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index e009985..b62cd9d 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -191,7 +191,6 @@ struct omap_i2c_dev { u32 latency;/* maximum MPU wkup latency */ struct pm_qos_request pm_qos_request; u32 speed; /* Speed of bus in kHz */ - u32 dtrev; /* extra revision from DT */ u32 flags; u16 cmd_err; u8 *buf; @@ -1076,7 +1075,7 @@ omap_i2c_probe(struct platform_device *pdev) int irq; int r; u32 rev; - u16 minor, major; + u16 minor, major, scheme; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1108,7 +1107,6 @@ omap_i2c_probe(struct platform_device *pdev) u32 freq = 10; /* default to 10 Hz */ pdata = match-data; - dev-dtrev = pdata-rev; dev-flags = pdata-flags; of_property_read_u32(node, clock-frequency, freq); @@ -1117,7 +1115,6 @@ omap_i2c_probe(struct platform_device *pdev) } else if (pdata != NULL) { dev-speed = pdata-clkrate; dev-flags = pdata-flags; - dev-dtrev = pdata-rev; } dev-dev = pdev-dev; @@ -1146,7 +1143,8 @@ omap_i2c_probe(struct platform_device *pdev) */ rev = __raw_readw(dev-base + 0x04); - switch (OMAP_I2C_SCHEME(rev)) { + scheme = OMAP_I2C_SCHEME(rev); + switch (scheme) { case OMAP_I2C_SCHEME_0: dev-regs = (u8 *)reg_map_ip_v1; dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; @@ -1231,7 +1229,7 @@ omap_i2c_probe(struct platform_device *pdev) } dev_info(dev-dev, bus %d rev%d.%d.%d at %d kHz\n, adap-nr, -dev-dtrev, major, minor, dev-speed); +scheme, major, minor, dev-speed); of_i2c_register_devices(adap); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207
The errata i207 is enabled for 2430 and 3xxx. Use the revision check to enable the erratum instead. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index d8e7709..44245d4 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1164,7 +1164,8 @@ omap_i2c_probe(struct platform_device *pdev) dev-errata = 0; - if (dev-flags OMAP_I2C_FLAG_APPLY_ERRATA_I207) + if (dev-rev = OMAP_I2C_REV_ON_2430 + dev-rev OMAP_I2C_REV_ON_4430_PLUS) dev-errata |= I2C_OMAP_ERRATA_I207; if (dev-rev = OMAP_I2C_REV_ON_3430_3530) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] i2c: omap: revision register updates
Does the followiing - Make the revision a 32- bit consisting of rev_lo amd rev_hi each of 16 bits. - Also use the revision register for the erratum i207. Also more cleanup is possible will check on that subsequently. Tested on OMAP4430sdp ,4460 ,omap3630 and 3430. todo: omap2 testing. Shubhrajyoti D (2): i2c: omap: use revision check for OMAP_I2C_FLAG_APPLY_ERRATA_I207 i2c: omap: Fix the revision register read drivers/i2c/busses/i2c-omap.c | 62 +++- 1 files changed, 48 insertions(+), 14 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] i2c: omap: Fix the revision register read
The revision register on OMAP4 is a 16-bit lo and a 16-bit hi. Currently the driver reads only the lower 8-bits. Fix the same by preventing the truncating of the rev register for OMAP4. Also use the scheme bit ie bit-14 of the hi register to know if it is OMAP_I2C_IP_VERSION_2. On platforms previous to OMAP4 the offset 0x04 is IE register whose bit-14 reset value is 0, the code uses the same to its advantage. Also since the omap_i2c_read_reg uses reg_map_ip_* a raw_readw is done to fetch the revision register. The dev-regs is populated after reading the rev_hi. A NULL check has been added in the resume handler to prevent the access before the setting of the regs. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 59 - 1 files changed, 46 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eae..d8e7709 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -49,9 +49,10 @@ #define OMAP_I2C_OMAP1_REV_2 0x20 /* I2C controller revisions present on specific hardware */ -#define OMAP_I2C_REV_ON_2430 0x36 -#define OMAP_I2C_REV_ON_3430_3530 0x3C -#define OMAP_I2C_REV_ON_3630_4430 0x40 +#define OMAP_I2C_REV_ON_2430 0x0036 +#define OMAP_I2C_REV_ON_3430_3530 0x003C +#define OMAP_I2C_REV_ON_3630 0x0040 +#define OMAP_I2C_REV_ON_4430_PLUS 0x5042 /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -202,7 +203,7 @@ struct omap_i2c_dev { * fifo_size==0 implies no fifo * if set, should be trsh+1 */ - u8 rev; + u32 rev; unsignedb_hw:1; /* bad h/w fixes */ unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - if (dev-rev OMAP_I2C_REV_ON_3630_4430) + if (dev-rev OMAP_I2C_REV_ON_3630) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ @@ -1052,6 +1053,14 @@ static const struct of_device_id omap_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, omap_i2c_of_match); #endif +#define OMAP_I2C_SCHEME(rev) (rev 0xc000) 14 + +#define OMAP_I2C_REV_SCHEME_0_MAJOR(rev) (rev 4) +#define OMAP_I2C_REV_SCHEME_0_MINOR(rev) (rev 0xf) + +#define OMAP_I2C_REV_SCHEME_1_MAJOR(rev) ((rev 0x0700) 7) +#define OMAP_I2C_REV_SCHEME_1_MINOR(rev) (rev 0x1f) + static int __devinit omap_i2c_probe(struct platform_device *pdev) { @@ -1064,6 +1073,8 @@ omap_i2c_probe(struct platform_device *pdev) const struct of_device_id *match; int irq; int r; + u32 rev; + u16 minor, major; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1117,11 +1128,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-reg_shift = (dev-flags OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) 3; - if (dev-dtrev == OMAP_I2C_IP_VERSION_2) - dev-regs = (u8 *)reg_map_ip_v2; - else - dev-regs = (u8 *)reg_map_ip_v1; - pm_runtime_enable(dev-dev); pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(dev-dev); @@ -1130,7 +1136,31 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + /* +* Read the Rev hi bit-[15:14] ie scheme this is 1 indicates ver2. +* On omap3 Offset 4 is IE Reg the bit [15:14] is XDR_IE which is 0 +* at reset. Also since the omap_i2c_read_reg uses reg_map_ip_* a +* raw_readw is done. +*/ + rev = __raw_readw(dev-base + 0x04); + + switch (OMAP_I2C_SCHEME(rev)) { + case 0: + dev-regs = (u8 *)reg_map_ip_v1; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + minor = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + major = OMAP_I2C_REV_SCHEME_0_MAJOR(dev-rev); + break; + case 1: + /* FALLTHROUGH */ + default: + dev-regs = (u8 *)reg_map_ip_v2; + rev = (rev 16) | + omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO); + minor = OMAP_I2C_REV_SCHEME_1_MINOR(rev); + major = OMAP_I2C_REV_SCHEME_1_MAJOR(rev); + dev-rev
[PATCH RFC] i2c: omap: Fix the revision register read
The revision register on OMAP4 is a 16-bit lo and a 16-bit hi. Currently the driver reads only the lower 8-bits. Fix the same by preventing the truncating of the rev register for OMAP4. Also use the scheme bit ie bit-14 of the hi register to know if it is OMAP_I2C_IP_VERSION_2. On platforms previous to OMAP4 the offset 0x04 is IE register whose bit-14 reset value is 0, the code uses the same to its advantage. The dev-regs is populated after reading the rev_hi. A NULL check has been added in the resume handler to prevent the access before the setting of the regs. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- todo: some of the flag checks can be removed in favour of revision check. drivers/i2c/busses/i2c-omap.c | 35 +-- 1 files changed, 25 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index db31eae..651a7f7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -51,7 +51,8 @@ /* I2C controller revisions present on specific hardware */ #define OMAP_I2C_REV_ON_2430 0x36 #define OMAP_I2C_REV_ON_3430_3530 0x3C -#define OMAP_I2C_REV_ON_3630_4430 0x40 +#define OMAP_I2C_REV_ON_3630 0x40 +#define OMAP_I2C_REV_ON_4430_PLUS 0x5040 /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) @@ -202,7 +203,7 @@ struct omap_i2c_dev { * fifo_size==0 implies no fifo * if set, should be trsh+1 */ - u8 rev; + u16 rev; unsignedb_hw:1; /* bad h/w fixes */ unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ @@ -490,7 +491,7 @@ static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - if (dev-rev OMAP_I2C_REV_ON_3630_4430) + if (dev-rev OMAP_I2C_REV_ON_3630) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ @@ -1064,6 +1065,8 @@ omap_i2c_probe(struct platform_device *pdev) const struct of_device_id *match; int irq; int r; + u16 rev_lo; + u16 rev_hi; /* NOTE: driver uses the static register mapping */ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -1117,11 +1120,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-reg_shift = (dev-flags OMAP_I2C_FLAG_BUS_SHIFT__SHIFT) 3; - if (dev-dtrev == OMAP_I2C_IP_VERSION_2) - dev-regs = (u8 *)reg_map_ip_v2; - else - dev-regs = (u8 *)reg_map_ip_v1; - pm_runtime_enable(dev-dev); pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); pm_runtime_use_autosuspend(dev-dev); @@ -1130,7 +1128,21 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + /* Read the Rev hi bit-14 ie scheme this is 1 indicates ver2 or + * highlander. + * On omap3 Offset 4 is IE Reg the bit 14 is XDR_IE which is 0 at reset. + */ + rev_hi = __raw_readw(dev-base + 0x04); + + if (rev_hi 0x4000) {/* If scheme 1*/ + dev-regs = (u8 *)reg_map_ip_v2; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_HI); + rev_lo = omap_i2c_read_reg(dev, OMAP_I2C_IP_V2_REVNB_LO); + dev_info(dev-dev, the low rev %x\n, rev_lo); + } else { + dev-regs = (u8 *)reg_map_ip_v1; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + } dev-errata = 0; @@ -1155,7 +1167,7 @@ omap_i2c_probe(struct platform_device *pdev) dev-fifo_size = (dev-fifo_size / 2); - if (dev-rev OMAP_I2C_REV_ON_3630_4430) + if (dev-rev OMAP_I2C_REV_ON_3630) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ @@ -1264,6 +1276,9 @@ static int omap_i2c_runtime_resume(struct device *dev) struct platform_device *pdev = to_platform_device(dev); struct omap_i2c_dev *_dev = platform_get_drvdata(pdev); + if (!_dev-regs) + return 0; + if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo
[PATCH v2] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v2 - add the iestate 0 check back. - Remove a stray change. - Applies on top of Felipe's patches. http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3636 beagle both idle and suspend. Functional testing on omap4sdp. drivers/i2c/busses/i2c-omap.c | 71 ++-- 1 files changed, 32 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5e5cefb..3d400b1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg
[PATCH 0/2] i2c: omap: cleanups
Applies on Felipe's series http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3630 beagle both idle and suspend. Functional testing on omap4sdp. Shubhrajyoti D (2): i2c: omap: re-factor omap_i2c_init function i2c: omap: make reset a seperate function drivers/i2c/busses/i2c-omap.c | 97 + 1 files changed, 49 insertions(+), 48 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] i2c: omap: make reset a seperate function
Implement reset as a seperate function. This will enable us to make sure that we don't do the calculation again on every transfer. Also at probe the reset is not added as the hwmod is doing that for us. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 28 ++-- 1 files changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 3d400b1..5a87ff9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -306,15 +306,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); } -static int omap_i2c_init(struct omap_i2c_dev *dev) +static int omap_i2c_reset(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0; - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; - unsigned long fclk_rate = 1200; unsigned long timeout; - unsigned long internal_clk = 0; - struct clk *fclk; - if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -360,6 +354,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev-westate = OMAP_I2C_WE_ALL; } } + return 0; +} + +static int omap_i2c_init(struct omap_i2c_dev *dev) +{ + u16 psc = 0, scll = 0, sclh = 0; + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; + unsigned long fclk_rate = 1200; + unsigned long internal_clk = 0; + struct clk *fclk; + if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -592,7 +597,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (timeout == 0) { dev_err(dev-dev, controller timed out\n); ret = -ETIMEDOUT; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } @@ -603,7 +609,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, || (dev-cmd_err OMAP_I2C_STAT_ROVR) || (dev-cmd_err OMAP_I2C_STAT_XUDF)) { ret = -EIO; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } @@ -621,7 +628,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, return 0; ret = -EREMOTEIO; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); } out: -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 71 ++-- 1 files changed, 32 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5e5cefb..3d400b1 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,31 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +358,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +444,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1268,23 +1276,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - } - - /* -* Don't write to this register if the IE state is 0 as it can -* cause deadlock. -*/ - if (_dev-iestate) - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev-iestate); + if (_dev-flags
[PATCHv4 0/2] i2c: omap: cleanups
Applies on Felipe's series http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3630 beagle both idle and suspend. Functional testing on omap4sdp. Todo: all the error cases may not need a reset. Shubhrajyoti D (2): i2c: omap: re-factor omap_i2c_init function i2c: omap: make reset a seperate function drivers/i2c/busses/i2c-omap.c | 97 + 1 files changed, 50 insertions(+), 47 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 2/2] i2c: omap: make reset a seperate function
Implement reset as a separate function. This will enable us to make sure that we don't do the calculation again on every transfer. Also at probe the reset is not added as the hwmod is doing that for us. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- some of the errors may not need a reset. will check and post separate patch. drivers/i2c/busses/i2c-omap.c | 25 - 1 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 38acf1a..a25b7b0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -309,15 +309,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); } -static int omap_i2c_init(struct omap_i2c_dev *dev) +static int omap_i2c_reset(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0; - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; - unsigned long fclk_rate = 1200; unsigned long timeout; - unsigned long internal_clk = 0; - struct clk *fclk; - if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -363,6 +357,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev-westate = OMAP_I2C_WE_ALL; } } + return 0; +} + +static int omap_i2c_init(struct omap_i2c_dev *dev) +{ + u16 psc = 0, scll = 0, sclh = 0; + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; + unsigned long fclk_rate = 1200; + unsigned long internal_clk = 0; + struct clk *fclk; + if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -595,7 +600,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (timeout == 0) { dev_err(dev-dev, controller timed out\n); ret = -ETIMEDOUT; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } @@ -606,7 +612,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (dev-cmd_err (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { ret = -EIO; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 1/2] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v4: add spaces for readability drivers/i2c/busses/i2c-omap.c | 74 +++- 1 files changed, 35 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index be329e9..38acf1a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,34 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +361,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +447,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1267,23 +1278,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - } - - /* -* Don't write to this register if the IE state is 0 as it can -* cause deadlock. -*/ - if (_dev-iestate) - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev
[PATCHv4 2/2] i2c: omap: make reset a seperate function
Implement reset as a separate function. This will enable us to make sure that we don't do the calculation again on every transfer. Also at probe the reset is not added as the hwmod is doing that for us. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- some of the errors may not need a reset. will check and post separate patch. drivers/i2c/busses/i2c-omap.c | 25 - 1 files changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 38acf1a..a25b7b0 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -309,15 +309,9 @@ static void __omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); } -static int omap_i2c_init(struct omap_i2c_dev *dev) +static int omap_i2c_reset(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0; - u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; - unsigned long fclk_rate = 1200; unsigned long timeout; - unsigned long internal_clk = 0; - struct clk *fclk; - if (dev-rev = OMAP_I2C_OMAP1_REV_2) { /* Disable I2C controller before soft reset */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, @@ -363,6 +357,17 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) dev-westate = OMAP_I2C_WE_ALL; } } + return 0; +} + +static int omap_i2c_init(struct omap_i2c_dev *dev) +{ + u16 psc = 0, scll = 0, sclh = 0; + u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; + unsigned long fclk_rate = 1200; + unsigned long internal_clk = 0; + struct clk *fclk; + if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -595,7 +600,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (timeout == 0) { dev_err(dev-dev, controller timed out\n); ret = -ETIMEDOUT; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } @@ -606,7 +612,8 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (dev-cmd_err (OMAP_I2C_STAT_AL | OMAP_I2C_STAT_ROVR | OMAP_I2C_STAT_XUDF)) { ret = -EIO; - omap_i2c_init(dev); + omap_i2c_reset(dev); + __omap_i2c_init(dev); goto out; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 0/2] i2c: omap: cleanups
Applies on Felipe's series http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3630 beagle both idle and suspend. Functional testing on omap4sdp. Todo: all the error cases may not need a reset. Shubhrajyoti D (2): i2c: omap: re-factor omap_i2c_init function i2c: omap: make reset a seperate function drivers/i2c/busses/i2c-omap.c | 97 + 1 files changed, 50 insertions(+), 47 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv4 1/2] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- v4: add spaces for readability drivers/i2c/busses/i2c-omap.c | 74 +++- 1 files changed, 35 insertions(+), 39 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index be329e9..38acf1a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,34 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + + /* +* Don't write to this register if the IE state is 0 as it can +* cause deadlock. +*/ + if (dev-iestate) + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); +} + static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +361,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +447,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1267,23 +1278,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_WE_REG, _dev-westate); - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - } - - /* -* Don't write to this register if the IE state is 0 as it can -* cause deadlock. -*/ - if (_dev-iestate) - omap_i2c_write_reg(_dev, OMAP_I2C_IE_REG, _dev
[PATCH] i2c: omap: re-factor omap_i2c_init function
re-factor omap_i2c_init() so that we can re-use it for resume. While at it also remove the bufstate variable as we write it in omap_i2c_resize_fifo for every transfer. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- Applies on Felipe's series http://www.spinics.net/lists/linux-omap/msg79995.html Tested with Terro sys fix + Felipe's stop sched_clock() during suspend on omap3636 beagle both idle and suspend. Functional testing on omap4sdp. drivers/i2c/busses/i2c-omap.c | 68 + 1 files changed, 28 insertions(+), 40 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5e5cefb..338cee7 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -209,7 +209,6 @@ struct omap_i2c_dev { u16 pscstate; u16 scllstate; u16 sclhstate; - u16 bufstate; u16 syscstate; u16 westate; u16 errata; @@ -285,9 +284,26 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) } } +static void __omap_i2c_init(struct omap_i2c_dev *dev) +{ + + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); + /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ + omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev-pscstate); + + /* SCL low and high time values */ + omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, dev-scllstate); + omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, dev-sclhstate); + if (dev-rev = OMAP_I2C_REV_ON_3430_3530) + omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, dev-westate); + /* Take the I2C module out of reset: */ + omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); + omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); + +} static int omap_i2c_init(struct omap_i2c_dev *dev) { - u16 psc = 0, scll = 0, sclh = 0, buf = 0; + u16 psc = 0, scll = 0, sclh = 0; u16 fsscll = 0, fssclh = 0, hsscll = 0, hssclh = 0; unsigned long fclk_rate = 1200; unsigned long timeout; @@ -337,11 +353,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * REVISIT: Some wkup sources might not be needed. */ dev-westate = OMAP_I2C_WE_ALL; - omap_i2c_write_reg(dev, OMAP_I2C_WE_REG, - dev-westate); } } - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); if (dev-flags OMAP_I2C_FLAG_ALWAYS_ARMXOR_CLK) { /* @@ -426,28 +439,18 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) sclh = fclk_rate / (dev-speed * 2) - 7 + psc; } - /* Setup clock prescaler to obtain approx 12MHz I2C module clock: */ - omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, psc); - - /* SCL low and high time values */ - omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); - omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - - /* Take the I2C module out of reset: */ - omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); - /* Enable interrupts */ dev-iestate = (OMAP_I2C_IE_XRDY | OMAP_I2C_IE_RRDY | OMAP_I2C_IE_NACK | OMAP_I2C_IE_AL) | ((dev-fifo_size) ? (OMAP_I2C_IE_RDR | OMAP_I2C_IE_XDR) : 0); - omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev-iestate); - if (dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - dev-pscstate = psc; - dev-scllstate = scll; - dev-sclhstate = sclh; - dev-bufstate = buf; - } + + dev-pscstate = psc; + dev-scllstate = scll; + dev-sclhstate = sclh; + + __omap_i2c_init(dev); + return 0; } @@ -1136,7 +1139,7 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR_VALUE(r)) goto err_free_mem; - dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; + dev-rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) 0xff; dev-errata = 0; @@ -1268,23 +1271,8 @@ static int omap_i2c_runtime_resume(struct device *dev) { struct omap_i2c_dev *_dev = dev_get_drvdata(dev); - if (_dev-flags OMAP_I2C_FLAG_RESET_REGS_POSTIDLE) { - omap_i2c_write_reg(_dev, OMAP_I2C_CON_REG, 0); - omap_i2c_write_reg(_dev, OMAP_I2C_PSC_REG, _dev-pscstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLL_REG, _dev-scllstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SCLH_REG, _dev-sclhstate); - omap_i2c_write_reg(_dev, OMAP_I2C_BUF_REG, _dev-bufstate); - omap_i2c_write_reg(_dev, OMAP_I2C_SYSC_REG, _dev-syscstate); - omap_i2c_write_reg(_dev
[PATCH 2/3] serial: omap: Remove the default setting of special character
Special character detect enable if enabled by default.Received data comparison with XOFF2 data happens by default. tty provides only XOFF1 no X0FF2 is provided so no need to enable check for XOFF2. Keeping this enabled might give some slow transfers due to dummy xoff2 comparison with xoff2 reset value. Since not all want the XOFF2 support lets not enable it by default. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/tty/serial/omap-serial.c |6 +- 1 files changed, 1 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index fd0fb8c..caf49a6 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -702,11 +702,7 @@ serial_omap_configure_xonxoff serial_out(up, UART_MCR, up-mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); - /* Enable special char function UARTi.EFR_REG[5] and -* load the new software flow control mode IXON or IXOFF -* and restore the UARTi.EFR_REG[4] ENHANCED_EN value. -*/ - serial_out(up, UART_EFR, up-efr | UART_EFR_SCD); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up-mcr ~UART_MCR_TCRTLR); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/3] serial: omap: Remove the hardcode serial_omap_console_ports array.
Currently the array serial_omap_console_ports is hard coded to 4. Make it depend on the maximum uart count. Post to [cfc55bc ARM: OMAP2+: serial: Change MAX_HSUART_PORTS to 6] the max ports is 6. Cc: AnilKumar Ch anilku...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/tty/serial/omap-serial.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index caf49a6..478383d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -1077,7 +1077,7 @@ out: #ifdef CONFIG_SERIAL_OMAP_CONSOLE -static struct uart_omap_port *serial_omap_console_ports[4]; +static struct uart_omap_port *serial_omap_console_ports[OMAP_MAX_HSUART_PORTS]; static struct uart_driver serial_omap_reg; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/3] serial: omap: Make context_loss_cnt signed
get_context_loss_count returns an int however it is stored in unsigned integer context_loss_cnt . This patch tries to make context_loss_cnt int. So that in case of errors the value (which may be negative) is not interpreted wrongly. In serial_omap_runtime_resume in case of errors returned by get_context_loss_count print a warning and do a restore. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/tty/serial/omap-serial.c | 12 1 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 6ede6fd..fd0fb8c 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -96,7 +96,7 @@ struct uart_omap_port { unsigned char msr_saved_flags; charname[20]; unsigned long port_activity; - u32 context_loss_cnt; + int context_loss_cnt; u32 errata; u8 wakeups_enabled; unsigned intirq_pending:1; @@ -1556,11 +1556,15 @@ static int serial_omap_runtime_resume(struct device *dev) { struct uart_omap_port *up = dev_get_drvdata(dev); - u32 loss_cnt = serial_omap_get_context_loss_count(up); + int loss_cnt = serial_omap_get_context_loss_count(up); - if (up-context_loss_cnt != loss_cnt) + if (loss_cnt 0) { + dev_err(dev, serial_omap_get_context_loss_count failed : %d\n, + loss_cnt); serial_omap_restore_context(up); - + } else if (up-context_loss_cnt != loss_cnt) { + serial_omap_restore_context(up); + } up-latency = up-calc_latency; schedule_work(up-qos_work); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] serial: omap: fix the overrun case
Overrun also causes an internal flag to be set, which disables further reception. Before the next frame can be received, the MPU must: • Reset the RX FIFO. • clear the internal flag. In the uart mode a dummy read is needed. Add the same. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- - functional testing on omap4sdp - Verified idle and suspend path hits off on beagle. drivers/tty/serial/omap-serial.c |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index a0d4460..bc22a2b 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -334,6 +334,13 @@ static unsigned int check_modem_status(struct uart_omap_port *up) static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) { unsigned int flag; + unsigned char ch = 0; + + if (!(lsr UART_LSR_BRK_ERROR_BITS)) + return; + + if (likely(lsr UART_LSR_DR)) + ch = serial_in(up, UART_RX); up-port.icount.rx++; flag = TTY_NORMAL; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] serial: omap: fix the reciever line error case
This patch does the following - In case of errors if there least one data character in the RX FIFO read it otherwise it may stall the receiver. This is recommended in the interrupt reset method in the table 23-246 of the omap4 TRM. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- - Tested on omap4sdp. - pm tested hitting off in idle and suspend. - v2 changes update the changelogs. - Also remove the dummy check as FE , PE , BI and OE are the only receiver errors. drivers/tty/serial/omap-serial.c |4 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index a0d4460..4fea16b 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -334,6 +334,10 @@ static unsigned int check_modem_status(struct uart_omap_port *up) static void serial_omap_rlsi(struct uart_omap_port *up, unsigned int lsr) { unsigned int flag; + unsigned char ch = 0; + + if (likely(lsr UART_LSR_DR)) + ch = serial_in(up, UART_RX); up-port.icount.rx++; flag = TTY_NORMAL; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 11/22] i2c: omap: switch to platform_get_irq()
From: Felipe Balbi ba...@ti.com that's a nice helper from drivers core which will give us the exact IRQ number, instead of a pointer to an IRQ resource. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index bac1f11..0da8169 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -993,11 +993,12 @@ omap_i2c_probe(struct platform_device *pdev) { struct omap_i2c_dev *dev; struct i2c_adapter *adap; - struct resource *mem, *irq; + struct resource *mem; struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; irq_handler_t isr; + int irq; int r; /* NOTE: driver uses the static register mapping */ @@ -1006,10 +1007,11 @@ omap_i2c_probe(struct platform_device *pdev) dev_err(pdev-dev, no mem resource?\n); return -ENODEV; } - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { + + irq = platform_get_irq(pdev, 0); + if (irq 0) { dev_err(pdev-dev, no irq resource?\n); - return -ENODEV; + return irq; } dev = devm_kzalloc(pdev-dev, sizeof(struct omap_i2c_dev), GFP_KERNEL); @@ -1043,7 +1045,7 @@ omap_i2c_probe(struct platform_device *pdev) } dev-dev = pdev-dev; - dev-irq = irq-start; + dev-irq = irq; platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 15/22] i2c: omap: simplify IRQ exit path
From: Felipe Balbi ba...@ti.com instead of having multiple return points, use a goto statement to make that clearer. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 20 1 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 96fd528..4af123f 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -853,24 +853,21 @@ omap_i2c_isr(int this_irq, void *dev_id) dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } complete: if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } /* @@ -883,8 +880,7 @@ complete: OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_ARDY)); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_RDR) { @@ -949,19 +945,19 @@ complete: dev_err(dev-dev, Receive overrun\n); err |= OMAP_I2C_STAT_ROVR; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); err |= OMAP_I2C_STAT_XUDF; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } } while (stat); +out: + omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 02/22] i2c: omap: simplify num_bytes handling
From: Felipe Balbi ba...@ti.com trivial patch, no functional changes If the fifo is disabled or fifo_size is 0 the num_bytes is set to 1. Else it is set to fifo_size or in case of a draining interrupt the remaining bytes in the buff stat. So the zero check is redundant and can be safely optimised. Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2d9b03c..236cb38 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -812,8 +812,7 @@ complete: OMAP_I2C_BUFSTAT_REG) 8) 0x3F; } - while (num_bytes) { - num_bytes--; + while (num_bytes--) { w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); if (dev-buf_len) { *dev-buf++ = w; @@ -855,8 +854,7 @@ complete: OMAP_I2C_BUFSTAT_REG) 0x3F; } - while (num_bytes) { - num_bytes--; + while (num_bytes--) { w = 0; if (dev-buf_len) { w = *dev-buf++; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 05/22] i2c: omap: simplify omap_i2c_ack_stat()
From: Felipe Balbi ba...@ti.com stat BIT(1) is the same as BIT(1), so let's simplify things a bit by removing stat from all omap_i2c_ack_stat() calls. Code snippet (extremely simplified): if (stat NACK) { ... omap_i2c_ack_stat(dev, stat NACK); } if (stat RDR) { ... omap_i2c_ack_stat(dev, stat RDR); } and so on. The tricky place is only WRT errata handling, for example: if (*stat (NACK | AL)) { omap_i2c_ack_stat(dev, *stat (XRDY | XDR)); ... } but in this case, the errata says we must clear XRDY and XDR if that errata triggers, so if they just got enabled or not, it doesn't matter. Another tricky place is RDR | RRDY (likewise for XDR | XRDY): if (stat (RDR | RRDY)) { ... omap_i2c_ack_stat(dev, stat (RDR | RRDY)); } again here there will be no issues because those IRQs never fire simultaneously and one will only after after we have handled the previous, that's because the same FIFO is used anyway and we won't shift data into FIFO until we tell the IP hey, I'm done with the FIFO, you can shift more data Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com [Added the explaination from the discurssion to the commit logs] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 19 ++- 1 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 30ea63c..f24eae9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -731,7 +731,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) while (--timeout !(*stat OMAP_I2C_STAT_XUDF)) { if (*stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { - omap_i2c_ack_stat(dev, *stat (OMAP_I2C_STAT_XRDY | + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); return -ETIMEDOUT; } @@ -792,10 +792,11 @@ complete: */ if (stat (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { - omap_i2c_ack_stat(dev, stat - (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | - OMAP_I2C_STAT_ARDY)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | + OMAP_I2C_STAT_RDR | + OMAP_I2C_STAT_XRDY | + OMAP_I2C_STAT_XDR | + OMAP_I2C_STAT_ARDY)); omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } @@ -842,8 +843,8 @@ complete: } } } - omap_i2c_ack_stat(dev, - stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | + OMAP_I2C_STAT_RDR)); continue; } @@ -890,8 +891,8 @@ complete: omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } - omap_i2c_ack_stat(dev, - stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | + OMAP_I2C_STAT_XDR)); continue; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 03/22] i2c: omap: decrease indentation level on data handling
From: Felipe Balbi ba...@ti.com The patch intends to decrease the indentation level on the data handling by using the fact that else of if (dev-buf_len) is same as if (!dev-buf_len) if (dev-buf_len) { aaa; } else { bbb; break; } to if (!dev-buf_len) { bbb; break; } aaa; Hence no functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 63 - 1 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 236cb38..0dd647a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -813,22 +813,7 @@ complete: 8) 0x3F; } while (num_bytes--) { - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); - if (dev-buf_len) { - *dev-buf++ = w; - dev-buf_len--; - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags -OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } - } - } else { + if (!dev-buf_len) { if (stat OMAP_I2C_STAT_RRDY) dev_err(dev-dev, RRDY IRQ while no data @@ -839,6 +824,21 @@ complete: requested\n); break; } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags + OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } } omap_i2c_ack_stat(dev, stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); @@ -855,22 +855,7 @@ complete: 0x3F; } while (num_bytes--) { - w = 0; - if (dev-buf_len) { - w = *dev-buf++; - dev-buf_len--; - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags -OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - w |= *dev-buf++ 8; - dev-buf_len--; - } - } - } else { + if (!dev-buf_len) { if (stat OMAP_I2C_STAT_XRDY) dev_err(dev-dev, XRDY IRQ while no @@ -882,6 +867,20 @@ complete: break; } + w = *dev-buf++; + dev-buf_len--; + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide
[PATCHv8 17/22] i2c: omap: get rid of the complete label
From: Felipe Balbi ba...@ti.com we can ack stat and complete the command from the errata handling itself. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 16 +--- 1 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f33bc5a..5d4bad4 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -775,6 +775,17 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev) if (stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); + if (stat OMAP_I2C_STAT_NACK) { + dev-cmd_err |= OMAP_I2C_STAT_NACK; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + } + + if (stat OMAP_I2C_STAT_AL) { + dev_err(dev-dev, Arbitration lost\n); + dev-cmd_err |= OMAP_I2C_STAT_AL; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + } + return -EIO; } @@ -875,7 +886,6 @@ omap_i2c_isr(int this_irq, void *dev_id) goto out; } -complete: if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); @@ -938,7 +948,7 @@ complete: ret = omap_i2c_transmit_data(dev, num_bytes, true); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) - goto complete; + goto out; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); continue; @@ -954,7 +964,7 @@ complete: ret = omap_i2c_transmit_data(dev, num_bytes, false); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) - goto complete; + goto out; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY); continue; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 07/22] i2c: omap: improve i462 errata handling
From: Felipe Balbi ba...@ti.com Make it not depend on ISR's local variables in order to make it easier to re-factor the transmit data loop. Also since we are waiting for XUDF(Transmitter underflow) just before writing data lets not flag the underflow. This is anyways going to go once we write the data. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 43 1 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 815577b..fb57221 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -725,27 +725,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id) * data to DATA_REG. Otherwise some data bytes can be lost while transferring * them from the memory to the I2C interface. */ -static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) +static int errata_omap3_i462(struct omap_i2c_dev *dev) { unsigned long timeout = 1; + u16 stat; - while (--timeout !(*stat OMAP_I2C_STAT_XUDF)) { - if (*stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { + do { + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + if (stat OMAP_I2C_STAT_XUDF) + break; + + if (stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - return -ETIMEDOUT; + return -EIO; } cpu_relax(); - *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); - } + } while (--timeout); if (!timeout) { dev_err(dev-dev, timeout waiting on XUDF bit\n); return 0; } - *err |= OMAP_I2C_STAT_XUDF; return 0; } @@ -903,9 +906,16 @@ complete: } } - if ((dev-errata I2C_OMAP_ERRATA_I462) - errata_omap3_i462(dev, stat, err)) - goto complete; + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + stat = omap_i2c_read_reg(dev, + OMAP_I2C_STAT_REG); + + if (ret 0) + goto complete; + } omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } @@ -943,9 +953,16 @@ complete: } } - if ((dev-errata I2C_OMAP_ERRATA_I462) - errata_omap3_i462(dev, stat, err)) - goto complete; + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + stat = omap_i2c_read_reg(dev, + OMAP_I2C_STAT_REG); + + if (ret 0) + goto complete; + } omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 01/22] i2c: omap: switch to devm_* API
From: Felipe Balbi ba...@ti.com that helps deleting some boiler plate code and lets driver-core manage our resources for us. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 41 - 1 files changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5d19a49..2d9b03c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -943,7 +943,7 @@ omap_i2c_probe(struct platform_device *pdev) { struct omap_i2c_dev *dev; struct i2c_adapter *adap; - struct resource *mem, *irq, *ioarea; + struct resource *mem, *irq; struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; @@ -962,17 +962,16 @@ omap_i2c_probe(struct platform_device *pdev) return -ENODEV; } - ioarea = request_mem_region(mem-start, resource_size(mem), - pdev-name); - if (!ioarea) { - dev_err(pdev-dev, I2C region already claimed\n); - return -EBUSY; + dev = devm_kzalloc(pdev-dev, sizeof(struct omap_i2c_dev), GFP_KERNEL); + if (!dev) { + dev_err(pdev-dev, Menory allocation failed\n); + return -ENOMEM; } - dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL); - if (!dev) { - r = -ENOMEM; - goto err_release_region; + dev-base = devm_request_and_ioremap(pdev-dev, mem); + if (!dev-base) { + dev_err(pdev-dev, I2C region already claimed\n); + return -ENOMEM; } match = of_match_device(of_match_ptr(omap_i2c_of_match), pdev-dev); @@ -995,11 +994,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-dev = pdev-dev; dev-irq = irq-start; - dev-base = ioremap(mem-start, resource_size(mem)); - if (!dev-base) { - r = -ENOMEM; - goto err_free_mem; - } platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); @@ -1057,7 +1051,8 @@ omap_i2c_probe(struct platform_device *pdev) isr = (dev-rev OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : omap_i2c_isr; - r = request_irq(dev-irq, isr, IRQF_NO_SUSPEND, pdev-name, dev); + r = devm_request_irq(pdev-dev, dev-irq, isr, IRQF_NO_SUSPEND, +pdev-name, dev); if (r) { dev_err(dev-dev, failure requesting irq %i\n, dev-irq); @@ -1081,7 +1076,7 @@ omap_i2c_probe(struct platform_device *pdev) r = i2c_add_numbered_adapter(adap); if (r) { dev_err(dev-dev, failure adding adapter\n); - goto err_free_irq; + goto err_unuse_clocks; } of_i2c_register_devices(adap); @@ -1090,18 +1085,12 @@ omap_i2c_probe(struct platform_device *pdev) return 0; -err_free_irq: - free_irq(dev-irq, dev); err_unuse_clocks: omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); pm_runtime_put(dev-dev); - iounmap(dev-base); pm_runtime_disable(pdev-dev); err_free_mem: platform_set_drvdata(pdev, NULL); - kfree(dev); -err_release_region: - release_mem_region(mem-start, resource_size(mem)); return r; } @@ -1109,12 +1098,10 @@ err_release_region: static int __devexit omap_i2c_remove(struct platform_device *pdev) { struct omap_i2c_dev *dev = platform_get_drvdata(pdev); - struct resource *mem; int ret; platform_set_drvdata(pdev, NULL); - free_irq(dev-irq, dev); i2c_del_adapter(dev-adapter); ret = pm_runtime_get_sync(pdev-dev); if (IS_ERR_VALUE(ret)) @@ -1123,10 +1110,6 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev) omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); - iounmap(dev-base); - kfree(dev); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem-start, resource_size(mem)); return 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 04/22] i2c: omap: add blank lines
From: Felipe Balbi ba...@ti.com trivial patch to aid readability. No functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0dd647a..30ea63c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -786,6 +786,7 @@ complete: dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; } + /* * ProDB0017052: Clear ARDY bit twice */ @@ -798,6 +799,7 @@ complete: omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } + if (stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { u8 num_bytes = 1; @@ -844,6 +846,7 @@ complete: stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); continue; } + if (stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) { u8 num_bytes = 1; if (dev-fifo_size) { @@ -891,10 +894,12 @@ complete: stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); continue; } + if (stat OMAP_I2C_STAT_ROVR) { dev_err(dev-dev, Receive overrun\n); dev-cmd_err |= OMAP_I2C_STAT_ROVR; } + if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); dev-cmd_err |= OMAP_I2C_STAT_XUDF; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 18/22] i2c: omap: remove redundant status read
Currently omap_i2c_ack_stat doesn't use the stat variable. After the read of the I2C_STAT_REG it is not used. Remove the redundant read of the status register. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5d4bad4..498a462 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -946,7 +946,6 @@ omap_i2c_isr(int this_irq, void *dev_id) num_bytes = dev-buf_len; ret = omap_i2c_transmit_data(dev, num_bytes, true); - stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) goto out; @@ -962,7 +961,6 @@ omap_i2c_isr(int this_irq, void *dev_id) num_bytes = dev-threshold; ret = omap_i2c_transmit_data(dev, num_bytes, false); - stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) goto out; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 06/22] i2c: omap: split out [XR]DR and [XR]RDY
From: Felipe Balbi ba...@ti.com While they do pretty much the same thing, there are a few peculiarities. Specially WRT erratas, it's best to split those out and re-factor the read/write loop to another function which both cases call. This last part will be done on another patch. While at that, also avoid an unncessary register read since dev-fifo_len will always contain the correct amount of data to be transferred. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 126 ++--- 1 files changed, 92 insertions(+), 34 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f24eae9..815577b 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -801,36 +801,62 @@ complete: return IRQ_HANDLED; } - if (stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { + if (stat OMAP_I2C_STAT_RDR) { u8 num_bytes = 1; + if (dev-fifo_size) + num_bytes = dev-buf_len; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, + RDR IRQ while no data +requested\n); + break; + } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags + OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } + } + if (dev-errata I2C_OMAP_ERRATA_I207) i2c_omap_errata_i207(dev, stat); - if (dev-fifo_size) { - if (stat OMAP_I2C_STAT_RRDY) - num_bytes = dev-fifo_size; - else/* read RXSTAT on RDR interrupt */ - num_bytes = (omap_i2c_read_reg(dev, - OMAP_I2C_BUFSTAT_REG) -8) 0x3F; - } + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); + continue; + } + + if (stat OMAP_I2C_STAT_RRDY) { + u8 num_bytes = 1; + + if (dev-fifo_size) + num_bytes = dev-fifo_size; + while (num_bytes--) { if (!dev-buf_len) { - if (stat OMAP_I2C_STAT_RRDY) - dev_err(dev-dev, + dev_err(dev-dev, RRDY IRQ while no data -requested\n); - if (stat OMAP_I2C_STAT_RDR) - dev_err(dev-dev, - RDR IRQ while no data -requested\n); +requested\n); break; } w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); *dev-buf++ = w; dev-buf_len--; + /* * Data reg in 2430, omap3 and * omap4 is 8 bit wide @@ -843,36 +869,68 @@ complete: } } } - omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | - OMAP_I2C_STAT_RDR)); + + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY); continue; } - if (stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR
[PATCHv8 10/22] i2c: omap: ack IRQ in parts
From: Felipe Balbi ba...@ti.com According to flow diagrams on OMAP TRMs, we should ACK the IRQ as they happen. Signed-off-by: Felipe Balbi ba...@ti.com [Ack the stat OMAP_I2C_STAT_AL in case of arbitration lost] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 28 1 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4045134..bac1f11 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -850,21 +850,19 @@ omap_i2c_isr(int this_irq, void *dev_id) } complete: - /* -* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be -* acked after the data operation is complete. -* Ref: TRM SWPU114Q Figure 18-31 -*/ - omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat - ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - - if (stat OMAP_I2C_STAT_NACK) + if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; + } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } /* @@ -941,12 +939,18 @@ complete: if (stat OMAP_I2C_STAT_ROVR) { dev_err(dev-dev, Receive overrun\n); - dev-cmd_err |= OMAP_I2C_STAT_ROVR; + err |= OMAP_I2C_STAT_ROVR; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); - dev-cmd_err |= OMAP_I2C_STAT_XUDF; + err |= OMAP_I2C_STAT_XUDF; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } } while (stat); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 00/23]I2C big cleanup
Changes since v1: - removed tabification on patch 6/17 - removed dev_err() which was introduced on patch 09/17 Changes since v2: - do not set full fifo depth in the RDR interrupt. - some changelog updates. - rebase to the Wolfram's tree. Changes since v3: - Remove a redundant read of status register - Read the dev-buf_len variable instead of the register as the information of the remaining bytes is there. Changes since v4: - Ack the arbitration lost. - Rebase to the i2c-embedded/for-next branch. Changes since v5: - Rebase to latest mainline - Added some more cleanup patches so as have a consolidated series. Changes since v6: - Fix comments on setting the pdev to NULL. - Trivial changelog update Changes since v7: - Remove a patch as the code is getting changed anyways - Changelogs update. Previous discussions can be found here http://www.spinics.net/lists/linux-i2c/msg09764.html This is the cleanup only series. Tested on omap4sdp and 3430sdp. The following changes since commit 55d512e245bc7699a8800e23df1a24195dd08217: Linux 3.6-rc5 (2012-09-08 16:43:45 -0700) are available in the git repository at: git://gitorious.org/linus-tree/linus-tree.git for_3.7/i2c/big_cleanups Felipe Balbi (22): i2c: omap: switch to devm_* API i2c: omap: simplify num_bytes handling i2c: omap: decrease indentation level on data handling i2c: omap: add blank lines i2c: omap: simplify omap_i2c_ack_stat() i2c: omap: split out [XR]DR and [XR]RDY i2c: omap: improve i462 errata handling i2c: omap: re-factor receive/transmit data loop i2c: omap: switch over to do {} while loop i2c: omap: ack IRQ in parts i2c: omap: switch to platform_get_irq() i2c: omap: bus: add a receiver flag i2c: omap: simplify errata check i2c: omap: always return IRQ_HANDLED i2c: omap: simplify IRQ exit path i2c: omap: resize fifos before each message i2c: omap: get rid of the complete label i2c: omap: always return IRQ_HANDLED i2c: omap: switch to threaded IRQ support i2c: omap: remove unnecessary pm_runtime_suspended check i2c: omap: switch over to autosuspend API i2c: omap: sanitize exit path Shubhrajyoti D (1): i2c: omap: remove redundant status read drivers/i2c/busses/i2c-omap.c | 442 + 1 files changed, 271 insertions(+), 171 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 20/22] i2c: omap: remove unnecessary pm_runtime_suspended check
From: Felipe Balbi ba...@ti.com before starting any messages we call pm_runtime_get_sync() which will make sure that by the time we program a transfer and our IRQ handler gets called, we're not suspended anymore. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 049331c..6d38a57 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -883,9 +883,6 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) u16 stat; int err = 0, count = 0; - if (pm_runtime_suspended(dev-dev)) - return IRQ_NONE; - spin_lock_irqsave(dev-lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 21/22] i2c: omap: switch over to autosuspend API
From: Felipe Balbi ba...@ti.com this helps us reduce unnecessary pm transitions in case we have another i2c message starting soon. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 12 ++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 6d38a57..122f517 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -55,6 +55,9 @@ /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) +/* timeout for pm runtime autosuspend */ +#define OMAP_I2C_PM_TIMEOUT1000/* ms */ + /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ enum { OMAP_I2C_REV_REG = 0, @@ -645,7 +648,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_wait_for_bb(dev); out: - pm_runtime_put(dev-dev); + pm_runtime_mark_last_busy(dev-dev); + pm_runtime_put_autosuspend(dev-dev); return r; } @@ -1113,6 +1117,9 @@ omap_i2c_probe(struct platform_device *pdev) dev-regs = (u8 *)reg_map_ip_v1; pm_runtime_enable(dev-dev); + pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(dev-dev); + r = pm_runtime_get_sync(dev-dev); if (IS_ERR_VALUE(r)) goto err_free_mem; @@ -1190,7 +1197,8 @@ omap_i2c_probe(struct platform_device *pdev) of_i2c_register_devices(adap); - pm_runtime_put(dev-dev); + pm_runtime_mark_last_busy(dev-dev); + pm_runtime_put_autosuspend(dev-dev); return 0; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 16/22] i2c: omap: resize fifos before each message
From: Felipe Balbi ba...@ti.com This patch will try to avoid the usage of draining feature by reconfiguring the FIFO the start condition of each message based on the message's size. By doing that, we will be better utilizing the FIFO when doing big transfers. While at that also drop the now unneeded check for dev-buf_len as we always know the amount of data to be transmitted. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 83 + 1 files changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4af123f..f33bc5a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -193,6 +193,7 @@ struct omap_i2c_dev { u8 *regs; size_t buf_len; struct i2c_adapter adapter; + u8 threshold; u8 fifo_size; /* use as flag and value * fifo_size==0 implies no fifo * if set, should be trsh+1 @@ -418,13 +419,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - if (dev-fifo_size) { - /* Note: setup required fifo size - 1. RTRSH and XTRSH */ - buf = (dev-fifo_size - 1) 8 | OMAP_I2C_BUF_RXFIF_CLR | - (dev-fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR; - omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - } - /* Take the I2C module out of reset: */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); @@ -462,6 +456,45 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev) return 0; } +static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) +{ + u16 buf; + + if (dev-flags OMAP_I2C_FLAG_NO_FIFO) + return; + + /* +* Set up notification threshold based on message size. We're doing +* this to try and avoid draining feature as much as possible. Whenever +* we have big messages to transfer (bigger than our total fifo size) +* then we might use draining feature to transfer the remaining bytes. +*/ + + dev-threshold = clamp(size, (u8) 1, dev-fifo_size); + + buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); + + if (is_rx) { + /* Clear RX Threshold */ + buf = ~(0x3f 8); + buf |= ((dev-threshold - 1) 8) | OMAP_I2C_BUF_RXFIF_CLR; + } else { + /* Clear TX Threshold */ + buf = ~0x3f; + buf |= (dev-threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR; + } + + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); + + if (dev-rev OMAP_I2C_REV_ON_3630_4430) + dev-b_hw = 1; /* Enable hardware fixes */ + + /* calculate wakeup latency constraint for MPU */ + if (dev-set_mpu_wkup_lat != NULL) + dev-latency = (100 * dev-threshold) / + (1000 * dev-speed / 8); +} + /* * Low level master read/write transaction. */ @@ -478,6 +511,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (msg-len == 0) return -EINVAL; + dev-receiver = !!(msg-flags I2C_M_RD); + omap_i2c_resize_fifo(dev, msg-len, dev-receiver); + omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg-addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ @@ -493,7 +529,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, INIT_COMPLETION(dev-cmd_complete); dev-cmd_err = 0; - dev-receiver = !!(msg-flags I2C_M_RD); w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -760,12 +795,6 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, u16 w; while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, %s without data, - is_rdr ? RDR : RRDY); - break; - } - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); *dev-buf++ = w; dev-buf_len--; @@ -775,10 +804,8 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, * omap4 is 8 bit wide */ if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } + *dev-buf++ = w 8; + dev-buf_len
[PATCHv8 13/22] i2c: omap: simplify errata check
From: Felipe Balbi ba...@ti.com omap_i2c_dev is allocated with kzalloc(), so we need not initialize b_hw to zero. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 3be147a..7918e48 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1095,9 +1095,7 @@ omap_i2c_probe(struct platform_device *pdev) dev-fifo_size = (dev-fifo_size / 2); - if (dev-rev = OMAP_I2C_REV_ON_3630_4430) - dev-b_hw = 0; /* Disable hardware fixes */ - else + if (dev-rev OMAP_I2C_REV_ON_3630_4430) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 12/22] i2c: omap: bus: add a receiver flag
From: Felipe Balbi ba...@ti.com that way we can ignore TX IRQs while in receiver mode and ignore RX IRQs while in transmitter mode. Signed-off-by: Felipe Balbi ba...@ti.com [Remove unnecessary braces] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0da8169..3be147a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -199,6 +199,7 @@ struct omap_i2c_dev { */ u8 rev; unsignedb_hw:1; /* bad h/w fixes */ + unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ u16 pscstate; u16 scllstate; @@ -492,6 +493,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, INIT_COMPLETION(dev-cmd_complete); dev-cmd_err = 0; + dev-receiver = !!(msg-flags I2C_M_RD); w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -837,6 +839,12 @@ omap_i2c_isr(int this_irq, void *dev_id) stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); stat = bits; + /* If we're in receiver mode, ignore XDR/XRDY */ + if (dev-receiver) + stat = ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY); + else + stat = ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY); + if (!stat) { /* my work here is done */ return IRQ_HANDLED; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 14/22] i2c: omap: always return IRQ_HANDLED
From: Felipe Balbi ba...@ti.com Always return IRQ_HANDLED otherwise we could get our IRQ line disabled due to many spurious IRQs. Signed-off-by: Felipe Balbi ba...@ti.com [Trivial changes to commitlogs] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7918e48..96fd528 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -962,7 +962,7 @@ complete: } } while (stat); - return count ? IRQ_HANDLED : IRQ_NONE; + return IRQ_HANDLED; } static const struct i2c_algorithm omap_i2c_algo = { -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 19/22] i2c: omap: switch to threaded IRQ support
From: Felipe Balbi ba...@ti.com for OMAP2, we can easily switch over to threaded IRQs on the I2C driver. This will allow us to spend less time in hardirq context. Signed-off-by: Felipe Balbi ba...@ti.com [Trivial formating changes] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 43 +++- 1 files changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 498a462..049331c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -176,6 +176,7 @@ enum { #define I2C_OMAP_ERRATA_I462 (1 1) struct omap_i2c_dev { + spinlock_t lock; /* IRQ synchronization */ struct device *dev; void __iomem*base; /* virtual */ int irq; @@ -854,9 +855,30 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, } static irqreturn_t -omap_i2c_isr(int this_irq, void *dev_id) +omap_i2c_isr(int irq, void *dev_id) { struct omap_i2c_dev *dev = dev_id; + irqreturn_t ret = IRQ_HANDLED; + u16 mask; + u16 stat; + + spin_lock(dev-lock); + mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(dev-lock); + + return ret; +} + +static irqreturn_t +omap_i2c_isr_thread(int this_irq, void *dev_id) +{ + struct omap_i2c_dev *dev = dev_id; + unsigned long flags; u16 bits; u16 stat; int err = 0, count = 0; @@ -864,6 +886,7 @@ omap_i2c_isr(int this_irq, void *dev_id) if (pm_runtime_suspended(dev-dev)) return IRQ_NONE; + spin_lock_irqsave(dev-lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); @@ -877,6 +900,7 @@ omap_i2c_isr(int this_irq, void *dev_id) if (!stat) { /* my work here is done */ + spin_unlock_irqrestore(dev-lock, flags); return IRQ_HANDLED; } @@ -985,6 +1009,8 @@ omap_i2c_isr(int this_irq, void *dev_id) out: omap_i2c_complete_cmd(dev, err); + spin_unlock_irqrestore(dev-lock, flags); + return IRQ_HANDLED; } @@ -1028,7 +1054,6 @@ omap_i2c_probe(struct platform_device *pdev) struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; - irq_handler_t isr; int irq; int r; @@ -1078,6 +1103,8 @@ omap_i2c_probe(struct platform_device *pdev) dev-dev = pdev-dev; dev-irq = irq; + spin_lock_init(dev-lock); + platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); @@ -1130,10 +1157,14 @@ omap_i2c_probe(struct platform_device *pdev) /* reset ASAP, clearing any IRQs */ omap_i2c_init(dev); - isr = (dev-rev OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : - omap_i2c_isr; - r = devm_request_irq(pdev-dev, dev-irq, isr, IRQF_NO_SUSPEND, -pdev-name, dev); + if (dev-rev OMAP_I2C_OMAP1_REV_2) + r = devm_request_irq(pdev-dev, dev-irq, omap_i2c_omap1_isr, + IRQF_NO_SUSPEND, pdev-name, dev); + else + r = devm_request_threaded_irq(pdev-dev, dev-irq, + omap_i2c_isr, omap_i2c_isr_thread, + IRQF_NO_SUSPEND | IRQF_ONESHOT, + pdev-name, dev); if (r) { dev_err(dev-dev, failure requesting irq %i\n, dev-irq); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 08/22] i2c: omap: re-factor receive/transmit data loop
From: Felipe Balbi ba...@ti.com re-factor the common parts to a separate function, so that code is easier to read and understand. No functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 204 1 files changed, 82 insertions(+), 122 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fb57221..2c7d7cc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -752,12 +752,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev) return 0; } +static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, + bool is_rdr) +{ + u16 w; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, %s without data, + is_rdr ? RDR : RRDY); + break; + } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } + } +} + +static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, + bool is_xdr) +{ + u16 w; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, %s without data, + is_xdr ? XDR : XRDY); + break; + } + + w = *dev-buf++; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + w |= *dev-buf++ 8; + dev-buf_len--; + } + } + + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + if (ret 0) + return ret; + } + + omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); + } + + return 0; +} + static irqreturn_t omap_i2c_isr(int this_irq, void *dev_id) { struct omap_i2c_dev *dev = dev_id; u16 bits; - u16 stat, w; + u16 stat; int err, count = 0; if (pm_runtime_suspended(dev-dev)) @@ -810,30 +879,7 @@ complete: if (dev-fifo_size) num_bytes = dev-buf_len; - while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, - RDR IRQ while no data -requested\n); - break; - } - - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); - *dev-buf++ = w; - dev-buf_len--; - - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags - OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } - } - } + omap_i2c_receive_data(dev, num_bytes, true); if (dev-errata I2C_OMAP_ERRATA_I207) i2c_omap_errata_i207(dev, stat); @@ -848,77 +894,22 @@ complete: if (dev-fifo_size) num_bytes = dev-fifo_size; - while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, - RRDY IRQ while no data -requested\n); - break
[PATCHv8 22/22] i2c: omap: sanitize exit path
From: Felipe Balbi ba...@ti.com move the goto out label one line down, so that it can be used when stat is read as zero. All other exits, can be done with a break statement. While at that, also break out as soon as we complete draining IRQ, since at that time we know we transferred everything there was to be transferred. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 26 +- 1 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 122f517..b149e32 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -901,27 +901,26 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) if (!stat) { /* my work here is done */ - spin_unlock_irqrestore(dev-lock, flags); - return IRQ_HANDLED; + goto out; } dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - goto out; + break; } if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); - goto out; + break; } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); - goto out; + break; } /* @@ -934,7 +933,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_ARDY)); - goto out; + break; } if (stat OMAP_I2C_STAT_RDR) { @@ -949,7 +948,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) i2c_omap_errata_i207(dev, stat); omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); - continue; + break; } if (stat OMAP_I2C_STAT_RRDY) { @@ -972,10 +971,10 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) ret = omap_i2c_transmit_data(dev, num_bytes, true); if (ret 0) - goto out; + break; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); - continue; + break; } if (stat OMAP_I2C_STAT_XRDY) { @@ -987,7 +986,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) ret = omap_i2c_transmit_data(dev, num_bytes, false); if (ret 0) - goto out; + break; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY); continue; @@ -997,19 +996,20 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) dev_err(dev-dev, Receive overrun\n); err |= OMAP_I2C_STAT_ROVR; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); - goto out; + break; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); err |= OMAP_I2C_STAT_XUDF; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); - goto out; + break; } } while (stat); -out: omap_i2c_complete_cmd(dev, err); + +out: spin_unlock_irqrestore(dev-lock, flags); return IRQ_HANDLED; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv8 09/22] i2c: omap: switch over to do {} while loop
From: Felipe Balbi ba...@ti.com this will make sure that we execute at least once. No functional changes otherwise. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 20 ++-- 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2c7d7cc..4045134 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -827,20 +827,28 @@ omap_i2c_isr(int this_irq, void *dev_id) struct omap_i2c_dev *dev = dev_id; u16 bits; u16 stat; - int err, count = 0; + int err = 0, count = 0; if (pm_runtime_suspended(dev-dev)) return IRQ_NONE; - bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); - while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) bits) { + do { + bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + stat = bits; + + if (!stat) { + /* my work here is done */ + return IRQ_HANDLED; + } + dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - break; + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } - err = 0; complete: /* * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be @@ -940,7 +948,7 @@ complete: dev_err(dev-dev, Transmit underflow\n); dev-cmd_err |= OMAP_I2C_STAT_XUDF; } - } + } while (stat); return count ? IRQ_HANDLED : IRQ_NONE; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] ARM: OMAP: rx51: Fix a section mismatch warn
rx51_si4713_dev is referenced only from rx51_init_si4713. So the memory for rx51_si4713_dev can be safely freed after init. Also it references rx51_si4713_board_info which is __initdata_or_module. fixes the below warning. WARNING: vmlinux.o(.data+0x30958): Section mismatch in reference from the variable rx51_si4713_dev to the (unknown reference) .init.data:(unknown) The variable rx51_si4713_dev references the (unknown reference) __initdata (unknown) If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console Reported-by: Wolfram Sang w.s...@pengutronix.de Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- arch/arm/mach-omap2/board-rx51-peripherals.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index df2534d..e2e1148 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -743,7 +743,7 @@ static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = .subdev_board_info = rx51_si4713_board_info, }; -static struct platform_device rx51_si4713_dev = { +static struct platform_device rx51_si4713_dev __initdata_or_module = { .name = radio-si4713, .id = -1, .dev= { -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] spi: omap2-mcspi: Cleanup the omap2_mcspi_txrx_dma function
Currently in omap2_mcspi_txrx_dma the tx and the rx support is interleaved. Make the rx related code in omap2_mcspi_rx_dma and the tx related code omap2_mcspi_tx_dma and call the functions. While at it remove the braces in the if statements which has only one line. Also fix [foo * bar to foo *bar] warn for the rx and tx variables. Only a cleanup no functional change. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 256 +++-- 1 files changed, 144 insertions(+), 112 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 1c1dd34..dd8fc88 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -315,49 +315,27 @@ static void omap2_mcspi_tx_callback(void *data) omap2_mcspi_set_dma_req(spi, 0, 0); } -static unsigned -omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) +static void omap2_mcspi_tx_dma(struct spi_device *spi, + struct spi_transfer *xfer, + struct dma_slave_config cfg) { struct omap2_mcspi *mcspi; - struct omap2_mcspi_cs *cs = spi-controller_state; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - int word_len, element_count; - int elements = 0; - u32 l; u8 * rx; const u8* tx; void __iomem*chstat_reg; - struct dma_slave_config cfg; - enum dma_slave_buswidth width; - unsigned es; + struct omap2_mcspi_cs *cs = spi-controller_state; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; - l = mcspi_cached_chconf0(spi); + count = xfer-len; + rx = xfer-rx_buf; + tx = xfer-tx_buf; chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; - if (cs-word_len = 8) { - width = DMA_SLAVE_BUSWIDTH_1_BYTE; - es = 1; - } else if (cs-word_len = 16) { - width = DMA_SLAVE_BUSWIDTH_2_BYTES; - es = 2; - } else { - width = DMA_SLAVE_BUSWIDTH_4_BYTES; - es = 4; - } - - memset(cfg, 0, sizeof(cfg)); - cfg.src_addr = cs-phys + OMAP2_MCSPI_RX0; - cfg.dst_addr = cs-phys + OMAP2_MCSPI_TX0; - cfg.src_addr_width = width; - cfg.dst_addr_width = width; - cfg.src_maxburst = 1; - cfg.dst_maxburst = 1; - - if (xfer-tx_buf mcspi_dma-dma_tx) { + if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; @@ -368,7 +346,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) sg_dma_len(sg) = xfer-len; tx = dmaengine_prep_slave_sg(mcspi_dma-dma_tx, sg, 1, - DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (tx) { tx-callback = omap2_mcspi_tx_callback; tx-callback_param = spi; @@ -377,8 +355,50 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) /* FIXME: fall back to PIO? */ } } + dma_async_issue_pending(mcspi_dma-dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 1); - if (xfer-rx_buf mcspi_dma-dma_rx) { + wait_for_completion(mcspi_dma-dma_tx_completion); + dma_unmap_single(mcspi-dev, xfer-tx_dma, count, +DMA_TO_DEVICE); + + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) 0) + dev_err(spi-dev, TXS timed out\n); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) 0) + dev_err(spi-dev, EOT timed out\n); + } +} + +static unsigned +omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, + struct dma_slave_config cfg, + unsigned es) +{ + struct omap2_mcspi *mcspi; + struct omap2_mcspi_dma *mcspi_dma; + unsigned intcount; + u32 l; + int elements = 0; + int word_len, element_count; + struct omap2_mcspi_cs *cs = spi-controller_state; + mcspi = spi_master_get_devdata(spi-master); + mcspi_dma = mcspi-dma_channels[spi-chip_select]; + count = xfer-len; + word_len = cs-word_len; + l = mcspi_cached_chconf0(spi); + + if (word_len = 8
[PATCHv7 00/23]I2C big cleanup
Changes since v1: - removed tabification on patch 6/17 - removed dev_err() which was introduced on patch 09/17 Changes since v2: - do not set full fifo depth in the RDR interrupt. - some changelog updates. - rebase to the Wolfram's tree. Changes since v3: - Remove a redundant read of status register - Read the dev-buf_len variable instead of the register as the information of the remaining bytes is there. Changes since v4: - Ack the arbitration lost. - Rebase to the i2c-embedded/for-next branch. Changes since v5: - Rebase to latest mainline - Added some more cleanup patches so as have a consolidated series. Changes since v6: - Fix comments on setting the pdev to NULL. - Trivial changelog update Previous discussions can be found here http://www.spinics.net/lists/linux-i2c/msg09482.html This is the cleanup only series. Tested on omap4sdp and 3430sdp. The following changes since commit 55d512e245bc7699a8800e23df1a24195dd08217: Linux 3.6-rc5 (2012-09-08 16:43:45 -0700) are available in the git repository at: git://gitorious.org/linus-tree/linus-tree.git for_3.7/i2c/big_cleanup Felipe Balbi (22): i2c: omap: switch to devm_* API i2c: omap: simplify num_bytes handling i2c: omap: decrease indentation level on data handling i2c: omap: add blank lines i2c: omap: simplify omap_i2c_ack_stat() i2c: omap: split out [XR]DR and [XR]RDY i2c: omap: improve i462 errata handling i2c: omap: re-factor receive/transmit data loop i2c: omap: switch over to do {} while loop i2c: omap: ack IRQ in parts i2c: omap: switch to platform_get_irq() i2c: omap: bus: add a receiver flag i2c: omap: simplify errata check i2c: omap: always return IRQ_HANDLED i2c: omap: simplify IRQ exit path i2c: omap: resize fifos before each message i2c: omap: get rid of the complete label i2c: omap: always return IRQ_HANDLED i2c: omap: switch to threaded IRQ support i2c: omap: remove unnecessary pm_runtime_suspended check i2c: omap: switch over to autosuspend API i2c: omap: sanitize exit path Shubhrajyoti D (1): i2c: omap: remove redundant status read drivers/i2c/busses/i2c-omap.c | 442 + 1 files changed, 271 insertions(+), 171 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 05/23] i2c: omap: simplify omap_i2c_ack_stat()
From: Felipe Balbi ba...@ti.com stat BIT(1) is the same as BIT(1), so let's simplify things a bit by removing stat from all omap_i2c_ack_stat() calls. Code snippet (extremely simplified): if (stat NACK) { ... omap_i2c_ack_stat(dev, stat NACK); } if (stat RDR) { ... omap_i2c_ack_stat(dev, stat RDR); } and so on. The tricky place is only WRT errata handling, for example: if (*stat (NACK | AL)) { omap_i2c_ack_stat(dev, *stat (XRDY | XDR)); ... } but in this case, the errata says we must clear XRDY and XDR if that errata triggers, so if they just got enabled or not, it doesn't matter. Another tricky place is RDR | RRDY (likewise for XDR | XRDY): if (stat (RDR | RRDY)) { ... omap_i2c_ack_stat(dev, stat (RDR | RRDY)); } again here there will be no issues because those IRQs never fire simultaneously and one will only after after we have handled the previous, that's because the same FIFO is used anyway and we won't shift data into FIFO until we tell the IP hey, I'm done with the FIFO, you can shift more data Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com [Added the explaination from the discurssion to the commit logs] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 19 ++- 1 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 30ea63c..f24eae9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -731,7 +731,7 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) while (--timeout !(*stat OMAP_I2C_STAT_XUDF)) { if (*stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { - omap_i2c_ack_stat(dev, *stat (OMAP_I2C_STAT_XRDY | + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); return -ETIMEDOUT; } @@ -792,10 +792,11 @@ complete: */ if (stat (OMAP_I2C_STAT_ARDY | OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { - omap_i2c_ack_stat(dev, stat - (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | - OMAP_I2C_STAT_ARDY)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | + OMAP_I2C_STAT_RDR | + OMAP_I2C_STAT_XRDY | + OMAP_I2C_STAT_XDR | + OMAP_I2C_STAT_ARDY)); omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } @@ -842,8 +843,8 @@ complete: } } } - omap_i2c_ack_stat(dev, - stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | + OMAP_I2C_STAT_RDR)); continue; } @@ -890,8 +891,8 @@ complete: omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } - omap_i2c_ack_stat(dev, - stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); + omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | + OMAP_I2C_STAT_XDR)); continue; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 06/23] i2c: omap: split out [XR]DR and [XR]RDY
From: Felipe Balbi ba...@ti.com While they do pretty much the same thing, there are a few peculiarities. Specially WRT erratas, it's best to split those out and re-factor the read/write loop to another function which both cases call. This last part will be done on another patch. While at that, also avoid an unncessary register read since dev-fifo_len will always contain the correct amount of data to be transferred. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 126 ++--- 1 files changed, 92 insertions(+), 34 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f24eae9..815577b 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -801,36 +801,62 @@ complete: return IRQ_HANDLED; } - if (stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { + if (stat OMAP_I2C_STAT_RDR) { u8 num_bytes = 1; + if (dev-fifo_size) + num_bytes = dev-buf_len; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, + RDR IRQ while no data +requested\n); + break; + } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags + OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } + } + if (dev-errata I2C_OMAP_ERRATA_I207) i2c_omap_errata_i207(dev, stat); - if (dev-fifo_size) { - if (stat OMAP_I2C_STAT_RRDY) - num_bytes = dev-fifo_size; - else/* read RXSTAT on RDR interrupt */ - num_bytes = (omap_i2c_read_reg(dev, - OMAP_I2C_BUFSTAT_REG) -8) 0x3F; - } + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); + continue; + } + + if (stat OMAP_I2C_STAT_RRDY) { + u8 num_bytes = 1; + + if (dev-fifo_size) + num_bytes = dev-fifo_size; + while (num_bytes--) { if (!dev-buf_len) { - if (stat OMAP_I2C_STAT_RRDY) - dev_err(dev-dev, + dev_err(dev-dev, RRDY IRQ while no data -requested\n); - if (stat OMAP_I2C_STAT_RDR) - dev_err(dev-dev, - RDR IRQ while no data -requested\n); +requested\n); break; } w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); *dev-buf++ = w; dev-buf_len--; + /* * Data reg in 2430, omap3 and * omap4 is 8 bit wide @@ -843,36 +869,68 @@ complete: } } } - omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_RRDY | - OMAP_I2C_STAT_RDR)); + + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RRDY); continue; } - if (stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR
[PATCHv7 04/23] i2c: omap: add blank lines
From: Felipe Balbi ba...@ti.com trivial patch to aid readability. No functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |5 + 1 files changed, 5 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0dd647a..30ea63c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -786,6 +786,7 @@ complete: dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; } + /* * ProDB0017052: Clear ARDY bit twice */ @@ -798,6 +799,7 @@ complete: omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } + if (stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)) { u8 num_bytes = 1; @@ -844,6 +846,7 @@ complete: stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); continue; } + if (stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)) { u8 num_bytes = 1; if (dev-fifo_size) { @@ -891,10 +894,12 @@ complete: stat (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); continue; } + if (stat OMAP_I2C_STAT_ROVR) { dev_err(dev-dev, Receive overrun\n); dev-cmd_err |= OMAP_I2C_STAT_ROVR; } + if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); dev-cmd_err |= OMAP_I2C_STAT_XUDF; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 03/23] i2c: omap: decrease indentation level on data handling
From: Felipe Balbi ba...@ti.com The patch intends to decrease the indentation level on the data handling by using the fact that else of if (dev-buf_len) is same as if (!dev-buf_len) if (dev-buf_len) { aaa; } else { bbb; break; } to if (!dev-buf_len) { bbb; break; } aaa; Hence no functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 63 - 1 files changed, 31 insertions(+), 32 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 236cb38..0dd647a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -813,22 +813,7 @@ complete: 8) 0x3F; } while (num_bytes--) { - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); - if (dev-buf_len) { - *dev-buf++ = w; - dev-buf_len--; - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags -OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } - } - } else { + if (!dev-buf_len) { if (stat OMAP_I2C_STAT_RRDY) dev_err(dev-dev, RRDY IRQ while no data @@ -839,6 +824,21 @@ complete: requested\n); break; } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags + OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } } omap_i2c_ack_stat(dev, stat (OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR)); @@ -855,22 +855,7 @@ complete: 0x3F; } while (num_bytes--) { - w = 0; - if (dev-buf_len) { - w = *dev-buf++; - dev-buf_len--; - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags -OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - w |= *dev-buf++ 8; - dev-buf_len--; - } - } - } else { + if (!dev-buf_len) { if (stat OMAP_I2C_STAT_XRDY) dev_err(dev-dev, XRDY IRQ while no @@ -882,6 +867,20 @@ complete: break; } + w = *dev-buf++; + dev-buf_len--; + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide
[PATCHv7 13/23] i2c: omap: simplify errata check
From: Felipe Balbi ba...@ti.com omap_i2c_dev is allocated with kzalloc(), so we need not initialize b_hw to zero. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 3be147a..7918e48 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1095,9 +1095,7 @@ omap_i2c_probe(struct platform_device *pdev) dev-fifo_size = (dev-fifo_size / 2); - if (dev-rev = OMAP_I2C_REV_ON_3630_4430) - dev-b_hw = 0; /* Disable hardware fixes */ - else + if (dev-rev OMAP_I2C_REV_ON_3630_4430) dev-b_hw = 1; /* Enable hardware fixes */ /* calculate wakeup latency constraint for MPU */ -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 07/23] i2c: omap: improve i462 errata handling
From: Felipe Balbi ba...@ti.com Make it not depend on ISR's local variables in order to make it easier to re-factor the transmit data loop. Also since we are waiting for XUDF(Transmitter underflow) just before writing data lets not flag the underflow. This is anyways going to go once we write the data. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 43 1 files changed, 30 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 815577b..fb57221 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -725,27 +725,30 @@ omap_i2c_omap1_isr(int this_irq, void *dev_id) * data to DATA_REG. Otherwise some data bytes can be lost while transferring * them from the memory to the I2C interface. */ -static int errata_omap3_i462(struct omap_i2c_dev *dev, u16 *stat, int *err) +static int errata_omap3_i462(struct omap_i2c_dev *dev) { unsigned long timeout = 1; + u16 stat; - while (--timeout !(*stat OMAP_I2C_STAT_XUDF)) { - if (*stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { + do { + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + if (stat OMAP_I2C_STAT_XUDF) + break; + + if (stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - return -ETIMEDOUT; + return -EIO; } cpu_relax(); - *stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); - } + } while (--timeout); if (!timeout) { dev_err(dev-dev, timeout waiting on XUDF bit\n); return 0; } - *err |= OMAP_I2C_STAT_XUDF; return 0; } @@ -903,9 +906,16 @@ complete: } } - if ((dev-errata I2C_OMAP_ERRATA_I462) - errata_omap3_i462(dev, stat, err)) - goto complete; + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + stat = omap_i2c_read_reg(dev, + OMAP_I2C_STAT_REG); + + if (ret 0) + goto complete; + } omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } @@ -943,9 +953,16 @@ complete: } } - if ((dev-errata I2C_OMAP_ERRATA_I462) - errata_omap3_i462(dev, stat, err)) - goto complete; + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + stat = omap_i2c_read_reg(dev, + OMAP_I2C_STAT_REG); + + if (ret 0) + goto complete; + } omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 10/23] i2c: omap: ack IRQ in parts
From: Felipe Balbi ba...@ti.com According to flow diagrams on OMAP TRMs, we should ACK the IRQ as they happen. Signed-off-by: Felipe Balbi ba...@ti.com [Ack the stat OMAP_I2C_STAT_AL in case of arbitration lost] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 28 1 files changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4045134..bac1f11 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -850,21 +850,19 @@ omap_i2c_isr(int this_irq, void *dev_id) } complete: - /* -* Ack the stat in one go, but [R/X]DR and [R/X]RDY should be -* acked after the data operation is complete. -* Ref: TRM SWPU114Q Figure 18-31 -*/ - omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, stat - ~(OMAP_I2C_STAT_RRDY | OMAP_I2C_STAT_RDR | - OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); - - if (stat OMAP_I2C_STAT_NACK) + if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; + } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } /* @@ -941,12 +939,18 @@ complete: if (stat OMAP_I2C_STAT_ROVR) { dev_err(dev-dev, Receive overrun\n); - dev-cmd_err |= OMAP_I2C_STAT_ROVR; + err |= OMAP_I2C_STAT_ROVR; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); - dev-cmd_err |= OMAP_I2C_STAT_XUDF; + err |= OMAP_I2C_STAT_XUDF; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } } while (stat); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 09/23] i2c: omap: switch over to do {} while loop
From: Felipe Balbi ba...@ti.com this will make sure that we execute at least once. No functional changes otherwise. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 20 ++-- 1 files changed, 14 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2c7d7cc..4045134 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -827,20 +827,28 @@ omap_i2c_isr(int this_irq, void *dev_id) struct omap_i2c_dev *dev = dev_id; u16 bits; u16 stat; - int err, count = 0; + int err = 0, count = 0; if (pm_runtime_suspended(dev-dev)) return IRQ_NONE; - bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); - while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) bits) { + do { + bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + stat = bits; + + if (!stat) { + /* my work here is done */ + return IRQ_HANDLED; + } + dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - break; + omap_i2c_complete_cmd(dev, err); + return IRQ_HANDLED; } - err = 0; complete: /* * Ack the stat in one go, but [R/X]DR and [R/X]RDY should be @@ -940,7 +948,7 @@ complete: dev_err(dev-dev, Transmit underflow\n); dev-cmd_err |= OMAP_I2C_STAT_XUDF; } - } + } while (stat); return count ? IRQ_HANDLED : IRQ_NONE; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 11/23] i2c: omap: switch to platform_get_irq()
From: Felipe Balbi ba...@ti.com that's a nice helper from drivers core which will give us the exact IRQ number, instead of a pointer to an IRQ resource. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 12 +++- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index bac1f11..0da8169 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -993,11 +993,12 @@ omap_i2c_probe(struct platform_device *pdev) { struct omap_i2c_dev *dev; struct i2c_adapter *adap; - struct resource *mem, *irq; + struct resource *mem; struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; irq_handler_t isr; + int irq; int r; /* NOTE: driver uses the static register mapping */ @@ -1006,10 +1007,11 @@ omap_i2c_probe(struct platform_device *pdev) dev_err(pdev-dev, no mem resource?\n); return -ENODEV; } - irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq) { + + irq = platform_get_irq(pdev, 0); + if (irq 0) { dev_err(pdev-dev, no irq resource?\n); - return -ENODEV; + return irq; } dev = devm_kzalloc(pdev-dev, sizeof(struct omap_i2c_dev), GFP_KERNEL); @@ -1043,7 +1045,7 @@ omap_i2c_probe(struct platform_device *pdev) } dev-dev = pdev-dev; - dev-irq = irq-start; + dev-irq = irq; platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 14/23] i2c: omap: always return IRQ_HANDLED
From: Felipe Balbi ba...@ti.com Always return IRQ_HANDLED otherwise we could get our IRQ line disabled due to many spurious IRQs. Signed-off-by: Felipe Balbi ba...@ti.com [Trivial changes to commitlogs] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7918e48..96fd528 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -962,7 +962,7 @@ complete: } } while (stat); - return count ? IRQ_HANDLED : IRQ_NONE; + return IRQ_HANDLED; } static const struct i2c_algorithm omap_i2c_algo = { -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 08/23] i2c: omap: re-factor receive/transmit data loop
From: Felipe Balbi ba...@ti.com re-factor the common parts to a separate function, so that code is easier to read and understand. No functional changes. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 204 1 files changed, 82 insertions(+), 122 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index fb57221..2c7d7cc 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -752,12 +752,81 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev) return 0; } +static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, + bool is_rdr) +{ + u16 w; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, %s without data, + is_rdr ? RDR : RRDY); + break; + } + + w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); + *dev-buf++ = w; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + *dev-buf++ = w 8; + dev-buf_len--; + } + } + } +} + +static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, + bool is_xdr) +{ + u16 w; + + while (num_bytes--) { + if (!dev-buf_len) { + dev_err(dev-dev, %s without data, + is_xdr ? XDR : XRDY); + break; + } + + w = *dev-buf++; + dev-buf_len--; + + /* +* Data reg in 2430, omap3 and +* omap4 is 8 bit wide +*/ + if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { + if (dev-buf_len) { + w |= *dev-buf++ 8; + dev-buf_len--; + } + } + + if (dev-errata I2C_OMAP_ERRATA_I462) { + int ret; + + ret = errata_omap3_i462(dev); + if (ret 0) + return ret; + } + + omap_i2c_write_reg(dev, OMAP_I2C_DATA_REG, w); + } + + return 0; +} + static irqreturn_t omap_i2c_isr(int this_irq, void *dev_id) { struct omap_i2c_dev *dev = dev_id; u16 bits; - u16 stat, w; + u16 stat; int err, count = 0; if (pm_runtime_suspended(dev-dev)) @@ -810,30 +879,7 @@ complete: if (dev-fifo_size) num_bytes = dev-buf_len; - while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, - RDR IRQ while no data -requested\n); - break; - } - - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); - *dev-buf++ = w; - dev-buf_len--; - - /* -* Data reg in 2430, omap3 and -* omap4 is 8 bit wide -*/ - if (dev-flags - OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } - } - } + omap_i2c_receive_data(dev, num_bytes, true); if (dev-errata I2C_OMAP_ERRATA_I207) i2c_omap_errata_i207(dev, stat); @@ -848,77 +894,22 @@ complete: if (dev-fifo_size) num_bytes = dev-fifo_size; - while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, - RRDY IRQ while no data -requested\n); - break
[PATCHv7 01/23] i2c: omap: switch to devm_* API
From: Felipe Balbi ba...@ti.com that helps deleting some boiler plate code and lets driver-core manage our resources for us. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 41 - 1 files changed, 12 insertions(+), 29 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5d19a49..2d9b03c 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -943,7 +943,7 @@ omap_i2c_probe(struct platform_device *pdev) { struct omap_i2c_dev *dev; struct i2c_adapter *adap; - struct resource *mem, *irq, *ioarea; + struct resource *mem, *irq; struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; @@ -962,17 +962,16 @@ omap_i2c_probe(struct platform_device *pdev) return -ENODEV; } - ioarea = request_mem_region(mem-start, resource_size(mem), - pdev-name); - if (!ioarea) { - dev_err(pdev-dev, I2C region already claimed\n); - return -EBUSY; + dev = devm_kzalloc(pdev-dev, sizeof(struct omap_i2c_dev), GFP_KERNEL); + if (!dev) { + dev_err(pdev-dev, Menory allocation failed\n); + return -ENOMEM; } - dev = kzalloc(sizeof(struct omap_i2c_dev), GFP_KERNEL); - if (!dev) { - r = -ENOMEM; - goto err_release_region; + dev-base = devm_request_and_ioremap(pdev-dev, mem); + if (!dev-base) { + dev_err(pdev-dev, I2C region already claimed\n); + return -ENOMEM; } match = of_match_device(of_match_ptr(omap_i2c_of_match), pdev-dev); @@ -995,11 +994,6 @@ omap_i2c_probe(struct platform_device *pdev) dev-dev = pdev-dev; dev-irq = irq-start; - dev-base = ioremap(mem-start, resource_size(mem)); - if (!dev-base) { - r = -ENOMEM; - goto err_free_mem; - } platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); @@ -1057,7 +1051,8 @@ omap_i2c_probe(struct platform_device *pdev) isr = (dev-rev OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : omap_i2c_isr; - r = request_irq(dev-irq, isr, IRQF_NO_SUSPEND, pdev-name, dev); + r = devm_request_irq(pdev-dev, dev-irq, isr, IRQF_NO_SUSPEND, +pdev-name, dev); if (r) { dev_err(dev-dev, failure requesting irq %i\n, dev-irq); @@ -1081,7 +1076,7 @@ omap_i2c_probe(struct platform_device *pdev) r = i2c_add_numbered_adapter(adap); if (r) { dev_err(dev-dev, failure adding adapter\n); - goto err_free_irq; + goto err_unuse_clocks; } of_i2c_register_devices(adap); @@ -1090,18 +1085,12 @@ omap_i2c_probe(struct platform_device *pdev) return 0; -err_free_irq: - free_irq(dev-irq, dev); err_unuse_clocks: omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); pm_runtime_put(dev-dev); - iounmap(dev-base); pm_runtime_disable(pdev-dev); err_free_mem: platform_set_drvdata(pdev, NULL); - kfree(dev); -err_release_region: - release_mem_region(mem-start, resource_size(mem)); return r; } @@ -1109,12 +1098,10 @@ err_release_region: static int __devexit omap_i2c_remove(struct platform_device *pdev) { struct omap_i2c_dev *dev = platform_get_drvdata(pdev); - struct resource *mem; int ret; platform_set_drvdata(pdev, NULL); - free_irq(dev-irq, dev); i2c_del_adapter(dev-adapter); ret = pm_runtime_get_sync(pdev-dev); if (IS_ERR_VALUE(ret)) @@ -1123,10 +1110,6 @@ static int __devexit omap_i2c_remove(struct platform_device *pdev) omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); pm_runtime_put(pdev-dev); pm_runtime_disable(pdev-dev); - iounmap(dev-base); - kfree(dev); - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem-start, resource_size(mem)); return 0; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 16/23] i2c: omap: resize fifos before each message
From: Felipe Balbi ba...@ti.com This patch will try to avoid the usage of draining feature by reconfiguring the FIFO the start condition of each message based on the message's size. By doing that, we will be better utilizing the FIFO when doing big transfers. While at that also drop the now unneeded check for dev-buf_len as we always know the amount of data to be transmitted. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 83 + 1 files changed, 51 insertions(+), 32 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4af123f..f33bc5a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -193,6 +193,7 @@ struct omap_i2c_dev { u8 *regs; size_t buf_len; struct i2c_adapter adapter; + u8 threshold; u8 fifo_size; /* use as flag and value * fifo_size==0 implies no fifo * if set, should be trsh+1 @@ -418,13 +419,6 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) omap_i2c_write_reg(dev, OMAP_I2C_SCLL_REG, scll); omap_i2c_write_reg(dev, OMAP_I2C_SCLH_REG, sclh); - if (dev-fifo_size) { - /* Note: setup required fifo size - 1. RTRSH and XTRSH */ - buf = (dev-fifo_size - 1) 8 | OMAP_I2C_BUF_RXFIF_CLR | - (dev-fifo_size - 1) | OMAP_I2C_BUF_TXFIF_CLR; - omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); - } - /* Take the I2C module out of reset: */ omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, OMAP_I2C_CON_EN); @@ -462,6 +456,45 @@ static int omap_i2c_wait_for_bb(struct omap_i2c_dev *dev) return 0; } +static void omap_i2c_resize_fifo(struct omap_i2c_dev *dev, u8 size, bool is_rx) +{ + u16 buf; + + if (dev-flags OMAP_I2C_FLAG_NO_FIFO) + return; + + /* +* Set up notification threshold based on message size. We're doing +* this to try and avoid draining feature as much as possible. Whenever +* we have big messages to transfer (bigger than our total fifo size) +* then we might use draining feature to transfer the remaining bytes. +*/ + + dev-threshold = clamp(size, (u8) 1, dev-fifo_size); + + buf = omap_i2c_read_reg(dev, OMAP_I2C_BUF_REG); + + if (is_rx) { + /* Clear RX Threshold */ + buf = ~(0x3f 8); + buf |= ((dev-threshold - 1) 8) | OMAP_I2C_BUF_RXFIF_CLR; + } else { + /* Clear TX Threshold */ + buf = ~0x3f; + buf |= (dev-threshold - 1) | OMAP_I2C_BUF_TXFIF_CLR; + } + + omap_i2c_write_reg(dev, OMAP_I2C_BUF_REG, buf); + + if (dev-rev OMAP_I2C_REV_ON_3630_4430) + dev-b_hw = 1; /* Enable hardware fixes */ + + /* calculate wakeup latency constraint for MPU */ + if (dev-set_mpu_wkup_lat != NULL) + dev-latency = (100 * dev-threshold) / + (1000 * dev-speed / 8); +} + /* * Low level master read/write transaction. */ @@ -478,6 +511,9 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, if (msg-len == 0) return -EINVAL; + dev-receiver = !!(msg-flags I2C_M_RD); + omap_i2c_resize_fifo(dev, msg-len, dev-receiver); + omap_i2c_write_reg(dev, OMAP_I2C_SA_REG, msg-addr); /* REVISIT: Could the STB bit of I2C_CON be used with probing? */ @@ -493,7 +529,6 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, INIT_COMPLETION(dev-cmd_complete); dev-cmd_err = 0; - dev-receiver = !!(msg-flags I2C_M_RD); w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -760,12 +795,6 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, u16 w; while (num_bytes--) { - if (!dev-buf_len) { - dev_err(dev-dev, %s without data, - is_rdr ? RDR : RRDY); - break; - } - w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); *dev-buf++ = w; dev-buf_len--; @@ -775,10 +804,8 @@ static void omap_i2c_receive_data(struct omap_i2c_dev *dev, u8 num_bytes, * omap4 is 8 bit wide */ if (dev-flags OMAP_I2C_FLAG_16BIT_DATA_REG) { - if (dev-buf_len) { - *dev-buf++ = w 8; - dev-buf_len--; - } + *dev-buf++ = w 8; + dev-buf_len
[PATCHv7 19/23] i2c: omap: always return IRQ_HANDLED
From: Felipe Balbi ba...@ti.com even if our clocks are disabled, we still handled the IRQ, so we should return IRQ_HANDLED. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 498a462..4a696bd 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -862,7 +862,7 @@ omap_i2c_isr(int this_irq, void *dev_id) int err = 0, count = 0; if (pm_runtime_suspended(dev-dev)) - return IRQ_NONE; + return IRQ_HANDLED; do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 20/23] i2c: omap: switch to threaded IRQ support
From: Felipe Balbi ba...@ti.com for OMAP2, we can easily switch over to threaded IRQs on the I2C driver. This will allow us to spend less time in hardirq context. Signed-off-by: Felipe Balbi ba...@ti.com [Trivial formating changes] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 43 +++- 1 files changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 4a696bd..e391370 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -176,6 +176,7 @@ enum { #define I2C_OMAP_ERRATA_I462 (1 1) struct omap_i2c_dev { + spinlock_t lock; /* IRQ synchronization */ struct device *dev; void __iomem*base; /* virtual */ int irq; @@ -854,9 +855,30 @@ static int omap_i2c_transmit_data(struct omap_i2c_dev *dev, u8 num_bytes, } static irqreturn_t -omap_i2c_isr(int this_irq, void *dev_id) +omap_i2c_isr(int irq, void *dev_id) { struct omap_i2c_dev *dev = dev_id; + irqreturn_t ret = IRQ_HANDLED; + u16 mask; + u16 stat; + + spin_lock(dev-lock); + mask = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); + stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); + + if (stat mask) + ret = IRQ_WAKE_THREAD; + + spin_unlock(dev-lock); + + return ret; +} + +static irqreturn_t +omap_i2c_isr_thread(int this_irq, void *dev_id) +{ + struct omap_i2c_dev *dev = dev_id; + unsigned long flags; u16 bits; u16 stat; int err = 0, count = 0; @@ -864,6 +886,7 @@ omap_i2c_isr(int this_irq, void *dev_id) if (pm_runtime_suspended(dev-dev)) return IRQ_HANDLED; + spin_lock_irqsave(dev-lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); @@ -877,6 +900,7 @@ omap_i2c_isr(int this_irq, void *dev_id) if (!stat) { /* my work here is done */ + spin_unlock_irqrestore(dev-lock, flags); return IRQ_HANDLED; } @@ -985,6 +1009,8 @@ omap_i2c_isr(int this_irq, void *dev_id) out: omap_i2c_complete_cmd(dev, err); + spin_unlock_irqrestore(dev-lock, flags); + return IRQ_HANDLED; } @@ -1028,7 +1054,6 @@ omap_i2c_probe(struct platform_device *pdev) struct omap_i2c_bus_platform_data *pdata = pdev-dev.platform_data; struct device_node *node = pdev-dev.of_node; const struct of_device_id *match; - irq_handler_t isr; int irq; int r; @@ -1078,6 +1103,8 @@ omap_i2c_probe(struct platform_device *pdev) dev-dev = pdev-dev; dev-irq = irq; + spin_lock_init(dev-lock); + platform_set_drvdata(pdev, dev); init_completion(dev-cmd_complete); @@ -1130,10 +1157,14 @@ omap_i2c_probe(struct platform_device *pdev) /* reset ASAP, clearing any IRQs */ omap_i2c_init(dev); - isr = (dev-rev OMAP_I2C_OMAP1_REV_2) ? omap_i2c_omap1_isr : - omap_i2c_isr; - r = devm_request_irq(pdev-dev, dev-irq, isr, IRQF_NO_SUSPEND, -pdev-name, dev); + if (dev-rev OMAP_I2C_OMAP1_REV_2) + r = devm_request_irq(pdev-dev, dev-irq, omap_i2c_omap1_isr, + IRQF_NO_SUSPEND, pdev-name, dev); + else + r = devm_request_threaded_irq(pdev-dev, dev-irq, + omap_i2c_isr, omap_i2c_isr_thread, + IRQF_NO_SUSPEND | IRQF_ONESHOT, + pdev-name, dev); if (r) { dev_err(dev-dev, failure requesting irq %i\n, dev-irq); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 12/23] i2c: omap: bus: add a receiver flag
From: Felipe Balbi ba...@ti.com that way we can ignore TX IRQs while in receiver mode and ignore RX IRQs while in transmitter mode. Signed-off-by: Felipe Balbi ba...@ti.com [Remove unnecessary braces] Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |8 1 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 0da8169..3be147a 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -199,6 +199,7 @@ struct omap_i2c_dev { */ u8 rev; unsignedb_hw:1; /* bad h/w fixes */ + unsignedreceiver:1; /* true when we're in receiver mode */ u16 iestate;/* Saved interrupt register */ u16 pscstate; u16 scllstate; @@ -492,6 +493,7 @@ static int omap_i2c_xfer_msg(struct i2c_adapter *adap, INIT_COMPLETION(dev-cmd_complete); dev-cmd_err = 0; + dev-receiver = !!(msg-flags I2C_M_RD); w = OMAP_I2C_CON_EN | OMAP_I2C_CON_MST | OMAP_I2C_CON_STT; @@ -837,6 +839,12 @@ omap_i2c_isr(int this_irq, void *dev_id) stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); stat = bits; + /* If we're in receiver mode, ignore XDR/XRDY */ + if (dev-receiver) + stat = ~(OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_XRDY); + else + stat = ~(OMAP_I2C_STAT_RDR | OMAP_I2C_STAT_RRDY); + if (!stat) { /* my work here is done */ return IRQ_HANDLED; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 18/23] i2c: omap: remove redundant status read
Remove the redundant read of the status register. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |2 -- 1 files changed, 0 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 5d4bad4..498a462 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -946,7 +946,6 @@ omap_i2c_isr(int this_irq, void *dev_id) num_bytes = dev-buf_len; ret = omap_i2c_transmit_data(dev, num_bytes, true); - stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) goto out; @@ -962,7 +961,6 @@ omap_i2c_isr(int this_irq, void *dev_id) num_bytes = dev-threshold; ret = omap_i2c_transmit_data(dev, num_bytes, false); - stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) goto out; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 21/23] i2c: omap: remove unnecessary pm_runtime_suspended check
From: Felipe Balbi ba...@ti.com before starting any messages we call pm_runtime_get_sync() which will make sure that by the time we program a transfer and our IRQ handler gets called, we're not suspended anymore. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |3 --- 1 files changed, 0 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index e391370..6d38a57 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -883,9 +883,6 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) u16 stat; int err = 0, count = 0; - if (pm_runtime_suspended(dev-dev)) - return IRQ_HANDLED; - spin_lock_irqsave(dev-lock, flags); do { bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 23/23] i2c: omap: sanitize exit path
From: Felipe Balbi ba...@ti.com move the goto out label one line down, so that it can be used when stat is read as zero. All other exits, can be done with a break statement. While at that, also break out as soon as we complete draining IRQ, since at that time we know we transferred everything there was to be transferred. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 26 +- 1 files changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 122f517..b149e32 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -901,27 +901,26 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) if (!stat) { /* my work here is done */ - spin_unlock_irqrestore(dev-lock, flags); - return IRQ_HANDLED; + goto out; } dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - goto out; + break; } if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); - goto out; + break; } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); - goto out; + break; } /* @@ -934,7 +933,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_ARDY)); - goto out; + break; } if (stat OMAP_I2C_STAT_RDR) { @@ -949,7 +948,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) i2c_omap_errata_i207(dev, stat); omap_i2c_ack_stat(dev, OMAP_I2C_STAT_RDR); - continue; + break; } if (stat OMAP_I2C_STAT_RRDY) { @@ -972,10 +971,10 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) ret = omap_i2c_transmit_data(dev, num_bytes, true); if (ret 0) - goto out; + break; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); - continue; + break; } if (stat OMAP_I2C_STAT_XRDY) { @@ -987,7 +986,7 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) ret = omap_i2c_transmit_data(dev, num_bytes, false); if (ret 0) - goto out; + break; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY); continue; @@ -997,19 +996,20 @@ omap_i2c_isr_thread(int this_irq, void *dev_id) dev_err(dev-dev, Receive overrun\n); err |= OMAP_I2C_STAT_ROVR; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); - goto out; + break; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); err |= OMAP_I2C_STAT_XUDF; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); - goto out; + break; } } while (stat); -out: omap_i2c_complete_cmd(dev, err); + +out: spin_unlock_irqrestore(dev-lock, flags); return IRQ_HANDLED; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 22/23] i2c: omap: switch over to autosuspend API
From: Felipe Balbi ba...@ti.com this helps us reduce unnecessary pm transitions in case we have another i2c message starting soon. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 12 ++-- 1 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 6d38a57..122f517 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -55,6 +55,9 @@ /* timeout waiting for the controller to respond */ #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) +/* timeout for pm runtime autosuspend */ +#define OMAP_I2C_PM_TIMEOUT1000/* ms */ + /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ enum { OMAP_I2C_REV_REG = 0, @@ -645,7 +648,8 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) omap_i2c_wait_for_bb(dev); out: - pm_runtime_put(dev-dev); + pm_runtime_mark_last_busy(dev-dev); + pm_runtime_put_autosuspend(dev-dev); return r; } @@ -1113,6 +1117,9 @@ omap_i2c_probe(struct platform_device *pdev) dev-regs = (u8 *)reg_map_ip_v1; pm_runtime_enable(dev-dev); + pm_runtime_set_autosuspend_delay(dev-dev, OMAP_I2C_PM_TIMEOUT); + pm_runtime_use_autosuspend(dev-dev); + r = pm_runtime_get_sync(dev-dev); if (IS_ERR_VALUE(r)) goto err_free_mem; @@ -1190,7 +1197,8 @@ omap_i2c_probe(struct platform_device *pdev) of_i2c_register_devices(adap); - pm_runtime_put(dev-dev); + pm_runtime_mark_last_busy(dev-dev); + pm_runtime_put_autosuspend(dev-dev); return 0; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 15/23] i2c: omap: simplify IRQ exit path
From: Felipe Balbi ba...@ti.com instead of having multiple return points, use a goto statement to make that clearer. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 20 1 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 96fd528..4af123f 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -853,24 +853,21 @@ omap_i2c_isr(int this_irq, void *dev_id) dev_dbg(dev-dev, IRQ (ISR = 0x%04x)\n, stat); if (count++ == 100) { dev_warn(dev-dev, Too much work in one IRQ\n); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } complete: if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_AL) { dev_err(dev-dev, Arbitration lost\n); err |= OMAP_I2C_STAT_AL; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_AL); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } /* @@ -883,8 +880,7 @@ complete: OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR | OMAP_I2C_STAT_ARDY)); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_RDR) { @@ -949,19 +945,19 @@ complete: dev_err(dev-dev, Receive overrun\n); err |= OMAP_I2C_STAT_ROVR; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_ROVR); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } if (stat OMAP_I2C_STAT_XUDF) { dev_err(dev-dev, Transmit underflow\n); err |= OMAP_I2C_STAT_XUDF; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XUDF); - omap_i2c_complete_cmd(dev, err); - return IRQ_HANDLED; + goto out; } } while (stat); +out: + omap_i2c_complete_cmd(dev, err); return IRQ_HANDLED; } -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 17/23] i2c: omap: get rid of the complete label
From: Felipe Balbi ba...@ti.com we can ack stat and complete the command from the errata handling itself. Signed-off-by: Felipe Balbi ba...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c | 16 +--- 1 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f33bc5a..5d4bad4 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -775,6 +775,17 @@ static int errata_omap3_i462(struct omap_i2c_dev *dev) if (stat (OMAP_I2C_STAT_NACK | OMAP_I2C_STAT_AL)) { omap_i2c_ack_stat(dev, (OMAP_I2C_STAT_XRDY | OMAP_I2C_STAT_XDR)); + if (stat OMAP_I2C_STAT_NACK) { + dev-cmd_err |= OMAP_I2C_STAT_NACK; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + } + + if (stat OMAP_I2C_STAT_AL) { + dev_err(dev-dev, Arbitration lost\n); + dev-cmd_err |= OMAP_I2C_STAT_AL; + omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); + } + return -EIO; } @@ -875,7 +886,6 @@ omap_i2c_isr(int this_irq, void *dev_id) goto out; } -complete: if (stat OMAP_I2C_STAT_NACK) { err |= OMAP_I2C_STAT_NACK; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_NACK); @@ -938,7 +948,7 @@ complete: ret = omap_i2c_transmit_data(dev, num_bytes, true); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) - goto complete; + goto out; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XDR); continue; @@ -954,7 +964,7 @@ complete: ret = omap_i2c_transmit_data(dev, num_bytes, false); stat = omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); if (ret 0) - goto complete; + goto out; omap_i2c_ack_stat(dev, OMAP_I2C_STAT_XRDY); continue; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv7 02/23] i2c: omap: simplify num_bytes handling
From: Felipe Balbi ba...@ti.com trivial patch, no functional changes If the fifo is disabled or fifo_size is 0 the num_bytes is set to 1. Else it is set to fifo_size or in case of a draining interrupt the remaining bytes in the buff stat. So the zero check is redundant and can be safely optimised. Signed-off-by: Felipe Balbi ba...@ti.com Reviewed-by : Santosh Shilimkar santosh.shilim...@ti.com Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/i2c/busses/i2c-omap.c |6 ++ 1 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 2d9b03c..236cb38 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -812,8 +812,7 @@ complete: OMAP_I2C_BUFSTAT_REG) 8) 0x3F; } - while (num_bytes) { - num_bytes--; + while (num_bytes--) { w = omap_i2c_read_reg(dev, OMAP_I2C_DATA_REG); if (dev-buf_len) { *dev-buf++ = w; @@ -855,8 +854,7 @@ complete: OMAP_I2C_BUFSTAT_REG) 0x3F; } - while (num_bytes) { - num_bytes--; + while (num_bytes--) { w = 0; if (dev-buf_len) { w = *dev-buf++; -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] spi: omap2-mcspi: Cleanup the omap2_mcspi_txrx_dma function
Currently in omap2_mcspi_txrx_dma has the rx and the rx support interleaved. Make the rx related code in omap2_mcspi_rx_dma and the tx related code omap2_mcspi_tx_dma and call functions. While at it also remove the braces in the if statements which has only one line. Also fix [foo * bar to foo *bar] warn for the rx and tx variables. Only a cleanup no functional change. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 256 +++-- 1 files changed, 144 insertions(+), 112 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 1c1dd34..dd8fc88 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -315,49 +315,27 @@ static void omap2_mcspi_tx_callback(void *data) omap2_mcspi_set_dma_req(spi, 0, 0); } -static unsigned -omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) +static void omap2_mcspi_tx_dma(struct spi_device *spi, + struct spi_transfer *xfer, + struct dma_slave_config cfg) { struct omap2_mcspi *mcspi; - struct omap2_mcspi_cs *cs = spi-controller_state; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - int word_len, element_count; - int elements = 0; - u32 l; u8 * rx; const u8* tx; void __iomem*chstat_reg; - struct dma_slave_config cfg; - enum dma_slave_buswidth width; - unsigned es; + struct omap2_mcspi_cs *cs = spi-controller_state; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; - l = mcspi_cached_chconf0(spi); + count = xfer-len; + rx = xfer-rx_buf; + tx = xfer-tx_buf; chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; - if (cs-word_len = 8) { - width = DMA_SLAVE_BUSWIDTH_1_BYTE; - es = 1; - } else if (cs-word_len = 16) { - width = DMA_SLAVE_BUSWIDTH_2_BYTES; - es = 2; - } else { - width = DMA_SLAVE_BUSWIDTH_4_BYTES; - es = 4; - } - - memset(cfg, 0, sizeof(cfg)); - cfg.src_addr = cs-phys + OMAP2_MCSPI_RX0; - cfg.dst_addr = cs-phys + OMAP2_MCSPI_TX0; - cfg.src_addr_width = width; - cfg.dst_addr_width = width; - cfg.src_maxburst = 1; - cfg.dst_maxburst = 1; - - if (xfer-tx_buf mcspi_dma-dma_tx) { + if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; @@ -368,7 +346,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) sg_dma_len(sg) = xfer-len; tx = dmaengine_prep_slave_sg(mcspi_dma-dma_tx, sg, 1, - DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (tx) { tx-callback = omap2_mcspi_tx_callback; tx-callback_param = spi; @@ -377,8 +355,50 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) /* FIXME: fall back to PIO? */ } } + dma_async_issue_pending(mcspi_dma-dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 1); - if (xfer-rx_buf mcspi_dma-dma_rx) { + wait_for_completion(mcspi_dma-dma_tx_completion); + dma_unmap_single(mcspi-dev, xfer-tx_dma, count, +DMA_TO_DEVICE); + + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) 0) + dev_err(spi-dev, TXS timed out\n); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) 0) + dev_err(spi-dev, EOT timed out\n); + } +} + +static unsigned +omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, + struct dma_slave_config cfg, + unsigned es) +{ + struct omap2_mcspi *mcspi; + struct omap2_mcspi_dma *mcspi_dma; + unsigned intcount; + u32 l; + int elements = 0; + int word_len, element_count; + struct omap2_mcspi_cs *cs = spi-controller_state; + mcspi = spi_master_get_devdata(spi-master); + mcspi_dma = mcspi-dma_channels[spi-chip_select]; + count = xfer-len; + word_len = cs-word_len; + l = mcspi_cached_chconf0(spi); + + if (word_len = 8
[PATCH] spi: omap2-mcspi: Cleanup the omap2_mcspi_txrx_dma function
Currently in omap2_mcspi_txrx_dma the tx and the rx support is interleaved. Make the rx related code in omap2_mcspi_rx_dma and the tx related code omap2_mcspi_tx_dma and call the functions. While at it remove the braces in the if statements which has only one line. Also fix [foo * bar to foo *bar] warn for the rx and tx variables. Only a cleanup no functional change. Signed-off-by: Shubhrajyoti D shubhrajy...@ti.com --- drivers/spi/spi-omap2-mcspi.c | 256 +++-- 1 files changed, 144 insertions(+), 112 deletions(-) diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index 1c1dd34..dd8fc88 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c @@ -315,49 +315,27 @@ static void omap2_mcspi_tx_callback(void *data) omap2_mcspi_set_dma_req(spi, 0, 0); } -static unsigned -omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) +static void omap2_mcspi_tx_dma(struct spi_device *spi, + struct spi_transfer *xfer, + struct dma_slave_config cfg) { struct omap2_mcspi *mcspi; - struct omap2_mcspi_cs *cs = spi-controller_state; struct omap2_mcspi_dma *mcspi_dma; unsigned intcount; - int word_len, element_count; - int elements = 0; - u32 l; u8 * rx; const u8* tx; void __iomem*chstat_reg; - struct dma_slave_config cfg; - enum dma_slave_buswidth width; - unsigned es; + struct omap2_mcspi_cs *cs = spi-controller_state; mcspi = spi_master_get_devdata(spi-master); mcspi_dma = mcspi-dma_channels[spi-chip_select]; - l = mcspi_cached_chconf0(spi); + count = xfer-len; + rx = xfer-rx_buf; + tx = xfer-tx_buf; chstat_reg = cs-base + OMAP2_MCSPI_CHSTAT0; - if (cs-word_len = 8) { - width = DMA_SLAVE_BUSWIDTH_1_BYTE; - es = 1; - } else if (cs-word_len = 16) { - width = DMA_SLAVE_BUSWIDTH_2_BYTES; - es = 2; - } else { - width = DMA_SLAVE_BUSWIDTH_4_BYTES; - es = 4; - } - - memset(cfg, 0, sizeof(cfg)); - cfg.src_addr = cs-phys + OMAP2_MCSPI_RX0; - cfg.dst_addr = cs-phys + OMAP2_MCSPI_TX0; - cfg.src_addr_width = width; - cfg.dst_addr_width = width; - cfg.src_maxburst = 1; - cfg.dst_maxburst = 1; - - if (xfer-tx_buf mcspi_dma-dma_tx) { + if (mcspi_dma-dma_tx) { struct dma_async_tx_descriptor *tx; struct scatterlist sg; @@ -368,7 +346,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) sg_dma_len(sg) = xfer-len; tx = dmaengine_prep_slave_sg(mcspi_dma-dma_tx, sg, 1, - DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (tx) { tx-callback = omap2_mcspi_tx_callback; tx-callback_param = spi; @@ -377,8 +355,50 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) /* FIXME: fall back to PIO? */ } } + dma_async_issue_pending(mcspi_dma-dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 1); - if (xfer-rx_buf mcspi_dma-dma_rx) { + wait_for_completion(mcspi_dma-dma_tx_completion); + dma_unmap_single(mcspi-dev, xfer-tx_dma, count, +DMA_TO_DEVICE); + + /* for TX_ONLY mode, be sure all words have shifted out */ + if (rx == NULL) { + if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_TXS) 0) + dev_err(spi-dev, TXS timed out\n); + else if (mcspi_wait_for_reg_bit(chstat_reg, + OMAP2_MCSPI_CHSTAT_EOT) 0) + dev_err(spi-dev, EOT timed out\n); + } +} + +static unsigned +omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, + struct dma_slave_config cfg, + unsigned es) +{ + struct omap2_mcspi *mcspi; + struct omap2_mcspi_dma *mcspi_dma; + unsigned intcount; + u32 l; + int elements = 0; + int word_len, element_count; + struct omap2_mcspi_cs *cs = spi-controller_state; + mcspi = spi_master_get_devdata(spi-master); + mcspi_dma = mcspi-dma_channels[spi-chip_select]; + count = xfer-len; + word_len = cs-word_len; + l = mcspi_cached_chconf0(spi); + + if (word_len = 8
[PATCHv2 0/3] spi: omap2-mcspi: spi cleanups
This patch does the following Calls the pm_runtime_* functions directly. Remove the MOD_REG_BIT macro usage thereby removiing un-needed branch. At remove dont use the autosuspend runtime calls. Changes from v1: Fix the comments on changelogs. Add acks to the patches. The following changes since commit 23dcfa61bac244e1200ff9ad19c6e9144dcb6bb5: Merge branch 'akpm' (Andrew's patch-bomb) (2012-08-21 17:22:22 -0700) are available in the git repository at: git://gitorious.org/linus-tree/linus-tree.git for_3.6/spi Shubhrajyoti D (3): spi: omap2-mcspi: Call pm_runtime_* functions directly spi: omap2-mcspi: Remove the macro MOD_REG_BIT spi: omap2-mcspi: At remove dont use the runtime_autosuspend calls drivers/spi/spi-omap2-mcspi.c | 55 ++--- 1 files changed, 24 insertions(+), 31 deletions(-) -- 1.7.5.4 -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html