diff options
author | weiyi.lu@mediatek.com <weiyi.lu@mediatek.com> | 2017-11-28 15:28:18 +0800 |
---|---|---|
committer | Matthias Brugger <matthias.bgg@gmail.com> | 2017-12-21 11:49:22 +0100 |
commit | fa7e843a901d4ea6b092fea67406f85e8ec60b22 (patch) | |
tree | 716939671bf7f30cad930048a903d33b8c222938 /drivers/soc/mediatek/mtk-infracfg.c | |
parent | 3dcf01c9707d49e8a38387f4dfe9f43dfb0e63eb (diff) |
soc: mediatek: extend bus protection API
MT2712 add "set/clear" bus control register to each control register set
instead of providing only one "enable" control register, we could avoid
the read-modify-write racing by declaring "bus_prot_reg_update" as "false"
in scp_soc_data or declaring as "true" to use the legacy update method.
By improving the mtk-infracfg bus protection implementation to
support set/clear bus protection control method by IC configuration.
Signed-off-by: Weiyi Lu <weiyi.lu@mediatek.com>
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
Diffstat (limited to 'drivers/soc/mediatek/mtk-infracfg.c')
-rw-r--r-- | drivers/soc/mediatek/mtk-infracfg.c | 26 |
1 files changed, 22 insertions, 4 deletions
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c index dba3055a9493..8c310de01e93 100644 --- a/drivers/soc/mediatek/mtk-infracfg.c +++ b/drivers/soc/mediatek/mtk-infracfg.c @@ -19,23 +19,33 @@ #define INFRA_TOPAXI_PROTECTEN 0x0220 #define INFRA_TOPAXI_PROTECTSTA1 0x0228 +#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 +#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 /** * mtk_infracfg_set_bus_protection - enable bus protection * @regmap: The infracfg regmap * @mask: The mask containing the protection bits to be enabled. + * @reg_update: The boolean flag determines to set the protection bits + * by regmap_update_bits with enable register(PROTECTEN) or + * by regmap_write with set register(PROTECTEN_SET). * * This function enables the bus protection bits for disabled power * domains so that the system does not hang when some unit accesses the * bus while in power down. */ -int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, + bool reg_update) { unsigned long expired; u32 val; int ret; - regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); + if (reg_update) + regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, + mask); + else + regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); expired = jiffies + HZ; @@ -59,16 +69,24 @@ int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) * mtk_infracfg_clear_bus_protection - disable bus protection * @regmap: The infracfg regmap * @mask: The mask containing the protection bits to be disabled. + * @reg_update: The boolean flag determines to clear the protection bits + * by regmap_update_bits with enable register(PROTECTEN) or + * by regmap_write with clear register(PROTECTEN_CLR). * * This function disables the bus protection bits previously enabled with * mtk_infracfg_set_bus_protection. */ -int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) + +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, + bool reg_update) { unsigned long expired; int ret; - regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); + if (reg_update) + regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); + else + regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask); expired = jiffies + HZ; |