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

windfarm_max6690_sensor.c (3290B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Windfarm PowerMac thermal control.  MAX6690 sensor.
      4 *
      5 * Copyright (C) 2005 Paul Mackerras, IBM Corp. <paulus@samba.org>
      6 */
      7#include <linux/types.h>
      8#include <linux/errno.h>
      9#include <linux/kernel.h>
     10#include <linux/init.h>
     11#include <linux/slab.h>
     12#include <linux/i2c.h>
     13
     14#include <asm/pmac_low_i2c.h>
     15
     16#include "windfarm.h"
     17
     18#define VERSION "1.0"
     19
     20/* This currently only exports the external temperature sensor,
     21   since that's all the control loops need. */
     22
     23/* Some MAX6690 register numbers */
     24#define MAX6690_INTERNAL_TEMP	0
     25#define MAX6690_EXTERNAL_TEMP	1
     26
     27struct wf_6690_sensor {
     28	struct i2c_client	*i2c;
     29	struct wf_sensor	sens;
     30};
     31
     32#define wf_to_6690(x)	container_of((x), struct wf_6690_sensor, sens)
     33
     34static int wf_max6690_get(struct wf_sensor *sr, s32 *value)
     35{
     36	struct wf_6690_sensor *max = wf_to_6690(sr);
     37	s32 data;
     38
     39	if (max->i2c == NULL)
     40		return -ENODEV;
     41
     42	/* chip gets initialized by firmware */
     43	data = i2c_smbus_read_byte_data(max->i2c, MAX6690_EXTERNAL_TEMP);
     44	if (data < 0)
     45		return data;
     46	*value = data << 16;
     47	return 0;
     48}
     49
     50static void wf_max6690_release(struct wf_sensor *sr)
     51{
     52	struct wf_6690_sensor *max = wf_to_6690(sr);
     53
     54	kfree(max);
     55}
     56
     57static const struct wf_sensor_ops wf_max6690_ops = {
     58	.get_value	= wf_max6690_get,
     59	.release	= wf_max6690_release,
     60	.owner		= THIS_MODULE,
     61};
     62
     63static int wf_max6690_probe(struct i2c_client *client,
     64			    const struct i2c_device_id *id)
     65{
     66	const char *name, *loc;
     67	struct wf_6690_sensor *max;
     68	int rc;
     69
     70	loc = of_get_property(client->dev.of_node, "hwsensor-location", NULL);
     71	if (!loc) {
     72		dev_warn(&client->dev, "Missing hwsensor-location property!\n");
     73		return -ENXIO;
     74	}
     75
     76	/*
     77	 * We only expose the external temperature register for
     78	 * now as this is all we need for our control loops
     79	 */
     80	if (!strcmp(loc, "BACKSIDE") || !strcmp(loc, "SYS CTRLR AMBIENT"))
     81		name = "backside-temp";
     82	else if (!strcmp(loc, "NB Ambient"))
     83		name = "north-bridge-temp";
     84	else if (!strcmp(loc, "GPU Ambient"))
     85		name = "gpu-temp";
     86	else
     87		return -ENXIO;
     88
     89	max = kzalloc(sizeof(struct wf_6690_sensor), GFP_KERNEL);
     90	if (max == NULL) {
     91		printk(KERN_ERR "windfarm: Couldn't create MAX6690 sensor: "
     92		       "no memory\n");
     93		return -ENOMEM;
     94	}
     95
     96	max->i2c = client;
     97	max->sens.name = name;
     98	max->sens.ops = &wf_max6690_ops;
     99	i2c_set_clientdata(client, max);
    100
    101	rc = wf_register_sensor(&max->sens);
    102	if (rc)
    103		kfree(max);
    104	return rc;
    105}
    106
    107static int wf_max6690_remove(struct i2c_client *client)
    108{
    109	struct wf_6690_sensor *max = i2c_get_clientdata(client);
    110
    111	max->i2c = NULL;
    112	wf_unregister_sensor(&max->sens);
    113
    114	return 0;
    115}
    116
    117static const struct i2c_device_id wf_max6690_id[] = {
    118	{ "MAC,max6690", 0 },
    119	{ }
    120};
    121MODULE_DEVICE_TABLE(i2c, wf_max6690_id);
    122
    123static const struct of_device_id wf_max6690_of_id[] = {
    124	{ .compatible = "max6690", },
    125	{ }
    126};
    127MODULE_DEVICE_TABLE(of, wf_max6690_of_id);
    128
    129static struct i2c_driver wf_max6690_driver = {
    130	.driver = {
    131		.name		= "wf_max6690",
    132		.of_match_table = wf_max6690_of_id,
    133	},
    134	.probe		= wf_max6690_probe,
    135	.remove		= wf_max6690_remove,
    136	.id_table	= wf_max6690_id,
    137};
    138
    139module_i2c_driver(wf_max6690_driver);
    140
    141MODULE_AUTHOR("Paul Mackerras <paulus@samba.org>");
    142MODULE_DESCRIPTION("MAX6690 sensor objects for PowerMac thermal control");
    143MODULE_LICENSE("GPL");