Skip to content

Commit ee405f1

Browse files
committed
Merge tag 'samsung-drivers-6.20' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into soc/drivers
Samsung SoC drivers for v6.20 1. Several improvements in Exynos ChipID Socinfo driver and finally adding Google GS101 SoC support. 2. Few cleanups from old code. 3. Documenting Axis Artpec-9 SoC PMU (Power Management Unit). * tag 'samsung-drivers-6.20' of https://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: ARM: s3c: remove a leftover hwmon-s3c.h header file dt-bindings: soc: samsung: exynos-pmu: Drop unnecessary select schema soc: samsung: exynos-chipid: add google,gs101-otp support soc: samsung: exynos-chipid: downgrade dev_info to dev_dbg for soc info soc: samsung: exynos-chipid: rename method dt-bindings: nvmem: add google,gs101-otp soc: samsung: exynos-chipid: use dev_err_probe where appropiate soc: samsung: exynos-chipid: use devm action to unregister soc device dt-bindings: samsung: exynos-pmu: Add compatible for ARTPEC-9 SoC Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2 parents ee5dde7 + 9001313 commit ee405f1

4 files changed

Lines changed: 154 additions & 99 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/nvmem/google,gs101-otp.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Google GS101 OTP Controller
8+
9+
maintainers:
10+
- Tudor Ambarus <tudor.ambarus@linaro.org>
11+
12+
description: |
13+
OTP controller drives a NVMEM memory where system or user specific data
14+
can be stored. The OTP controller register space is of interest as well
15+
because it contains dedicated registers where it stores the Product ID
16+
and the Chip ID (apart other things like TMU or ASV info).
17+
18+
allOf:
19+
- $ref: nvmem.yaml#
20+
21+
properties:
22+
compatible:
23+
items:
24+
- const: google,gs101-otp
25+
26+
clocks:
27+
maxItems: 1
28+
29+
clock-names:
30+
const: pclk
31+
32+
interrupts:
33+
maxItems: 1
34+
35+
reg:
36+
maxItems: 1
37+
38+
power-domains:
39+
maxItems: 1
40+
41+
required:
42+
- compatible
43+
- reg
44+
- clocks
45+
- clock-names
46+
- interrupts
47+
48+
unevaluatedProperties: false
49+
50+
examples:
51+
- |
52+
#include <dt-bindings/clock/google,gs101.h>
53+
#include <dt-bindings/interrupt-controller/arm-gic.h>
54+
55+
efuse@10000000 {
56+
compatible = "google,gs101-otp";
57+
reg = <0x10000000 0xf084>;
58+
clocks = <&cmu_misc CLK_GOUT_MISC_OTP_CON_TOP_PCLK>;
59+
clock-names = "pclk";
60+
interrupts = <GIC_SPI 752 IRQ_TYPE_LEVEL_HIGH>;
61+
};

Documentation/devicetree/bindings/soc/samsung/exynos-pmu.yaml

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,6 @@ title: Samsung Exynos SoC series Power Management Unit (PMU)
99
maintainers:
1010
- Krzysztof Kozlowski <krzk@kernel.org>
1111

12-
# Custom select to avoid matching all nodes with 'syscon'
13-
select:
14-
properties:
15-
compatible:
16-
contains:
17-
enum:
18-
- google,gs101-pmu
19-
- samsung,exynos3250-pmu
20-
- samsung,exynos4210-pmu
21-
- samsung,exynos4212-pmu
22-
- samsung,exynos4412-pmu
23-
- samsung,exynos5250-pmu
24-
- samsung,exynos5260-pmu
25-
- samsung,exynos5410-pmu
26-
- samsung,exynos5420-pmu
27-
- samsung,exynos5433-pmu
28-
- samsung,exynos7-pmu
29-
- samsung,exynos850-pmu
30-
- samsung-s5pv210-pmu
31-
required:
32-
- compatible
33-
3412
properties:
3513
compatible:
3614
oneOf:
@@ -52,6 +30,7 @@ properties:
5230
- const: syscon
5331
- items:
5432
- enum:
33+
- axis,artpec9-pmu
5534
- samsung,exynos2200-pmu
5635
- samsung,exynos7870-pmu
5736
- samsung,exynos7885-pmu

drivers/soc/samsung/exynos-chipid.c

Lines changed: 92 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
#include <linux/array_size.h>
1616
#include <linux/device.h>
17-
#include <linux/errno.h>
17+
#include <linux/device/devres.h>
18+
#include <linux/err.h>
19+
#include <linux/ioport.h>
1820
#include <linux/mfd/syscon.h>
1921
#include <linux/module.h>
2022
#include <linux/of.h>
@@ -27,9 +29,11 @@
2729
#include "exynos-asv.h"
2830

