cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

acpi_tad.c (15647B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * ACPI Time and Alarm (TAD) Device Driver
      4 *
      5 * Copyright (C) 2018 Intel Corporation
      6 * Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
      7 *
      8 * This driver is based on Section 9.18 of the ACPI 6.2 specification revision.
      9 *
     10 * It only supports the system wakeup capabilities of the TAD.
     11 *
     12 * Provided are sysfs attributes, available under the TAD platform device,
     13 * allowing user space to manage the AC and DC wakeup timers of the TAD:
     14 * set and read their values, set and check their expire timer wake policies,
     15 * check and clear their status and check the capabilities of the TAD reported
     16 * by AML.  The DC timer attributes are only present if the TAD supports a
     17 * separate DC alarm timer.
     18 *
     19 * The wakeup events handling and power management of the TAD is expected to
     20 * be taken care of by the ACPI PM domain attached to its platform device.
     21 */
     22
     23#include <linux/acpi.h>
     24#include <linux/kernel.h>
     25#include <linux/module.h>
     26#include <linux/platform_device.h>
     27#include <linux/pm_runtime.h>
     28#include <linux/suspend.h>
     29
     30MODULE_LICENSE("GPL v2");
     31MODULE_AUTHOR("Rafael J. Wysocki");
     32
     33/* ACPI TAD capability flags (ACPI 6.2, Section 9.18.2) */
     34#define ACPI_TAD_AC_WAKE	BIT(0)
     35#define ACPI_TAD_DC_WAKE	BIT(1)
     36#define ACPI_TAD_RT		BIT(2)
     37#define ACPI_TAD_RT_IN_MS	BIT(3)
     38#define ACPI_TAD_S4_S5__GWS	BIT(4)
     39#define ACPI_TAD_AC_S4_WAKE	BIT(5)
     40#define ACPI_TAD_AC_S5_WAKE	BIT(6)
     41#define ACPI_TAD_DC_S4_WAKE	BIT(7)
     42#define ACPI_TAD_DC_S5_WAKE	BIT(8)
     43
     44/* ACPI TAD alarm timer selection */
     45#define ACPI_TAD_AC_TIMER	(u32)0
     46#define ACPI_TAD_DC_TIMER	(u32)1
     47
     48/* Special value for disabled timer or expired timer wake policy. */
     49#define ACPI_TAD_WAKE_DISABLED	(~(u32)0)
     50
     51struct acpi_tad_driver_data {
     52	u32 capabilities;
     53};
     54
     55struct acpi_tad_rt {
     56	u16 year;  /* 1900 - 9999 */
     57	u8 month;  /* 1 - 12 */
     58	u8 day;    /* 1 - 31 */
     59	u8 hour;   /* 0 - 23 */
     60	u8 minute; /* 0 - 59 */
     61	u8 second; /* 0 - 59 */
     62	u8 valid;  /* 0 (failed) or 1 (success) for reads, 0 for writes */
     63	u16 msec;  /* 1 - 1000 */
     64	s16 tz;    /* -1440 to 1440 or 2047 (unspecified) */
     65	u8 daylight;
     66	u8 padding[3]; /* must be 0 */
     67} __packed;
     68
     69static int acpi_tad_set_real_time(struct device *dev, struct acpi_tad_rt *rt)
     70{
     71	acpi_handle handle = ACPI_HANDLE(dev);
     72	union acpi_object args[] = {
     73		{ .type = ACPI_TYPE_BUFFER, },
     74	};
     75	struct acpi_object_list arg_list = {
     76		.pointer = args,
     77		.count = ARRAY_SIZE(args),
     78	};
     79	unsigned long long retval;
     80	acpi_status status;
     81
     82	if (rt->year < 1900 || rt->year > 9999 ||
     83	    rt->month < 1 || rt->month > 12 ||
     84	    rt->hour > 23 || rt->minute > 59 || rt->second > 59 ||
     85	    rt->tz < -1440 || (rt->tz > 1440 && rt->tz != 2047) ||
     86	    rt->daylight > 3)
     87		return -ERANGE;
     88
     89	args[0].buffer.pointer = (u8 *)rt;
     90	args[0].buffer.length = sizeof(*rt);
     91
     92	pm_runtime_get_sync(dev);
     93
     94	status = acpi_evaluate_integer(handle, "_SRT", &arg_list, &retval);
     95
     96	pm_runtime_put_sync(dev);
     97
     98	if (ACPI_FAILURE(status) || retval)
     99		return -EIO;
    100
    101	return 0;
    102}
    103
    104static int acpi_tad_get_real_time(struct device *dev, struct acpi_tad_rt *rt)
    105{
    106	acpi_handle handle = ACPI_HANDLE(dev);
    107	struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER };
    108	union acpi_object *out_obj;
    109	struct acpi_tad_rt *data;
    110	acpi_status status;
    111	int ret = -EIO;
    112
    113	pm_runtime_get_sync(dev);
    114
    115	status = acpi_evaluate_object(handle, "_GRT", NULL, &output);
    116
    117	pm_runtime_put_sync(dev);
    118
    119	if (ACPI_FAILURE(status))
    120		goto out_free;
    121
    122	out_obj = output.pointer;
    123	if (out_obj->type != ACPI_TYPE_BUFFER)
    124		goto out_free;
    125
    126	if (out_obj->buffer.length != sizeof(*rt))
    127		goto out_free;
    128
    129	data = (struct acpi_tad_rt *)(out_obj->buffer.pointer);
    130	if (!data->valid)
    131		goto out_free;
    132
    133	memcpy(rt, data, sizeof(*rt));
    134	ret = 0;
    135
    136out_free:
    137	ACPI_FREE(output.pointer);
    138	return ret;
    139}
    140
    141static char *acpi_tad_rt_next_field(char *s, int *val)
    142{
    143	char *p;
    144
    145	p = strchr(s, ':');
    146	if (!p)
    147		return NULL;
    148
    149	*p = '\0';
    150	if (kstrtoint(s, 10, val))
    151		return NULL;
    152
    153	return p + 1;
    154}
    155
    156static ssize_t time_store(struct device *dev, struct device_attribute *attr,
    157			  const char *buf, size_t count)
    158{
    159	struct acpi_tad_rt rt;
    160	char *str, *s;
    161	int val, ret = -ENODATA;
    162
    163	str = kmemdup_nul(buf, count, GFP_KERNEL);
    164	if (!str)
    165		return -ENOMEM;
    166
    167	s = acpi_tad_rt_next_field(str, &val);
    168	if (!s)
    169		goto out_free;
    170
    171	rt.year = val;
    172
    173	s = acpi_tad_rt_next_field(s, &val);
    174	if (!s)
    175		goto out_free;
    176
    177	rt.month = val;
    178
    179	s = acpi_tad_rt_next_field(s, &val);
    180	if (!s)
    181		goto out_free;
    182
    183	rt.day = val;
    184
    185	s = acpi_tad_rt_next_field(s, &val);
    186	if (!s)
    187		goto out_free;
    188
    189	rt.hour = val;
    190
    191	s = acpi_tad_rt_next_field(s, &val);
    192	if (!s)
    193		goto out_free;
    194
    195	rt.minute = val;
    196
    197	s = acpi_tad_rt_next_field(s, &val);
    198	if (!s)
    199		goto out_free;
    200
    201	rt.second = val;
    202
    203	s = acpi_tad_rt_next_field(s, &val);
    204	if (!s)
    205		goto out_free;
    206
    207	rt.tz = val;
    208
    209	if (kstrtoint(s, 10, &val))
    210		goto out_free;
    211
    212	rt.daylight = val;
    213
    214	rt.valid = 0;
    215	rt.msec = 0;
    216	memset(rt.padding, 0, 3);
    217
    218	ret = acpi_tad_set_real_time(dev, &rt);
    219
    220out_free:
    221	kfree(str);
    222	return ret ? ret : count;
    223}
    224
    225static ssize_t time_show(struct device *dev, struct device_attribute *attr,
    226			 char *buf)
    227{
    228	struct acpi_tad_rt rt;
    229	int ret;
    230
    231	ret = acpi_tad_get_real_time(dev, &rt);
    232	if (ret)
    233		return ret;
    234
    235	return sprintf(buf, "%u:%u:%u:%u:%u:%u:%d:%u\n",
    236		       rt.year, rt.month, rt.day, rt.hour, rt.minute, rt.second,
    237		       rt.tz, rt.daylight);
    238}
    239
    240static DEVICE_ATTR_RW(time);
    241
    242static struct attribute *acpi_tad_time_attrs[] = {
    243	&dev_attr_time.attr,
    244	NULL,
    245};
    246static const struct attribute_group acpi_tad_time_attr_group = {
    247	.attrs	= acpi_tad_time_attrs,
    248};
    249
    250static int acpi_tad_wake_set(struct device *dev, char *method, u32 timer_id,
    251			     u32 value)
    252{
    253	acpi_handle handle = ACPI_HANDLE(dev);
    254	union acpi_object args[] = {
    255		{ .type = ACPI_TYPE_INTEGER, },
    256		{ .type = ACPI_TYPE_INTEGER, },
    257	};
    258	struct acpi_object_list arg_list = {
    259		.pointer = args,
    260		.count = ARRAY_SIZE(args),
    261	};
    262	unsigned long long retval;
    263	acpi_status status;
    264
    265	args[0].integer.value = timer_id;
    266	args[1].integer.value = value;
    267
    268	pm_runtime_get_sync(dev);
    269
    270	status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
    271
    272	pm_runtime_put_sync(dev);
    273
    274	if (ACPI_FAILURE(status) || retval)
    275		return -EIO;
    276
    277	return 0;
    278}
    279
    280static int acpi_tad_wake_write(struct device *dev, const char *buf, char *method,
    281			       u32 timer_id, const char *specval)
    282{
    283	u32 value;
    284
    285	if (sysfs_streq(buf, specval)) {
    286		value = ACPI_TAD_WAKE_DISABLED;
    287	} else {
    288		int ret = kstrtou32(buf, 0, &value);
    289
    290		if (ret)
    291			return ret;
    292
    293		if (value == ACPI_TAD_WAKE_DISABLED)
    294			return -EINVAL;
    295	}
    296
    297	return acpi_tad_wake_set(dev, method, timer_id, value);
    298}
    299
    300static ssize_t acpi_tad_wake_read(struct device *dev, char *buf, char *method,
    301				  u32 timer_id, const char *specval)
    302{
    303	acpi_handle handle = ACPI_HANDLE(dev);
    304	union acpi_object args[] = {
    305		{ .type = ACPI_TYPE_INTEGER, },
    306	};
    307	struct acpi_object_list arg_list = {
    308		.pointer = args,
    309		.count = ARRAY_SIZE(args),
    310	};
    311	unsigned long long retval;
    312	acpi_status status;
    313
    314	args[0].integer.value = timer_id;
    315
    316	pm_runtime_get_sync(dev);
    317
    318	status = acpi_evaluate_integer(handle, method, &arg_list, &retval);
    319
    320	pm_runtime_put_sync(dev);
    321
    322	if (ACPI_FAILURE(status))
    323		return -EIO;
    324
    325	if ((u32)retval == ACPI_TAD_WAKE_DISABLED)
    326		return sprintf(buf, "%s\n", specval);
    327
    328	return sprintf(buf, "%u\n", (u32)retval);
    329}
    330
    331static const char *alarm_specval = "disabled";
    332
    333static int acpi_tad_alarm_write(struct device *dev, const char *buf,
    334				u32 timer_id)
    335{
    336	return acpi_tad_wake_write(dev, buf, "_STV", timer_id, alarm_specval);
    337}
    338
    339static ssize_t acpi_tad_alarm_read(struct device *dev, char *buf, u32 timer_id)
    340{
    341	return acpi_tad_wake_read(dev, buf, "_TIV", timer_id, alarm_specval);
    342}
    343
    344static const char *policy_specval = "never";
    345
    346static int acpi_tad_policy_write(struct device *dev, const char *buf,
    347				 u32 timer_id)
    348{
    349	return acpi_tad_wake_write(dev, buf, "_STP", timer_id, policy_specval);
    350}
    351
    352static ssize_t acpi_tad_policy_read(struct device *dev, char *buf, u32 timer_id)
    353{
    354	return acpi_tad_wake_read(dev, buf, "_TIP", timer_id, policy_specval);
    355}
    356
    357static int acpi_tad_clear_status(struct device *dev, u32 timer_id)
    358{
    359	acpi_handle handle = ACPI_HANDLE(dev);
    360	union acpi_object args[] = {
    361		{ .type = ACPI_TYPE_INTEGER, },
    362	};
    363	struct acpi_object_list arg_list = {
    364		.pointer = args,
    365		.count = ARRAY_SIZE(args),
    366	};
    367	unsigned long long retval;
    368	acpi_status status;
    369
    370	args[0].integer.value = timer_id;
    371
    372	pm_runtime_get_sync(dev);
    373
    374	status = acpi_evaluate_integer(handle, "_CWS", &arg_list, &retval);
    375
    376	pm_runtime_put_sync(dev);
    377
    378	if (ACPI_FAILURE(status) || retval)
    379		return -EIO;
    380
    381	return 0;
    382}
    383
    384static int acpi_tad_status_write(struct device *dev, const char *buf, u32 timer_id)
    385{
    386	int ret, value;
    387
    388	ret = kstrtoint(buf, 0, &value);
    389	if (ret)
    390		return ret;
    391
    392	if (value)
    393		return -EINVAL;
    394
    395	return acpi_tad_clear_status(dev, timer_id);
    396}
    397
    398static ssize_t acpi_tad_status_read(struct device *dev, char *buf, u32 timer_id)
    399{
    400	acpi_handle handle = ACPI_HANDLE(dev);
    401	union acpi_object args[] = {
    402		{ .type = ACPI_TYPE_INTEGER, },
    403	};
    404	struct acpi_object_list arg_list = {
    405		.pointer = args,
    406		.count = ARRAY_SIZE(args),
    407	};
    408	unsigned long long retval;
    409	acpi_status status;
    410
    411	args[0].integer.value = timer_id;
    412
    413	pm_runtime_get_sync(dev);
    414
    415	status = acpi_evaluate_integer(handle, "_GWS", &arg_list, &retval);
    416
    417	pm_runtime_put_sync(dev);
    418
    419	if (ACPI_FAILURE(status))
    420		return -EIO;
    421
    422	return sprintf(buf, "0x%02X\n", (u32)retval);
    423}
    424
    425static ssize_t caps_show(struct device *dev, struct device_attribute *attr,
    426			 char *buf)
    427{
    428	struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
    429
    430	return sprintf(buf, "0x%02X\n", dd->capabilities);
    431}
    432
    433static DEVICE_ATTR_RO(caps);
    434
    435static ssize_t ac_alarm_store(struct device *dev, struct device_attribute *attr,
    436			      const char *buf, size_t count)
    437{
    438	int ret = acpi_tad_alarm_write(dev, buf, ACPI_TAD_AC_TIMER);
    439
    440	return ret ? ret : count;
    441}
    442
    443static ssize_t ac_alarm_show(struct device *dev, struct device_attribute *attr,
    444			     char *buf)
    445{
    446	return acpi_tad_alarm_read(dev, buf, ACPI_TAD_AC_TIMER);
    447}
    448
    449static DEVICE_ATTR_RW(ac_alarm);
    450
    451static ssize_t ac_policy_store(struct device *dev, struct device_attribute *attr,
    452			       const char *buf, size_t count)
    453{
    454	int ret = acpi_tad_policy_write(dev, buf, ACPI_TAD_AC_TIMER);
    455
    456	return ret ? ret : count;
    457}
    458
    459static ssize_t ac_policy_show(struct device *dev, struct device_attribute *attr,
    460			      char *buf)
    461{
    462	return acpi_tad_policy_read(dev, buf, ACPI_TAD_AC_TIMER);
    463}
    464
    465static DEVICE_ATTR_RW(ac_policy);
    466
    467static ssize_t ac_status_store(struct device *dev, struct device_attribute *attr,
    468			       const char *buf, size_t count)
    469{
    470	int ret = acpi_tad_status_write(dev, buf, ACPI_TAD_AC_TIMER);
    471
    472	return ret ? ret : count;
    473}
    474
    475static ssize_t ac_status_show(struct device *dev, struct device_attribute *attr,
    476			      char *buf)
    477{
    478	return acpi_tad_status_read(dev, buf, ACPI_TAD_AC_TIMER);
    479}
    480
    481static DEVICE_ATTR_RW(ac_status);
    482
    483static struct attribute *acpi_tad_attrs[] = {
    484	&dev_attr_caps.attr,
    485	&dev_attr_ac_alarm.attr,
    486	&dev_attr_ac_policy.attr,
    487	&dev_attr_ac_status.attr,
    488	NULL,
    489};
    490static const struct attribute_group acpi_tad_attr_group = {
    491	.attrs	= acpi_tad_attrs,
    492};
    493
    494static ssize_t dc_alarm_store(struct device *dev, struct device_attribute *attr,
    495			      const char *buf, size_t count)
    496{
    497	int ret = acpi_tad_alarm_write(dev, buf, ACPI_TAD_DC_TIMER);
    498
    499	return ret ? ret : count;
    500}
    501
    502static ssize_t dc_alarm_show(struct device *dev, struct device_attribute *attr,
    503			     char *buf)
    504{
    505	return acpi_tad_alarm_read(dev, buf, ACPI_TAD_DC_TIMER);
    506}
    507
    508static DEVICE_ATTR_RW(dc_alarm);
    509
    510static ssize_t dc_policy_store(struct device *dev, struct device_attribute *attr,
    511			       const char *buf, size_t count)
    512{
    513	int ret = acpi_tad_policy_write(dev, buf, ACPI_TAD_DC_TIMER);
    514
    515	return ret ? ret : count;
    516}
    517
    518static ssize_t dc_policy_show(struct device *dev, struct device_attribute *attr,
    519			      char *buf)
    520{
    521	return acpi_tad_policy_read(dev, buf, ACPI_TAD_DC_TIMER);
    522}
    523
    524static DEVICE_ATTR_RW(dc_policy);
    525
    526static ssize_t dc_status_store(struct device *dev, struct device_attribute *attr,
    527			       const char *buf, size_t count)
    528{
    529	int ret = acpi_tad_status_write(dev, buf, ACPI_TAD_DC_TIMER);
    530
    531	return ret ? ret : count;
    532}
    533
    534static ssize_t dc_status_show(struct device *dev, struct device_attribute *attr,
    535			      char *buf)
    536{
    537	return acpi_tad_status_read(dev, buf, ACPI_TAD_DC_TIMER);
    538}
    539
    540static DEVICE_ATTR_RW(dc_status);
    541
    542static struct attribute *acpi_tad_dc_attrs[] = {
    543	&dev_attr_dc_alarm.attr,
    544	&dev_attr_dc_policy.attr,
    545	&dev_attr_dc_status.attr,
    546	NULL,
    547};
    548static const struct attribute_group acpi_tad_dc_attr_group = {
    549	.attrs	= acpi_tad_dc_attrs,
    550};
    551
    552static int acpi_tad_disable_timer(struct device *dev, u32 timer_id)
    553{
    554	return acpi_tad_wake_set(dev, "_STV", timer_id, ACPI_TAD_WAKE_DISABLED);
    555}
    556
    557static int acpi_tad_remove(struct platform_device *pdev)
    558{
    559	struct device *dev = &pdev->dev;
    560	struct acpi_tad_driver_data *dd = dev_get_drvdata(dev);
    561
    562	device_init_wakeup(dev, false);
    563
    564	pm_runtime_get_sync(dev);
    565
    566	if (dd->capabilities & ACPI_TAD_DC_WAKE)
    567		sysfs_remove_group(&dev->kobj, &acpi_tad_dc_attr_group);
    568
    569	sysfs_remove_group(&dev->kobj, &acpi_tad_attr_group);
    570
    571	acpi_tad_disable_timer(dev, ACPI_TAD_AC_TIMER);
    572	acpi_tad_clear_status(dev, ACPI_TAD_AC_TIMER);
    573	if (dd->capabilities & ACPI_TAD_DC_WAKE) {
    574		acpi_tad_disable_timer(dev, ACPI_TAD_DC_TIMER);
    575		acpi_tad_clear_status(dev, ACPI_TAD_DC_TIMER);
    576	}
    577
    578	pm_runtime_put_sync(dev);
    579	pm_runtime_disable(dev);
    580	return 0;
    581}
    582
    583static int acpi_tad_probe(struct platform_device *pdev)
    584{
    585	struct device *dev = &pdev->dev;
    586	acpi_handle handle = ACPI_HANDLE(dev);
    587	struct acpi_tad_driver_data *dd;
    588	acpi_status status;
    589	unsigned long long caps;
    590	int ret;
    591
    592	/*
    593	 * Initialization failure messages are mostly about firmware issues, so
    594	 * print them at the "info" level.
    595	 */
    596	status = acpi_evaluate_integer(handle, "_GCP", NULL, &caps);
    597	if (ACPI_FAILURE(status)) {
    598		dev_info(dev, "Unable to get capabilities\n");
    599		return -ENODEV;
    600	}
    601
    602	if (!(caps & ACPI_TAD_AC_WAKE)) {
    603		dev_info(dev, "Unsupported capabilities\n");
    604		return -ENODEV;
    605	}
    606
    607	if (!acpi_has_method(handle, "_PRW")) {
    608		dev_info(dev, "Missing _PRW\n");
    609		return -ENODEV;
    610	}
    611
    612	dd = devm_kzalloc(dev, sizeof(*dd), GFP_KERNEL);
    613	if (!dd)
    614		return -ENOMEM;
    615
    616	dd->capabilities = caps;
    617	dev_set_drvdata(dev, dd);
    618
    619	/*
    620	 * Assume that the ACPI PM domain has been attached to the device and
    621	 * simply enable system wakeup and runtime PM and put the device into
    622	 * runtime suspend.  Everything else should be taken care of by the ACPI
    623	 * PM domain callbacks.
    624	 */
    625	device_init_wakeup(dev, true);
    626	dev_pm_set_driver_flags(dev, DPM_FLAG_SMART_SUSPEND |
    627				     DPM_FLAG_MAY_SKIP_RESUME);
    628	/*
    629	 * The platform bus type layer tells the ACPI PM domain powers up the
    630	 * device, so set the runtime PM status of it to "active".
    631	 */
    632	pm_runtime_set_active(dev);
    633	pm_runtime_enable(dev);
    634	pm_runtime_suspend(dev);
    635
    636	ret = sysfs_create_group(&dev->kobj, &acpi_tad_attr_group);
    637	if (ret)
    638		goto fail;
    639
    640	if (caps & ACPI_TAD_DC_WAKE) {
    641		ret = sysfs_create_group(&dev->kobj, &acpi_tad_dc_attr_group);
    642		if (ret)
    643			goto fail;
    644	}
    645
    646	if (caps & ACPI_TAD_RT) {
    647		ret = sysfs_create_group(&dev->kobj, &acpi_tad_time_attr_group);
    648		if (ret)
    649			goto fail;
    650	}
    651
    652	return 0;
    653
    654fail:
    655	acpi_tad_remove(pdev);
    656	return ret;
    657}
    658
    659static const struct acpi_device_id acpi_tad_ids[] = {
    660	{"ACPI000E", 0},
    661	{}
    662};
    663
    664static struct platform_driver acpi_tad_driver = {
    665	.driver = {
    666		.name = "acpi-tad",
    667		.acpi_match_table = acpi_tad_ids,
    668	},
    669	.probe = acpi_tad_probe,
    670	.remove = acpi_tad_remove,
    671};
    672MODULE_DEVICE_TABLE(acpi, acpi_tad_ids);
    673
    674module_platform_driver(acpi_tad_driver);