Skip to content

Commit 390c010

Browse files
MrVanShawn Guo
authored andcommitted
soc: imx8m: Cleanup with adding imx8m_soc_[un]prepare
There is a common flow to i.MX8M family, map OCOTP register base and enable ocotp clk first before read Unique ID from OCOTP. So introduce imx8m_soc_prepare to do ioremap and enable the ocotp clk, and introduce imx8m_soc_unprepare to disable the clk and do iounmap. With this patch, no need to spread the ioremap and clk handling in each soc_revision hook. Signed-off-by: Peng Fan <[email protected]> Reviewed-by: Marco Felsch <[email protected]> Signed-off-by: Shawn Guo <[email protected]>
1 parent 0af2f6b commit 390c010

File tree

1 file changed

+72
-61
lines changed

1 file changed

+72
-61
lines changed

drivers/soc/imx/soc-imx8m.c

Lines changed: 72 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,13 @@
3030

3131
struct imx8_soc_data {
3232
char *name;
33-
int (*soc_revision)(u32 *socrev, u64 *socuid);
33+
const char *ocotp_compatible;
34+
int (*soc_revision)(struct platform_device *pdev, u32 *socrev, u64 *socuid);
35+
};
36+
37+
struct imx8_soc_drvdata {
38+
void __iomem *ocotp_base;
39+
struct clk *clk;
3440
};
3541

3642
#ifdef CONFIG_HAVE_ARM_SMCCC
@@ -49,30 +55,12 @@ static u32 imx8mq_soc_revision_from_atf(void)
4955
static inline u32 imx8mq_soc_revision_from_atf(void) { return 0; };
5056
#endif
5157

