* [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM
@ 2010-09-21 14:07 Rajendra Nayak
2010-09-21 14:07 ` [PATCH v3 1/5] OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 Rajendra Nayak
2010-09-27 20:02 ` [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Kevin Hilman
0 siblings, 2 replies; 17+ messages in thread
From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw)
To: linux-arm-kernel
This series makes I2C device registration use hwmod and omap_device api's
and converts the I2C driver to use runtime PM api's.
Patches apply on the pm-core branch from Kevin's tree.
v3 has minor review comment fixes over v2
The series is boot tested on a 2430sdp platform along with being tested
on 3430sdp and 4430sdp.
4430sdp tests are done using the below series
http://www.spinics.net/lists/linux-omap/msg36023.html
Paul Walmsley (2):
OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430
OMAP: I2C: split device registration and convert OMAP2+ to
omap_device
Rajendra Nayak (3):
OMAP3: hwmod: add I2C hwmods for OMAP3430
OMAP4: hwmod: add I2C hwmods for OMAP4430
OMAP: I2C: Convert i2c driver to use PM runtime api's
arch/arm/mach-omap2/cm-regbits-24xx.h | 4 +
arch/arm/mach-omap2/omap_hwmod_2420_data.c | 140 ++++++++++++++++-
arch/arm/mach-omap2/omap_hwmod_2430_data.c | 154 ++++++++++++++++++-
arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 232 +++++++++++++++++++++++++++
arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 237 ++++++++++++++++++++++++++++
arch/arm/mach-omap2/prm-regbits-34xx.h | 3 +
arch/arm/plat-omap/i2c.c | 124 ++++++---------
arch/arm/plat-omap/include/plat/i2c.h | 16 ++
arch/arm/plat-omap/include/plat/l4_3xxx.h | 24 +++
drivers/i2c/busses/i2c-omap.c | 67 +++------
include/linux/i2c-omap.h | 5 +
11 files changed, 881 insertions(+), 125 deletions(-)
create mode 100644 arch/arm/plat-omap/include/plat/l4_3xxx.h
^ permalink raw reply [flat|nested] 17+ messages in thread* [PATCH v3 1/5] OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 2010-09-21 14:07 [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Rajendra Nayak @ 2010-09-21 14:07 ` Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 2/5] OMAP3: hwmod: add I2C hwmods for OMAP3430 Rajendra Nayak 2010-09-27 20:02 ` [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Kevin Hilman 1 sibling, 1 reply; 17+ messages in thread From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw) To: linux-arm-kernel From: Paul Walmsley <paul@pwsan.com> Add hwmod structures for I2C controllers on OMAP2420/2430. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Rajendra Nayak <rnayak@ti.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/mach-omap2/cm-regbits-24xx.h | 4 + arch/arm/mach-omap2/omap_hwmod_2420_data.c | 140 +++++++++++++++++++++++++- arch/arm/mach-omap2/omap_hwmod_2430_data.c | 154 +++++++++++++++++++++++++++- 3 files changed, 294 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/cm-regbits-24xx.h b/arch/arm/mach-omap2/cm-regbits-24xx.h index da51cc3..5986e2b 100644 --- a/arch/arm/mach-omap2/cm-regbits-24xx.h +++ b/arch/arm/mach-omap2/cm-regbits-24xx.h @@ -126,8 +126,12 @@ #define OMAP24XX_ST_HDQ_MASK (1 << 23) #define OMAP2420_ST_I2C2_SHIFT 20 #define OMAP2420_ST_I2C2_MASK (1 << 20) +#define OMAP2430_ST_I2CHS1_SHIFT 20 +#define OMAP2430_ST_I2CHS1_MASK (1 << 20) #define OMAP2420_ST_I2C1_SHIFT 19 #define OMAP2420_ST_I2C1_MASK (1 << 19) +#define OMAP2430_ST_I2CHS2_SHIFT 19 +#define OMAP2430_ST_I2CHS2_MASK (1 << 19) #define OMAP24XX_ST_MCBSP2_SHIFT 16 #define OMAP24XX_ST_MCBSP2_MASK (1 << 16) #define OMAP24XX_ST_MCBSP1_SHIFT 15 diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 3cc768e..d5e1c9d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -15,9 +15,12 @@ #include <mach/irqs.h> #include <plat/cpu.h> #include <plat/dma.h> +#include <plat/i2c.h> +#include <plat/omap24xx.h> #include "omap_hwmod_common_data.h" +#include "cm-regbits-24xx.h" #include "prm-regbits-24xx.h" /* @@ -71,6 +74,8 @@ static struct omap_hwmod omap2420_l3_main_hwmod = { }; static struct omap_hwmod omap2420_l4_wkup_hwmod; +static struct omap_hwmod omap2420_i2c1_hwmod; +static struct omap_hwmod omap2420_i2c2_hwmod; /* L4_CORE -> L4_WKUP interface */ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { @@ -79,6 +84,45 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__l4_wkup = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* I2C IP block address space length (in bytes) */ +#define OMAP2_I2C_AS_LEN 128 + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_addr_space omap2420_i2c1_addr_space[] = { + { + .pa_start = 0x48070000, + .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_core__i2c1 = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_i2c1_hwmod, + .clk = "i2c1_ick", + .addr = omap2420_i2c1_addr_space, + .addr_cnt = ARRAY_SIZE(omap2420_i2c1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_addr_space omap2420_i2c2_addr_space[] = { + { + .pa_start = 0x48072000, + .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2420_l4_core__i2c2 = { + .master = &omap2420_l4_core_hwmod, + .slave = &omap2420_i2c2_hwmod, + .clk = "i2c2_ick", + .addr = omap2420_i2c2_addr_space, + .addr_cnt = ARRAY_SIZE(omap2420_i2c2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { &omap2420_l3_main__l4_core, @@ -87,6 +131,8 @@ static struct omap_hwmod_ocp_if *omap2420_l4_core_slaves[] = { /* Master interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap2420_l4_core_masters[] = { &omap2420_l4_core__l4_wkup, + &omap2420_l4_core__i2c1, + &omap2420_l4_core__i2c2 }; /* L4 CORE */ @@ -165,12 +211,104 @@ static struct omap_hwmod omap2420_iva_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420) }; +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = SYSC_HAS_SOFTRESET, + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr; + +/* I2C1 */ + +static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = { + { .irq = INT_24XX_I2C1_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX }, +}; + +static struct omap_hwmod_ocp_if *omap2420_i2c1_slaves[] = { + &omap2420_l4_core__i2c1, +}; + +static struct omap_hwmod omap2420_i2c1_hwmod = { + .name = "i2c1", + .mpu_irqs = i2c1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), + .sdma_reqs = i2c1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs), + .main_clk = "i2c1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_I2C1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_I2C1_SHIFT, + }, + }, + .slaves = omap2420_i2c1_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_i2c1_slaves), + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + +/* I2C2 */ + +static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = { + { .irq = INT_24XX_I2C2_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX }, +}; + +static struct omap_hwmod_ocp_if *omap2420_i2c2_slaves[] = { + &omap2420_l4_core__i2c2, +}; + +static struct omap_hwmod omap2420_i2c2_hwmod = { + .name = "i2c2", + .mpu_irqs = i2c2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), + .sdma_reqs = i2c2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs), + .main_clk = "i2c2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_I2C2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_I2C2_SHIFT, + }, + }, + .slaves = omap2420_i2c2_slaves, + .slaves_cnt = ARRAY_SIZE(omap2420_i2c2_slaves), + .class = &i2c_class, + .dev_attr = &i2c_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2420), +}; + static __initdata struct omap_hwmod *omap2420_hwmods[] = { &omap2420_l3_main_hwmod, &omap2420_l4_core_hwmod, &omap2420_l4_wkup_hwmod, &omap2420_mpu_hwmod, &omap2420_iva_hwmod, + &omap2420_i2c1_hwmod, + &omap2420_i2c2_hwmod, NULL, }; @@ -178,5 +316,3 @@ int __init omap2420_hwmod_init(void) { return omap_hwmod_init(omap2420_hwmods); } - - diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 4526628..72d5f7a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -15,10 +15,13 @@ #include <mach/irqs.h> #include <plat/cpu.h> #include <plat/dma.h> +#include <plat/i2c.h> +#include <plat/omap24xx.h> #include "omap_hwmod_common_data.h" #include "prm-regbits-24xx.h" +#include "cm-regbits-24xx.h" /* * OMAP2430 hardware module integration data @@ -71,6 +74,47 @@ static struct omap_hwmod omap2430_l3_main_hwmod = { }; static struct omap_hwmod omap2430_l4_wkup_hwmod; +static struct omap_hwmod omap2430_i2c1_hwmod; +static struct omap_hwmod omap2430_i2c2_hwmod; + +/* I2C IP block address space length (in bytes) */ +#define OMAP2_I2C_AS_LEN 128 + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_addr_space omap2430_i2c1_addr_space[] = { + { + .pa_start = 0x48070000, + .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__i2c1 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_i2c1_hwmod, + .clk = "i2c1_ick", + .addr = omap2430_i2c1_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_i2c1_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_addr_space omap2430_i2c2_addr_space[] = { + { + .pa_start = 0x48072000, + .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap2430_l4_core__i2c2 = { + .master = &omap2430_l4_core_hwmod, + .slave = &omap2430_i2c2_hwmod, + .clk = "i2c2_ick", + .addr = omap2430_i2c2_addr_space, + .addr_cnt = ARRAY_SIZE(omap2430_i2c2_addr_space), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; /* L4_CORE -> L4_WKUP interface */ static struct omap_hwmod_ocp_if omap2430_l4_core__l4_wkup = { @@ -165,12 +209,120 @@ static struct omap_hwmod omap2430_iva_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430) }; +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, +}; + +static struct omap_i2c_dev_attr i2c_dev_attr; + +/* I2C1 */ + +static struct omap_i2c_dev_attr i2c1_dev_attr = { + .fifo_depth = 8, /* bytes */ +}; + +static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = { + { .irq = INT_24XX_I2C1_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX }, +}; + +static struct omap_hwmod_ocp_if *omap2430_i2c1_slaves[] = { + &omap2430_l4_core__i2c1, +}; + +static struct omap_hwmod omap2430_i2c1_hwmod = { + .name = "i2c1", + .mpu_irqs = i2c1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), + .sdma_reqs = i2c1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs), + .main_clk = "i2c1_fck", + .prcm = { + .omap2 = { + /* + * NOTE: The CM_FCLKEN* and CM_ICLKEN* for + * I2CHS IP's do not follow the usual pattern. + * prcm_reg_id alone cannot be used to program + * the iclk and fclk. Needs to be handled using + * additonal flags when clk handling is moved + * to hwmod framework. + */ + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_I2CHS1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_I2CHS1_SHIFT, + }, + }, + .slaves = omap2430_i2c1_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_i2c1_slaves), + .class = &i2c_class, + .dev_attr = &i2c1_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + +/* I2C2 */ + +static struct omap_i2c_dev_attr i2c2_dev_attr = { + .fifo_depth = 8, /* bytes */ +}; + +static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = { + { .irq = INT_24XX_I2C2_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX }, +}; + +static struct omap_hwmod_ocp_if *omap2430_i2c2_slaves[] = { + &omap2430_l4_core__i2c2, +}; + +static struct omap_hwmod omap2430_i2c2_hwmod = { + .name = "i2c2", + .mpu_irqs = i2c2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), + .sdma_reqs = i2c2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs), + .main_clk = "i2c2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2430_EN_I2CHS2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2430_ST_I2CHS2_SHIFT, + }, + }, + .slaves = omap2430_i2c2_slaves, + .slaves_cnt = ARRAY_SIZE(omap2430_i2c2_slaves), + .class = &i2c_class, + .dev_attr = &i2c2_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP2430), +}; + static __initdata struct omap_hwmod *omap2430_hwmods[] = { &omap2430_l3_main_hwmod, &omap2430_l4_core_hwmod, &omap2430_l4_wkup_hwmod, &omap2430_mpu_hwmod, &omap2430_iva_hwmod, + &omap2430_i2c1_hwmod, + &omap2430_i2c2_hwmod, NULL, }; @@ -178,5 +330,3 @@ int __init omap2430_hwmod_init(void) { return omap_hwmod_init(omap2430_hwmods); } - - -- 1.5.4.7 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 2/5] OMAP3: hwmod: add I2C hwmods for OMAP3430 2010-09-21 14:07 ` [PATCH v3 1/5] OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 Rajendra Nayak @ 2010-09-21 14:07 ` Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 3/5] OMAP4: hwmod: add I2C hwmods for OMAP4430 Rajendra Nayak 0 siblings, 1 reply; 17+ messages in thread From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw) To: linux-arm-kernel Add hwmod structures for I2C controllers on OMAP3430. This patch was developed in collaboration with Paul Walmsley <paul@pwsan.com>. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Paul Walmsley <paul@pwsan.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 232 ++++++++++++++++++++++++++++ arch/arm/mach-omap2/prm-regbits-34xx.h | 3 + arch/arm/plat-omap/include/plat/i2c.h | 16 ++ arch/arm/plat-omap/include/plat/l4_3xxx.h | 24 +++ 4 files changed, 275 insertions(+), 0 deletions(-) create mode 100644 arch/arm/plat-omap/include/plat/l4_3xxx.h diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 5d8eb58..a3ccab7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -17,6 +17,9 @@ #include <mach/irqs.h> #include <plat/cpu.h> #include <plat/dma.h> +#include <plat/l4_3xxx.h> +#include <plat/i2c.h> +#include <plat/omap34xx.h> #include "omap_hwmod_common_data.h" @@ -36,6 +39,9 @@ static struct omap_hwmod omap3xxx_iva_hwmod; static struct omap_hwmod omap3xxx_l3_main_hwmod; static struct omap_hwmod omap3xxx_l4_core_hwmod; static struct omap_hwmod omap3xxx_l4_per_hwmod; +static struct omap_hwmod omap3xxx_i2c1_hwmod; +static struct omap_hwmod omap3xxx_i2c2_hwmod; +static struct omap_hwmod omap3xxx_i2c3_hwmod; /* L3 -> L4_CORE interface */ static struct omap_hwmod_ocp_if omap3xxx_l3_main__l4_core = { @@ -90,6 +96,85 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__l4_wkup = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; + +/* I2C IP block address space length (in bytes) */ +#define OMAP2_I2C_AS_LEN 128 + +/* L4 CORE -> I2C1 interface */ +static struct omap_hwmod_addr_space omap3xxx_i2c1_addr_space[] = { + { + .pa_start = 0x48070000, + .pa_end = 0x48070000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__i2c1 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c1_hwmod, + .clk = "i2c1_ick", + .addr = omap3xxx_i2c1_addr_space, + .addr_cnt = ARRAY_SIZE(omap3xxx_i2c1_addr_space), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C1_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C2 interface */ +static struct omap_hwmod_addr_space omap3xxx_i2c2_addr_space[] = { + { + .pa_start = 0x48072000, + .pa_end = 0x48072000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__i2c2 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c2_hwmod, + .clk = "i2c2_ick", + .addr = omap3xxx_i2c2_addr_space, + .addr_cnt = ARRAY_SIZE(omap3xxx_i2c2_addr_space), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C2_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* L4 CORE -> I2C3 interface */ +static struct omap_hwmod_addr_space omap3xxx_i2c3_addr_space[] = { + { + .pa_start = 0x48060000, + .pa_end = 0x48060000 + OMAP2_I2C_AS_LEN - 1, + .flags = ADDR_TYPE_RT, + }, +}; + +static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_i2c3_hwmod, + .clk = "i2c3_ick", + .addr = omap3xxx_i2c3_addr_space, + .addr_cnt = ARRAY_SIZE(omap3xxx_i2c3_addr_space), + .fw = { + .omap2 = { + .l4_fw_region = OMAP3_L4_CORE_FW_I2C3_REGION, + .l4_prot_group = 7, + .flags = OMAP_FIREWALL_L4, + } + }, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* Slave interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { &omap3xxx_l3_main__l4_core, @@ -98,6 +183,9 @@ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { /* Master interfaces on the L4_CORE interconnect */ static struct omap_hwmod_ocp_if *omap3xxx_l4_core_masters[] = { &omap3xxx_l4_core__l4_wkup, + &omap3_l4_core__i2c1, + &omap3_l4_core__i2c2, + &omap3_l4_core__i2c3, }; /* L4 CORE */ @@ -197,6 +285,147 @@ static struct omap_hwmod omap3xxx_iva_hwmod = { .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430) }; + +/* I2C common */ +static struct omap_hwmod_class_sysconfig i2c_sysc = { + .rev_offs = 0x00, + .sysc_offs = 0x20, + .syss_offs = 0x10, + .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE | + SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class i2c_class = { + .name = "i2c", + .sysc = &i2c_sysc, +}; + +/* I2C1 */ + +static struct omap_i2c_dev_attr i2c1_dev_attr = { + .fifo_depth = 8, /* bytes */ +}; + +static struct omap_hwmod_irq_info i2c1_mpu_irqs[] = { + { .irq = INT_24XX_I2C1_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c1_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C1_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C1_RX }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_i2c1_slaves[] = { + &omap3_l4_core__i2c1, +}; + +static struct omap_hwmod omap3xxx_i2c1_hwmod = { + .name = "i2c1", + .mpu_irqs = i2c1_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c1_mpu_irqs), + .sdma_reqs = i2c1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c1_sdma_reqs), + .main_clk = "i2c1_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C1_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C1_SHIFT, + }, + }, + .slaves = omap3xxx_i2c1_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c1_slaves), + .class = &i2c_class, + .dev_attr = &i2c1_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* I2C2 */ + +static struct omap_i2c_dev_attr i2c2_dev_attr = { + .fifo_depth = 8, /* bytes */ +}; + +static struct omap_hwmod_irq_info i2c2_mpu_irqs[] = { + { .irq = INT_24XX_I2C2_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c2_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP24XX_DMA_I2C2_TX }, + { .name = "rx", .dma_req = OMAP24XX_DMA_I2C2_RX }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_i2c2_slaves[] = { + &omap3_l4_core__i2c2, +}; + +static struct omap_hwmod omap3xxx_i2c2_hwmod = { + .name = "i2c2", + .mpu_irqs = i2c2_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c2_mpu_irqs), + .sdma_reqs = i2c2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c2_sdma_reqs), + .main_clk = "i2c2_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C2_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C2_SHIFT, + }, + }, + .slaves = omap3xxx_i2c2_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c2_slaves), + .class = &i2c_class, + .dev_attr = &i2c2_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + +/* I2C3 */ + +static struct omap_i2c_dev_attr i2c3_dev_attr = { + .fifo_depth = 64, /* bytes */ +}; + +static struct omap_hwmod_irq_info i2c3_mpu_irqs[] = { + { .irq = INT_34XX_I2C3_IRQ, }, +}; + +static struct omap_hwmod_dma_info i2c3_sdma_reqs[] = { + { .name = "tx", .dma_req = OMAP34XX_DMA_I2C3_TX }, + { .name = "rx", .dma_req = OMAP34XX_DMA_I2C3_RX }, +}; + +static struct omap_hwmod_ocp_if *omap3xxx_i2c3_slaves[] = { + &omap3_l4_core__i2c3, +}; + +static struct omap_hwmod omap3xxx_i2c3_hwmod = { + .name = "i2c3", + .mpu_irqs = i2c3_mpu_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(i2c3_mpu_irqs), + .sdma_reqs = i2c3_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(i2c3_sdma_reqs), + .main_clk = "i2c3_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_I2C3_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_I2C3_SHIFT, + }, + }, + .slaves = omap3xxx_i2c3_slaves, + .slaves_cnt = ARRAY_SIZE(omap3xxx_i2c3_slaves), + .class = &i2c_class, + .dev_attr = &i2c3_dev_attr, + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430), +}; + static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_l3_main_hwmod, &omap3xxx_l4_core_hwmod, @@ -204,6 +433,9 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { &omap3xxx_l4_wkup_hwmod, &omap3xxx_mpu_hwmod, &omap3xxx_iva_hwmod, + &omap3xxx_i2c1_hwmod, + &omap3xxx_i2c2_hwmod, + &omap3xxx_i2c3_hwmod, NULL, }; diff --git a/arch/arm/mach-omap2/prm-regbits-34xx.h b/arch/arm/mach-omap2/prm-regbits-34xx.h index 7fd6023..51c354e 100644 --- a/arch/arm/mach-omap2/prm-regbits-34xx.h +++ b/arch/arm/mach-omap2/prm-regbits-34xx.h @@ -101,8 +101,11 @@ #define OMAP3430_GRPSEL_MCSPI3_MASK (1 << 20) #define OMAP3430_GRPSEL_MCSPI2_MASK (1 << 19) #define OMAP3430_GRPSEL_MCSPI1_MASK (1 << 18) +#define OMAP3430_GRPSEL_I2C3_SHIFT 17 #define OMAP3430_GRPSEL_I2C3_MASK (1 << 17) +#define OMAP3430_GRPSEL_I2C2_SHIFT 16 #define OMAP3430_GRPSEL_I2C2_MASK (1 << 16) +#define OMAP3430_GRPSEL_I2C1_SHIFT 15 #define OMAP3430_GRPSEL_I2C1_MASK (1 << 15) #define OMAP3430_GRPSEL_UART2_MASK (1 << 14) #define OMAP3430_GRPSEL_UART1_MASK (1 << 13) diff --git a/arch/arm/plat-omap/include/plat/i2c.h b/arch/arm/plat-omap/include/plat/i2c.h index 87f6bf2..86d0199 100644 --- a/arch/arm/plat-omap/include/plat/i2c.h +++ b/arch/arm/plat-omap/include/plat/i2c.h @@ -18,6 +18,8 @@ * 02110-1301 USA * */ +#ifndef __ASM_ARCH_I2C_H +#define __ASM_ARCH_I2C_H #include <linux/i2c.h> @@ -34,5 +36,19 @@ static inline int omap_register_i2c_bus(int bus_id, u32 clkrate, } #endif +/** + * i2c_dev_attr - OMAP I2C controller device attributes for omap_hwmod + * @fifo_depth: total controller FIFO size (in bytes) + * @flags: differences in hardware support capability + * + * @fifo_depth represents what exists on the hardware, not what is + * actually configured at runtime by the device driver. + */ +struct omap_i2c_dev_attr { + u8 fifo_depth; + u8 flags; +}; + void __init omap1_i2c_mux_pins(int bus_id); void __init omap2_i2c_mux_pins(int bus_id); +#endif diff --git a/arch/arm/plat-omap/include/plat/l4_3xxx.h b/arch/arm/plat-omap/include/plat/l4_3xxx.h new file mode 100644 index 0000000..5e19493 --- /dev/null +++ b/arch/arm/plat-omap/include/plat/l4_3xxx.h @@ -0,0 +1,24 @@ +/* + * arch/arm/plat-omap/include/mach/l4_3xxx.h - L4 firewall definitions + * + * Copyright (C) 2009 Nokia Corporation + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#ifndef __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H +#define __ARCH_ARM_PLAT_OMAP_INCLUDE_MACH_L4_3XXX_H + +/* L4 CORE */ +#define OMAP3_L4_CORE_FW_I2C1_REGION 21 +#define OMAP3_L4_CORE_FW_I2C1_TA_REGION 22 +#define OMAP3_L4_CORE_FW_I2C2_REGION 23 +#define OMAP3_L4_CORE_FW_I2C2_TA_REGION 24 +#define OMAP3_L4_CORE_FW_I2C3_REGION 73 +#define OMAP3_L4_CORE_FW_I2C3_TA_REGION 74 + +#endif -- 1.5.4.7 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 3/5] OMAP4: hwmod: add I2C hwmods for OMAP4430 2010-09-21 14:07 ` [PATCH v3 2/5] OMAP3: hwmod: add I2C hwmods for OMAP3430 Rajendra Nayak @ 2010-09-21 14:07 ` Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 4/5] OMAP: I2C: split device registration and convert OMAP2+ to omap_device Rajendra Nayak 0 siblings, 1 reply; 17+ messages in thread From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw) To: linux-arm-kernel Add hwmod structures for I2C controllers on OMAP4430. Signed-off-by: Rajendra Nayak <rnayak@ti.com> Signed-off-by: Benoit Cousson <b-cousson@ti.com> --- arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 237 ++++++++++++++++++++++++++++ 1 files changed, 237 insertions(+), 0 deletions(-) diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index e20b0ee..2cb63fc 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -383,6 +383,238 @@ static struct omap_hwmod omap44xx_l4_wkup_hwmod = { }; /* + * 'i2c' class + * multimaster high-speed i2c controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = { + .sysc_offs = 0x0010, + .syss_offs = 0x0090, + .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE | + SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SOFTRESET | + SYSC_HAS_AUTOIDLE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { + .name = "i2c", + .sysc = &omap44xx_i2c_sysc, +}; + +/* i2c1 */ +static struct omap_hwmod omap44xx_i2c1_hwmod; +static struct omap_hwmod_irq_info omap44xx_i2c1_irqs[] = { + { .irq = 56 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_i2c1_sdma_reqs[] = { + { .name = "tx", .dma_req = 26 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 27 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_i2c1_addrs[] = { + { + .pa_start = 0x48070000, + .pa_end = 0x480700ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> i2c1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c1_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_i2c1_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_i2c1_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* i2c1 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_i2c1_slaves[] = { + &omap44xx_l4_per__i2c1, +}; + +static struct omap_hwmod omap44xx_i2c1_hwmod = { + .name = "i2c1", + .class = &omap44xx_i2c_hwmod_class, + .flags = HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_i2c1_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c1_irqs), + .sdma_reqs = omap44xx_i2c1_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c1_sdma_reqs), + .main_clk = "i2c1_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_L4PER_I2C1_CLKCTRL, + }, + }, + .slaves = omap44xx_i2c1_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_i2c1_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* i2c2 */ +static struct omap_hwmod omap44xx_i2c2_hwmod; +static struct omap_hwmod_irq_info omap44xx_i2c2_irqs[] = { + { .irq = 57 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_i2c2_sdma_reqs[] = { + { .name = "tx", .dma_req = 28 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 29 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_i2c2_addrs[] = { + { + .pa_start = 0x48072000, + .pa_end = 0x480720ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> i2c2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c2_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_i2c2_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_i2c2_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* i2c2 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_i2c2_slaves[] = { + &omap44xx_l4_per__i2c2, +}; + +static struct omap_hwmod omap44xx_i2c2_hwmod = { + .name = "i2c2", + .class = &omap44xx_i2c_hwmod_class, + .flags = HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_i2c2_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c2_irqs), + .sdma_reqs = omap44xx_i2c2_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c2_sdma_reqs), + .main_clk = "i2c2_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_L4PER_I2C2_CLKCTRL, + }, + }, + .slaves = omap44xx_i2c2_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_i2c2_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* i2c3 */ +static struct omap_hwmod omap44xx_i2c3_hwmod; +static struct omap_hwmod_irq_info omap44xx_i2c3_irqs[] = { + { .irq = 61 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_i2c3_sdma_reqs[] = { + { .name = "tx", .dma_req = 24 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 25 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_i2c3_addrs[] = { + { + .pa_start = 0x48060000, + .pa_end = 0x480600ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> i2c3 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c3 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c3_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_i2c3_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_i2c3_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* i2c3 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_i2c3_slaves[] = { + &omap44xx_l4_per__i2c3, +}; + +static struct omap_hwmod omap44xx_i2c3_hwmod = { + .name = "i2c3", + .class = &omap44xx_i2c_hwmod_class, + .flags = HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_i2c3_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c3_irqs), + .sdma_reqs = omap44xx_i2c3_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c3_sdma_reqs), + .main_clk = "i2c3_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_L4PER_I2C3_CLKCTRL, + }, + }, + .slaves = omap44xx_i2c3_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_i2c3_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* i2c4 */ +static struct omap_hwmod omap44xx_i2c4_hwmod; +static struct omap_hwmod_irq_info omap44xx_i2c4_irqs[] = { + { .irq = 62 + OMAP44XX_IRQ_GIC_START }, +}; + +static struct omap_hwmod_dma_info omap44xx_i2c4_sdma_reqs[] = { + { .name = "tx", .dma_req = 123 + OMAP44XX_DMA_REQ_START }, + { .name = "rx", .dma_req = 124 + OMAP44XX_DMA_REQ_START }, +}; + +static struct omap_hwmod_addr_space omap44xx_i2c4_addrs[] = { + { + .pa_start = 0x48350000, + .pa_end = 0x483500ff, + .flags = ADDR_TYPE_RT + }, +}; + +/* l4_per -> i2c4 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__i2c4 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_i2c4_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_i2c4_addrs, + .addr_cnt = ARRAY_SIZE(omap44xx_i2c4_addrs), + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* i2c4 slave ports */ +static struct omap_hwmod_ocp_if *omap44xx_i2c4_slaves[] = { + &omap44xx_l4_per__i2c4, +}; + +static struct omap_hwmod omap44xx_i2c4_hwmod = { + .name = "i2c4", + .class = &omap44xx_i2c_hwmod_class, + .flags = HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_i2c4_irqs, + .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_i2c4_irqs), + .sdma_reqs = omap44xx_i2c4_sdma_reqs, + .sdma_reqs_cnt = ARRAY_SIZE(omap44xx_i2c4_sdma_reqs), + .main_clk = "i2c4_fck", + .prcm = { + .omap4 = { + .clkctrl_reg = OMAP4430_CM_L4PER_I2C4_CLKCTRL, + }, + }, + .slaves = omap44xx_i2c4_slaves, + .slaves_cnt = ARRAY_SIZE(omap44xx_i2c4_slaves), + .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), +}; + +/* * 'mpu_bus' class * instance(s): mpu_private */ @@ -467,6 +699,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { &omap44xx_l4_cfg_hwmod, &omap44xx_l4_per_hwmod, &omap44xx_l4_wkup_hwmod, + /* i2c class */ + &omap44xx_i2c1_hwmod, + &omap44xx_i2c2_hwmod, + &omap44xx_i2c3_hwmod, + &omap44xx_i2c4_hwmod, /* mpu_bus class */ &omap44xx_mpu_private_hwmod, -- 1.5.4.7 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 4/5] OMAP: I2C: split device registration and convert OMAP2+ to omap_device 2010-09-21 14:07 ` [PATCH v3 3/5] OMAP4: hwmod: add I2C hwmods for OMAP4430 Rajendra Nayak @ 2010-09-21 14:07 ` Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's Rajendra Nayak 0 siblings, 1 reply; 17+ messages in thread From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw) To: linux-arm-kernel From: Paul Walmsley <paul@pwsan.com> Split the OMAP1 and OMAP2+ platform_device build and register code. Convert the OMAP2+ variant to use omap_device. This patch was developed in collaboration with Rajendra Nayak <rnayak@ti.com>. Signed-off-by: Paul Walmsley <paul@pwsan.com> Signed-off-by: Rajendra Nayak <rnayak@ti.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> --- arch/arm/plat-omap/i2c.c | 124 ++++++++++++++++++---------------------------- include/linux/i2c-omap.h | 5 ++ 2 files changed, 54 insertions(+), 75 deletions(-) diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index a5ce4f0..a5bff9c 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -27,18 +27,18 @@ #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/i2c-omap.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/clk.h> #include <mach/irqs.h> #include <plat/mux.h> #include <plat/i2c.h> #include <plat/omap-pm.h> +#include <plat/omap_device.h> #define OMAP_I2C_SIZE 0x3f #define OMAP1_I2C_BASE 0xfffb3800 -#define OMAP2_I2C_BASE1 0x48070000 -#define OMAP2_I2C_BASE2 0x48072000 -#define OMAP2_I2C_BASE3 0x48060000 -#define OMAP4_I2C_BASE4 0x48350000 static const char name[] = "i2c_omap"; @@ -55,15 +55,6 @@ static const char name[] = "i2c_omap"; static struct resource i2c_resources[][2] = { { I2C_RESOURCE_BUILDER(0, 0) }, -#if defined(CONFIG_ARCH_OMAP2PLUS) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, 0) }, -#endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, 0) }, -#endif -#if defined(CONFIG_ARCH_OMAP4) - { I2C_RESOURCE_BUILDER(OMAP4_I2C_BASE4, 0) }, -#endif }; #define I2C_DEV_BUILDER(bus_id, res, data) \ @@ -77,18 +68,11 @@ static struct resource i2c_resources[][2] = { }, \ } -static struct omap_i2c_bus_platform_data i2c_pdata[ARRAY_SIZE(i2c_resources)]; +#define MAX_OMAP_I2C_HWMOD_NAME_LEN 16 +#define OMAP_I2C_MAX_CONTROLLERS 4 +static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS]; static struct platform_device omap_i2c_devices[] = { I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_pdata[0]), -#if defined(CONFIG_ARCH_OMAP2PLUS) - I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_pdata[1]), -#endif -#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) - I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_pdata[2]), -#endif -#if defined(CONFIG_ARCH_OMAP4) - I2C_DEV_BUILDER(4, i2c_resources[3], &i2c_pdata[3]), -#endif }; #define OMAP_I2C_CMDLINE_SETUP (BIT(31)) @@ -109,35 +93,20 @@ static int __init omap_i2c_nr_ports(void) return ports; } -/* Shared between omap2 and 3 */ -static resource_size_t omap2_i2c_irq[3] __initdata = { - INT_24XX_I2C1_IRQ, - INT_24XX_I2C2_IRQ, - INT_34XX_I2C3_IRQ, -}; - -static resource_size_t omap4_i2c_irq[4] __initdata = { - OMAP44XX_IRQ_I2C1, - OMAP44XX_IRQ_I2C2, - OMAP44XX_IRQ_I2C3, - OMAP44XX_IRQ_I2C4, -}; - -static inline int omap1_i2c_add_bus(struct platform_device *pdev, int bus_id) +static inline int omap1_i2c_add_bus(int bus_id) { - struct omap_i2c_bus_platform_data *pd; - struct resource *res; - - pd = pdev->dev.platform_data; - res = pdev->resource; - res[0].start = OMAP1_I2C_BASE; - res[0].end = res[0].start + OMAP_I2C_SIZE; - res[1].start = INT_I2C; + struct platform_device *pdev; + struct omap_i2c_bus_platform_data *pdata; + omap1_i2c_mux_pins(bus_id); + pdev = &omap_i2c_devices[bus_id - 1]; + pdata = &i2c_pdata[bus_id - 1]; + return platform_device_register(pdev); } + /* * XXX This function is a temporary compatibility wrapper - only * needed until the I2C driver can be converted to call @@ -148,52 +117,57 @@ static void omap_pm_set_max_mpu_wakeup_lat_compat(struct device *dev, long t) omap_pm_set_max_mpu_wakeup_lat(dev, t); } -static inline int omap2_i2c_add_bus(struct platform_device *pdev, int bus_id) -{ - struct resource *res; - resource_size_t *irq; +static struct omap_device_pm_latency omap_i2c_latency[] = { + [0] = { + .deactivate_func = omap_device_idle_hwmods, + .activate_func = omap_device_enable_hwmods, + .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, + }, +}; - res = pdev->resource; +static inline int omap2_i2c_add_bus(int bus_id) +{ + int l; + struct omap_hwmod *oh; + struct omap_device *od; + char oh_name[MAX_OMAP_I2C_HWMOD_NAME_LEN]; + struct omap_i2c_bus_platform_data *pdata; - if (!cpu_is_omap44xx()) - irq = omap2_i2c_irq; - else - irq = omap4_i2c_irq; + omap2_i2c_mux_pins(bus_id); - if (bus_id == 1) { - res[0].start = OMAP2_I2C_BASE1; - res[0].end = res[0].start + OMAP_I2C_SIZE; + l = snprintf(oh_name, MAX_OMAP_I2C_HWMOD_NAME_LEN, "i2c%d", bus_id); + WARN(l >= MAX_OMAP_I2C_HWMOD_NAME_LEN, + "String buffer overflow in I2C%d device setup\n", bus_id); + oh = omap_hwmod_lookup(oh_name); + if (!oh) { + pr_err("Could not look up %s\n", oh_name); + return -EEXIST; } - res[1].start = irq[bus_id - 1]; - omap2_i2c_mux_pins(bus_id); - + pdata = &i2c_pdata[bus_id - 1]; /* * When waiting for completion of a i2c transfer, we need to * set a wake up latency constraint for the MPU. This is to * ensure quick enough wakeup from idle, when transfer * completes. + * Only omap3 has support for constraints */ - if (cpu_is_omap34xx()) { - struct omap_i2c_bus_platform_data *pd; - - pd = pdev->dev.platform_data; - pd->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; - } - - return platform_device_register(pdev); + if (cpu_is_omap34xx()) + pdata->set_mpu_wkup_lat = omap_pm_set_max_mpu_wakeup_lat_compat; + od = omap_device_build(name, bus_id, oh, pdata, + sizeof(struct omap_i2c_bus_platform_data), + omap_i2c_latency, ARRAY_SIZE(omap_i2c_latency), 0); + WARN(IS_ERR(od), "Could not build omap_device for %s\n", name); + + return PTR_ERR(od); } static int __init omap_i2c_add_bus(int bus_id) { - struct platform_device *pdev; - - pdev = &omap_i2c_devices[bus_id - 1]; - if (cpu_class_is_omap1()) - return omap1_i2c_add_bus(pdev, bus_id); + return omap1_i2c_add_bus(bus_id); else - return omap2_i2c_add_bus(pdev, bus_id); + return omap2_i2c_add_bus(bus_id); } /** diff --git a/include/linux/i2c-omap.h b/include/linux/i2c-omap.h index 78ebf50..7472449 100644 --- a/include/linux/i2c-omap.h +++ b/include/linux/i2c-omap.h @@ -1,9 +1,14 @@ #ifndef __I2C_OMAP_H__ #define __I2C_OMAP_H__ +#include <linux/platform_device.h> + struct omap_i2c_bus_platform_data { u32 clkrate; void (*set_mpu_wkup_lat)(struct device *dev, long set); + int (*device_enable) (struct platform_device *pdev); + int (*device_shutdown) (struct platform_device *pdev); + int (*device_idle) (struct platform_device *pdev); }; #endif -- 1.5.4.7 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-21 14:07 ` [PATCH v3 4/5] OMAP: I2C: split device registration and convert OMAP2+ to omap_device Rajendra Nayak @ 2010-09-21 14:07 ` Rajendra Nayak 2010-09-27 22:36 ` Ben Dooks 0 siblings, 1 reply; 17+ messages in thread From: Rajendra Nayak @ 2010-09-21 14:07 UTC (permalink / raw) To: linux-arm-kernel This patch converts the i2c driver to use PM runtime apis Signed-off-by: Rajendra Nayak <rnayak@ti.com> Cc: Kevin Hilman <khilman@deeprootsystems.com> Cc: Paul Walmsley <paul@pwsan.com> --- drivers/i2c/busses/i2c-omap.c | 67 +++++++++++++---------------------------- 1 files changed, 21 insertions(+), 46 deletions(-) diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index 7674efb..126bde9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -39,6 +39,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/i2c-omap.h> +#include <linux/pm_runtime.h> /* I2C controller revisions */ #define OMAP_I2C_REV_2 0x20 @@ -175,8 +176,6 @@ struct omap_i2c_dev { void __iomem *base; /* virtual */ int irq; int reg_shift; /* bit shift for I2C register addresses */ - struct clk *iclk; /* Interface clock */ - struct clk *fclk; /* Functional clock */ struct completion cmd_complete; struct resource *ioarea; u32 latency; /* maximum mpu wkup latency */ @@ -265,45 +264,18 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) (i2c_dev->regs[reg] << i2c_dev->reg_shift)); } -static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) +static void omap_i2c_unidle(struct omap_i2c_dev *dev) { - int ret; + struct platform_device *pdev; + struct omap_i2c_bus_platform_data *pdata; - dev->iclk = clk_get(dev->dev, "ick"); - if (IS_ERR(dev->iclk)) { - ret = PTR_ERR(dev->iclk); - dev->iclk = NULL; - return ret; - } + WARN_ON(!dev->idle); - dev->fclk = clk_get(dev->dev, "fck"); - if (IS_ERR(dev->fclk)) { - ret = PTR_ERR(dev->fclk); - if (dev->iclk != NULL) { - clk_put(dev->iclk); - dev->iclk = NULL; - } - dev->fclk = NULL; - return ret; - } + pdev = to_platform_device(dev->dev); + pdata = pdev->dev.platform_data; - return 0; -} + pm_runtime_get_sync(&pdev->dev); -static void omap_i2c_put_clocks(struct omap_i2c_dev *dev) -{ - clk_put(dev->fclk); - dev->fclk = NULL; - clk_put(dev->iclk); - dev->iclk = NULL; -} - -static void omap_i2c_unidle(struct omap_i2c_dev *dev) -{ - WARN_ON(!dev->idle); - - clk_enable(dev->iclk); - clk_enable(dev->fclk); if (cpu_is_omap34xx()) { omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); @@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) static void omap_i2c_idle(struct omap_i2c_dev *dev) { + struct platform_device *pdev; + struct omap_i2c_bus_platform_data *pdata; u16 iv; WARN_ON(dev->idle); + pdev = to_platform_device(dev->dev); + pdata = pdev->dev.platform_data; + dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); if (dev->rev >= OMAP_I2C_REV_ON_4430) omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); @@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); } dev->idle = 1; - clk_disable(dev->fclk); - clk_disable(dev->iclk); + + pm_runtime_put_sync(&pdev->dev); } static int omap_i2c_init(struct omap_i2c_dev *dev) @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) unsigned long fclk_rate = 12000000; unsigned long timeout; unsigned long internal_clk = 0; + struct clk *fclk; if (dev->rev >= OMAP_I2C_REV_2) { /* Disable I2C controller before soft reset */ @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) * always returns 12MHz for the functional clock, we can * do this bit unconditionally. */ - fclk_rate = clk_get_rate(dev->fclk); + fclk = clk_get(dev->dev, "fck"); + fclk_rate = clk_get_rate(fclk); /* TRM for 5912 says the I2C clock must be prescaled to be * between 7 - 12 MHz. The XOR input clock is typically @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) internal_clk = 9600; else internal_clk = 4000; - fclk_rate = clk_get_rate(dev->fclk) / 1000; + fclk = clk_get(dev->dev, "fck"); + fclk_rate = clk_get_rate(fclk) / 1000; /* Compute prescaler divisor */ psc = fclk_rate / internal_clk; @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) else dev->reg_shift = 2; - if ((r = omap_i2c_get_clocks(dev)) != 0) - goto err_iounmap; - if (cpu_is_omap44xx()) dev->regs = (u8 *) omap4_reg_map; else dev->regs = (u8 *) reg_map; + pm_runtime_enable(&pdev->dev); omap_i2c_unidle(dev); dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; @@ -1125,8 +1103,6 @@ err_free_irq: err_unuse_clocks: omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); omap_i2c_idle(dev); - omap_i2c_put_clocks(dev); -err_iounmap: iounmap(dev->base); err_free_mem: platform_set_drvdata(pdev, NULL); @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) free_irq(dev->irq, dev); i2c_del_adapter(&dev->adapter); omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); - omap_i2c_put_clocks(dev); iounmap(dev->base); kfree(dev); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- 1.5.4.7 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-21 14:07 ` [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's Rajendra Nayak @ 2010-09-27 22:36 ` Ben Dooks 2010-09-28 5:58 ` Nayak, Rajendra 0 siblings, 1 reply; 17+ messages in thread From: Ben Dooks @ 2010-09-27 22:36 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 21, 2010 at 07:37:16PM +0530, Rajendra Nayak wrote: > This patch converts the i2c driver to use PM runtime apis > > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > Cc: Kevin Hilman <khilman@deeprootsystems.com> > Cc: Paul Walmsley <paul@pwsan.com> > --- > drivers/i2c/busses/i2c-omap.c | 67 +++++++++++++---------------------------- > 1 files changed, 21 insertions(+), 46 deletions(-) > > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c > index 7674efb..126bde9 100644 > --- a/drivers/i2c/busses/i2c-omap.c > +++ b/drivers/i2c/busses/i2c-omap.c > @@ -39,6 +39,7 @@ > #include <linux/io.h> > #include <linux/slab.h> > #include <linux/i2c-omap.h> > +#include <linux/pm_runtime.h> > > /* I2C controller revisions */ > #define OMAP_I2C_REV_2 0x20 > @@ -175,8 +176,6 @@ struct omap_i2c_dev { > void __iomem *base; /* virtual */ > int irq; > int reg_shift; /* bit shift for I2C register addresses */ > - struct clk *iclk; /* Interface clock */ > - struct clk *fclk; /* Functional clock */ > struct completion cmd_complete; > struct resource *ioarea; > u32 latency; /* maximum mpu wkup latency */ > @@ -265,45 +264,18 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) > (i2c_dev->regs[reg] << i2c_dev->reg_shift)); > } > > -static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) > +static void omap_i2c_unidle(struct omap_i2c_dev *dev) > { > - int ret; > + struct platform_device *pdev; > + struct omap_i2c_bus_platform_data *pdata; > > - dev->iclk = clk_get(dev->dev, "ick"); > - if (IS_ERR(dev->iclk)) { > - ret = PTR_ERR(dev->iclk); > - dev->iclk = NULL; > - return ret; > - } > + WARN_ON(!dev->idle); > > - dev->fclk = clk_get(dev->dev, "fck"); > - if (IS_ERR(dev->fclk)) { > - ret = PTR_ERR(dev->fclk); > - if (dev->iclk != NULL) { > - clk_put(dev->iclk); > - dev->iclk = NULL; > - } > - dev->fclk = NULL; > - return ret; > - } > + pdev = to_platform_device(dev->dev); > + pdata = pdev->dev.platform_data; > > - return 0; > -} > + pm_runtime_get_sync(&pdev->dev); > > -static void omap_i2c_put_clocks(struct omap_i2c_dev *dev) > -{ > - clk_put(dev->fclk); > - dev->fclk = NULL; > - clk_put(dev->iclk); > - dev->iclk = NULL; > -} > - > -static void omap_i2c_unidle(struct omap_i2c_dev *dev) > -{ > - WARN_ON(!dev->idle); > - > - clk_enable(dev->iclk); > - clk_enable(dev->fclk); > if (cpu_is_omap34xx()) { > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); > @@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) > > static void omap_i2c_idle(struct omap_i2c_dev *dev) > { > + struct platform_device *pdev; > + struct omap_i2c_bus_platform_data *pdata; > u16 iv; > > WARN_ON(dev->idle); > > + pdev = to_platform_device(dev->dev); > + pdata = pdev->dev.platform_data; > + > dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); > if (dev->rev >= OMAP_I2C_REV_ON_4430) > omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); > @@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) > omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); > } > dev->idle = 1; > - clk_disable(dev->fclk); > - clk_disable(dev->iclk); > + > + pm_runtime_put_sync(&pdev->dev); > } > > static int omap_i2c_init(struct omap_i2c_dev *dev) > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > unsigned long fclk_rate = 12000000; > unsigned long timeout; > unsigned long internal_clk = 0; > + struct clk *fclk; > > if (dev->rev >= OMAP_I2C_REV_2) { > /* Disable I2C controller before soft reset */ > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > * always returns 12MHz for the functional clock, we can > * do this bit unconditionally. > */ > - fclk_rate = clk_get_rate(dev->fclk); > + fclk = clk_get(dev->dev, "fck"); > + fclk_rate = clk_get_rate(fclk); > > /* TRM for 5912 says the I2C clock must be prescaled to be > * between 7 - 12 MHz. The XOR input clock is typically > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > internal_clk = 9600; > else > internal_clk = 4000; > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > + fclk = clk_get(dev->dev, "fck"); > + fclk_rate = clk_get_rate(fclk) / 1000; You don't put the clk after getting it and using it once? > /* Compute prescaler divisor */ > psc = fclk_rate / internal_clk; > @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) > else > dev->reg_shift = 2; > > - if ((r = omap_i2c_get_clocks(dev)) != 0) > - goto err_iounmap; > - > if (cpu_is_omap44xx()) > dev->regs = (u8 *) omap4_reg_map; > else > dev->regs = (u8 *) reg_map; > > + pm_runtime_enable(&pdev->dev); > omap_i2c_unidle(dev); > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > @@ -1125,8 +1103,6 @@ err_free_irq: > err_unuse_clocks: > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > omap_i2c_idle(dev); > - omap_i2c_put_clocks(dev); > -err_iounmap: > iounmap(dev->base); > err_free_mem: > platform_set_drvdata(pdev, NULL); > @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) > free_irq(dev->irq, dev); > i2c_del_adapter(&dev->adapter); > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > - omap_i2c_put_clocks(dev); > iounmap(dev->base); > kfree(dev); > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > -- > 1.5.4.7 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- -- Ben Q: What's a light-year? A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-27 22:36 ` Ben Dooks @ 2010-09-28 5:58 ` Nayak, Rajendra 2010-09-28 6:59 ` Nayak, Rajendra 0 siblings, 1 reply; 17+ messages in thread From: Nayak, Rajendra @ 2010-09-28 5:58 UTC (permalink / raw) To: linux-arm-kernel > -----Original Message----- > From: Ben Dooks [mailto:ben-i2c at fluff.org] > Sent: Tuesday, September 28, 2010 4:07 AM > To: Nayak, Rajendra > Cc: linux-omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org; linux-i2c at vger.kernel.org; ben-linux at fluff.org; > khali at linux-fr.org; Kevin Hilman; Paul Walmsley > Subject: Re: [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's > > On Tue, Sep 21, 2010 at 07:37:16PM +0530, Rajendra Nayak wrote: > > This patch converts the i2c driver to use PM runtime apis > > > > Signed-off-by: Rajendra Nayak <rnayak@ti.com> > > Cc: Kevin Hilman <khilman@deeprootsystems.com> > > Cc: Paul Walmsley <paul@pwsan.com> > > --- > > drivers/i2c/busses/i2c-omap.c | 67 +++++++++++++---------------------------- > > 1 files changed, 21 insertions(+), 46 deletions(-) > > > > diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c > > index 7674efb..126bde9 100644 > > --- a/drivers/i2c/busses/i2c-omap.c > > +++ b/drivers/i2c/busses/i2c-omap.c > > @@ -39,6 +39,7 @@ > > #include <linux/io.h> > > #include <linux/slab.h> > > #include <linux/i2c-omap.h> > > +#include <linux/pm_runtime.h> > > > > /* I2C controller revisions */ > > #define OMAP_I2C_REV_2 0x20 > > @@ -175,8 +176,6 @@ struct omap_i2c_dev { > > void __iomem *base; /* virtual */ > > int irq; > > int reg_shift; /* bit shift for I2C register addresses */ > > - struct clk *iclk; /* Interface clock */ > > - struct clk *fclk; /* Functional clock */ > > struct completion cmd_complete; > > struct resource *ioarea; > > u32 latency; /* maximum mpu wkup latency */ > > @@ -265,45 +264,18 @@ static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) > > (i2c_dev->regs[reg] << i2c_dev->reg_shift)); > > } > > > > -static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) > > +static void omap_i2c_unidle(struct omap_i2c_dev *dev) > > { > > - int ret; > > + struct platform_device *pdev; > > + struct omap_i2c_bus_platform_data *pdata; > > > > - dev->iclk = clk_get(dev->dev, "ick"); > > - if (IS_ERR(dev->iclk)) { > > - ret = PTR_ERR(dev->iclk); > > - dev->iclk = NULL; > > - return ret; > > - } > > + WARN_ON(!dev->idle); > > > > - dev->fclk = clk_get(dev->dev, "fck"); > > - if (IS_ERR(dev->fclk)) { > > - ret = PTR_ERR(dev->fclk); > > - if (dev->iclk != NULL) { > > - clk_put(dev->iclk); > > - dev->iclk = NULL; > > - } > > - dev->fclk = NULL; > > - return ret; > > - } > > + pdev = to_platform_device(dev->dev); > > + pdata = pdev->dev.platform_data; > > > > - return 0; > > -} > > + pm_runtime_get_sync(&pdev->dev); > > > > -static void omap_i2c_put_clocks(struct omap_i2c_dev *dev) > > -{ > > - clk_put(dev->fclk); > > - dev->fclk = NULL; > > - clk_put(dev->iclk); > > - dev->iclk = NULL; > > -} > > - > > -static void omap_i2c_unidle(struct omap_i2c_dev *dev) > > -{ > > - WARN_ON(!dev->idle); > > - > > - clk_enable(dev->iclk); > > - clk_enable(dev->fclk); > > if (cpu_is_omap34xx()) { > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > omap_i2c_write_reg(dev, OMAP_I2C_PSC_REG, dev->pscstate); > > @@ -326,10 +298,15 @@ static void omap_i2c_unidle(struct omap_i2c_dev *dev) > > > > static void omap_i2c_idle(struct omap_i2c_dev *dev) > > { > > + struct platform_device *pdev; > > + struct omap_i2c_bus_platform_data *pdata; > > u16 iv; > > > > WARN_ON(dev->idle); > > > > + pdev = to_platform_device(dev->dev); > > + pdata = pdev->dev.platform_data; > > + > > dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG); > > if (dev->rev >= OMAP_I2C_REV_ON_4430) > > omap_i2c_write_reg(dev, OMAP_I2C_IRQENABLE_CLR, 1); > > @@ -345,8 +322,8 @@ static void omap_i2c_idle(struct omap_i2c_dev *dev) > > omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG); > > } > > dev->idle = 1; > > - clk_disable(dev->fclk); > > - clk_disable(dev->iclk); > > + > > + pm_runtime_put_sync(&pdev->dev); > > } > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > unsigned long fclk_rate = 12000000; > > unsigned long timeout; > > unsigned long internal_clk = 0; > > + struct clk *fclk; > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > /* Disable I2C controller before soft reset */ > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > * always returns 12MHz for the functional clock, we can > > * do this bit unconditionally. > > */ > > - fclk_rate = clk_get_rate(dev->fclk); > > + fclk = clk_get(dev->dev, "fck"); > > + fclk_rate = clk_get_rate(fclk); > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > * between 7 - 12 MHz. The XOR input clock is typically > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > internal_clk = 9600; > > else > > internal_clk = 4000; > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > + fclk = clk_get(dev->dev, "fck"); > > + fclk_rate = clk_get_rate(fclk) / 1000; > > You don't put the clk after getting it and using it once? clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate is used to merely know the existing rate of the clock. > > > /* Compute prescaler divisor */ > > psc = fclk_rate / internal_clk; > > @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) > > else > > dev->reg_shift = 2; > > > > - if ((r = omap_i2c_get_clocks(dev)) != 0) > > - goto err_iounmap; > > - > > if (cpu_is_omap44xx()) > > dev->regs = (u8 *) omap4_reg_map; > > else > > dev->regs = (u8 *) reg_map; > > > > + pm_runtime_enable(&pdev->dev); > > omap_i2c_unidle(dev); > > > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > @@ -1125,8 +1103,6 @@ err_free_irq: > > err_unuse_clocks: > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > omap_i2c_idle(dev); > > - omap_i2c_put_clocks(dev); > > -err_iounmap: > > iounmap(dev->base); > > err_free_mem: > > platform_set_drvdata(pdev, NULL); > > @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) > > free_irq(dev->irq, dev); > > i2c_del_adapter(&dev->adapter); > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > - omap_i2c_put_clocks(dev); > > iounmap(dev->base); > > kfree(dev); > > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > -- > > 1.5.4.7 > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > > the body of a message to majordomo at vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > -- > -- > Ben > > Q: What's a light-year? > A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 5:58 ` Nayak, Rajendra @ 2010-09-28 6:59 ` Nayak, Rajendra 2010-09-28 7:48 ` Russell King - ARM Linux 2010-09-28 23:33 ` Ben Dooks 0 siblings, 2 replies; 17+ messages in thread From: Nayak, Rajendra @ 2010-09-28 6:59 UTC (permalink / raw) To: linux-arm-kernel <snip>... > > > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > unsigned long fclk_rate = 12000000; > > > unsigned long timeout; > > > unsigned long internal_clk = 0; > > > + struct clk *fclk; > > > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > > /* Disable I2C controller before soft reset */ > > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > * always returns 12MHz for the functional clock, we can > > > * do this bit unconditionally. > > > */ > > > - fclk_rate = clk_get_rate(dev->fclk); > > > + fclk = clk_get(dev->dev, "fck"); > > > + fclk_rate = clk_get_rate(fclk); > > > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > > * between 7 - 12 MHz. The XOR input clock is typically > > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > internal_clk = 9600; > > > else > > > internal_clk = 4000; > > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > > + fclk = clk_get(dev->dev, "fck"); > > > + fclk_rate = clk_get_rate(fclk) / 1000; > > > > You don't put the clk after getting it and using it once? > > clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate > is used to merely know the existing rate of the clock. Sorry, I guess you did mean the clk_get above the clk_get_rate does not have an equivalent clk_put. I could put a clk_put for readability, but a clk_put on OMAP actually does map to an empty function. See arch/arm/plat-omap/include/plat/clkdev.h clk_get merely returns a pointer to the clk struct and does not do any usecounting, hence a clk_put does not do anything. > > > > > > /* Compute prescaler divisor */ > > > psc = fclk_rate / internal_clk; > > > @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) > > > else > > > dev->reg_shift = 2; > > > > > > - if ((r = omap_i2c_get_clocks(dev)) != 0) > > > - goto err_iounmap; > > > - > > > if (cpu_is_omap44xx()) > > > dev->regs = (u8 *) omap4_reg_map; > > > else > > > dev->regs = (u8 *) reg_map; > > > > > > + pm_runtime_enable(&pdev->dev); > > > omap_i2c_unidle(dev); > > > > > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > > @@ -1125,8 +1103,6 @@ err_free_irq: > > > err_unuse_clocks: > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > omap_i2c_idle(dev); > > > - omap_i2c_put_clocks(dev); > > > -err_iounmap: > > > iounmap(dev->base); > > > err_free_mem: > > > platform_set_drvdata(pdev, NULL); > > > @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) > > > free_irq(dev->irq, dev); > > > i2c_del_adapter(&dev->adapter); > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > - omap_i2c_put_clocks(dev); > > > iounmap(dev->base); > > > kfree(dev); > > > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > > -- > > > 1.5.4.7 > > > > > > -- > > > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > > > the body of a message to majordomo at vger.kernel.org > > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > -- > > -- > > Ben > > > > Q: What's a light-year? > > A: One-third less calories than a regular year. > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 6:59 ` Nayak, Rajendra @ 2010-09-28 7:48 ` Russell King - ARM Linux 2010-09-28 8:56 ` Nayak, Rajendra 2010-09-28 23:33 ` Ben Dooks 1 sibling, 1 reply; 17+ messages in thread From: Russell King - ARM Linux @ 2010-09-28 7:48 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 28, 2010 at 12:29:01PM +0530, Nayak, Rajendra wrote: > <snip>... > > > > > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > unsigned long fclk_rate = 12000000; > > > > unsigned long timeout; > > > > unsigned long internal_clk = 0; > > > > + struct clk *fclk; > > > > > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > > > /* Disable I2C controller before soft reset */ > > > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > * always returns 12MHz for the functional clock, we can > > > > * do this bit unconditionally. > > > > */ > > > > - fclk_rate = clk_get_rate(dev->fclk); > > > > + fclk = clk_get(dev->dev, "fck"); > > > > + fclk_rate = clk_get_rate(fclk); > > > > > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > > > * between 7 - 12 MHz. The XOR input clock is typically > > > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > internal_clk = 9600; > > > > else > > > > internal_clk = 4000; > > > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > > > + fclk = clk_get(dev->dev, "fck"); > > > > + fclk_rate = clk_get_rate(fclk) / 1000; > > > > > > You don't put the clk after getting it and using it once? > > > > clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate > > is used to merely know the existing rate of the clock. > > Sorry, I guess you did mean the clk_get above the clk_get_rate does not have > an equivalent clk_put. > I could put a clk_put for readability, but a clk_put on OMAP actually does map > to an empty function. > See arch/arm/plat-omap/include/plat/clkdev.h > clk_get merely returns a pointer to the clk struct and does not do any usecounting, > hence a clk_put does not do anything. That's no reason to avoid using it. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 7:48 ` Russell King - ARM Linux @ 2010-09-28 8:56 ` Nayak, Rajendra 0 siblings, 0 replies; 17+ messages in thread From: Nayak, Rajendra @ 2010-09-28 8:56 UTC (permalink / raw) To: linux-arm-kernel > -----Original Message----- > From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk] > Sent: Tuesday, September 28, 2010 1:19 PM > To: Nayak, Rajendra > Cc: Ben Dooks; Paul Walmsley; Kevin Hilman; linux-i2c at vger.kernel.org; ben-linux at fluff.org; khali at linux-fr.org; linux- > omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org > Subject: Re: [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's > > On Tue, Sep 28, 2010 at 12:29:01PM +0530, Nayak, Rajendra wrote: > > <snip>... > > > > > > > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > unsigned long fclk_rate = 12000000; > > > > > unsigned long timeout; > > > > > unsigned long internal_clk = 0; > > > > > + struct clk *fclk; > > > > > > > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > > > > /* Disable I2C controller before soft reset */ > > > > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > * always returns 12MHz for the functional clock, we can > > > > > * do this bit unconditionally. > > > > > */ > > > > > - fclk_rate = clk_get_rate(dev->fclk); > > > > > + fclk = clk_get(dev->dev, "fck"); > > > > > + fclk_rate = clk_get_rate(fclk); > > > > > > > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > > > > * between 7 - 12 MHz. The XOR input clock is typically > > > > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > internal_clk = 9600; > > > > > else > > > > > internal_clk = 4000; > > > > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > > > > + fclk = clk_get(dev->dev, "fck"); > > > > > + fclk_rate = clk_get_rate(fclk) / 1000; > > > > > > > > You don't put the clk after getting it and using it once? > > > > > > clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate > > > is used to merely know the existing rate of the clock. > > > > Sorry, I guess you did mean the clk_get above the clk_get_rate does not have > > an equivalent clk_put. > > I could put a clk_put for readability, but a clk_put on OMAP actually does map > > to an empty function. > > See arch/arm/plat-omap/include/plat/clkdev.h > > clk_get merely returns a pointer to the clk struct and does not do any usecounting, > > hence a clk_put does not do anything. > > That's no reason to avoid using it. Ok, I'll post an updated patch with the matching clk_put's in place. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 6:59 ` Nayak, Rajendra 2010-09-28 7:48 ` Russell King - ARM Linux @ 2010-09-28 23:33 ` Ben Dooks 2010-09-29 4:00 ` Nayak, Rajendra 2010-10-07 17:37 ` Kevin Hilman 1 sibling, 2 replies; 17+ messages in thread From: Ben Dooks @ 2010-09-28 23:33 UTC (permalink / raw) To: linux-arm-kernel On Tue, Sep 28, 2010 at 12:29:01PM +0530, Nayak, Rajendra wrote: > <snip>... > > > > > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > unsigned long fclk_rate = 12000000; > > > > unsigned long timeout; > > > > unsigned long internal_clk = 0; > > > > + struct clk *fclk; > > > > > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > > > /* Disable I2C controller before soft reset */ > > > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > * always returns 12MHz for the functional clock, we can > > > > * do this bit unconditionally. > > > > */ > > > > - fclk_rate = clk_get_rate(dev->fclk); > > > > + fclk = clk_get(dev->dev, "fck"); > > > > + fclk_rate = clk_get_rate(fclk); > > > > > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > > > * between 7 - 12 MHz. The XOR input clock is typically > > > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > internal_clk = 9600; > > > > else > > > > internal_clk = 4000; > > > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > > > + fclk = clk_get(dev->dev, "fck"); > > > > + fclk_rate = clk_get_rate(fclk) / 1000; > > > > > > You don't put the clk after getting it and using it once? > > > > clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate > > is used to merely know the existing rate of the clock. > > Sorry, I guess you did mean the clk_get above the clk_get_rate does not have > an equivalent clk_put. > I could put a clk_put for readability, but a clk_put on OMAP actually does map > to an empty function. > See arch/arm/plat-omap/include/plat/clkdev.h > clk_get merely returns a pointer to the clk struct and does not do any usecounting, > hence a clk_put does not do anything. clk_get() should have a reference counter, and on many systems does. This is why we ask people to put clk_put() when they don't need the clock any more. It may not do anything on your system, but it will set a good example to anyone copying your driver code. As such, I should really go and read up all about this new runtime-pm and hwmod stuff before further commentign on the changes. > > > > > > > > > /* Compute prescaler divisor */ > > > > psc = fclk_rate / internal_clk; > > > > @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) > > > > else > > > > dev->reg_shift = 2; > > > > > > > > - if ((r = omap_i2c_get_clocks(dev)) != 0) > > > > - goto err_iounmap; > > > > - > > > > if (cpu_is_omap44xx()) > > > > dev->regs = (u8 *) omap4_reg_map; > > > > else > > > > dev->regs = (u8 *) reg_map; > > > > > > > > + pm_runtime_enable(&pdev->dev); > > > > omap_i2c_unidle(dev); > > > > > > > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > > > @@ -1125,8 +1103,6 @@ err_free_irq: > > > > err_unuse_clocks: > > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > > omap_i2c_idle(dev); > > > > - omap_i2c_put_clocks(dev); > > > > -err_iounmap: > > > > iounmap(dev->base); > > > > err_free_mem: > > > > platform_set_drvdata(pdev, NULL); > > > > @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) > > > > free_irq(dev->irq, dev); > > > > i2c_del_adapter(&dev->adapter); > > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > > - omap_i2c_put_clocks(dev); > > > > iounmap(dev->base); > > > > kfree(dev); > > > > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > > > -- > > > > 1.5.4.7 > > > > > > > > -- > > > > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > > > > the body of a message to majordomo at vger.kernel.org > > > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > > > -- > > > -- > > > Ben > > > > > > Q: What's a light-year? > > > A: One-third less calories than a regular year. > > > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > > the body of a message to majordomo at vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel at lists.infradead.org > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- -- Ben Q: What's a light-year? A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 23:33 ` Ben Dooks @ 2010-09-29 4:00 ` Nayak, Rajendra 2010-10-07 17:37 ` Kevin Hilman 1 sibling, 0 replies; 17+ messages in thread From: Nayak, Rajendra @ 2010-09-29 4:00 UTC (permalink / raw) To: linux-arm-kernel > -----Original Message----- > From: Ben Dooks [mailto:ben-i2c at fluff.org] > Sent: Wednesday, September 29, 2010 5:04 AM > To: Nayak, Rajendra > Cc: Ben Dooks; Paul Walmsley; Kevin Hilman; linux-i2c at vger.kernel.org; ben-linux at fluff.org; khali at linux-fr.org; linux- > omap at vger.kernel.org; linux-arm-kernel at lists.infradead.org > Subject: Re: [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's > > On Tue, Sep 28, 2010 at 12:29:01PM +0530, Nayak, Rajendra wrote: > > <snip>... > > > > > > > > > > static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > @@ -356,6 +333,7 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > unsigned long fclk_rate = 12000000; > > > > > unsigned long timeout; > > > > > unsigned long internal_clk = 0; > > > > > + struct clk *fclk; > > > > > > > > > > if (dev->rev >= OMAP_I2C_REV_2) { > > > > > /* Disable I2C controller before soft reset */ > > > > > @@ -414,7 +392,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > * always returns 12MHz for the functional clock, we can > > > > > * do this bit unconditionally. > > > > > */ > > > > > - fclk_rate = clk_get_rate(dev->fclk); > > > > > + fclk = clk_get(dev->dev, "fck"); > > > > > + fclk_rate = clk_get_rate(fclk); > > > > > > > > > > /* TRM for 5912 says the I2C clock must be prescaled to be > > > > > * between 7 - 12 MHz. The XOR input clock is typically > > > > > @@ -443,7 +422,8 @@ static int omap_i2c_init(struct omap_i2c_dev *dev) > > > > > internal_clk = 9600; > > > > > else > > > > > internal_clk = 4000; > > > > > - fclk_rate = clk_get_rate(dev->fclk) / 1000; > > > > > + fclk = clk_get(dev->dev, "fck"); > > > > > + fclk_rate = clk_get_rate(fclk) / 1000; > > > > > > > > You don't put the clk after getting it and using it once? > > > > > > clk_get needs an equivalent clk_put and not clk_get_rate. clk_get_rate > > > is used to merely know the existing rate of the clock. > > > > Sorry, I guess you did mean the clk_get above the clk_get_rate does not have > > an equivalent clk_put. > > I could put a clk_put for readability, but a clk_put on OMAP actually does map > > to an empty function. > > See arch/arm/plat-omap/include/plat/clkdev.h > > clk_get merely returns a pointer to the clk struct and does not do any usecounting, > > hence a clk_put does not do anything. > > clk_get() should have a reference counter, and on many systems does. > > This is why we ask people to put clk_put() when they don't need the > clock any more. It may not do anything on your system, but it will > set a good example to anyone copying your driver code. I agree. There is an updated patch now posted with the clk_put's in place. > > As such, I should really go and read up all about this new runtime-pm > and hwmod stuff before further commentign on the changes. Ok. Thanks. > > > > > > > > > > > > > /* Compute prescaler divisor */ > > > > > psc = fclk_rate / internal_clk; > > > > > @@ -1046,14 +1026,12 @@ omap_i2c_probe(struct platform_device *pdev) > > > > > else > > > > > dev->reg_shift = 2; > > > > > > > > > > - if ((r = omap_i2c_get_clocks(dev)) != 0) > > > > > - goto err_iounmap; > > > > > - > > > > > if (cpu_is_omap44xx()) > > > > > dev->regs = (u8 *) omap4_reg_map; > > > > > else > > > > > dev->regs = (u8 *) reg_map; > > > > > > > > > > + pm_runtime_enable(&pdev->dev); > > > > > omap_i2c_unidle(dev); > > > > > > > > > > dev->rev = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) & 0xff; > > > > > @@ -1125,8 +1103,6 @@ err_free_irq: > > > > > err_unuse_clocks: > > > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > > > omap_i2c_idle(dev); > > > > > - omap_i2c_put_clocks(dev); > > > > > -err_iounmap: > > > > > iounmap(dev->base); > > > > > err_free_mem: > > > > > platform_set_drvdata(pdev, NULL); > > > > > @@ -1148,7 +1124,6 @@ omap_i2c_remove(struct platform_device *pdev) > > > > > free_irq(dev->irq, dev); > > > > > i2c_del_adapter(&dev->adapter); > > > > > omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0); > > > > > - omap_i2c_put_clocks(dev); > > > > > iounmap(dev->base); > > > > > kfree(dev); > > > > > mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); > > > > > -- > > > > > 1.5.4.7 > > > > > > > > > > -- > > > > > To unsubscribe from this list: send the line "unsubscribe linux-i2c" in > > > > > the body of a message to majordomo at vger.kernel.org > > > > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > > > > > -- > > > > -- > > > > Ben > > > > > > > > Q: What's a light-year? > > > > A: One-third less calories than a regular year. > > > > > > -- > > > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > > > the body of a message to majordomo at vger.kernel.org > > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > _______________________________________________ > > linux-arm-kernel mailing list > > linux-arm-kernel at lists.infradead.org > > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel > > -- > -- > Ben > > Q: What's a light-year? > A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-09-28 23:33 ` Ben Dooks 2010-09-29 4:00 ` Nayak, Rajendra @ 2010-10-07 17:37 ` Kevin Hilman 2010-10-27 7:35 ` Ben Dooks 1 sibling, 1 reply; 17+ messages in thread From: Kevin Hilman @ 2010-10-07 17:37 UTC (permalink / raw) To: linux-arm-kernel Ben Dooks <ben-i2c@fluff.org> writes: [...] > As such, I should really go and read up all about this new runtime-pm > and hwmod stuff before further commentign on the changes. ping >From bogus@does.not.exist.com Wed Oct 6 18:52:23 2010 From: bogus@does.not.exist.com () Date: Wed, 06 Oct 2010 22:52:23 -0000 Subject: No subject Message-ID: <mailman.2.1286473034.390.linux-arm-kernel@lists.infradead.org> omap_hwmod. You can think of this change as simply using the runtime PM API instead of the clock API for enabling and idling the device. With your ack (on this patch only) we'd like to merge this along with the rest of the series for 2.6.37. Kevin ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-10-07 17:37 ` Kevin Hilman @ 2010-10-27 7:35 ` Ben Dooks 2010-11-09 17:41 ` Kevin Hilman 0 siblings, 1 reply; 17+ messages in thread From: Ben Dooks @ 2010-10-27 7:35 UTC (permalink / raw) To: linux-arm-kernel On Thu, Oct 07, 2010 at 10:37:03AM -0700, Kevin Hilman wrote: > Ben Dooks <ben-i2c@fluff.org> writes: > > [...] > > > As such, I should really go and read up all about this new runtime-pm > > and hwmod stuff before further commentign on the changes. > > ping > > >From the drivers perspective, you don't neet to know anything about > omap_hwmod. You can think of this change as simply using the runtime PM > API instead of the clock API for enabling and idling the device. > > With your ack (on this patch only) we'd like to merge this along with > the rest of the series for 2.6.37. Acked-by: Ben Dooks <ben-linux@fluff.org> please post via your tree. -- Ben Q: What's a light-year? A: One-third less calories than a regular year. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's 2010-10-27 7:35 ` Ben Dooks @ 2010-11-09 17:41 ` Kevin Hilman 0 siblings, 0 replies; 17+ messages in thread From: Kevin Hilman @ 2010-11-09 17:41 UTC (permalink / raw) To: linux-arm-kernel Ben Dooks <ben-i2c@fluff.org> writes: > On Thu, Oct 07, 2010 at 10:37:03AM -0700, Kevin Hilman wrote: >> Ben Dooks <ben-i2c@fluff.org> writes: >> >> [...] >> >> > As such, I should really go and read up all about this new runtime-pm >> > and hwmod stuff before further commentign on the changes. >> >> ping >> >> >From the drivers perspective, you don't neet to know anything about >> omap_hwmod. You can think of this change as simply using the runtime PM >> API instead of the clock API for enabling and idling the device. >> >> With your ack (on this patch only) we'd like to merge this along with >> the rest of the series for 2.6.37. > > Acked-by: Ben Dooks <ben-linux@fluff.org> > > please post via your tree. Thanks Ben, Will queue up for 2.6.38. Kevin ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM 2010-09-21 14:07 [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 1/5] OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 Rajendra Nayak @ 2010-09-27 20:02 ` Kevin Hilman 1 sibling, 0 replies; 17+ messages in thread From: Kevin Hilman @ 2010-09-27 20:02 UTC (permalink / raw) To: linux-arm-kernel Ben, Rajendra Nayak <rnayak@ti.com> writes: > This series makes I2C device registration use hwmod and omap_device api's > and converts the I2C driver to use runtime PM api's. > > Patches apply on the pm-core branch from Kevin's tree. If you're OK with the driver changes in PATCH 5/5, with your Ack, we can queue this via the OMAP tree with all the platform changes that it depends on. Thanks, Kevin > v3 has minor review comment fixes over v2 > The series is boot tested on a 2430sdp platform along with being tested > on 3430sdp and 4430sdp. > > 4430sdp tests are done using the below series > http://www.spinics.net/lists/linux-omap/msg36023.html > > Paul Walmsley (2): > OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 > OMAP: I2C: split device registration and convert OMAP2+ to > omap_device > > Rajendra Nayak (3): > OMAP3: hwmod: add I2C hwmods for OMAP3430 > OMAP4: hwmod: add I2C hwmods for OMAP4430 > OMAP: I2C: Convert i2c driver to use PM runtime api's > > arch/arm/mach-omap2/cm-regbits-24xx.h | 4 + > arch/arm/mach-omap2/omap_hwmod_2420_data.c | 140 ++++++++++++++++- > arch/arm/mach-omap2/omap_hwmod_2430_data.c | 154 ++++++++++++++++++- > arch/arm/mach-omap2/omap_hwmod_3xxx_data.c | 232 +++++++++++++++++++++++++++ > arch/arm/mach-omap2/omap_hwmod_44xx_data.c | 237 ++++++++++++++++++++++++++++ > arch/arm/mach-omap2/prm-regbits-34xx.h | 3 + > arch/arm/plat-omap/i2c.c | 124 ++++++--------- > arch/arm/plat-omap/include/plat/i2c.h | 16 ++ > arch/arm/plat-omap/include/plat/l4_3xxx.h | 24 +++ > drivers/i2c/busses/i2c-omap.c | 67 +++------ > include/linux/i2c-omap.h | 5 + > 11 files changed, 881 insertions(+), 125 deletions(-) > create mode 100644 arch/arm/plat-omap/include/plat/l4_3xxx.h > > -- > To unsubscribe from this list: send the line "unsubscribe linux-omap" in > the body of a message to majordomo at vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2010-11-09 17:41 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-09-21 14:07 [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 1/5] OMAP2xxx: hwmod: add I2C hwmods for OMAP2420, 2430 Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 2/5] OMAP3: hwmod: add I2C hwmods for OMAP3430 Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 3/5] OMAP4: hwmod: add I2C hwmods for OMAP4430 Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 4/5] OMAP: I2C: split device registration and convert OMAP2+ to omap_device Rajendra Nayak 2010-09-21 14:07 ` [PATCH v3 5/5] OMAP: I2C: Convert i2c driver to use PM runtime api's Rajendra Nayak 2010-09-27 22:36 ` Ben Dooks 2010-09-28 5:58 ` Nayak, Rajendra 2010-09-28 6:59 ` Nayak, Rajendra 2010-09-28 7:48 ` Russell King - ARM Linux 2010-09-28 8:56 ` Nayak, Rajendra 2010-09-28 23:33 ` Ben Dooks 2010-09-29 4:00 ` Nayak, Rajendra 2010-10-07 17:37 ` Kevin Hilman 2010-10-27 7:35 ` Ben Dooks 2010-11-09 17:41 ` Kevin Hilman 2010-09-27 20:02 ` [PATCH v3 0/5] Convert I2C driver to use omap_device/runtime PM Kevin Hilman
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).