2931
struct exynos_chipid_variant {
30-
unsigned int rev_reg; /* revision register offset */
32+
unsigned int main_rev_reg; /* main revision register offset */
33+
unsigned int sub_rev_reg; /* sub revision register offset */
3134
unsigned int main_rev_shift; /* main revision offset in rev_reg */
3235
unsigned int sub_rev_shift; /* sub revision offset in rev_reg */
36+
bool efuse;
3337
};
3438

3539
struct exynos_chipid_info {
@@ -68,9 +72,11 @@ static const struct exynos_soc_id {
6872
{ "EXYNOS990", 0xE9830000 },
6973
{ "EXYNOSAUTOV9", 0xAAA80000 },
7074
{ "EXYNOSAUTOV920", 0x0A920000 },
75+
/* Compatible with: google,gs101-otp */
76+
{ "GS101", 0x9845000 },
7177
};
7278

73-
static const char *product_id_to_soc_id(unsigned int product_id)
79+
static const char *exynos_product_id_to_name(unsigned int product_id)
7480
{
7581
int i;
7682

@@ -80,30 +86,70 @@ static const char *product_id_to_soc_id(unsigned int product_id)
8086
return NULL;
8187
}
8288

83-
static int exynos_chipid_get_chipid_info(struct regmap *regmap,
84-
const struct exynos_chipid_variant *data,
89+
static int exynos_chipid_get_chipid_info(struct device *dev,
90+
struct regmap *regmap, const struct exynos_chipid_variant *data,
8591
struct exynos_chipid_info *soc_info)
8692
{
8793
int ret;
8894
unsigned int val, main_rev, sub_rev;
8995

9096
ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &val);
9197
if (ret < 0)
92-
return ret;
98+
return dev_err_probe(dev, ret, "failed to read Product ID\n");
9399
soc_info->product_id = val & EXYNOS_MASK;
94100

95-
if (data->rev_reg != EXYNOS_CHIPID_REG_PRO_ID) {
96-
ret = regmap_read(regmap, data->rev_reg, &val);
101+
if (data->sub_rev_reg == EXYNOS_CHIPID_REG_PRO_ID) {
102+
/* exynos4210 case */
103+
main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
104+
sub_rev = (val >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
105+
} else {
106+
unsigned int val2;
107+
108+
ret = regmap_read(regmap, data->sub_rev_reg, &val2);
97109
if (ret < 0)
98-
return ret;
110+
return dev_err_probe(dev, ret,
111+
"failed to read revision\n");
112+
113+
if (data->main_rev_reg == EXYNOS_CHIPID_REG_PRO_ID)
114+
/* gs101 case */
115+
main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
116+
else
117+
/* exynos850 case */
118+
main_rev = (val2 >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
119+
120+
sub_rev = (val2 >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
99121
}
100-
main_rev = (val >> data->main_rev_shift) & EXYNOS_REV_PART_MASK;
101-
sub_rev = (val >> data->sub_rev_shift) & EXYNOS_REV_PART_MASK;
122+
102123
soc_info->revision = (main_rev << EXYNOS_REV_PART_SHIFT) | sub_rev;
103124

104125
return 0;
105126
}
106127

128+
static struct regmap *exynos_chipid_get_efuse_regmap(struct platform_device *pdev)
129+
{
130+
struct resource *res;
131+
void __iomem *base;
132+
133+
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
134+
if (IS_ERR(base))
135+
return ERR_CAST(base);
136+
137+
const struct regmap_config reg_config = {
138+
.reg_bits = 32,
139+
.reg_stride = 4,
140+
.val_bits = 32,
141+
.use_relaxed_mmio = true,
142+
.max_register = (resource_size(res) - reg_config.reg_stride),
143+
};
144+
145+
return devm_regmap_init_mmio_clk(&pdev->dev, "pclk", base, &reg_config);
146+
}
147+
148+
static void exynos_chipid_unregister_soc(void *data)
149+
{
150+
soc_device_unregister(data);
151+
}
152+
107153
static int exynos_chipid_probe(struct platform_device *pdev)
108154
{
109155
const struct exynos_chipid_variant *drv_data;
@@ -117,13 +163,19 @@ static int exynos_chipid_probe(struct platform_device *pdev)
117163

118164
drv_data = of_device_get_match_data(dev);
119165
if (!drv_data)
120-
return -EINVAL;
166+
return dev_err_probe(dev, -EINVAL,
167+
"failed to get match data\n");
168+
169+
if (drv_data->efuse)
170+
regmap = exynos_chipid_get_efuse_regmap(pdev);
171+
else
172+
regmap = device_node_to_regmap(dev->of_node);
121173

122-
regmap = device_node_to_regmap(dev->of_node);
123174
if (IS_ERR(regmap))
124-
return PTR_ERR(regmap);
175+
return dev_err_probe(dev, PTR_ERR(regmap),
176+
"failed to get regmap\n");
125177

126-
ret = exynos_chipid_get_chipid_info(regmap, drv_data, &soc_info);
178+
ret = exynos_chipid_get_chipid_info(dev, regmap, drv_data, &soc_info);
127179
if (ret < 0)
128180
return ret;
129181

@@ -141,55 +193,55 @@ static int exynos_chipid_probe(struct platform_device *pdev)
141193
soc_info.revision);
142194
if (!soc_dev_attr->revision)
143195
return -ENOMEM;
144-
soc_dev_attr->soc_id = product_id_to_soc_id(soc_info.product_id);
145-
if (!soc_dev_attr->soc_id) {
146-
pr_err("Unknown SoC\n");
147-
return -ENODEV;
148-
}
196+
197+
soc_dev_attr->soc_id = exynos_product_id_to_name(soc_info.product_id);
198+
if (!soc_dev_attr->soc_id)
199+
return dev_err_probe(dev, -ENODEV, "Unknown SoC\n");
149200

150201
/* please note that the actual registration will be deferred */
151202
soc_dev = soc_device_register(soc_dev_attr);
152203
if (IS_ERR(soc_dev))
153-
return PTR_ERR(soc_dev);
204+
return dev_err_probe(dev, PTR_ERR(soc_dev),
205+
"failed to register to the soc interface\n");
154206

155-
ret = exynos_asv_init(dev, regmap);
207+
ret = devm_add_action_or_reset(dev, exynos_chipid_unregister_soc,
208+
soc_dev);
156209
if (ret)
157-
goto err;
210+
return dev_err_probe(dev, ret, "failed to add devm action\n");
158211

159-
platform_set_drvdata(pdev, soc_dev);
212+
ret = exynos_asv_init(dev, regmap);
213+
if (ret)
214+
return ret;
160215

161-
dev_info(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
162-
soc_dev_attr->soc_id, soc_info.product_id, soc_info.revision);
216+
dev_dbg(dev, "Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
217+
soc_dev_attr->soc_id, soc_info.product_id, soc_info.revision);
163218

164219
return 0;
165-
166-
err:
167-
soc_device_unregister(soc_dev);
168-
169-
return ret;
170-
}
171-
172-
static void exynos_chipid_remove(struct platform_device *pdev)
173-
{
174-
struct soc_device *soc_dev = platform_get_drvdata(pdev);
175-
176-
soc_device_unregister(soc_dev);
177220
}
178221

179222
static const struct exynos_chipid_variant exynos4210_chipid_drv_data = {
180-
.rev_reg = 0x0,
181223
.main_rev_shift = 4,
182224
.sub_rev_shift = 0,
183225
};
184226

185227
static const struct exynos_chipid_variant exynos850_chipid_drv_data = {
186-
.rev_reg = 0x10,
228+
.main_rev_reg = 0x10,
229+
.sub_rev_reg = 0x10,
187230
.main_rev_shift = 20,
188231
.sub_rev_shift = 16,
189232
};
190233

234+
static const struct exynos_chipid_variant gs101_chipid_drv_data = {
235+
.sub_rev_reg = 0x10,
236+
.sub_rev_shift = 16,
237+
.efuse = true,
238+
};
239+
191240
static const struct of_device_id exynos_chipid_of_device_ids[] = {
192241
{
242+
.compatible = "google,gs101-otp",
243+
.data = &gs101_chipid_drv_data,
244+
}, {
193245
.compatible = "samsung,exynos4210-chipid",
194246
.data = &exynos4210_chipid_drv_data,
195247
}, {
@@ -206,7 +258,6 @@ static struct platform_driver exynos_chipid_driver = {
206258
.of_match_table = exynos_chipid_of_device_ids,
207259
},
208260
.probe = exynos_chipid_probe,
209-
.remove = exynos_chipid_remove,
210261
};
211262
module_platform_driver(exynos_chipid_driver);
212263

include/linux/platform_data/hwmon-s3c.h

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)