Blame view

drivers/acpi/acpi_apd.c 6.37 KB
d2912cb15   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-only
92082a888   Ken Xue   ACPI: add AMD ACP...
2
3
4
5
6
7
  /*
   * AMD ACPI support for ACPI2platform device.
   *
   * Copyright (c) 2014,2015 AMD Corporation.
   * Authors: Ken Xue <Ken.Xue@amd.com>
   *	Wu, Jeff <Jeff.Wu@amd.com>
92082a888   Ken Xue   ACPI: add AMD ACP...
8
9
10
   */
  
  #include <linux/clk-provider.h>
3f4ba94e3   Akshu Agrawal   ACPI: APD: Add AM...
11
  #include <linux/platform_data/clk-st.h>
92082a888   Ken Xue   ACPI: add AMD ACP...
12
13
14
15
16
  #include <linux/platform_device.h>
  #include <linux/pm_domain.h>
  #include <linux/clkdev.h>
  #include <linux/acpi.h>
  #include <linux/err.h>
62e59c4e6   Stephen Boyd   clk: Remove io.h ...
17
  #include <linux/io.h>
92082a888   Ken Xue   ACPI: add AMD ACP...
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  #include <linux/pm.h>
  
  #include "internal.h"
  
  ACPI_MODULE_NAME("acpi_apd");
  struct apd_private_data;
  
  /**
   * ACPI_APD_SYSFS : add device attributes in sysfs
   * ACPI_APD_PM : attach power domain to device
   */
  #define ACPI_APD_SYSFS	BIT(0)
  #define ACPI_APD_PM	BIT(1)
  
  /**
   * struct apd_device_desc - a descriptor for apd device
   * @flags: device flags like %ACPI_APD_SYSFS, %ACPI_APD_PM
   * @fixed_clk_rate: fixed rate input clock source for acpi device;
   *			0 means no fixed rate input clock source
   * @setup: a hook routine to set device resource during create platform device
   *
   * Device description defined as acpi_device_id.driver_data
   */
  struct apd_device_desc {
  	unsigned int flags;
  	unsigned int fixed_clk_rate;
7ff55d174   Heikki Krogerus   ACPI / APD: Provi...
44
  	struct property_entry *properties;
92082a888   Ken Xue   ACPI: add AMD ACP...
45
46
47
48
49
50
51
52
  	int (*setup)(struct apd_private_data *pdata);
  };
  
  struct apd_private_data {
  	struct clk *clk;
  	struct acpi_device *adev;
  	const struct apd_device_desc *dev_desc;
  };
b790eb20b   Loc Ho   ACPI / APD: Add A...
53
  #if defined(CONFIG_X86_AMD_PLATFORM_DEVICE) || defined(CONFIG_ARM64)
92082a888   Ken Xue   ACPI: add AMD ACP...
54
55
56
57
58
  #define APD_ADDR(desc)	((unsigned long)&desc)
  
  static int acpi_apd_setup(struct apd_private_data *pdata)
  {
  	const struct apd_device_desc *dev_desc = pdata->dev_desc;
b244883ca   Colin Ian King   ACPI: APD: remove...
59
  	struct clk *clk;
92082a888   Ken Xue   ACPI: add AMD ACP...
60
61
62
63
  
  	if (dev_desc->fixed_clk_rate) {
  		clk = clk_register_fixed_rate(&pdata->adev->dev,
  					dev_name(&pdata->adev->dev),
cdd9a6b2a   Stephen Boyd   ACPI / APD: Remov...
64
  					NULL, 0, dev_desc->fixed_clk_rate);
92082a888   Ken Xue   ACPI: add AMD ACP...
65
66
67
68
69
70
  		clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev));
  		pdata->clk = clk;
  	}
  
  	return 0;
  }
b790eb20b   Loc Ho   ACPI / APD: Add A...
71
  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
