1df7f9acdSAndy Shevchenko // SPDX-License-Identifier: GPL-2.0-only
2df7f9acdSAndy Shevchenko /*
3df7f9acdSAndy Shevchenko * Performance Limit Reasons via TPMI
4df7f9acdSAndy Shevchenko *
5df7f9acdSAndy Shevchenko * Copyright (c) 2024, Intel Corporation.
6df7f9acdSAndy Shevchenko */
7df7f9acdSAndy Shevchenko
8df7f9acdSAndy Shevchenko #include <linux/array_size.h>
9df7f9acdSAndy Shevchenko #include <linux/auxiliary_bus.h>
10df7f9acdSAndy Shevchenko #include <linux/bitfield.h>
11df7f9acdSAndy Shevchenko #include <linux/bitmap.h>
12df7f9acdSAndy Shevchenko #include <linux/debugfs.h>
13df7f9acdSAndy Shevchenko #include <linux/device.h>
14df7f9acdSAndy Shevchenko #include <linux/err.h>
15df7f9acdSAndy Shevchenko #include <linux/gfp_types.h>
16df7f9acdSAndy Shevchenko #include <linux/intel_tpmi.h>
17df7f9acdSAndy Shevchenko #include <linux/io.h>
18df7f9acdSAndy Shevchenko #include <linux/iopoll.h>
19df7f9acdSAndy Shevchenko #include <linux/kstrtox.h>
20df7f9acdSAndy Shevchenko #include <linux/lockdep.h>
21df7f9acdSAndy Shevchenko #include <linux/module.h>
22df7f9acdSAndy Shevchenko #include <linux/mod_devicetable.h>
23df7f9acdSAndy Shevchenko #include <linux/mutex.h>
24df7f9acdSAndy Shevchenko #include <linux/seq_file.h>
25df7f9acdSAndy Shevchenko #include <linux/sprintf.h>
26df7f9acdSAndy Shevchenko #include <linux/types.h>
27df7f9acdSAndy Shevchenko
28df7f9acdSAndy Shevchenko #include "tpmi_power_domains.h"
29df7f9acdSAndy Shevchenko
30df7f9acdSAndy Shevchenko #define PLR_HEADER 0x00
31df7f9acdSAndy Shevchenko #define PLR_MAILBOX_INTERFACE 0x08
32df7f9acdSAndy Shevchenko #define PLR_MAILBOX_DATA 0x10
33df7f9acdSAndy Shevchenko #define PLR_DIE_LEVEL 0x18
34df7f9acdSAndy Shevchenko
35df7f9acdSAndy Shevchenko #define PLR_MODULE_ID_MASK GENMASK_ULL(19, 12)
36df7f9acdSAndy Shevchenko #define PLR_RUN_BUSY BIT_ULL(63)
37df7f9acdSAndy Shevchenko
38df7f9acdSAndy Shevchenko #define PLR_COMMAND_WRITE 1
39df7f9acdSAndy Shevchenko
40df7f9acdSAndy Shevchenko #define PLR_INVALID GENMASK_ULL(63, 0)
41df7f9acdSAndy Shevchenko
42df7f9acdSAndy Shevchenko #define PLR_TIMEOUT_US 5
43df7f9acdSAndy Shevchenko #define PLR_TIMEOUT_MAX_US 1000
44df7f9acdSAndy Shevchenko
45df7f9acdSAndy Shevchenko #define PLR_COARSE_REASON_BITS 32
46df7f9acdSAndy Shevchenko
47df7f9acdSAndy Shevchenko struct tpmi_plr;
48df7f9acdSAndy Shevchenko
49df7f9acdSAndy Shevchenko struct tpmi_plr_die {
50df7f9acdSAndy Shevchenko void __iomem *base;
51df7f9acdSAndy Shevchenko struct mutex lock; /* Protect access to PLR mailbox */
52df7f9acdSAndy Shevchenko int package_id;
53df7f9acdSAndy Shevchenko int die_id;
54df7f9acdSAndy Shevchenko struct tpmi_plr *plr;
55df7f9acdSAndy Shevchenko };
56df7f9acdSAndy Shevchenko
57df7f9acdSAndy Shevchenko struct tpmi_plr {
58df7f9acdSAndy Shevchenko struct dentry *dbgfs_dir;
59df7f9acdSAndy Shevchenko struct tpmi_plr_die *die_info;
60df7f9acdSAndy Shevchenko int num_dies;
61df7f9acdSAndy Shevchenko struct auxiliary_device *auxdev;
62df7f9acdSAndy Shevchenko };
63df7f9acdSAndy Shevchenko
64df7f9acdSAndy Shevchenko static const char * const plr_coarse_reasons[] = {
65df7f9acdSAndy Shevchenko "FREQUENCY",
66df7f9acdSAndy Shevchenko "CURRENT",
67df7f9acdSAndy Shevchenko "POWER",
68df7f9acdSAndy Shevchenko "THERMAL",
69df7f9acdSAndy Shevchenko "PLATFORM",
70df7f9acdSAndy Shevchenko "MCP",
71df7f9acdSAndy Shevchenko "RAS",
72df7f9acdSAndy Shevchenko "MISC",
73df7f9acdSAndy Shevchenko "QOS",
74df7f9acdSAndy Shevchenko "DFC",
75df7f9acdSAndy Shevchenko };
76df7f9acdSAndy Shevchenko
77df7f9acdSAndy Shevchenko static const char * const plr_fine_reasons[] = {
78df7f9acdSAndy Shevchenko "FREQUENCY_CDYN0",
79df7f9acdSAndy Shevchenko "FREQUENCY_CDYN1",
80df7f9acdSAndy Shevchenko "FREQUENCY_CDYN2",
81df7f9acdSAndy Shevchenko "FREQUENCY_CDYN3",
82df7f9acdSAndy Shevchenko "FREQUENCY_CDYN4",
83df7f9acdSAndy Shevchenko "FREQUENCY_CDYN5",
84df7f9acdSAndy Shevchenko "FREQUENCY_FCT",
85df7f9acdSAndy Shevchenko "FREQUENCY_PCS_TRL",
86df7f9acdSAndy Shevchenko "CURRENT_MTPMAX",
87df7f9acdSAndy Shevchenko "POWER_FAST_RAPL",
88df7f9acdSAndy Shevchenko "POWER_PKG_PL1_MSR_TPMI",
89df7f9acdSAndy Shevchenko "POWER_PKG_PL1_MMIO",
90df7f9acdSAndy Shevchenko "POWER_PKG_PL1_PCS",
91df7f9acdSAndy Shevchenko "POWER_PKG_PL2_MSR_TPMI",
92df7f9acdSAndy Shevchenko "POWER_PKG_PL2_MMIO",
93df7f9acdSAndy Shevchenko "POWER_PKG_PL2_PCS",
94df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL1_MSR_TPMI",
95df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL1_MMIO",
96df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL1_PCS",
97df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL2_MSR_TPMI",
98df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL2_MMIO",
99df7f9acdSAndy Shevchenko "POWER_PLATFORM_PL2_PCS",
100df7f9acdSAndy Shevchenko "UNKNOWN(22)",
101df7f9acdSAndy Shevchenko "THERMAL_PER_CORE",
102df7f9acdSAndy Shevchenko "DFC_UFS",
103df7f9acdSAndy Shevchenko "PLATFORM_PROCHOT",
104df7f9acdSAndy Shevchenko "PLATFORM_HOT_VR",
105df7f9acdSAndy Shevchenko "UNKNOWN(27)",
106df7f9acdSAndy Shevchenko "UNKNOWN(28)",
107df7f9acdSAndy Shevchenko "MISC_PCS_PSTATE",
108df7f9acdSAndy Shevchenko };
109df7f9acdSAndy Shevchenko
plr_read(struct tpmi_plr_die * plr_die,int offset)110df7f9acdSAndy Shevchenko static u64 plr_read(struct tpmi_plr_die *plr_die, int offset)
111df7f9acdSAndy Shevchenko {
112df7f9acdSAndy Shevchenko return readq(plr_die->base + offset);
113df7f9acdSAndy Shevchenko }
114df7f9acdSAndy Shevchenko
plr_write(u64 val,struct tpmi_plr_die * plr_die,int offset)115df7f9acdSAndy Shevchenko static void plr_write(u64 val, struct tpmi_plr_die *plr_die, int offset)
116df7f9acdSAndy Shevchenko {
117df7f9acdSAndy Shevchenko writeq(val, plr_die->base + offset);
118df7f9acdSAndy Shevchenko }
119df7f9acdSAndy Shevchenko
plr_read_cpu_status(struct tpmi_plr_die * plr_die,int cpu,u64 * status)120df7f9acdSAndy Shevchenko static int plr_read_cpu_status(struct tpmi_plr_die *plr_die, int cpu,
121df7f9acdSAndy Shevchenko u64 *status)
122df7f9acdSAndy Shevchenko {
123df7f9acdSAndy Shevchenko u64 regval;
124df7f9acdSAndy Shevchenko int ret;
125df7f9acdSAndy Shevchenko
126df7f9acdSAndy Shevchenko lockdep_assert_held(&plr_die->lock);
127df7f9acdSAndy Shevchenko
128df7f9acdSAndy Shevchenko regval = FIELD_PREP(PLR_MODULE_ID_MASK, tpmi_get_punit_core_number(cpu));
129df7f9acdSAndy Shevchenko regval |= PLR_RUN_BUSY;
130df7f9acdSAndy Shevchenko
131df7f9acdSAndy Shevchenko plr_write(regval, plr_die, PLR_MAILBOX_INTERFACE);
132df7f9acdSAndy Shevchenko
133df7f9acdSAndy Shevchenko ret = readq_poll_timeout(plr_die->base + PLR_MAILBOX_INTERFACE, regval,
134df7f9acdSAndy Shevchenko !(regval & PLR_RUN_BUSY), PLR_TIMEOUT_US,
135df7f9acdSAndy Shevchenko PLR_TIMEOUT_MAX_US);
136df7f9acdSAndy Shevchenko if (ret)
137df7f9acdSAndy Shevchenko return ret;
138df7f9acdSAndy Shevchenko
139df7f9acdSAndy Shevchenko *status = plr_read(plr_die, PLR_MAILBOX_DATA);
140df7f9acdSAndy Shevchenko
141df7f9acdSAndy Shevchenko return 0;
142df7f9acdSAndy Shevchenko }
143df7f9acdSAndy Shevchenko
plr_clear_cpu_status(struct tpmi_plr_die * plr_die,int cpu)144df7f9acdSAndy Shevchenko static int plr_clear_cpu_status(struct tpmi_plr_die *plr_die, int cpu)
145df7f9acdSAndy Shevchenko {
146df7f9acdSAndy Shevchenko u64 regval;
147df7f9acdSAndy Shevchenko
148df7f9acdSAndy Shevchenko lockdep_assert_held(&plr_die->lock);
149df7f9acdSAndy Shevchenko
150df7f9acdSAndy Shevchenko regval = FIELD_PREP(PLR_MODULE_ID_MASK, tpmi_get_punit_core_number(cpu));
151df7f9acdSAndy Shevchenko regval |= PLR_RUN_BUSY | PLR_COMMAND_WRITE;
152df7f9acdSAndy Shevchenko
153df7f9acdSAndy Shevchenko plr_write(0, plr_die, PLR_MAILBOX_DATA);
154df7f9acdSAndy Shevchenko
155df7f9acdSAndy Shevchenko plr_write(regval, plr_die, PLR_MAILBOX_INTERFACE);
156df7f9acdSAndy Shevchenko
157df7f9acdSAndy Shevchenko return readq_poll_timeout(plr_die->base + PLR_MAILBOX_INTERFACE, regval,
158df7f9acdSAndy Shevchenko !(regval & PLR_RUN_BUSY), PLR_TIMEOUT_US,
159df7f9acdSAndy Shevchenko PLR_TIMEOUT_MAX_US);
160df7f9acdSAndy Shevchenko }
161df7f9acdSAndy Shevchenko
plr_print_bits(struct seq_file * s,u64 val,int bits)162df7f9acdSAndy Shevchenko static void plr_print_bits(struct seq_file *s, u64 val, int bits)
163df7f9acdSAndy Shevchenko {
164df7f9acdSAndy Shevchenko const unsigned long mask[] = { BITMAP_FROM_U64(val) };
165df7f9acdSAndy Shevchenko int bit, index;
166df7f9acdSAndy Shevchenko
167df7f9acdSAndy Shevchenko for_each_set_bit(bit, mask, bits) {
168df7f9acdSAndy Shevchenko const char *str = NULL;
169df7f9acdSAndy Shevchenko
170df7f9acdSAndy Shevchenko if (bit < PLR_COARSE_REASON_BITS) {
171df7f9acdSAndy Shevchenko if (bit < ARRAY_SIZE(plr_coarse_reasons))
172df7f9acdSAndy Shevchenko str = plr_coarse_reasons[bit];
173df7f9acdSAndy Shevchenko } else {
174df7f9acdSAndy Shevchenko index = bit - PLR_COARSE_REASON_BITS;
175df7f9acdSAndy Shevchenko if (index < ARRAY_SIZE(plr_fine_reasons))
176df7f9acdSAndy Shevchenko str = plr_fine_reasons[index];
177df7f9acdSAndy Shevchenko }
178df7f9acdSAndy Shevchenko
179df7f9acdSAndy Shevchenko if (str)
180df7f9acdSAndy Shevchenko seq_printf(s, " %s", str);
181df7f9acdSAndy Shevchenko else
182df7f9acdSAndy Shevchenko seq_printf(s, " UNKNOWN(%d)", bit);
183df7f9acdSAndy Shevchenko }
184df7f9acdSAndy Shevchenko
185df7f9acdSAndy Shevchenko if (!val)
186df7f9acdSAndy Shevchenko seq_puts(s, " none");
187df7f9acdSAndy Shevchenko
188df7f9acdSAndy Shevchenko seq_putc(s, '\n');
189df7f9acdSAndy Shevchenko }
190df7f9acdSAndy Shevchenko
plr_status_show(struct seq_file * s,void * unused)191df7f9acdSAndy Shevchenko static int plr_status_show(struct seq_file *s, void *unused)
192df7f9acdSAndy Shevchenko {
193df7f9acdSAndy Shevchenko struct tpmi_plr_die *plr_die = s->private;
194df7f9acdSAndy Shevchenko int ret;
195df7f9acdSAndy Shevchenko u64 val;
196df7f9acdSAndy Shevchenko
197df7f9acdSAndy Shevchenko val = plr_read(plr_die, PLR_DIE_LEVEL);
198df7f9acdSAndy Shevchenko seq_puts(s, "cpus");
199df7f9acdSAndy Shevchenko plr_print_bits(s, val, 32);
200df7f9acdSAndy Shevchenko
201df7f9acdSAndy Shevchenko guard(mutex)(&plr_die->lock);
202df7f9acdSAndy Shevchenko
203df7f9acdSAndy Shevchenko for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
204df7f9acdSAndy Shevchenko if (plr_die->die_id != tpmi_get_power_domain_id(cpu))
205df7f9acdSAndy Shevchenko continue;
206df7f9acdSAndy Shevchenko
207df7f9acdSAndy Shevchenko if (plr_die->package_id != topology_physical_package_id(cpu))
208df7f9acdSAndy Shevchenko continue;
209df7f9acdSAndy Shevchenko
210df7f9acdSAndy Shevchenko seq_printf(s, "cpu%d", cpu);
211df7f9acdSAndy Shevchenko ret = plr_read_cpu_status(plr_die, cpu, &val);
212df7f9acdSAndy Shevchenko if (ret) {
213df7f9acdSAndy Shevchenko dev_err(&plr_die->plr->auxdev->dev, "Failed to read PLR for cpu %d, ret=%d\n",
214df7f9acdSAndy Shevchenko cpu, ret);
215df7f9acdSAndy Shevchenko return ret;
216df7f9acdSAndy Shevchenko }
217df7f9acdSAndy Shevchenko
218df7f9acdSAndy Shevchenko plr_print_bits(s, val, 64);
219df7f9acdSAndy Shevchenko }
220df7f9acdSAndy Shevchenko
221df7f9acdSAndy Shevchenko return 0;
222df7f9acdSAndy Shevchenko }
223df7f9acdSAndy Shevchenko
plr_status_write(struct file * filp,const char __user * ubuf,size_t count,loff_t * ppos)224df7f9acdSAndy Shevchenko static ssize_t plr_status_write(struct file *filp, const char __user *ubuf,
225df7f9acdSAndy Shevchenko size_t count, loff_t *ppos)
226df7f9acdSAndy Shevchenko {
227df7f9acdSAndy Shevchenko struct seq_file *s = filp->private_data;
228df7f9acdSAndy Shevchenko struct tpmi_plr_die *plr_die = s->private;
229df7f9acdSAndy Shevchenko bool val;
230df7f9acdSAndy Shevchenko int ret;
231df7f9acdSAndy Shevchenko
232df7f9acdSAndy Shevchenko ret = kstrtobool_from_user(ubuf, count, &val);
233df7f9acdSAndy Shevchenko if (ret)
234df7f9acdSAndy Shevchenko return ret;
235df7f9acdSAndy Shevchenko
236df7f9acdSAndy Shevchenko if (val != 0)
237df7f9acdSAndy Shevchenko return -EINVAL;
238df7f9acdSAndy Shevchenko
239df7f9acdSAndy Shevchenko plr_write(0, plr_die, PLR_DIE_LEVEL);
240df7f9acdSAndy Shevchenko
241df7f9acdSAndy Shevchenko guard(mutex)(&plr_die->lock);
242df7f9acdSAndy Shevchenko
243df7f9acdSAndy Shevchenko for (int cpu = 0; cpu < nr_cpu_ids; cpu++) {
244df7f9acdSAndy Shevchenko if (plr_die->die_id != tpmi_get_power_domain_id(cpu))
245df7f9acdSAndy Shevchenko continue;
246df7f9acdSAndy Shevchenko
247df7f9acdSAndy Shevchenko if (plr_die->package_id != topology_physical_package_id(cpu))
248df7f9acdSAndy Shevchenko continue;
249df7f9acdSAndy Shevchenko
250df7f9acdSAndy Shevchenko plr_clear_cpu_status(plr_die, cpu);
251df7f9acdSAndy Shevchenko }
252df7f9acdSAndy Shevchenko
253df7f9acdSAndy Shevchenko return count;
254df7f9acdSAndy Shevchenko }
255df7f9acdSAndy Shevchenko DEFINE_SHOW_STORE_ATTRIBUTE(plr_status);
256df7f9acdSAndy Shevchenko
intel_plr_probe(struct auxiliary_device * auxdev,const struct auxiliary_device_id * id)257df7f9acdSAndy Shevchenko static int intel_plr_probe(struct auxiliary_device *auxdev, const struct auxiliary_device_id *id)
258df7f9acdSAndy Shevchenko {
259df7f9acdSAndy Shevchenko struct intel_tpmi_plat_info *plat_info;
260df7f9acdSAndy Shevchenko struct dentry *dentry;
261df7f9acdSAndy Shevchenko int i, num_resources;
262df7f9acdSAndy Shevchenko struct resource *res;
263df7f9acdSAndy Shevchenko struct tpmi_plr *plr;
264df7f9acdSAndy Shevchenko void __iomem *base;
265df7f9acdSAndy Shevchenko char name[17];
266df7f9acdSAndy Shevchenko int err;
267df7f9acdSAndy Shevchenko
268df7f9acdSAndy Shevchenko plat_info = tpmi_get_platform_data(auxdev);
269df7f9acdSAndy Shevchenko if (!plat_info)
270df7f9acdSAndy Shevchenko return dev_err_probe(&auxdev->dev, -EINVAL, "No platform info\n");
271df7f9acdSAndy Shevchenko
272df7f9acdSAndy Shevchenko dentry = tpmi_get_debugfs_dir(auxdev);
273df7f9acdSAndy Shevchenko if (!dentry)
274df7f9acdSAndy Shevchenko return dev_err_probe(&auxdev->dev, -ENODEV, "No TPMI debugfs directory.\n");
275df7f9acdSAndy Shevchenko
276df7f9acdSAndy Shevchenko num_resources = tpmi_get_resource_count(auxdev);
277df7f9acdSAndy Shevchenko if (!num_resources)
278df7f9acdSAndy Shevchenko return -EINVAL;
279df7f9acdSAndy Shevchenko
280df7f9acdSAndy Shevchenko plr = devm_kzalloc(&auxdev->dev, sizeof(*plr), GFP_KERNEL);
281df7f9acdSAndy Shevchenko if (!plr)
282df7f9acdSAndy Shevchenko return -ENOMEM;
283df7f9acdSAndy Shevchenko
284df7f9acdSAndy Shevchenko plr->die_info = devm_kcalloc(&auxdev->dev, num_resources, sizeof(*plr->die_info),
285df7f9acdSAndy Shevchenko GFP_KERNEL);
286df7f9acdSAndy Shevchenko if (!plr->die_info)
287df7f9acdSAndy Shevchenko return -ENOMEM;
288df7f9acdSAndy Shevchenko
289df7f9acdSAndy Shevchenko plr->num_dies = num_resources;
290df7f9acdSAndy Shevchenko plr->dbgfs_dir = debugfs_create_dir("plr", dentry);
291df7f9acdSAndy Shevchenko plr->auxdev = auxdev;
292df7f9acdSAndy Shevchenko
293df7f9acdSAndy Shevchenko for (i = 0; i < num_resources; i++) {
294df7f9acdSAndy Shevchenko res = tpmi_get_resource_at_index(auxdev, i);
295df7f9acdSAndy Shevchenko if (!res) {
296df7f9acdSAndy Shevchenko err = dev_err_probe(&auxdev->dev, -EINVAL, "No resource\n");
297df7f9acdSAndy Shevchenko goto err;
298df7f9acdSAndy Shevchenko }
299df7f9acdSAndy Shevchenko
300df7f9acdSAndy Shevchenko base = devm_ioremap_resource(&auxdev->dev, res);
301df7f9acdSAndy Shevchenko if (IS_ERR(base)) {
302df7f9acdSAndy Shevchenko err = PTR_ERR(base);
303df7f9acdSAndy Shevchenko goto err;
304df7f9acdSAndy Shevchenko }
305df7f9acdSAndy Shevchenko
306df7f9acdSAndy Shevchenko plr->die_info[i].base = base;
307df7f9acdSAndy Shevchenko plr->die_info[i].package_id = plat_info->package_id;
308df7f9acdSAndy Shevchenko plr->die_info[i].die_id = i;
309df7f9acdSAndy Shevchenko plr->die_info[i].plr = plr;
310df7f9acdSAndy Shevchenko mutex_init(&plr->die_info[i].lock);
311df7f9acdSAndy Shevchenko
312df7f9acdSAndy Shevchenko if (plr_read(&plr->die_info[i], PLR_HEADER) == PLR_INVALID)
313df7f9acdSAndy Shevchenko continue;
314df7f9acdSAndy Shevchenko
315df7f9acdSAndy Shevchenko snprintf(name, sizeof(name), "domain%d", i);
316df7f9acdSAndy Shevchenko
317df7f9acdSAndy Shevchenko dentry = debugfs_create_dir(name, plr->dbgfs_dir);
318df7f9acdSAndy Shevchenko debugfs_create_file("status", 0444, dentry, &plr->die_info[i],
319df7f9acdSAndy Shevchenko &plr_status_fops);
320df7f9acdSAndy Shevchenko }
321df7f9acdSAndy Shevchenko
322df7f9acdSAndy Shevchenko auxiliary_set_drvdata(auxdev, plr);
323df7f9acdSAndy Shevchenko
324df7f9acdSAndy Shevchenko return 0;
325df7f9acdSAndy Shevchenko
326df7f9acdSAndy Shevchenko err:
327df7f9acdSAndy Shevchenko debugfs_remove_recursive(plr->dbgfs_dir);
328df7f9acdSAndy Shevchenko return err;
329df7f9acdSAndy Shevchenko }
330df7f9acdSAndy Shevchenko
intel_plr_remove(struct auxiliary_device * auxdev)331df7f9acdSAndy Shevchenko static void intel_plr_remove(struct auxiliary_device *auxdev)
332df7f9acdSAndy Shevchenko {
333df7f9acdSAndy Shevchenko struct tpmi_plr *plr = auxiliary_get_drvdata(auxdev);
334df7f9acdSAndy Shevchenko
335df7f9acdSAndy Shevchenko debugfs_remove_recursive(plr->dbgfs_dir);
336df7f9acdSAndy Shevchenko }
337df7f9acdSAndy Shevchenko
338df7f9acdSAndy Shevchenko static const struct auxiliary_device_id intel_plr_id_table[] = {
339df7f9acdSAndy Shevchenko { .name = "intel_vsec.tpmi-plr" },
340df7f9acdSAndy Shevchenko {}
341df7f9acdSAndy Shevchenko };
342df7f9acdSAndy Shevchenko MODULE_DEVICE_TABLE(auxiliary, intel_plr_id_table);
343df7f9acdSAndy Shevchenko
344df7f9acdSAndy Shevchenko static struct auxiliary_driver intel_plr_aux_driver = {
345df7f9acdSAndy Shevchenko .id_table = intel_plr_id_table,
346df7f9acdSAndy Shevchenko .remove = intel_plr_remove,
347df7f9acdSAndy Shevchenko .probe = intel_plr_probe,
348df7f9acdSAndy Shevchenko };
349df7f9acdSAndy Shevchenko module_auxiliary_driver(intel_plr_aux_driver);
350df7f9acdSAndy Shevchenko
351*cdd30ebbSPeter Zijlstra MODULE_IMPORT_NS("INTEL_TPMI");
352*cdd30ebbSPeter Zijlstra MODULE_IMPORT_NS("INTEL_TPMI_POWER_DOMAIN");
353df7f9acdSAndy Shevchenko MODULE_DESCRIPTION("Intel TPMI PLR Driver");
354df7f9acdSAndy Shevchenko MODULE_LICENSE("GPL");
355