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

gpio-fan.c (14230B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * gpio-fan.c - Hwmon driver for fans connected to GPIO lines.
      4 *
      5 * Copyright (C) 2010 LaCie
      6 *
      7 * Author: Simon Guinot <sguinot@lacie.com>
      8 */
      9
     10#include <linux/module.h>
     11#include <linux/init.h>
     12#include <linux/slab.h>
     13#include <linux/interrupt.h>
     14#include <linux/irq.h>
     15#include <linux/platform_device.h>
     16#include <linux/err.h>
     17#include <linux/mutex.h>
     18#include <linux/hwmon.h>
     19#include <linux/gpio/consumer.h>
     20#include <linux/of.h>
     21#include <linux/of_platform.h>
     22#include <linux/thermal.h>
     23
     24struct gpio_fan_speed {
     25	int rpm;
     26	int ctrl_val;
     27};
     28
     29struct gpio_fan_data {
     30	struct device		*dev;
     31	struct device		*hwmon_dev;
     32	/* Cooling device if any */
     33	struct thermal_cooling_device *cdev;
     34	struct mutex		lock; /* lock GPIOs operations. */
     35	int			num_gpios;
     36	struct gpio_desc	**gpios;
     37	int			num_speed;
     38	struct gpio_fan_speed	*speed;
     39	int			speed_index;
     40#ifdef CONFIG_PM_SLEEP
     41	int			resume_speed;
     42#endif
     43	bool			pwm_enable;
     44	struct gpio_desc	*alarm_gpio;
     45	struct work_struct	alarm_work;
     46};
     47
     48/*
     49 * Alarm GPIO.
     50 */
     51
     52static void fan_alarm_notify(struct work_struct *ws)
     53{
     54	struct gpio_fan_data *fan_data =
     55		container_of(ws, struct gpio_fan_data, alarm_work);
     56
     57	sysfs_notify(&fan_data->hwmon_dev->kobj, NULL, "fan1_alarm");
     58	kobject_uevent(&fan_data->hwmon_dev->kobj, KOBJ_CHANGE);
     59}
     60
     61static irqreturn_t fan_alarm_irq_handler(int irq, void *dev_id)
     62{
     63	struct gpio_fan_data *fan_data = dev_id;
     64
     65	schedule_work(&fan_data->alarm_work);
     66
     67	return IRQ_NONE;
     68}
     69
     70static ssize_t fan1_alarm_show(struct device *dev,
     71			       struct device_attribute *attr, char *buf)
     72{
     73	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
     74
     75	return sprintf(buf, "%d\n",
     76		       gpiod_get_value_cansleep(fan_data->alarm_gpio));
     77}
     78
     79static DEVICE_ATTR_RO(fan1_alarm);
     80
     81static int fan_alarm_init(struct gpio_fan_data *fan_data)
     82{
     83	int alarm_irq;
     84	struct device *dev = fan_data->dev;
     85
     86	/*
     87	 * If the alarm GPIO don't support interrupts, just leave
     88	 * without initializing the fail notification support.
     89	 */
     90	alarm_irq = gpiod_to_irq(fan_data->alarm_gpio);
     91	if (alarm_irq <= 0)
     92		return 0;
     93
     94	INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
     95	irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
     96	return devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler,
     97				IRQF_SHARED, "GPIO fan alarm", fan_data);
     98}
     99
    100/*
    101 * Control GPIOs.
    102 */
    103
    104/* Must be called with fan_data->lock held, except during initialization. */
    105static void __set_fan_ctrl(struct gpio_fan_data *fan_data, int ctrl_val)
    106{
    107	int i;
    108
    109	for (i = 0; i < fan_data->num_gpios; i++)
    110		gpiod_set_value_cansleep(fan_data->gpios[i],
    111					 (ctrl_val >> i) & 1);
    112}
    113
    114static int __get_fan_ctrl(struct gpio_fan_data *fan_data)
    115{
    116	int i;
    117	int ctrl_val = 0;
    118
    119	for (i = 0; i < fan_data->num_gpios; i++) {
    120		int value;
    121
    122		value = gpiod_get_value_cansleep(fan_data->gpios[i]);
    123		ctrl_val |= (value << i);
    124	}
    125	return ctrl_val;
    126}
    127
    128/* Must be called with fan_data->lock held, except during initialization. */
    129static void set_fan_speed(struct gpio_fan_data *fan_data, int speed_index)
    130{
    131	if (fan_data->speed_index == speed_index)
    132		return;
    133
    134	__set_fan_ctrl(fan_data, fan_data->speed[speed_index].ctrl_val);
    135	fan_data->speed_index = speed_index;
    136}
    137
    138static int get_fan_speed_index(struct gpio_fan_data *fan_data)
    139{
    140	int ctrl_val = __get_fan_ctrl(fan_data);
    141	int i;
    142
    143	for (i = 0; i < fan_data->num_speed; i++)
    144		if (fan_data->speed[i].ctrl_val == ctrl_val)
    145			return i;
    146
    147	dev_warn(fan_data->dev,
    148		 "missing speed array entry for GPIO value 0x%x\n", ctrl_val);
    149
    150	return -ENODEV;
    151}
    152
    153static int rpm_to_speed_index(struct gpio_fan_data *fan_data, unsigned long rpm)
    154{
    155	struct gpio_fan_speed *speed = fan_data->speed;
    156	int i;
    157
    158	for (i = 0; i < fan_data->num_speed; i++)
    159		if (speed[i].rpm >= rpm)
    160			return i;
    161
    162	return fan_data->num_speed - 1;
    163}
    164
    165static ssize_t pwm1_show(struct device *dev, struct device_attribute *attr,
    166			 char *buf)
    167{
    168	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    169	u8 pwm = fan_data->speed_index * 255 / (fan_data->num_speed - 1);
    170
    171	return sprintf(buf, "%d\n", pwm);
    172}
    173
    174static ssize_t pwm1_store(struct device *dev, struct device_attribute *attr,
    175			  const char *buf, size_t count)
    176{
    177	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    178	unsigned long pwm;
    179	int speed_index;
    180	int ret = count;
    181
    182	if (kstrtoul(buf, 10, &pwm) || pwm > 255)
    183		return -EINVAL;
    184
    185	mutex_lock(&fan_data->lock);
    186
    187	if (!fan_data->pwm_enable) {
    188		ret = -EPERM;
    189		goto exit_unlock;
    190	}
    191
    192	speed_index = DIV_ROUND_UP(pwm * (fan_data->num_speed - 1), 255);
    193	set_fan_speed(fan_data, speed_index);
    194
    195exit_unlock:
    196	mutex_unlock(&fan_data->lock);
    197
    198	return ret;
    199}
    200
    201static ssize_t pwm1_enable_show(struct device *dev,
    202				struct device_attribute *attr, char *buf)
    203{
    204	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    205
    206	return sprintf(buf, "%d\n", fan_data->pwm_enable);
    207}
    208
    209static ssize_t pwm1_enable_store(struct device *dev,
    210				 struct device_attribute *attr,
    211				 const char *buf, size_t count)
    212{
    213	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    214	unsigned long val;
    215
    216	if (kstrtoul(buf, 10, &val) || val > 1)
    217		return -EINVAL;
    218
    219	if (fan_data->pwm_enable == val)
    220		return count;
    221
    222	mutex_lock(&fan_data->lock);
    223
    224	fan_data->pwm_enable = val;
    225
    226	/* Disable manual control mode: set fan at full speed. */
    227	if (val == 0)
    228		set_fan_speed(fan_data, fan_data->num_speed - 1);
    229
    230	mutex_unlock(&fan_data->lock);
    231
    232	return count;
    233}
    234
    235static ssize_t pwm1_mode_show(struct device *dev,
    236			      struct device_attribute *attr, char *buf)
    237{
    238	return sprintf(buf, "0\n");
    239}
    240
    241static ssize_t fan1_min_show(struct device *dev,
    242			     struct device_attribute *attr, char *buf)
    243{
    244	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    245
    246	return sprintf(buf, "%d\n", fan_data->speed[0].rpm);
    247}
    248
    249static ssize_t fan1_max_show(struct device *dev,
    250			     struct device_attribute *attr, char *buf)
    251{
    252	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    253
    254	return sprintf(buf, "%d\n",
    255		       fan_data->speed[fan_data->num_speed - 1].rpm);
    256}
    257
    258static ssize_t fan1_input_show(struct device *dev,
    259			       struct device_attribute *attr, char *buf)
    260{
    261	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    262
    263	return sprintf(buf, "%d\n", fan_data->speed[fan_data->speed_index].rpm);
    264}
    265
    266static ssize_t set_rpm(struct device *dev, struct device_attribute *attr,
    267		       const char *buf, size_t count)
    268{
    269	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    270	unsigned long rpm;
    271	int ret = count;
    272
    273	if (kstrtoul(buf, 10, &rpm))
    274		return -EINVAL;
    275
    276	mutex_lock(&fan_data->lock);
    277
    278	if (!fan_data->pwm_enable) {
    279		ret = -EPERM;
    280		goto exit_unlock;
    281	}
    282
    283	set_fan_speed(fan_data, rpm_to_speed_index(fan_data, rpm));
    284
    285exit_unlock:
    286	mutex_unlock(&fan_data->lock);
    287
    288	return ret;
    289}
    290
    291static DEVICE_ATTR_RW(pwm1);
    292static DEVICE_ATTR_RW(pwm1_enable);
    293static DEVICE_ATTR_RO(pwm1_mode);
    294static DEVICE_ATTR_RO(fan1_min);
    295static DEVICE_ATTR_RO(fan1_max);
    296static DEVICE_ATTR_RO(fan1_input);
    297static DEVICE_ATTR(fan1_target, 0644, fan1_input_show, set_rpm);
    298
    299static umode_t gpio_fan_is_visible(struct kobject *kobj,
    300				   struct attribute *attr, int index)
    301{
    302	struct device *dev = kobj_to_dev(kobj);
    303	struct gpio_fan_data *data = dev_get_drvdata(dev);
    304
    305	if (index == 0 && !data->alarm_gpio)
    306		return 0;
    307	if (index > 0 && !data->gpios)
    308		return 0;
    309
    310	return attr->mode;
    311}
    312
    313static struct attribute *gpio_fan_attributes[] = {
    314	&dev_attr_fan1_alarm.attr,		/* 0 */
    315	&dev_attr_pwm1.attr,			/* 1 */
    316	&dev_attr_pwm1_enable.attr,
    317	&dev_attr_pwm1_mode.attr,
    318	&dev_attr_fan1_input.attr,
    319	&dev_attr_fan1_target.attr,
    320	&dev_attr_fan1_min.attr,
    321	&dev_attr_fan1_max.attr,
    322	NULL
    323};
    324
    325static const struct attribute_group gpio_fan_group = {
    326	.attrs = gpio_fan_attributes,
    327	.is_visible = gpio_fan_is_visible,
    328};
    329
    330static const struct attribute_group *gpio_fan_groups[] = {
    331	&gpio_fan_group,
    332	NULL
    333};
    334
    335static int fan_ctrl_init(struct gpio_fan_data *fan_data)
    336{
    337	int num_gpios = fan_data->num_gpios;
    338	struct gpio_desc **gpios = fan_data->gpios;
    339	int i, err;
    340
    341	for (i = 0; i < num_gpios; i++) {
    342		/*
    343		 * The GPIO descriptors were retrieved with GPIOD_ASIS so here
    344		 * we set the GPIO into output mode, carefully preserving the
    345		 * current value by setting it to whatever it is already set
    346		 * (no surprise changes in default fan speed).
    347		 */
    348		err = gpiod_direction_output(gpios[i],
    349					gpiod_get_value_cansleep(gpios[i]));
    350		if (err)
    351			return err;
    352	}
    353
    354	fan_data->pwm_enable = true; /* Enable manual fan speed control. */
    355	fan_data->speed_index = get_fan_speed_index(fan_data);
    356	if (fan_data->speed_index < 0)
    357		return fan_data->speed_index;
    358
    359	return 0;
    360}
    361
    362static int gpio_fan_get_max_state(struct thermal_cooling_device *cdev,
    363				  unsigned long *state)
    364{
    365	struct gpio_fan_data *fan_data = cdev->devdata;
    366
    367	if (!fan_data)
    368		return -EINVAL;
    369
    370	*state = fan_data->num_speed - 1;
    371	return 0;
    372}
    373
    374static int gpio_fan_get_cur_state(struct thermal_cooling_device *cdev,
    375				  unsigned long *state)
    376{
    377	struct gpio_fan_data *fan_data = cdev->devdata;
    378
    379	if (!fan_data)
    380		return -EINVAL;
    381
    382	*state = fan_data->speed_index;
    383	return 0;
    384}
    385
    386static int gpio_fan_set_cur_state(struct thermal_cooling_device *cdev,
    387				  unsigned long state)
    388{
    389	struct gpio_fan_data *fan_data = cdev->devdata;
    390
    391	if (!fan_data)
    392		return -EINVAL;
    393
    394	set_fan_speed(fan_data, state);
    395	return 0;
    396}
    397
    398static const struct thermal_cooling_device_ops gpio_fan_cool_ops = {
    399	.get_max_state = gpio_fan_get_max_state,
    400	.get_cur_state = gpio_fan_get_cur_state,
    401	.set_cur_state = gpio_fan_set_cur_state,
    402};
    403
    404/*
    405 * Translate OpenFirmware node properties into platform_data
    406 */
    407static int gpio_fan_get_of_data(struct gpio_fan_data *fan_data)
    408{
    409	struct gpio_fan_speed *speed;
    410	struct device *dev = fan_data->dev;
    411	struct device_node *np = dev->of_node;
    412	struct gpio_desc **gpios;
    413	unsigned i;
    414	u32 u;
    415	struct property *prop;
    416	const __be32 *p;
    417
    418	/* Alarm GPIO if one exists */
    419	fan_data->alarm_gpio = devm_gpiod_get_optional(dev, "alarm", GPIOD_IN);
    420	if (IS_ERR(fan_data->alarm_gpio))
    421		return PTR_ERR(fan_data->alarm_gpio);
    422
    423	/* Fill GPIO pin array */
    424	fan_data->num_gpios = gpiod_count(dev, NULL);
    425	if (fan_data->num_gpios <= 0) {
    426		if (fan_data->alarm_gpio)
    427			return 0;
    428		dev_err(dev, "DT properties empty / missing");
    429		return -ENODEV;
    430	}
    431	gpios = devm_kcalloc(dev,
    432			     fan_data->num_gpios, sizeof(struct gpio_desc *),
    433			     GFP_KERNEL);
    434	if (!gpios)
    435		return -ENOMEM;
    436	for (i = 0; i < fan_data->num_gpios; i++) {
    437		gpios[i] = devm_gpiod_get_index(dev, NULL, i, GPIOD_ASIS);
    438		if (IS_ERR(gpios[i]))
    439			return PTR_ERR(gpios[i]);
    440	}
    441	fan_data->gpios = gpios;
    442
    443	/* Get number of RPM/ctrl_val pairs in speed map */
    444	prop = of_find_property(np, "gpio-fan,speed-map", &i);
    445	if (!prop) {
    446		dev_err(dev, "gpio-fan,speed-map DT property missing");
    447		return -ENODEV;
    448	}
    449	i = i / sizeof(u32);
    450	if (i == 0 || i & 1) {
    451		dev_err(dev, "gpio-fan,speed-map contains zero/odd number of entries");
    452		return -ENODEV;
    453	}
    454	fan_data->num_speed = i / 2;
    455
    456	/*
    457	 * Populate speed map
    458	 * Speed map is in the form <RPM ctrl_val RPM ctrl_val ...>
    459	 * this needs splitting into pairs to create gpio_fan_speed structs
    460	 */
    461	speed = devm_kcalloc(dev,
    462			fan_data->num_speed, sizeof(struct gpio_fan_speed),
    463			GFP_KERNEL);
    464	if (!speed)
    465		return -ENOMEM;
    466	p = NULL;
    467	for (i = 0; i < fan_data->num_speed; i++) {
    468		p = of_prop_next_u32(prop, p, &u);
    469		if (!p)
    470			return -ENODEV;
    471		speed[i].rpm = u;
    472		p = of_prop_next_u32(prop, p, &u);
    473		if (!p)
    474			return -ENODEV;
    475		speed[i].ctrl_val = u;
    476	}
    477	fan_data->speed = speed;
    478
    479	return 0;
    480}
    481
    482static const struct of_device_id of_gpio_fan_match[] = {
    483	{ .compatible = "gpio-fan", },
    484	{},
    485};
    486MODULE_DEVICE_TABLE(of, of_gpio_fan_match);
    487
    488static void gpio_fan_stop(void *data)
    489{
    490	set_fan_speed(data, 0);
    491}
    492
    493static int gpio_fan_probe(struct platform_device *pdev)
    494{
    495	int err;
    496	struct gpio_fan_data *fan_data;
    497	struct device *dev = &pdev->dev;
    498	struct device_node *np = dev->of_node;
    499
    500	fan_data = devm_kzalloc(dev, sizeof(struct gpio_fan_data),
    501				GFP_KERNEL);
    502	if (!fan_data)
    503		return -ENOMEM;
    504
    505	fan_data->dev = dev;
    506	err = gpio_fan_get_of_data(fan_data);
    507	if (err)
    508		return err;
    509
    510	platform_set_drvdata(pdev, fan_data);
    511	mutex_init(&fan_data->lock);
    512
    513	/* Configure control GPIOs if available. */
    514	if (fan_data->gpios && fan_data->num_gpios > 0) {
    515		if (!fan_data->speed || fan_data->num_speed <= 1)
    516			return -EINVAL;
    517		err = fan_ctrl_init(fan_data);
    518		if (err)
    519			return err;
    520		err = devm_add_action_or_reset(dev, gpio_fan_stop, fan_data);
    521		if (err)
    522			return err;
    523	}
    524
    525	/* Make this driver part of hwmon class. */
    526	fan_data->hwmon_dev =
    527		devm_hwmon_device_register_with_groups(dev,
    528						       "gpio_fan", fan_data,
    529						       gpio_fan_groups);
    530	if (IS_ERR(fan_data->hwmon_dev))
    531		return PTR_ERR(fan_data->hwmon_dev);
    532
    533	/* Configure alarm GPIO if available. */
    534	if (fan_data->alarm_gpio) {
    535		err = fan_alarm_init(fan_data);
    536		if (err)
    537			return err;
    538	}
    539
    540	/* Optional cooling device register for Device tree platforms */
    541	fan_data->cdev = devm_thermal_of_cooling_device_register(dev, np,
    542				"gpio-fan", fan_data, &gpio_fan_cool_ops);
    543
    544	dev_info(dev, "GPIO fan initialized\n");
    545
    546	return 0;
    547}
    548
    549static void gpio_fan_shutdown(struct platform_device *pdev)
    550{
    551	struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
    552
    553	if (fan_data->gpios)
    554		set_fan_speed(fan_data, 0);
    555}
    556
    557#ifdef CONFIG_PM_SLEEP
    558static int gpio_fan_suspend(struct device *dev)
    559{
    560	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    561
    562	if (fan_data->gpios) {
    563		fan_data->resume_speed = fan_data->speed_index;
    564		set_fan_speed(fan_data, 0);
    565	}
    566
    567	return 0;
    568}
    569
    570static int gpio_fan_resume(struct device *dev)
    571{
    572	struct gpio_fan_data *fan_data = dev_get_drvdata(dev);
    573
    574	if (fan_data->gpios)
    575		set_fan_speed(fan_data, fan_data->resume_speed);
    576
    577	return 0;
    578}
    579
    580static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
    581#define GPIO_FAN_PM	(&gpio_fan_pm)
    582#else
    583#define GPIO_FAN_PM	NULL
    584#endif
    585
    586static struct platform_driver gpio_fan_driver = {
    587	.probe		= gpio_fan_probe,
    588	.shutdown	= gpio_fan_shutdown,
    589	.driver	= {
    590		.name	= "gpio-fan",
    591		.pm	= GPIO_FAN_PM,
    592		.of_match_table = of_match_ptr(of_gpio_fan_match),
    593	},
    594};
    595
    596module_platform_driver(gpio_fan_driver);
    597
    598MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
    599MODULE_DESCRIPTION("GPIO FAN driver");
    600MODULE_LICENSE("GPL");
    601MODULE_ALIAS("platform:gpio-fan");