3f4ba94e3   Akshu Agrawal   ACPI: APD: Add AM...
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  
  static int misc_check_res(struct acpi_resource *ares, void *data)
  {
  	struct resource res;
  
  	return !acpi_dev_resource_memory(ares, &res);
  }
  
  static int st_misc_setup(struct apd_private_data *pdata)
  {
  	struct acpi_device *adev = pdata->adev;
  	struct platform_device *clkdev;
  	struct st_clk_data *clk_data;
  	struct resource_entry *rentry;
  	struct list_head resource_list;
  	int ret;
  
  	clk_data = devm_kzalloc(&adev->dev, sizeof(*clk_data), GFP_KERNEL);
  	if (!clk_data)
  		return -ENOMEM;
  
  	INIT_LIST_HEAD(&resource_list);
  	ret = acpi_dev_get_resources(adev, &resource_list, misc_check_res,
  				     NULL);
  	if (ret < 0)
  		return -ENOENT;
  
  	list_for_each_entry(rentry, &resource_list, node) {
  		clk_data->base = devm_ioremap(&adev->dev, rentry->res->start,
  					      resource_size(rentry->res));
  		break;
  	}
  
  	acpi_dev_free_resource_list(&resource_list);
  
  	clkdev = platform_device_register_data(&adev->dev, "clk-st",
  					       PLATFORM_DEVID_NONE, clk_data,
  					       sizeof(*clk_data));
  	return PTR_ERR_OR_ZERO(clkdev);
  }
a217726a7   Julia Lawall   ACPI / APD: const...
112
  static const struct apd_device_desc cz_i2c_desc = {
92082a888   Ken Xue   ACPI: add AMD ACP...
113
114
115
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 133000000,
  };
4881f0bad   Nehal Shah   ACPI / APD: Add c...
116
117
118
119
  static const struct apd_device_desc wt_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 150000000,
  };
7ff55d174   Heikki Krogerus   ACPI / APD: Provi...
120
121
122
123
124
125
  static struct property_entry uart_properties[] = {
  	PROPERTY_ENTRY_U32("reg-io-width", 4),
  	PROPERTY_ENTRY_U32("reg-shift", 2),
  	PROPERTY_ENTRY_BOOL("snps,uart-16550-compatible"),
  	{ },
  };
a217726a7   Julia Lawall   ACPI / APD: const...
126
  static const struct apd_device_desc cz_uart_desc = {
92082a888   Ken Xue   ACPI: add AMD ACP...
127
128
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 48000000,
7ff55d174   Heikki Krogerus   ACPI / APD: Provi...
129
  	.properties = uart_properties,
92082a888   Ken Xue   ACPI: add AMD ACP...
130
  };
3f4ba94e3   Akshu Agrawal   ACPI: APD: Add AM...
131
132
133
134
  
  static const struct apd_device_desc st_misc_desc = {
  	.setup = st_misc_setup,
  };
b790eb20b   Loc Ho   ACPI / APD: Add A...
135
136
137
  #endif
  
  #ifdef CONFIG_ARM64
a217726a7   Julia Lawall   ACPI / APD: const...
138
  static const struct apd_device_desc xgene_i2c_desc = {
b790eb20b   Loc Ho   ACPI / APD: Add A...
139
140
141
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 100000000,
  };
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
142

a217726a7   Julia Lawall   ACPI / APD: const...
143
  static const struct apd_device_desc vulcan_spi_desc = {
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
144
145
146
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 133000000,
  };
6e14cf361   Hanjun Guo   ACPI / APD: Add c...
147
148
149
150
151
152
153
154
155
156
  
  static const struct apd_device_desc hip07_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 200000000,
  };
  
  static const struct apd_device_desc hip08_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 250000000,
  };
11330a9fe   Chuanhua Han   i2c: imx: ACPI su...
157

c01a4a136   Hanjun Guo   ACPI / APD: Add c...
158
159
160
161
  static const struct apd_device_desc hip08_lite_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 125000000,
  };
1977dbefe   Jayachandran C   ACPI / APD: Add c...
162
163
164
165
  static const struct apd_device_desc thunderx2_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 125000000,
  };
56131d6d8   Jay Fang   ACPI / APD: Add c...
166

11330a9fe   Chuanhua Han   i2c: imx: ACPI su...
167
168
169
170
  static const struct apd_device_desc nxp_i2c_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 350000000,
  };
56131d6d8   Jay Fang   ACPI / APD: Add c...
171
172
173
174
  static const struct apd_device_desc hip08_spi_desc = {
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 250000000,
  };
b790eb20b   Loc Ho   ACPI / APD: Add A...
175
  #endif
