Blame view

drivers/acpi/acpi_apd.c 4.26 KB
92082a888   Ken Xue   ACPI: add AMD ACP...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * 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>
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  
  #include <linux/clk-provider.h>
  #include <linux/platform_device.h>
  #include <linux/pm_domain.h>
  #include <linux/clkdev.h>
  #include <linux/acpi.h>
  #include <linux/err.h>
92082a888   Ken Xue   ACPI: add AMD ACP...
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
44
  #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...
45
  	struct property_entry *properties;
92082a888   Ken Xue   ACPI: add AMD ACP...
46
47
48
49
50
51
52
53
  	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...
54
  #if defined(CONFIG_X86_AMD_PLATFORM_DEVICE) || defined(CONFIG_ARM64)
92082a888   Ken Xue   ACPI: add AMD ACP...
55
56
57
58
59
60
61
62
63
64
  #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;
  	struct clk *clk = ERR_PTR(-ENODEV);
  
  	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...
65
  					NULL, 0, dev_desc->fixed_clk_rate);
92082a888   Ken Xue   ACPI: add AMD ACP...
66
67
68
69
70
71
  		clk_register_clkdev(clk, NULL, dev_name(&pdata->adev->dev));
  		pdata->clk = clk;
  	}
  
  	return 0;
  }
b790eb20b   Loc Ho   ACPI / APD: Add A...
72
  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
a217726a7   Julia Lawall   ACPI / APD: const...
73
  static const struct apd_device_desc cz_i2c_desc = {
92082a888   Ken Xue   ACPI: add AMD ACP...
74
75
76
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 133000000,
  };
7ff55d174   Heikki Krogerus   ACPI / APD: Provi...
77
78
79
80
81
82
  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...
83
  static const struct apd_device_desc cz_uart_desc = {
92082a888   Ken Xue   ACPI: add AMD ACP...
84
85
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 48000000,
7ff55d174   Heikki Krogerus   ACPI / APD: Provi...
86
  	.properties = uart_properties,
92082a888   Ken Xue   ACPI: add AMD ACP...
87
  };
b790eb20b   Loc Ho   ACPI / APD: Add A...
88
89
90
  #endif
  
  #ifdef CONFIG_ARM64
a217726a7   Julia Lawall   ACPI / APD: const...
91
  static const struct apd_device_desc xgene_i2c_desc = {
b790eb20b   Loc Ho   ACPI / APD: Add A...
92
93
94
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 100000000,
  };
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
95

a217726a7   Julia Lawall   ACPI / APD: const...
96
  static const struct apd_device_desc vulcan_spi_desc = {
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
97
98
99
  	.setup = acpi_apd_setup,
  	.fixed_clk_rate = 133000000,
  };
b790eb20b   Loc Ho   ACPI / APD: Add A...
100
  #endif
92082a888   Ken Xue   ACPI: add AMD ACP...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
  
  #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: ...
121
  		pdev = acpi_create_platform_device(adev, NULL);
92082a888   Ken Xue   ACPI: add AMD ACP...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
  		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: ...
139
  	pdev = acpi_create_platform_device(adev, dev_desc->properties);
92082a888   Ken Xue   ACPI: add AMD ACP...
140
141
142
143
144
145
146
147
148
149
150
151
152
  	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...
153
  #ifdef CONFIG_X86_AMD_PLATFORM_DEVICE
92082a888   Ken Xue   ACPI: add AMD ACP...
154
  	{ "AMD0010", APD_ADDR(cz_i2c_desc) },
e4e666ba7   Xiangliang Yu   i2c: designware: ...
155
  	{ "AMDI0010", APD_ADDR(cz_i2c_desc) },
92082a888   Ken Xue   ACPI: add AMD ACP...
156
  	{ "AMD0020", APD_ADDR(cz_uart_desc) },
f5eda99ee   Wang Hongcheng   ACPI / APD: Add d...
157
  	{ "AMDI0020", APD_ADDR(cz_uart_desc) },
92082a888   Ken Xue   ACPI: add AMD ACP...
158
  	{ "AMD0030", },
b790eb20b   Loc Ho   ACPI / APD: Add A...
159
160
161
  #endif
  #ifdef CONFIG_ARM64
  	{ "APMC0D0F", APD_ADDR(xgene_i2c_desc) },
bd2058dc1   Kamlakant Patel   ACPI / APD: Add d...
162
  	{ "BRCM900D", APD_ADDR(vulcan_spi_desc) },
b790eb20b   Loc Ho   ACPI / APD: Add A...
163
  #endif
92082a888   Ken Xue   ACPI: add AMD ACP...
164
165
166
167
168
169
170
171
172
173
174
175
  	{ }
  };
  
  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);
  }