This patch implements an idea from Igor Stoppa <igor.stoppa@xxxxxxxxx> from last year. We use functions to modify PRM/CM register bits, rather than open-coding those operations. The patch provides functions that do read + AND + OR + write sequences on CM and PRM registers: {cm,prm}_rmw_reg_bits(), and {cm,prm}_rmw_mod_reg_bits(). Several convenience functions are then implemented on top of those functions for setting and clearing bits: {cm,prm}_{set,clear}_mod_reg_bits(). These functions don't provide any locking; it is expected that the caller will handle this. Thanks to Jouni Högander <jouni.hogander@xxxxxxxxx> for catching some embarrassing errors in earlier versions of this code. Signed-off-by: Paul Walmsley <paul@xxxxxxxxx> --- arch/arm/mach-omap2/cm.h | 34 +++++++++++++++++++++++++++++++++- arch/arm/mach-omap2/prm.h | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 4 deletions(-) Index: linux-omap/arch/arm/mach-omap2/cm.h =================================================================== --- linux-omap.orig/arch/arm/mach-omap2/cm.h 2008-03-30 16:15:32.000000000 -0600 +++ linux-omap/arch/arm/mach-omap2/cm.h 2008-03-30 16:27:15.000000000 -0600 @@ -14,6 +14,8 @@ * published by the Free Software Foundation. */ +#include <asm/io.h> + #include "prcm-common.h" #ifndef __ASSEMBLER__ @@ -54,6 +56,20 @@ { return __raw_readl(addr); } + +/* Read-modify-write bits in a CM register */ +static u32 __attribute__((unused)) cm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *va) +{ + u32 v; + + v = cm_read_reg(va); + v &= ~mask; + v |= bits; + cm_write_reg(v, va); + + return v; +} + #endif /* @@ -83,7 +99,6 @@ #define CM_CLKSEL2 0x0044 #define CM_CLKSTCTRL 0x0048 - /* Architecture-specific registers */ #define OMAP24XX_CM_FCLKEN2 0x0004 @@ -122,6 +137,23 @@ { return cm_read_reg(OMAP_CM_REGADDR(module, idx)); } + +/* Read-modify-write bits in a CM register (by domain) */ +static inline u32 __attribute__((unused)) cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) +{ + return cm_rmw_reg_bits(mask, bits, OMAP_CM_REGADDR(module, idx)); +} + +static inline u32 __attribute__((unused)) cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return cm_rmw_mod_reg_bits(bits, bits, module, idx); +} + +static inline u32 __attribute__((unused)) cm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return cm_rmw_mod_reg_bits(bits, 0x0, module, idx); +} + #endif /* CM register bits shared between 24XX and 3430 */ Index: linux-omap/arch/arm/mach-omap2/prm.h =================================================================== --- linux-omap.orig/arch/arm/mach-omap2/prm.h 2008-03-30 16:15:32.000000000 -0600 +++ linux-omap/arch/arm/mach-omap2/prm.h 2008-03-30 16:27:15.000000000 -0600 @@ -4,8 +4,8 @@ /* * OMAP2/3 Power/Reset Management (PRM) register definitions * - * Copyright (C) 2007 Texas Instruments, Inc. - * Copyright (C) 2007 Nokia Corporation + * Copyright (C) 2007-2008 Texas Instruments, Inc. + * Copyright (C) 2007-2008 Nokia Corporation * * Written by Paul Walmsley * @@ -14,6 +14,9 @@ * published by the Free Software Foundation. */ +#include <asm/io.h> +#include <asm/bitops.h> + #include "prcm-common.h" #ifndef __ASSEMBLER__ @@ -61,7 +64,6 @@ #define OMAP3430_PRM_IRQSTATUS_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x0018) #define OMAP3430_PRM_IRQENABLE_MPU OMAP_PRM_REGADDR(OCP_MOD, 0x001c) - #define OMAP3430_PRM_VC_SMPS_SA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0020) #define OMAP3430_PRM_VC_SMPS_VOL_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0024) #define OMAP3430_PRM_VC_SMPS_CMD_RA OMAP_PRM_REGADDR(OMAP3430_GR_MOD, 0x0028) @@ -113,6 +115,19 @@ return __raw_readl(addr); } +/* Read-modify-write bits in a PRM register */ +static u32 __attribute__((unused)) prm_rmw_reg_bits(u32 mask, u32 bits, void __iomem *va) +{ + u32 v; + + v = prm_read_reg(va); + v &= ~mask; + v |= bits; + prm_write_reg(v, va); + + return v; +} + #endif /* @@ -154,6 +169,22 @@ #define OMAP3430_PRM_IRQSTATUS_IVA2 0x00f8 #define OMAP3430_PRM_IRQENABLE_IVA2 0x00fc +/* Read-modify-write bits in a PRM register (by domain) */ +static u32 __attribute__((unused)) prm_rmw_mod_reg_bits(u32 mask, u32 bits, + s16 module, s16 idx) +{ + return prm_rmw_reg_bits(mask, bits, OMAP_PRM_REGADDR(module, idx)); +} + +static u32 __attribute__((unused)) prm_set_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return prm_rmw_mod_reg_bits(bits, bits, module, idx); +} + +static u32 __attribute__((unused)) prm_clear_mod_reg_bits(u32 bits, s16 module, s16 idx) +{ + return prm_rmw_mod_reg_bits(bits, 0x0, module, idx); +} /* Architecture-specific registers */ -- -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html