Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9628d859 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge branch 'vexpress-drivers' of git://git.linaro.org/people/pawelmoll/linux into next/drivers

Versatile Express changes from Pawel Moll <pawel.moll@arm.com>:

* 'vexpress-drivers' of git://git.linaro.org/people/pawelmoll/linux

:
  ARM: vexpress: Reset driver
  hwmon: Versatile Express hwmon driver

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 6f0c0580 790440bc
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
Versatile Express hwmon sensors
-------------------------------

Requires node properties:
- "compatible" value : one of
	"arm,vexpress-volt"
	"arm,vexpress-amp"
	"arm,vexpress-temp"
	"arm,vexpress-power"
	"arm,vexpress-energy"
- "arm,vexpress-sysreg,func" when controlled via vexpress-sysreg
  (see Documentation/devicetree/bindings/arm/vexpress-sysreg.txt
  for more details)

Optional node properties:
- label : string describing the monitored value

Example:
	energy@0 {
		compatible = "arm,vexpress-energy";
		arm,vexpress-sysreg,func = <13 0>;
		label = "A15 Jcore";
	};
+34 −0
Original line number Diff line number Diff line
Kernel driver vexpress
======================

Supported systems:
  * ARM Ltd. Versatile Express platform
    Prefix: 'vexpress'
    Datasheets:
      * "Hardware Description" sections of the Technical Reference Manuals
        for the Versatile Express boards:
        http://infocenter.arm.com/help/topic/com.arm.doc.subset.boards.express/index.html
      * Section "4.4.14. System Configuration registers" of the V2M-P1 TRM:
        http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0447-/index.html

Author: Pawel Moll

Description
-----------

Versatile Express platform (http://www.arm.com/versatileexpress/) is a
reference & prototyping system for ARM Ltd. processors. It can be set up
from a wide range of boards, each of them containing (apart of the main
chip/FPGA) a number of microcontrollers responsible for platform
configuration and control. Theses microcontrollers can also monitor the
board and its environment by a number of internal and external sensors,
providing information about power lines voltages and currents, board
temperature and power usage. Some of them also calculate consumed energy
and provide a cumulative use counter.

The configuration devices are _not_ memory mapped and must be accessed
via a custom interface, abstracted by the "vexpress_config" API.

As these devices are non-discoverable, they must be described in a Device
Tree passed to the kernel. Details of the DT binding for them can be found
in Documentation/devicetree/bindings/hwmon/vexpress.txt.
+141 −0
Original line number Diff line number Diff line
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * Copyright (C) 2012 ARM Limited
 */

#include <linux/jiffies.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/stat.h>
#include <linux/vexpress.h>

static void vexpress_reset_do(struct device *dev, const char *what)
{
	int err = -ENOENT;
	struct vexpress_config_func *func =
			vexpress_config_func_get_by_dev(dev);

	if (func) {
		unsigned long timeout;

		err = vexpress_config_write(func, 0, 0);

		timeout = jiffies + HZ;
		while (time_before(jiffies, timeout))
			cpu_relax();
	}

	dev_emerg(dev, "Unable to %s (%d)\n", what, err);
}

static struct device *vexpress_power_off_device;

void vexpress_power_off(void)
{
	vexpress_reset_do(vexpress_power_off_device, "power off");
}

static struct device *vexpress_restart_device;

void vexpress_restart(char str, const char *cmd)
{
	vexpress_reset_do(vexpress_restart_device, "restart");
}

static ssize_t vexpress_reset_active_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%d\n", vexpress_restart_device == dev);
}

static ssize_t vexpress_reset_active_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	long value;
	int err = kstrtol(buf, 0, &value);

	if (!err && value)
		vexpress_restart_device = dev;

	return err ? err : count;
}

DEVICE_ATTR(active, S_IRUGO | S_IWUSR, vexpress_reset_active_show,
		vexpress_reset_active_store);


enum vexpress_reset_func { FUNC_RESET, FUNC_SHUTDOWN, FUNC_REBOOT };

static struct of_device_id vexpress_reset_of_match[] = {
	{
		.compatible = "arm,vexpress-reset",
		.data = (void *)FUNC_RESET,
	}, {
		.compatible = "arm,vexpress-shutdown",
		.data = (void *)FUNC_SHUTDOWN
	}, {
		.compatible = "arm,vexpress-reboot",
		.data = (void *)FUNC_REBOOT
	},
	{}
};

static int vexpress_reset_probe(struct platform_device *pdev)
{
	enum vexpress_reset_func func;
	const struct of_device_id *match =
			of_match_device(vexpress_reset_of_match, &pdev->dev);

	if (match)
		func = (enum vexpress_reset_func)match->data;
	else
		func = pdev->id_entry->driver_data;

	switch (func) {
	case FUNC_SHUTDOWN:
		vexpress_power_off_device = &pdev->dev;
		break;
	case FUNC_RESET:
		if (!vexpress_restart_device)
			vexpress_restart_device = &pdev->dev;
		device_create_file(&pdev->dev, &dev_attr_active);
		break;
	case FUNC_REBOOT:
		vexpress_restart_device = &pdev->dev;
		device_create_file(&pdev->dev, &dev_attr_active);
		break;
	};

	return 0;
}

static const struct platform_device_id vexpress_reset_id_table[] = {
	{ .name = "vexpress-reset", .driver_data = FUNC_RESET, },
	{ .name = "vexpress-shutdown", .driver_data = FUNC_SHUTDOWN, },
	{ .name = "vexpress-reboot", .driver_data = FUNC_REBOOT, },
	{}
};

static struct platform_driver vexpress_reset_driver = {
	.probe = vexpress_reset_probe,
	.driver = {
		.name = "vexpress-reset",
		.of_match_table = vexpress_reset_of_match,
	},
	.id_table = vexpress_reset_id_table,
};

static int __init vexpress_reset_init(void)
{
	return platform_driver_register(&vexpress_reset_driver);
}
device_initcall(vexpress_reset_init);
+8 −0
Original line number Diff line number Diff line
@@ -1197,6 +1197,14 @@ config SENSORS_TWL4030_MADC
	This driver can also be built as a module. If so it will be called
	twl4030-madc-hwmon.

config SENSORS_VEXPRESS
	tristate "Versatile Express"
	depends on VEXPRESS_CONFIG
	help
	  This driver provides support for hardware sensors available on
	  the ARM Ltd's Versatile Express platform. It can provide wide
	  range of information like temperature, power, energy.

config SENSORS_VIA_CPUTEMP
	tristate "VIA CPU temperature sensor"
	depends on X86
+1 −0
Original line number Diff line number Diff line
@@ -121,6 +121,7 @@ obj-$(CONFIG_SENSORS_TMP102) += tmp102.o
obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
obj-$(CONFIG_SENSORS_VEXPRESS)	+= vexpress.o
obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o
obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
obj-$(CONFIG_SENSORS_VT1211)	+= vt1211.o
Loading