diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2015-06-24 02:17:02 -0400 |
---|---|---|
committer | Matthias Brugger <matthias.bgg@gmail.com> | 2015-07-06 12:36:31 -0400 |
commit | 16a624a9c81814cc2f1353eff2e502430c3fa79a (patch) | |
tree | 3c96296333870a05928a846967084de73e1446fd /drivers/soc | |
parent | d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff) |
soc: mediatek: Add infracfg misc driver support
This adds support for some miscellaneous bits of the infracfg controller.
The mtk_infracfg_set/clear_bus_protection functions are necessary for
the scpsys power domain driver to handle the bus protection bits which
are contained in the infacfg register space.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Daniel Kurtz <djkurtz@chromium.org>
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/mediatek/Kconfig | 9 | ||||
-rw-r--r-- | drivers/soc/mediatek/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/mediatek/mtk-infracfg.c | 91 |
3 files changed, 101 insertions, 0 deletions
diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 3c1850332a90..e609a6f5e2eb 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig | |||
@@ -1,6 +1,15 @@ | |||
1 | # | 1 | # |
2 | # MediaTek SoC drivers | 2 | # MediaTek SoC drivers |
3 | # | 3 | # |
4 | config MTK_INFRACFG | ||
5 | bool "MediaTek INFRACFG Support" | ||
6 | depends on ARCH_MEDIATEK || COMPILE_TEST | ||
7 | select REGMAP | ||
8 | help | ||
9 | Say yes here to add support for the MediaTek INFRACFG controller. The | ||
10 | INFRACFG controller contains various infrastructure registers not | ||
11 | directly associated to any device. | ||
12 | |||
4 | config MTK_PMIC_WRAP | 13 | config MTK_PMIC_WRAP |
5 | tristate "MediaTek PMIC Wrapper Support" | 14 | tristate "MediaTek PMIC Wrapper Support" |
6 | depends on ARCH_MEDIATEK | 15 | depends on ARCH_MEDIATEK |
diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index ecaf4defd7f6..3fa940fb4eab 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile | |||
@@ -1 +1,2 @@ | |||
1 | obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o | ||
1 | obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o | 2 | obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o |
diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c new file mode 100644 index 000000000000..dba3055a9493 --- /dev/null +++ b/drivers/soc/mediatek/mtk-infracfg.c | |||
@@ -0,0 +1,91 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/export.h> | ||
15 | #include <linux/jiffies.h> | ||
16 | #include <linux/regmap.h> | ||
17 | #include <linux/soc/mediatek/infracfg.h> | ||
18 | #include <asm/processor.h> | ||
19 | |||
20 | #define INFRA_TOPAXI_PROTECTEN 0x0220 | ||
21 | #define INFRA_TOPAXI_PROTECTSTA1 0x0228 | ||
22 | |||
23 | /** | ||
24 | * mtk_infracfg_set_bus_protection - enable bus protection | ||
25 | * @regmap: The infracfg regmap | ||
26 | * @mask: The mask containing the protection bits to be enabled. | ||
27 | * | ||
28 | * This function enables the bus protection bits for disabled power | ||
29 | * domains so that the system does not hang when some unit accesses the | ||
30 | * bus while in power down. | ||
31 | */ | ||
32 | int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) | ||
33 | { | ||
34 | unsigned long expired; | ||
35 | u32 val; | ||
36 | int ret; | ||
37 | |||
38 | regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); | ||
39 | |||
40 | expired = jiffies + HZ; | ||
41 | |||
42 | while (1) { | ||
43 | ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); | ||
44 | if (ret) | ||
45 | return ret; | ||
46 | |||
47 | if ((val & mask) == mask) | ||
48 | break; | ||
49 | |||
50 | cpu_relax(); | ||
51 | if (time_after(jiffies, expired)) | ||
52 | return -EIO; | ||
53 | } | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | /** | ||
59 | * mtk_infracfg_clear_bus_protection - disable bus protection | ||
60 | * @regmap: The infracfg regmap | ||
61 | * @mask: The mask containing the protection bits to be disabled. | ||
62 | * | ||
63 | * This function disables the bus protection bits previously enabled with | ||
64 | * mtk_infracfg_set_bus_protection. | ||
65 | */ | ||
66 | int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) | ||
67 | { | ||
68 | unsigned long expired; | ||
69 | int ret; | ||
70 | |||
71 | regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); | ||
72 | |||
73 | expired = jiffies + HZ; | ||
74 | |||
75 | while (1) { | ||
76 | u32 val; | ||
77 | |||
78 | ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); | ||
79 | if (ret) | ||
80 | return ret; | ||
81 | |||
82 | if (!(val & mask)) | ||
83 | break; | ||
84 | |||
85 | cpu_relax(); | ||
86 | if (time_after(jiffies, expired)) | ||
87 | return -EIO; | ||
88 | } | ||
89 | |||
90 | return 0; | ||
91 | } | ||