52-
static int imx8mq_soc_revision(u32 *socrev, u64 *socuid)
58+
static int imx8mq_soc_revision(struct platform_device *pdev, u32 *socrev, u64 *socuid)
5359
{
54-
struct device_node *np __free(device_node) =
55-
of_find_compatible_node(NULL, NULL, "fsl,imx8mq-ocotp");
56-
void __iomem *ocotp_base;
60+
struct imx8_soc_drvdata *drvdata = platform_get_drvdata(pdev);
61+
void __iomem *ocotp_base = drvdata->ocotp_base;
5762
u32 magic;
5863
u32 rev;
59-
struct clk *clk;
60-
int ret;
61-
62-
if (!np)
63-
return -EINVAL;
64-
65-
ocotp_base = of_iomap(np, 0);
66-
if (!ocotp_base)
67-
return -EINVAL;
68-
69-
clk = of_clk_get_by_name(np, NULL);
70-
if (IS_ERR(clk)) {
71-
ret = PTR_ERR(clk);
72-
goto err_clk;
73-
}
74-
75-
clk_prepare_enable(clk);
7664

7765
/*
7866
* SOC revision on older imx8mq is not available in fuses so query
@@ -91,55 +79,24 @@ static int imx8mq_soc_revision(u32 *socrev, u64 *socuid)
9179

9280
*socrev = rev;
9381

94-
clk_disable_unprepare(clk);
95-
clk_put(clk);
96-
iounmap(ocotp_base);
97-
9882
return 0;
99-
100-
err_clk:
101-
iounmap(ocotp_base);
102-
return ret;
10383
}
10484

105-
static int imx8mm_soc_uid(u64 *socuid)
85+
static int imx8mm_soc_uid(struct platform_device *pdev, u64 *socuid)
10686
{
107-
struct device_node *np __free(device_node) =
108-
of_find_compatible_node(NULL, NULL, "fsl,imx8mm-ocotp");
109-
void __iomem *ocotp_base;
110-
struct clk *clk;
111-
int ret = 0;
87+
struct imx8_soc_drvdata *drvdata = platform_get_drvdata(pdev);
88+
void __iomem *ocotp_base = drvdata->ocotp_base;
11289
u32 offset = of_machine_is_compatible("fsl,imx8mp") ?
11390
IMX8MP_OCOTP_UID_OFFSET : 0;
11491

115-
if (!np)
116-
return -EINVAL;
117-
118-
ocotp_base = of_iomap(np, 0);
119-
if (!ocotp_base)
120-
return -EINVAL;
121-
122-
clk = of_clk_get_by_name(np, NULL);
123-
if (IS_ERR(clk)) {
124-
ret = PTR_ERR(clk);
125-
goto err_clk;
126-
}
127-
128-
clk_prepare_enable(clk);
129-
13092
*socuid = readl_relaxed(ocotp_base + OCOTP_UID_HIGH + offset);
13193
*socuid <<= 32;
13294
*socuid |= readl_relaxed(ocotp_base + OCOTP_UID_LOW + offset);
13395

134-
clk_disable_unprepare(clk);
135-
clk_put(clk);
136-
137-
err_clk:
138-
iounmap(ocotp_base);
139-
return ret;
96+
return 0;
14097
}
14198

142-
static int imx8mm_soc_revision(u32 *socrev, u64 *socuid)
99+
static int imx8mm_soc_revision(struct platform_device *pdev, u32 *socrev, u64 *socuid)
143100
{
144101
struct device_node *np __free(device_node) =
145102
of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
@@ -156,26 +113,66 @@ static int imx8mm_soc_revision(u32 *socrev, u64 *socuid)
156113

157114
iounmap(anatop_base);
158115

159-
return imx8mm_soc_uid(socuid);
116+
return imx8mm_soc_uid(pdev, socuid);
117+
}
118+
119+
static int imx8m_soc_prepare(struct platform_device *pdev, const char *ocotp_compatible)
120+
{
121+
struct device_node *np __free(device_node) =
122+
of_find_compatible_node(NULL, NULL, ocotp_compatible);
123+
struct imx8_soc_drvdata *drvdata = platform_get_drvdata(pdev);
124+
int ret = 0;
125+
126+
if (!np)
127+
return -EINVAL;
128+
129+
drvdata->ocotp_base = of_iomap(np, 0);
130+
if (!drvdata->ocotp_base)
131+
return -EINVAL;
132+
133+
drvdata->clk = of_clk_get_by_name(np, NULL);
134+
if (IS_ERR(drvdata->clk)) {
135+
ret = PTR_ERR(drvdata->clk);
136+
goto err_clk;
137+
}
138+
139+
return clk_prepare_enable(drvdata->clk);
140+
141+
err_clk:
142+
iounmap(drvdata->ocotp_base);
143+
return ret;
144+
}
145+
146+
static void imx8m_soc_unprepare(struct platform_device *pdev)
147+
{
148+
struct imx8_soc_drvdata *drvdata = platform_get_drvdata(pdev);
149+
150+
clk_disable_unprepare(drvdata->clk);
151+
clk_put(drvdata->clk);
152+
iounmap(drvdata->ocotp_base);
160153
}
161154

162155
static const struct imx8_soc_data imx8mq_soc_data = {
163156
.name = "i.MX8MQ",
157+
.ocotp_compatible = "fsl,imx8mq-ocotp",
164158
.soc_revision = imx8mq_soc_revision,
165159
};
166160

167161
static const struct imx8_soc_data imx8mm_soc_data = {
168162
.name = "i.MX8MM",
163+
.ocotp_compatible = "fsl,imx8mm-ocotp",
169164
.soc_revision = imx8mm_soc_revision,
170165
};
171166

172167
static const struct imx8_soc_data imx8mn_soc_data = {
173168
.name = "i.MX8MN",
169+
.ocotp_compatible = "fsl,imx8mm-ocotp",
174170
.soc_revision = imx8mm_soc_revision,
175171
};
176172

177173
static const struct imx8_soc_data imx8mp_soc_data = {
178174
.name = "i.MX8MP",
175+
.ocotp_compatible = "fsl,imx8mm-ocotp",
179176
.soc_revision = imx8mm_soc_revision,
180177
};
181178

@@ -207,6 +204,7 @@ static int imx8m_soc_probe(struct platform_device *pdev)
207204
struct soc_device_attribute *soc_dev_attr;
208205
struct platform_device *cpufreq_dev;
209206
const struct imx8_soc_data *data;
207+
struct imx8_soc_drvdata *drvdata;
210208
struct device *dev = &pdev->dev;
211209
const struct of_device_id *id;
212210
struct soc_device *soc_dev;
@@ -218,6 +216,12 @@ static int imx8m_soc_probe(struct platform_device *pdev)
218216
if (!soc_dev_attr)
219217
return -ENOMEM;
220218

219+
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
220+
if (!drvdata)
221+
return -ENOMEM;
222+
223+
platform_set_drvdata(pdev, drvdata);
224+
221225
soc_dev_attr->family = "Freescale i.MX";
222226

223227
ret = of_property_read_string(of_root, "model", &soc_dev_attr->machine);
@@ -231,11 +235,18 @@ static int imx8m_soc_probe(struct platform_device *pdev)
231235
data = id->data;
232236
if (data) {
233237
soc_dev_attr->soc_id = data->name;
238+
ret = imx8m_soc_prepare(pdev, data->ocotp_compatible);
239+
if (ret)
240+
return ret;
241+
234242
if (data->soc_revision) {
235-
ret = data->soc_revision(&soc_rev, &soc_uid);
236-
if (ret)
243+
ret = data->soc_revision(pdev, &soc_rev, &soc_uid);
244+
if (ret) {
245+
imx8m_soc_unprepare(pdev);
237246
return ret;
247+
}
238248
}
249+
imx8m_soc_unprepare(pdev);
239250
}
240251

241252
soc_dev_attr->revision = imx8_revision(dev, soc_rev);

0 commit comments

Comments
 (0)