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

pwm-fan.c (11980B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * pwm-fan.c - Hwmon driver for fans connected to PWM lines.
      4 *
      5 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
      6 *
      7 * Author: Kamil Debski <k.debski@samsung.com>
      8 */
      9
     10#include <linux/hwmon.h>
     11#include <linux/interrupt.h>
     12#include <linux/module.h>
     13#include <linux/mutex.h>
     14#include <linux/of.h>
     15#include <linux/platform_device.h>
     16#include <linux/pwm.h>
     17#include <linux/regulator/consumer.h>
     18#include <linux/sysfs.h>
     19#include <linux/thermal.h>
     20#include <linux/timer.h>
     21
     22#define MAX_PWM 255
     23
     24struct pwm_fan_tach {
     25	int irq;
     26	atomic_t pulses;
     27	unsigned int rpm;
     28	u8 pulses_per_revolution;
     29};
     30
     31struct pwm_fan_ctx {
     32	struct mutex lock;
     33	struct pwm_device *pwm;
     34	struct pwm_state pwm_state;
     35	struct regulator *reg_en;
     36
     37	int tach_count;
     38	struct pwm_fan_tach *tachs;
     39	ktime_t sample_start;
     40	struct timer_list rpm_timer;
     41
     42	unsigned int pwm_value;
     43	unsigned int pwm_fan_state;
     44	unsigned int pwm_fan_max_state;
     45	unsigned int *pwm_fan_cooling_levels;
     46	struct thermal_cooling_device *cdev;
     47
     48	struct hwmon_chip_info info;
     49	struct hwmon_channel_info fan_channel;
     50};
     51
     52/* This handler assumes self resetting edge triggered interrupt. */
     53static irqreturn_t pulse_handler(int irq, void *dev_id)
     54{
     55	struct pwm_fan_tach *tach = dev_id;
     56
     57	atomic_inc(&tach->pulses);
     58
     59	return IRQ_HANDLED;
     60}
     61
     62static void sample_timer(struct timer_list *t)
     63{
     64	struct pwm_fan_ctx *ctx = from_timer(ctx, t, rpm_timer);
     65	unsigned int delta = ktime_ms_delta(ktime_get(), ctx->sample_start);
     66	int i;
     67
     68	if (delta) {
     69		for (i = 0; i < ctx->tach_count; i++) {
     70			struct pwm_fan_tach *tach = &ctx->tachs[i];
     71			int pulses;
     72
     73			pulses = atomic_read(&tach->pulses);
     74			atomic_sub(pulses, &tach->pulses);
     75			tach->rpm = (unsigned int)(pulses * 1000 * 60) /
     76				(tach->pulses_per_revolution * delta);
     77		}
     78
     79		ctx->sample_start = ktime_get();
     80	}
     81
     82	mod_timer(&ctx->rpm_timer, jiffies + HZ);
     83}
     84
     85static int  __set_pwm(struct pwm_fan_ctx *ctx, unsigned long pwm)
     86{
     87	unsigned long period;
     88	int ret = 0;
     89	struct pwm_state *state = &ctx->pwm_state;
     90
     91	mutex_lock(&ctx->lock);
     92	if (ctx->pwm_value == pwm)
     93		goto exit_set_pwm_err;
     94
     95	period = state->period;
     96	state->duty_cycle = DIV_ROUND_UP(pwm * (period - 1), MAX_PWM);
     97	state->enabled = pwm ? true : false;
     98
     99	ret = pwm_apply_state(ctx->pwm, state);
    100	if (!ret)
    101		ctx->pwm_value = pwm;
    102exit_set_pwm_err:
    103	mutex_unlock(&ctx->lock);
    104	return ret;
    105}
    106
    107static void pwm_fan_update_state(struct pwm_fan_ctx *ctx, unsigned long pwm)
    108{
    109	int i;
    110
    111	for (i = 0; i < ctx->pwm_fan_max_state; ++i)
    112		if (pwm < ctx->pwm_fan_cooling_levels[i + 1])
    113			break;
    114
    115	ctx->pwm_fan_state = i;
    116}
    117
    118static int pwm_fan_write(struct device *dev, enum hwmon_sensor_types type,
    119			 u32 attr, int channel, long val)
    120{
    121	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
    122	int ret;
    123
    124	if (val < 0 || val > MAX_PWM)
    125		return -EINVAL;
    126
    127	ret = __set_pwm(ctx, val);
    128	if (ret)
    129		return ret;
    130
    131	pwm_fan_update_state(ctx, val);
    132	return 0;
    133}
    134
    135static int pwm_fan_read(struct device *dev, enum hwmon_sensor_types type,
    136			u32 attr, int channel, long *val)
    137{
    138	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
    139
    140	switch (type) {
    141	case hwmon_pwm:
    142		*val = ctx->pwm_value;
    143		return 0;
    144
    145	case hwmon_fan:
    146		*val = ctx->tachs[channel].rpm;
    147		return 0;
    148
    149	default:
    150		return -ENOTSUPP;
    151	}
    152}
    153
    154static umode_t pwm_fan_is_visible(const void *data,
    155				  enum hwmon_sensor_types type,
    156				  u32 attr, int channel)
    157{
    158	switch (type) {
    159	case hwmon_pwm:
    160		return 0644;
    161
    162	case hwmon_fan:
    163		return 0444;
    164
    165	default:
    166		return 0;
    167	}
    168}
    169
    170static const struct hwmon_ops pwm_fan_hwmon_ops = {
    171	.is_visible = pwm_fan_is_visible,
    172	.read = pwm_fan_read,
    173	.write = pwm_fan_write,
    174};
    175
    176/* thermal cooling device callbacks */
    177static int pwm_fan_get_max_state(struct thermal_cooling_device *cdev,
    178				 unsigned long *state)
    179{
    180	struct pwm_fan_ctx *ctx = cdev->devdata;
    181
    182	if (!ctx)
    183		return -EINVAL;
    184
    185	*state = ctx->pwm_fan_max_state;
    186
    187	return 0;
    188}
    189
    190static int pwm_fan_get_cur_state(struct thermal_cooling_device *cdev,
    191				 unsigned long *state)
    192{
    193	struct pwm_fan_ctx *ctx = cdev->devdata;
    194
    195	if (!ctx)
    196		return -EINVAL;
    197
    198	*state = ctx->pwm_fan_state;
    199
    200	return 0;
    201}
    202
    203static int
    204pwm_fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
    205{
    206	struct pwm_fan_ctx *ctx = cdev->devdata;
    207	int ret;
    208
    209	if (!ctx || (state > ctx->pwm_fan_max_state))
    210		return -EINVAL;
    211
    212	if (state == ctx->pwm_fan_state)
    213		return 0;
    214
    215	ret = __set_pwm(ctx, ctx->pwm_fan_cooling_levels[state]);
    216	if (ret) {
    217		dev_err(&cdev->device, "Cannot set pwm!\n");
    218		return ret;
    219	}
    220
    221	ctx->pwm_fan_state = state;
    222
    223	return ret;
    224}
    225
    226static const struct thermal_cooling_device_ops pwm_fan_cooling_ops = {
    227	.get_max_state = pwm_fan_get_max_state,
    228	.get_cur_state = pwm_fan_get_cur_state,
    229	.set_cur_state = pwm_fan_set_cur_state,
    230};
    231
    232static int pwm_fan_of_get_cooling_data(struct device *dev,
    233				       struct pwm_fan_ctx *ctx)
    234{
    235	struct device_node *np = dev->of_node;
    236	int num, i, ret;
    237
    238	if (!of_find_property(np, "cooling-levels", NULL))
    239		return 0;
    240
    241	ret = of_property_count_u32_elems(np, "cooling-levels");
    242	if (ret <= 0) {
    243		dev_err(dev, "Wrong data!\n");
    244		return ret ? : -EINVAL;
    245	}
    246
    247	num = ret;
    248	ctx->pwm_fan_cooling_levels = devm_kcalloc(dev, num, sizeof(u32),
    249						   GFP_KERNEL);
    250	if (!ctx->pwm_fan_cooling_levels)
    251		return -ENOMEM;
    252
    253	ret = of_property_read_u32_array(np, "cooling-levels",
    254					 ctx->pwm_fan_cooling_levels, num);
    255	if (ret) {
    256		dev_err(dev, "Property 'cooling-levels' cannot be read!\n");
    257		return ret;
    258	}
    259
    260	for (i = 0; i < num; i++) {
    261		if (ctx->pwm_fan_cooling_levels[i] > MAX_PWM) {
    262			dev_err(dev, "PWM fan state[%d]:%d > %d\n", i,
    263				ctx->pwm_fan_cooling_levels[i], MAX_PWM);
    264			return -EINVAL;
    265		}
    266	}
    267
    268	ctx->pwm_fan_max_state = num - 1;
    269
    270	return 0;
    271}
    272
    273static void pwm_fan_regulator_disable(void *data)
    274{
    275	regulator_disable(data);
    276}
    277
    278static void pwm_fan_pwm_disable(void *__ctx)
    279{
    280	struct pwm_fan_ctx *ctx = __ctx;
    281
    282	ctx->pwm_state.enabled = false;
    283	pwm_apply_state(ctx->pwm, &ctx->pwm_state);
    284	del_timer_sync(&ctx->rpm_timer);
    285}
    286
    287static int pwm_fan_probe(struct platform_device *pdev)
    288{
    289	struct thermal_cooling_device *cdev;
    290	struct device *dev = &pdev->dev;
    291	struct pwm_fan_ctx *ctx;
    292	struct device *hwmon;
    293	int ret;
    294	const struct hwmon_channel_info **channels;
    295	u32 *fan_channel_config;
    296	int channel_count = 1;	/* We always have a PWM channel. */
    297	int i;
    298
    299	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
    300	if (!ctx)
    301		return -ENOMEM;
    302
    303	mutex_init(&ctx->lock);
    304
    305	ctx->pwm = devm_of_pwm_get(dev, dev->of_node, NULL);
    306	if (IS_ERR(ctx->pwm))
    307		return dev_err_probe(dev, PTR_ERR(ctx->pwm), "Could not get PWM\n");
    308
    309	platform_set_drvdata(pdev, ctx);
    310
    311	ctx->reg_en = devm_regulator_get_optional(dev, "fan");
    312	if (IS_ERR(ctx->reg_en)) {
    313		if (PTR_ERR(ctx->reg_en) != -ENODEV)
    314			return PTR_ERR(ctx->reg_en);
    315
    316		ctx->reg_en = NULL;
    317	} else {
    318		ret = regulator_enable(ctx->reg_en);
    319		if (ret) {
    320			dev_err(dev, "Failed to enable fan supply: %d\n", ret);
    321			return ret;
    322		}
    323		ret = devm_add_action_or_reset(dev, pwm_fan_regulator_disable,
    324					       ctx->reg_en);
    325		if (ret)
    326			return ret;
    327	}
    328
    329	pwm_init_state(ctx->pwm, &ctx->pwm_state);
    330
    331	/*
    332	 * __set_pwm assumes that MAX_PWM * (period - 1) fits into an unsigned
    333	 * long. Check this here to prevent the fan running at a too low
    334	 * frequency.
    335	 */
    336	if (ctx->pwm_state.period > ULONG_MAX / MAX_PWM + 1) {
    337		dev_err(dev, "Configured period too big\n");
    338		return -EINVAL;
    339	}
    340
    341	/* Set duty cycle to maximum allowed and enable PWM output */
    342	ret = __set_pwm(ctx, MAX_PWM);
    343	if (ret) {
    344		dev_err(dev, "Failed to configure PWM: %d\n", ret);
    345		return ret;
    346	}
    347	timer_setup(&ctx->rpm_timer, sample_timer, 0);
    348	ret = devm_add_action_or_reset(dev, pwm_fan_pwm_disable, ctx);
    349	if (ret)
    350		return ret;
    351
    352	ctx->tach_count = platform_irq_count(pdev);
    353	if (ctx->tach_count < 0)
    354		return dev_err_probe(dev, ctx->tach_count,
    355				     "Could not get number of fan tachometer inputs\n");
    356	dev_dbg(dev, "%d fan tachometer inputs\n", ctx->tach_count);
    357
    358	if (ctx->tach_count) {
    359		channel_count++;	/* We also have a FAN channel. */
    360
    361		ctx->tachs = devm_kcalloc(dev, ctx->tach_count,
    362					  sizeof(struct pwm_fan_tach),
    363					  GFP_KERNEL);
    364		if (!ctx->tachs)
    365			return -ENOMEM;
    366
    367		ctx->fan_channel.type = hwmon_fan;
    368		fan_channel_config = devm_kcalloc(dev, ctx->tach_count + 1,
    369						  sizeof(u32), GFP_KERNEL);
    370		if (!fan_channel_config)
    371			return -ENOMEM;
    372		ctx->fan_channel.config = fan_channel_config;
    373	}
    374
    375	channels = devm_kcalloc(dev, channel_count + 1,
    376				sizeof(struct hwmon_channel_info *), GFP_KERNEL);
    377	if (!channels)
    378		return -ENOMEM;
    379
    380	channels[0] = HWMON_CHANNEL_INFO(pwm, HWMON_PWM_INPUT);
    381
    382	for (i = 0; i < ctx->tach_count; i++) {
    383		struct pwm_fan_tach *tach = &ctx->tachs[i];
    384		u32 ppr = 2;
    385
    386		tach->irq = platform_get_irq(pdev, i);
    387		if (tach->irq == -EPROBE_DEFER)
    388			return tach->irq;
    389		if (tach->irq > 0) {
    390			ret = devm_request_irq(dev, tach->irq, pulse_handler, 0,
    391					       pdev->name, tach);
    392			if (ret) {
    393				dev_err(dev,
    394					"Failed to request interrupt: %d\n",
    395					ret);
    396				return ret;
    397			}
    398		}
    399
    400		of_property_read_u32_index(dev->of_node,
    401					   "pulses-per-revolution",
    402					   i,
    403					   &ppr);
    404		tach->pulses_per_revolution = ppr;
    405		if (!tach->pulses_per_revolution) {
    406			dev_err(dev, "pulses-per-revolution can't be zero.\n");
    407			return -EINVAL;
    408		}
    409
    410		fan_channel_config[i] = HWMON_F_INPUT;
    411
    412		dev_dbg(dev, "tach%d: irq=%d, pulses_per_revolution=%d\n",
    413			i, tach->irq, tach->pulses_per_revolution);
    414	}
    415
    416	if (ctx->tach_count > 0) {
    417		ctx->sample_start = ktime_get();
    418		mod_timer(&ctx->rpm_timer, jiffies + HZ);
    419
    420		channels[1] = &ctx->fan_channel;
    421	}
    422
    423	ctx->info.ops = &pwm_fan_hwmon_ops;
    424	ctx->info.info = channels;
    425
    426	hwmon = devm_hwmon_device_register_with_info(dev, "pwmfan",
    427						     ctx, &ctx->info, NULL);
    428	if (IS_ERR(hwmon)) {
    429		dev_err(dev, "Failed to register hwmon device\n");
    430		return PTR_ERR(hwmon);
    431	}
    432
    433	ret = pwm_fan_of_get_cooling_data(dev, ctx);
    434	if (ret)
    435		return ret;
    436
    437	ctx->pwm_fan_state = ctx->pwm_fan_max_state;
    438	if (IS_ENABLED(CONFIG_THERMAL)) {
    439		cdev = devm_thermal_of_cooling_device_register(dev,
    440			dev->of_node, "pwm-fan", ctx, &pwm_fan_cooling_ops);
    441		if (IS_ERR(cdev)) {
    442			ret = PTR_ERR(cdev);
    443			dev_err(dev,
    444				"Failed to register pwm-fan as cooling device: %d\n",
    445				ret);
    446			return ret;
    447		}
    448		ctx->cdev = cdev;
    449	}
    450
    451	return 0;
    452}
    453
    454static int pwm_fan_disable(struct device *dev)
    455{
    456	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
    457	int ret;
    458
    459	if (ctx->pwm_value) {
    460		/* keep ctx->pwm_state unmodified for pwm_fan_resume() */
    461		struct pwm_state state = ctx->pwm_state;
    462
    463		state.duty_cycle = 0;
    464		state.enabled = false;
    465		ret = pwm_apply_state(ctx->pwm, &state);
    466		if (ret < 0)
    467			return ret;
    468	}
    469
    470	if (ctx->reg_en) {
    471		ret = regulator_disable(ctx->reg_en);
    472		if (ret) {
    473			dev_err(dev, "Failed to disable fan supply: %d\n", ret);
    474			return ret;
    475		}
    476	}
    477
    478	return 0;
    479}
    480
    481static void pwm_fan_shutdown(struct platform_device *pdev)
    482{
    483	pwm_fan_disable(&pdev->dev);
    484}
    485
    486#ifdef CONFIG_PM_SLEEP
    487static int pwm_fan_suspend(struct device *dev)
    488{
    489	return pwm_fan_disable(dev);
    490}
    491
    492static int pwm_fan_resume(struct device *dev)
    493{
    494	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
    495	int ret;
    496
    497	if (ctx->reg_en) {
    498		ret = regulator_enable(ctx->reg_en);
    499		if (ret) {
    500			dev_err(dev, "Failed to enable fan supply: %d\n", ret);
    501			return ret;
    502		}
    503	}
    504
    505	if (ctx->pwm_value == 0)
    506		return 0;
    507
    508	return pwm_apply_state(ctx->pwm, &ctx->pwm_state);
    509}
    510#endif
    511
    512static SIMPLE_DEV_PM_OPS(pwm_fan_pm, pwm_fan_suspend, pwm_fan_resume);
    513
    514static const struct of_device_id of_pwm_fan_match[] = {
    515	{ .compatible = "pwm-fan", },
    516	{},
    517};
    518MODULE_DEVICE_TABLE(of, of_pwm_fan_match);
    519
    520static struct platform_driver pwm_fan_driver = {
    521	.probe		= pwm_fan_probe,
    522	.shutdown	= pwm_fan_shutdown,
    523	.driver	= {
    524		.name		= "pwm-fan",
    525		.pm		= &pwm_fan_pm,
    526		.of_match_table	= of_pwm_fan_match,
    527	},
    528};
    529
    530module_platform_driver(pwm_fan_driver);
    531
    532MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
    533MODULE_ALIAS("platform:pwm-fan");
    534MODULE_DESCRIPTION("PWM FAN driver");
    535MODULE_LICENSE("GPL");