92082a888   Ken Xue   ACPI: add AMD ACP...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
  
  #else
  
  #define APD_ADDR(desc) (0UL)
  
  #endif /* CONFIG_X86_AMD_PLATFORM_DEVICE */
  
  /**
  * Create platform device during acpi scan attach handle.
  * Return value > 0 on success of creating device.
  */
  static int acpi_apd_create_device(struct acpi_device *adev,
  				   const struct acpi_device_id *id)
  {
  	const struct apd_device_desc *dev_desc = (void *)id->driver_data;
  	struct apd_private_data *pdata;
  	struct platform_device *pdev;
  	int ret;
  
  	if (!dev_desc) {
1571875be   Heikki Krogerus   ACPI / platform: ...
196
  		pdev = acpi_create_platform_device(adev, NULL);
92082a888   Ken Xue   ACPI: add AMD ACP...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
  		return IS_ERR_OR_NULL(pdev) ? PTR_ERR(pdev) : 1;
  	}
  
  	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
  	if (!pdata)
  		return -ENOMEM;
  
  	pdata->adev = adev;
  	pdata->dev_desc = dev_desc;
  
  	if (dev_desc->setup) {
  		ret = dev_desc->setup(pdata);
  		if (ret)
  			goto err_out;
  	}
  
  	adev->driver_data = pdata;
1571875be   Heikki Krogerus   ACPI / platform: ...
214
  	pdev = acpi_create_platform_device(adev, dev_desc->properties);
92082a888   Ken Xue   ACPI: add AMD ACP...
215
216
217
218
219
220
221
222
223
224
225
226
227
  	if (!IS_ERR_OR_NULL(pdev))
  		return 1;
  
  	ret = PTR_ERR(pdev);
  	adev->driver_data = NULL;
  
   err_out:
  	kfree(pdata);
  	return ret;
  }
  
  static const struct acpi_device_id acpi_apd_device_ids[] = {
  	/* Generic apd devices */
b790eb20b   Loc Ho   ACPI / APD: Add A...
228
  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
92082a888   Ken Xue   ACPI: add AMD ACP...
229
  	{ "AMD0010", APD_ADDR(cz_i2c_desc) },
4881f0bad   Nehal Shah   ACPI / APD: Add c...
230
  	{ "AMDI0010", APD_ADDR(wt_i2c_desc) },
92082a888   Ken Xue   ACPI: add AMD ACP...
231
  	{ "AMD0020", APD_ADDR(cz_uart_desc) },
f5eda99ee   Wang Hongcheng   ACPI / APD: Add d...
232
  	{ "AMDI0020", APD_ADDR(cz_uart_desc) },
92082a888   Ken Xue   ACPI: add AMD ACP...
233
  	{ "AMD0030", },
3f4ba94e3   Akshu Agrawal   ACPI: APD: Add AM...
234
  	{ "AMD0040", APD_ADDR(st_misc_desc)},
b790eb20b   Loc Ho   ACPI / APD: Add A...
235
236
237
  #endif
  #ifdef CONFIG_ARM64
  	{ "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
238
  	{ "BRCM900D", APD_ADDR(vulcan_spi_desc) },
251831bd4   Jayachandran C   spi: xlp: update ...
239
  	{ "CAV900D",  APD_ADDR(vulcan_spi_desc) },
1977dbefe   Jayachandran C   ACPI / APD: Add c...
240
  	{ "CAV9007",  APD_ADDR(thunderx2_i2c_desc) },
f7f3dd5b4   Hanjun Guo   ACPI: APD: Fix HI...
241
242
  	{ "HISI02A1", APD_ADDR(hip07_i2c_desc) },
  	{ "HISI02A2", APD_ADDR(hip08_i2c_desc) },
c01a4a136   Hanjun Guo   ACPI / APD: Add c...
243
  	{ "HISI02A3", APD_ADDR(hip08_lite_i2c_desc) },
56131d6d8   Jay Fang   ACPI / APD: Add c...
244
  	{ "HISI0173", APD_ADDR(hip08_spi_desc) },
11330a9fe   Chuanhua Han   i2c: imx: ACPI su...
245
  	{ "NXP0001", APD_ADDR(nxp_i2c_desc) },
b790eb20b   Loc Ho   ACPI / APD: Add A...
246
  #endif
92082a888   Ken Xue   ACPI: add AMD ACP...
247
248
249
250
251
252
253
254
255
256
257
258
  	{ }
  };
  
  static struct acpi_scan_handler apd_handler = {
  	.ids = acpi_apd_device_ids,
  	.attach = acpi_apd_create_device,
  };
  
  void __init acpi_apd_init(void)
  {
  	acpi_scan_add_handler(&apd_handler);
  }