summaryrefslogtreecommitdiffstats
path: root/drivers/sbus/char
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-11-23 02:00:47 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-11-23 02:00:47 +0000
commit06615f62b17d7de6e12d2f5ec6b88cf30af08413 (patch)
tree8766f208847d4876a6db619aebbf54d53b76eb44 /drivers/sbus/char
parentfa9bdb574f4febb751848a685d9a9017e04e1d53 (diff)
Merge with Linux 2.4.0-test10.
Diffstat (limited to 'drivers/sbus/char')
-rw-r--r--drivers/sbus/char/Makefile129
-rw-r--r--drivers/sbus/char/bpp.c2
-rw-r--r--drivers/sbus/char/envctrl.c2112
-rw-r--r--drivers/sbus/char/sab82532.c22
-rw-r--r--drivers/sbus/char/su.c22
-rw-r--r--drivers/sbus/char/sunkbd.c20
-rw-r--r--drivers/sbus/char/vfc_dev.c2
-rw-r--r--drivers/sbus/char/zs.c22
8 files changed, 792 insertions, 1539 deletions
diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile
index 7c5a21b2c..ad8b7e140 100644
--- a/drivers/sbus/char/Makefile
+++ b/drivers/sbus/char/Makefile
@@ -1,128 +1,47 @@
#
-# Makefile for the linux kernel.
+# Makefile for the kernel miscellaneous SPARC device drivers.
#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-# Note 2! The CFLAGS definitions are now in the main makefile...
-
# Dave Redman Frame Buffer tuning support.
-# OK this is kind of ugly but it does allow drivers to be added fairly
-# easily. and you can even choose what sort of support you want.
+#
+# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org>
+# Rewritten to use lists instead of if-statements.
+#
O_TARGET := sunchar.o
O_OBJS := ${O_OBJ} sunkbd.o sunkbdmap.o sunmouse.o sunserial.o zs.o
-M_OBJS :=
-ifeq ($(ARCH),sparc64)
+vfc-objs := vfc_dev.o vfc_i2c.o
ifeq ($(CONFIG_PCI),y)
-
-OX_OBJS += su.o
-O_OBJS += pcikbd.o
-
-ifeq ($(CONFIG_SAB82532),y)
-O_OBJS += sab82532.o
-else
- ifeq ($(CONFIG_SAB82532),m)
- M_OBJS += sab82532.o
- endif
-endif
-
-ifeq ($(CONFIG_ENVCTRL),y)
-O_OBJS += envctrl.o
-else
- ifeq ($(CONFIG_ENVCTRL),m)
- M_OBJS += envctrl.o
- endif
-endif
-
-ifeq ($(CONFIG_DISPLAY7SEG),y)
-O_OBJS += display7seg.o
-else
- ifeq ($(CONFIG_DISPLAY7SEG),m)
- M_OBJS += display7seg.o
- endif
-endif
-
-endif # eq($(CONFIG_PCI,y)
-
-ifeq ($(CONFIG_OBP_FLASH),y)
-O_OBJS += flash.o
-else
- ifeq ($(CONFIG_OBP_FLASH),m)
- M_OBJS += flash.o
- endif
+OX_OBJS += su.o
+O_OBJS += pcikbd.o
endif
-else # !eq($(ARCH),sparc64)
+ifeq ($(ARCH),sparc64)
ifeq ($(CONFIG_PCI),y)
-OX_OBJS += su.o
-O_OBJS += pcikbd.o
-endif
-
-endif # !eq($(ARCH),sparc64)
-
-ifeq ($(CONFIG_SUN_OPENPROMIO),y)
-O_OBJS += openprom.o
-else
- ifeq ($(CONFIG_SUN_OPENPROMIO),m)
- M_OBJS += openprom.o
- endif
+obj-$(CONFIG_SAB82532) += sab82532.o
+obj-$(CONFIG_ENVCTRL) += envctrl.o
+obj-$(CONFIG_DISPLAY7SEG) += display7seg.o
endif
-ifeq ($(CONFIG_SUN_MOSTEK_RTC),y)
-O_OBJS += rtc.o
-else
- ifeq ($(CONFIG_SUN_MOSTEK_RTC),m)
- M_OBJS += rtc.o
- endif
+obj-$(CONFIG_OBP_FLASH) += flash.o
endif
-ifeq ($(CONFIG_SUN_BPP),y)
-O_OBJS += bpp.o
-else
- ifeq ($(CONFIG_SUN_BPP),m)
- M_OBJS += bpp.o
- endif
-endif
-
-ifeq ($(CONFIG_SUN_VIDEOPIX),y)
-O_OBJS += vfc.o
-else
- ifeq ($(CONFIG_SUN_VIDEOPIX),m)
- M_OBJS += vfc.o
- endif
-endif
+obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o
+obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o
+obj-$(CONFIG_SUN_BPP) += bpp.o
+obj-$(CONFIG_SUN_VIDEOPIX) += vfc.o
+obj-$(CONFIG_SUN_AURORA) += aurora.o
+obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o
+obj-$(CONFIG_SUN_JSFLASH) += jsflash.o
-ifeq ($(CONFIG_SUN_AURORA),y)
-O_OBJS += aurora.o
-else
- ifeq ($(CONFIG_SUN_AURORA),m)
- M_OBJS += aurora.o
- endif
-endif
-
-ifeq ($(CONFIG_TADPOLE_TS102_UCTRL),y)
-O_OBJS += uctrl.o
-else
- ifeq ($(CONFIG_TADPOLE_TS102_UCTRL),m)
- M_OBJS += uctrl.o
- endif
-endif
-
-ifeq ($(CONFIG_SUN_JSFLASH),y)
-O_OBJS += jsflash.o
-endif
-ifeq ($(CONFIG_SUN_JSFLASH),m)
-M_OBJS += jsflash.o
-endif
+O_OBJS += $(obj-y)
+M_OBJS := $(obj-m)
include $(TOPDIR)/Rules.make
sunkbdmap.o: sunkeymap.c
-vfc.o: vfc_dev.o vfc_i2c.o
- $(LD) -r -o vfc.o vfc_dev.o vfc_i2c.o
+vfc.o: $(vfc-objs)
+ $(LD) -r -o $@ $(vfc-objs)
diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c
index 133246129..4579404e3 100644
--- a/drivers/sbus/char/bpp.c
+++ b/drivers/sbus/char/bpp.c
@@ -1015,7 +1015,7 @@ static inline void freeLptPort(int idx)
#endif
-static devfs_handle_t devfs_handle = NULL;
+static devfs_handle_t devfs_handle;
#ifdef MODULE
int init_module(void)
diff --git a/drivers/sbus/char/envctrl.c b/drivers/sbus/char/envctrl.c
index dbba073de..31c9de932 100644
--- a/drivers/sbus/char/envctrl.c
+++ b/drivers/sbus/char/envctrl.c
@@ -1,23 +1,29 @@
-/* $Id: envctrl.c,v 1.17 2000/06/19 06:24:47 davem Exp $
+/* $Id: envctrl.c,v 1.18 2000/10/17 16:20:35 davem Exp $
* envctrl.c: Temperature and Fan monitoring on Machines providing it.
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 2000 Vinh Truong (vinh.truong@eng.sun.com)
+ * VT - The implementation is to support Sun Microelectronics (SME) platform
+ * environment monitoring. SME platforms use pcf8584 as the i2c bus
+ * controller to access pcf8591 (8-bit A/D and D/A converter) and
+ * pcf8571 (256 x 8-bit static low-voltage RAM with I2C-bus interface).
+ * At board level, it follows SME Firmware I2C Specification. Reference:
+ * http://www-eu2.semiconductors.com/pip/PCF8584P
+ * http://www-eu2.semiconductors.com/pip/PCF8574AP
+ * http://www-eu2.semiconductors.com/pip/PCF8591P
+ *
*/
-#include <linux/version.h>
#include <linux/config.h>
#include <linux/module.h>
-
-#define __KERNEL_SYSCALLS__
#include <linux/sched.h>
-#include <linux/unistd.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/init.h>
-#include <linux/malloc.h>
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/malloc.h>
#include <asm/ebus.h>
#include <asm/uaccess.h>
@@ -25,18 +31,6 @@
#define ENVCTRL_MINOR 162
-
-#undef U450_SUPPORT /* might fry you machine, careful here !!! */
-
-
-#undef DEBUG
-#undef DEBUG_BUS_SCAN
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
-#define schedule_timeout(a) { current->timeout = jiffies + (a); schedule(); }
-#endif
-
#define PCF8584_ADDRESS 0x55
#define CONTROL_PIN 0x80
@@ -71,1532 +65,879 @@
#define CLK_8 0x18
#define CLK_12 0x1c
+#define OBD_SEND_START 0xc5 /* value to generate I2c_bus START condition */
+#define OBD_SEND_STOP 0xc3 /* value to generate I2c_bus STOP condition */
-#define I2C_WRITE 0x00
-#define I2C_READ 0x01
-
-/* PCF8584 register offsets */
-#define I2C_DATA 0x00UL
-#define I2C_CSR 0x01UL
-#define I2C_REG_SIZE 0x02UL
-
-struct i2c_device {
- unsigned char addr;
- struct i2c_device *next;
-};
-
-static unsigned long i2c_regs;
-static struct i2c_device *i2c_devices;
-
-static int errno;
-
-#define MAX_TEMPERATURE 111
-#define MAX_FAN_SPEED 63
-
-
-/*
- * UltraAXi constants.
+/* Monitor type of i2c child device.
+ * Firmware definitions.
*/
-#define AXI_THERM_ADDR 0x9e
-#define AXI_THERM_PORT_CPU 0
-#define AXI_THERM_PORT_MOD 1
-#define AXI_THERM_PORT_PCI 2
-#define AXI_THERM_PORT_DISK 3
-
-#define AXI_FAN_ADDR 0x4e
-#define AXI_FAN_PORT_FRONT 0
-#define AXI_FAN_PORT_BACK 1
-
-#define AXI_PIO_ADDR 0x70
+#define PCF8584_MAX_CHANNELS 8
+#define PCF8584_FANSTAT_TYPE 3 /* fan status monitor */
+#define PCF8584_VOLTAGE_TYPE 2 /* voltage monitor */
+#define PCF8584_TEMP_TYPE 1 /* temperature monitor*/
-/*
- * Ultra 450 constants.
+/* Monitor type of i2c child device.
+ * Driver definitions.
*/
-#define U450_FAN_ADDR 0x4e
-#define U450_FAN_PORT_CPU 0
-#define U450_FAN_PORT_PS 1
-
-#define U450_PIO_ADDR 0x70
-#define U450_TIMER_ADDR 0xa0
-
-static unsigned char
-axi_cpu_temp_table[256] =
-{
- 0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x69, 0x67,
- 0x66, 0x65, 0x64, 0x63, 0x61, 0x60, 0x5f, 0x5e,
- 0x5d, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x55, 0x54,
- 0x53, 0x52, 0x50, 0x4f, 0x4e, 0x4d, 0x4c, 0x4a,
- 0x49, 0x48, 0x47, 0x46, 0x44, 0x43, 0x42, 0x41,
- 0x40, 0x3e, 0x3d, 0x3c, 0x3c, 0x3b, 0x3b, 0x3a,
- 0x3a, 0x39, 0x39, 0x38, 0x38, 0x37, 0x37, 0x36,
- 0x36, 0x35, 0x35, 0x34, 0x34, 0x33, 0x33, 0x32,
- 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2e,
- 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2a, 0x2a,
- 0x29, 0x29, 0x28, 0x28, 0x27, 0x27, 0x26, 0x26,
- 0x25, 0x25, 0x24, 0x24, 0x23, 0x23, 0x22, 0x22,
- 0x21, 0x21, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1b, 0x1b, 0x1b, 0x1b, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x19, 0x19, 0x19, 0x19, 0x18,
- 0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x17, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15,
- 0x15, 0x14, 0x14, 0x14, 0x14, 0x13, 0x13, 0x13,
- 0x13, 0x12, 0x12, 0x12, 0x12, 0x12, 0x11, 0x11,
- 0x11, 0x11, 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08,
- 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04,
- 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char
-axi_mod_temp_table[256] =
-{
- 0x65, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
- 0x5d, 0x5c, 0x5b, 0x5a, 0x59, 0x58, 0x57, 0x56,
- 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, 0x4f, 0x4e,
- 0x4d, 0x4c, 0x4b, 0x4a, 0x49, 0x48, 0x47, 0x46,
- 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f, 0x3e,
- 0x3d, 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x39,
- 0x39, 0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35,
- 0x35, 0x35, 0x34, 0x34, 0x33, 0x33, 0x32, 0x32,
- 0x31, 0x31, 0x30, 0x30, 0x2f, 0x2f, 0x2e, 0x2e,
- 0x2e, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b, 0x2b, 0x2a,
- 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x27, 0x27,
- 0x26, 0x26, 0x25, 0x25, 0x24, 0x24, 0x23, 0x23,
- 0x23, 0x22, 0x22, 0x21, 0x21, 0x20, 0x20, 0x1f,
- 0x1f, 0x1e, 0x1e, 0x1e, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x19, 0x19,
- 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x16, 0x16, 0x16, 0x16, 0x15,
- 0x15, 0x15, 0x15, 0x14, 0x14, 0x14, 0x14, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x12, 0x12, 0x12, 0x12,
- 0x11, 0x11, 0x11, 0x11, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08,
- 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05,
- 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static unsigned char
-axi_fan_speeds[112] =
-{
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20,
- 0x22, 0x23, 0x25, 0x27, 0x28, 0x2a, 0x2b, 0x2d,
- 0x2f, 0x30, 0x32, 0x33, 0x35, 0x37, 0x38, 0x3a,
- 0x3b, 0x3d, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
-};
-
-
-struct therm_regs {
- u32 addr;
- u32 port;
- u32 min_temp;
- u32 warning;
- u32 shutdown;
- u32 num;
- u32 den;
-};
+#define ENVCTRL_NOMON 0
+#define ENVCTRL_CPUTEMP_MON 1 /* cpu temperature monitor */
+#define ENVCTRL_CPUVOLTAGE_MON 2 /* voltage monitor */
+#define ENVCTRL_FANSTAT_MON 3 /* fan status monitor */
+#define ENVCTRL_ETHERTEMP_MON 4 /* ethernet temperarture */
+ /* monitor */
+#define ENVCTRL_VOLTAGESTAT_MON 5 /* voltage status monitor */
+#define ENVCTRL_MTHRBDTEMP_MON 6 /* motherboard temperature */
+#define ENVCTRL_SCSITEMP_MON 7 /* scsi temperarture */
+
+/* Child device type.
+ * Driver definitions.
+ */
+#define I2C_ADC 0 /* pcf8591 */
+#define I2C_GPIO 1 /* pcf8571 */
-struct thermistor {
- char name[8];
- struct therm_regs regs;
- unsigned char (*temperature) (struct thermistor *);
- unsigned char (*fan_speed) (struct thermistor *);
- struct thermistor *next; /* all thermistors */
- struct thermistor *chain; /* thermistors for one fan */
+/* Data read from child device may need to decode
+ * through a data table and a scale.
+ * Translation type as defined by firmware.
+ */
+#define ENVCTRL_TRANSLATE_NO 0
+#define ENVCTRL_TRANSLATE_PARTIAL 1
+#define ENVCTRL_TRANSLATE_COMBINED 2
+#define ENVCTRL_TRANSLATE_FULL 3 /* table[data] */
+#define ENVCTRL_TRANSLATE_SCALE 4 /* table[data]/scale */
+
+/* Driver miscellaneous definitions. */
+#define ENVCTRL_MAX_CPU 4
+#define CHANNEL_DESC_SZ 256
+
+struct pcf8584_reg {
+ unsigned char data;
+ unsigned char csr;
};
-struct fan_regs {
- u32 addr;
- u32 port;
+/* Each child device can be monitored by up to PCF8584_MAX_CHANNELS.
+ * Property of a port or channel as defined by the firmware.
+ */
+struct pcf8584_channel {
+ unsigned char chnl_no;
+ unsigned char io_direction;
+ unsigned char type;
+ unsigned char last;
};
-struct fan {
- char name[8];
- struct fan_regs regs;
- int (*set_speed)(struct fan *, unsigned char value);
- int (*check_failure)(struct fan *);
- unsigned char value;
- struct thermistor *monitor;
- struct fan *next;
+/* Each child device may have one or more tables of bytes to help decode
+ * data. Table property as defined by the firmware.
+ */
+struct pcf8584_tblprop {
+ unsigned int type;
+ unsigned int scale;
+ unsigned int offset; /* offset from the beginning of the table */
+ unsigned int size;
};
-
-struct environment {
- struct thermistor *thermistors;
- struct fan *fans;
- unsigned char *cpu_temp_table;
- unsigned char *cpu_fan_speeds;
- unsigned char *ps_temp_table;
- unsigned char *ps_fan_speeds;
- void (*enable) (struct environment *);
- void (*disable) (struct environment *);
- void (*keep_alive) (struct environment *);
- int interval;
- pid_t kenvd_pid;
- wait_queue_head_t kenvd_wait;
- int terminate;
+/* i2c child */
+struct i2c_child_t {
+ /* Either ADC or GPIO. */
+ unsigned char i2ctype;
+ unsigned long addr;
+ struct pcf8584_channel chnl_array[PCF8584_MAX_CHANNELS];
+
+ /* Channel info. */
+ unsigned int total_chnls; /* Number of monitor channels. */
+ unsigned char fan_mask; /* Byte mask for fan status channels. */
+ unsigned char voltage_mask; /* Byte mask for voltage status channels. */
+ struct pcf8584_tblprop tblprop_array[PCF8584_MAX_CHANNELS];
+
+ /* Properties of all monitor channels. */
+ unsigned int total_tbls; /* Number of monitor tables. */
+ char *tables; /* Pointer to table(s). */
+ char chnls_desc[CHANNEL_DESC_SZ]; /* Channel description. */
+ char mon_type[PCF8584_MAX_CHANNELS];
};
+volatile static struct pcf8584_reg *i2c = NULL;
+static struct i2c_child_t i2c_childlist[ENVCTRL_MAX_CPU*2];
+static unsigned char chnls_mask[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
+static unsigned int warning_temperature = 0;
+static unsigned int shutdown_temperature = 0;
+static char read_cpu;
-static struct environment envctrl;
-
+/* Forward declarations. */
+static struct i2c_child_t *envctrl_get_i2c_child(unsigned char);
-#ifdef DEBUG_BUS_SCAN
-struct i2c_addr_map {
- unsigned char addr;
- unsigned char mask;
- char *name;
-};
-
-static struct i2c_addr_map devmap[] = {
- { 0x70, 0xf0, "PCF8574A" },
- { 0x40, 0xf0, "TDA8444" },
- { 0x90, 0xf0, "PCF8591" },
- { 0xa0, 0xf0, "PCF8583" },
-};
-#define NR_DEVMAP (sizeof(devmap) / sizeof(devmap[0]))
-#endif
-
-static __inline__ int
-PUT_DATA(unsigned long data, char *buffer, int user)
+/* Function description: Read a byte from an i2c controller register.
+ * Return: A byte from the passed in address.
+ */
+static inline unsigned char envctrl_readb(volatile unsigned char *p)
{
- if (user) {
- u8 tmp = readb(data);
- if (put_user(tmp, buffer))
- return -EFAULT;
- } else {
- *buffer = readb(data);
- }
- return 0;
+ return readb(p);
}
-static __inline__ int
-GET_DATA(unsigned long data, const char *buffer, int user)
+/* Function description: Write a byte to an i2c controller register.
+ * Return: Nothing.
+ */
+static inline void envctrl_writeb(unsigned char val, volatile unsigned char *p)
{
- if (user) {
- u8 tmp;
- if (get_user(tmp, buffer))
- return -EFAULT;
- writeb(tmp, data);
- } else {
- writeb(*buffer, data);
- }
- return 0;
+ writeb(val, p);
}
-
-static int
-i2c_read(unsigned char dev, char *buffer, int len, int user)
+/* Function Description: Test the PIN bit (Pending Interrupt Not)
+ * to test when serial transmission is completed .
+ * Return : None.
+ */
+static void envtrl_i2c_test_pin(void)
{
- unsigned char dummy;
- unsigned char stat;
- int error = -ENODEV;
- int count = 0;
-
- writeb((dev & 0xfe) | I2C_READ, i2c_regs + I2C_DATA);
-
- while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB))
- udelay(1);
-
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK,
- i2c_regs + I2C_CSR);
-
- do {
- udelay(1);
- while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN)
- udelay(1);
-
- if (stat & STATUS_LRB)
- goto stop;
+ int limit = 1000000;
- error = 0;
- if (len == 0) {
- count--;
+ while (--limit > 0) {
+ if (!(envctrl_readb(&i2c->csr) & STATUS_PIN))
break;
- }
-
- if (count == (len - 1))
- break;
-
- if (count++ > 0) {
- error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user);
- if (error)
- break;
- } else
- dummy = readb(i2c_regs + I2C_DATA);
- } while (1);
-
- writeb(CONTROL_ES0, i2c_regs + I2C_CSR);
- if (!error && (count++ > 0))
- error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user);
- else
- dummy = readb(i2c_regs + I2C_DATA);
-
- udelay(1);
- while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN)
udelay(1);
+ }
-stop:
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK,
- i2c_regs + I2C_CSR);
- if (!error && (count++ > 0))
- error = PUT_DATA(i2c_regs + I2C_DATA, buffer++, user);
- else
- dummy = readb(i2c_regs + I2C_DATA);
-
- if (error)
- return error;
- return count - 1;
+ if (limit <= 0)
+ printk(KERN_INFO "envctrl: Pin status will not clear.\n");
}
-static int
-i2c_write(unsigned char dev, const char *buffer, int len, int user)
+/* Function Description: Test busy bit.
+ * Return : None.
+ */
+static void envctrl_i2c_test_bb(void)
{
- int error = -ENODEV;
- int count = 0;
- int timeout;
-
- timeout = 1000000;
- while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB) && --timeout)
- udelay(1);
- if (!timeout) {
- printk("%s [%d]: TIMEOUT\n", __FUNCTION__, __LINE__);
- return -ENODEV;
- }
-
- writeb((dev & 0xfe) | I2C_WRITE, i2c_regs + I2C_DATA);
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK,
- i2c_regs + I2C_CSR);
-
- do {
- unsigned char stat;
-
- udelay(1);
- timeout = 1000000;
- while (((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN) && --timeout)
- udelay(1);
-
- if (!timeout) {
- printk("%s [%d]: TIMEOUT\n", __FUNCTION__, __LINE__);
- break;
- }
+ int limit = 1000000;
- if (stat & STATUS_LRB)
+ while (--limit > 0) {
+ /* Busy bit 0 means busy. */
+ if (envctrl_readb(&i2c->csr) & STATUS_BB)
break;
+ udelay(1);
+ }
- error = count;
- if (count == len)
- break;
-
- error = GET_DATA(i2c_regs + I2C_DATA, buffer++, user);
- if (error)
- break;
-
- count++;
- } while (1);
-
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK,
- i2c_regs + I2C_CSR);
- return error;
+ if (limit <= 0)
+ printk(KERN_INFO "envctrl: Busy bit will not clear.\n");
}
-#ifdef U450_SUPPORT
-static int
-i2c_write_read(unsigned char dev, char *outbuf, int outlen,
- char *inbuf, int inlen, int user)
+/* Function Description: Send the adress for a read access.
+ * Return : 0 if not acknowledged, otherwise acknowledged.
+ */
+static int envctrl_i2c_read_addr(unsigned char addr)
{
- unsigned char dummy;
- unsigned char stat;
- int error = -ENODEV;
- int count = 0;
-
- while (!(readb(i2c_regs + I2C_CSR) & STATUS_BB))
- udelay(1);
-
- writeb((dev & 0xfe) | I2C_WRITE, i2c_regs + I2C_DATA);
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STA | CONTROL_ACK,
- i2c_regs + I2C_CSR);
-
- do {
- unsigned char stat;
-
- udelay(1);
- while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN)
- udelay(1);
+ envctrl_i2c_test_bb();
- if (stat & STATUS_LRB)
- break;
+ /* Load address. */
+ envctrl_writeb(addr + 1, &i2c->data);
- error = count;
- if (count == outlen)
- break;
+ envctrl_i2c_test_bb();
- error = GET_DATA(i2c_regs + I2C_DATA, outbuf++, user);
- if (error)
- break;
+ envctrl_writeb(OBD_SEND_START, &i2c->csr);
- count++;
- } while (1);
+ /* Wait for PIN. */
+ envtrl_i2c_test_pin();
- if (error < 0) {
- writeb(CONTROL_PIN | CONTROL_ES0 |
- CONTROL_STO | CONTROL_ACK, i2c_regs + I2C_CSR);
- return error;
+ /* CSR 0 means acknowledged. */
+ if (!(envctrl_readb(&i2c->csr) & STATUS_LRB)) {
+ return envctrl_readb(&i2c->data);
+ } else {
+ envctrl_writeb(OBD_SEND_STOP, &i2c->csr);
+ return 0;
}
-
- writeb(CONTROL_ES0 | CONTROL_STA | CONTROL_ACK, i2c_regs + I2C_CSR);
- udelay(1);
- writeb((dev & 0xfe) | I2C_READ, i2c_regs + I2C_DATA);
-
- count = 0;
- do {
- udelay(1);
- while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN)
- udelay(1);
-
- if (stat & STATUS_LRB)
- goto stop;
-
- error = 0;
- if (inlen == 0) {
- count--;
- break;
- }
-
- if (count == (inlen - 1))
- break;
-
- if (count++ > 0) {
- error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user);
- if (error)
- break;
- } else
- dummy = readb(i2c_regs + I2C_DATA);
- } while (1);
-
- writeb(CONTROL_ES0, i2c_regs + I2C_CSR);
- if (!error && (count++ > 0))
- error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user);
- else
- dummy = readb(i2c_regs + I2C_DATA);
-
- udelay(1);
- while ((stat = readb(i2c_regs + I2C_CSR)) & STATUS_PIN)
- udelay(1);
-
-stop:
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_STO | CONTROL_ACK,
- i2c_regs + I2C_CSR);
- if (!error && (count++ > 0))
- error = PUT_DATA(i2c_regs + I2C_DATA, inbuf++, user);
- else
- dummy = readb(i2c_regs + I2C_DATA);
-
- if (error)
- return error;
- return count - 1;
}
-#endif /* U450_SUPPORT */
-static struct i2c_device *
-i2c_find_device(unsigned char addr)
+/* Function Description: Send the adress for write mode.
+ * Return : None.
+ */
+static void envctrl_i2c_write_addr(unsigned char addr)
{
- struct i2c_device *dev;
+ envctrl_i2c_test_bb();
+ envctrl_writeb(addr, &i2c->data);
- for (dev = i2c_devices; dev; dev = dev->next) {
- if (dev->addr == addr)
- return dev;
- }
- return 0;
+ /* Generate Start condition. */
+ envctrl_writeb(OBD_SEND_START, &i2c->csr);
}
-static void
-i2c_free_devices(void)
+/* Function Description: Read 1 byte of data from addr
+ * set by envctrl_i2c_read_addr()
+ * Return : Data from address set by envctrl_i2c_read_addr().
+ */
+static unsigned char envctrl_i2c_read_data(void)
{
- struct i2c_device *dev;
-
- dev = i2c_devices;
- while (dev) {
- i2c_devices = dev->next;
- kfree(dev);
- dev = i2c_devices;
- }
+ envtrl_i2c_test_pin();
+ envctrl_writeb(CONTROL_ES0, &i2c->csr); /* Send neg ack. */
+ return envctrl_readb(&i2c->data);
}
-static __init int i2c_scan_bus(void)
+/* Function Description: Instruct the device which port to read data from.
+ * Return : None.
+ */
+static void envctrl_i2c_write_data(unsigned char port)
{
- struct i2c_device *dev, **last;
- unsigned int addr;
- int count = 0;
-
- last = &i2c_devices;
- for (addr = 0; addr < 256; addr += 2) {
- if (i2c_write(addr, 0, 0, 0) == 0) {
-#ifdef DEBUG_BUS_SCAN
- int i;
- for (i = 0; i < NR_DEVMAP; i++)
- if ((addr & devmap[i].mask) == devmap[i].addr)
- break;
- printk("envctrl: i2c device at %02x: %s\n", addr,
- i < NR_DEVMAP ? devmap[i].name : "unknown");
-#endif
-
- dev = kmalloc(sizeof(struct i2c_device), GFP_KERNEL);
- if (!dev) {
- printk("i2c: can't alloc i2c_device\n");
- i2c_free_devices();
- return -ENOMEM;
- }
- memset(dev, 0, sizeof(struct i2c_device));
-
- dev->addr = addr;
-
- *last = dev;
- last = &dev->next;
-
- count++;
- }
- }
- if (!count) {
- printk("%s: no devices found\n", __FUNCTION__);
- return -ENODEV;
- }
- return 0;
+ envtrl_i2c_test_pin();
+ envctrl_writeb(port, &i2c->data);
}
-
-static int
-read_8591(unsigned char dev, unsigned char offset, unsigned char *value)
+/* Function Description: Generate Stop condition after last byte is sent.
+ * Return : None.
+ */
+static void envctrl_i2c_stop(void)
{
- unsigned char data[2];
-
- data[0] = 0x40 | offset;
- if (i2c_write(dev, data, 1, 0) != 1)
- return -1;
- if (i2c_read(dev, data, 2, 0) != 2)
- return -1;
- *value = data[1];
- return 0;
+ envtrl_i2c_test_pin();
+ envctrl_writeb(OBD_SEND_STOP, &i2c->csr);
}
-static int
-write_8444(unsigned char dev, unsigned char offset, unsigned char value)
+/* Function Description: Read adc device.
+ * Return : Data at address and port.
+ */
+static unsigned char envctrl_i2c_read_8591(unsigned char addr, unsigned char port)
{
- unsigned char data[2];
+ /* Send address. */
+ envctrl_i2c_write_addr(addr);
- data[0] = offset;
- data[1] = value;
- if (i2c_write(dev, data, 2, 0) != 2)
- return -1;
- return 0;
-}
+ /* Setup port to read. */
+ envctrl_i2c_write_data(port);
+ envctrl_i2c_stop();
-#ifdef U450_SUPPORT
-static int
-read_8583(unsigned char dev, unsigned char offset, unsigned char *value)
-{
- unsigned char data;
+ /* Read port. */
+ envctrl_i2c_read_addr(addr);
- data = offset;
- if (i2c_write_read(dev, &data, 1, &data, 1, 0) != 1)
- return -1;
- *value = data;
- return 0;
-}
-
-static int
-write_8583(unsigned char dev, unsigned char offset, unsigned char value)
-{
- unsigned char data[2];
+ /* Do a single byte read and send stop. */
+ envctrl_i2c_read_data();
+ envctrl_i2c_stop();
- data[0] = offset;
- data[1] = value;
- if (i2c_write(dev, data, 2, 0) != 2)
- return -1;
- return 0;
+ return envctrl_readb(&i2c->data);
}
-#endif /* U450_SUPPORT */
-struct thermistor *
-find_thermistor(const char *name, struct thermistor *from)
+/* Function Description: Read gpio device.
+ * Return : Data at address.
+ */
+static unsigned char envctrl_i2c_read_8574(unsigned char addr)
{
- int n;
+ unsigned char rd;
- if (!from)
- from = envctrl.thermistors;
- else
- from = from->next;
+ envctrl_i2c_read_addr(addr);
- n = strlen(name);
- while (from && strncmp(from->name, name, n))
- from = from->next;
+ /* Do a single byte read and send stop. */
+ rd = envctrl_i2c_read_data();
+ envctrl_i2c_stop();
- return from;
+ return rd;
}
-void
-check_temperatures(struct environment *env)
+/* Function Description: Decode data read from an adc device using firmware
+ * table.
+ * Return: Number of read bytes. Data is stored in bufdata in ascii format.
+ */
+static int envctrl_i2c_data_translate(unsigned char data, int translate_type,
+ int scale, char *tbl, char *bufdata)
{
- struct thermistor *t;
-
- for (t = env->thermistors; t; t = t->next) {
-#ifdef DEBUG
- printk("Thermistor `%s' [%02x:%d]: "
- "%d C (%d C, %d C)\n",
- t->name, t->regs.addr, t->regs.port,
- t->temperature(t), t->regs.warning, t->regs.shutdown);
-#endif
+ int len = 0;
- /*
- * Implement slow-down or shutdown here...
- */
- }
-}
+ switch (translate_type) {
+ case ENVCTRL_TRANSLATE_NO:
+ /* No decode necessary. */
+ len = 1;
+ bufdata[0] = data;
+ break;
-void
-check_fan_speeds(struct environment *env)
-{
- unsigned char speed, max;
- struct thermistor *t;
- struct fan *f;
-
- for (f = env->fans; f; f = f->next) {
-#ifdef DEBUG
- printk("Fan `%s' [%02x:%d]:", f->name,
- f->regs.addr, f->regs.port);
-#endif
- max = 0;
- for (t = f->monitor; t; t = t->chain) {
- speed = t->fan_speed(t);
- if (speed > max)
- max = speed;
-#ifdef DEBUG
- printk(" %s:%02x", t->name, speed);
-#endif
- }
+ case ENVCTRL_TRANSLATE_FULL:
+ /* Decode this way: data = table[data]. */
+ len = 1;
+ bufdata[0] = tbl[data];
+ break;
- f->set_speed(f, max);
-#ifdef DEBUG
- printk(" -> %02x\n", f->value);
-#endif
- }
-}
+ case ENVCTRL_TRANSLATE_SCALE:
+ /* Decode this way: data = table[data]/scale */
+ sprintf(bufdata,"%d ", (tbl[data] * 10) / (scale));
+ len = strlen(bufdata);
+ bufdata[len - 1] = bufdata[len - 2];
+ bufdata[len - 2] = '.';
+ break;
-void
-envctrl_fans_blast(struct environment *env)
-{
- struct fan *f;
+ default:
+ break;
+ };
- for (f = env->fans; f; f = f->next)
- f->set_speed(f, MAX_FAN_SPEED);
+ return len;
}
-int
-kenvd(void *data)
+/* Function Description: Read cpu-related data such as cpu temperature, voltage.
+ * Return: Number of read bytes. Data is stored in bufdata in ascii format.
+ */
+static int envctrl_read_cpu_info(struct i2c_child_t *pchild,
+ char mon_type, unsigned char *bufdata)
{
- struct environment *env = data;
-
- MOD_INC_USE_COUNT;
- lock_kernel();
-
- env->kenvd_pid = current->pid;
-
- exit_files(current);
- exit_mm(current);
-
- spin_lock_irq(&current->sigmask_lock);
- siginitsetinv(&current->blocked, sigmask(SIGKILL));
- recalc_sigpending(current);
- spin_unlock_irq(&current->sigmask_lock);
-
- current->session = 1;
- current->pgrp = 1;
- strcpy(current->comm, "kenvd");
-
- if (env->enable)
- env->enable(env);
-
- while (!env->terminate) {
-
- check_temperatures(env);
- check_fan_speeds(env);
- if (env->keep_alive)
- env->keep_alive(env);
-
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(env->interval * HZ);
+ unsigned char data;
+ int i;
+ char *tbl, j = -1;
- if (signal_pending(current)) {
- spin_lock_irq(&current->sigmask_lock);
- flush_signals(current);
- spin_unlock_irq(&current->sigmask_lock);
- break;
+ /* Find the right monitor type and channel. */
+ for (i = 0; i < PCF8584_MAX_CHANNELS; i++) {
+ if (pchild->mon_type[i] == mon_type) {
+ if (++j == read_cpu) {
+ break;
+ }
}
}
- if (env->disable)
- env->disable(env);
+ if (j != read_cpu)
+ return 0;
- env->kenvd_pid = 0;
- wake_up(&envctrl.kenvd_wait);
+ /* Read data from address and port. */
+ data = envctrl_i2c_read_8591((unsigned char)pchild->addr,
+ (unsigned char)pchild->chnl_array[i].chnl_no);
- MOD_DEC_USE_COUNT;
- return 0;
-}
+ /* Find decoding table. */
+ tbl = pchild->tables + pchild->tblprop_array[i].offset;
-void
-envctrl_stop(void)
-{
- DECLARE_WAITQUEUE(wait, current);
- struct thermistor *t;
- struct fan *f;
- pid_t pid;
-
- if (envctrl.kenvd_pid) {
- pid = envctrl.kenvd_pid;
-
- current->state = TASK_INTERRUPTIBLE;
- add_wait_queue(&envctrl.kenvd_wait, &wait);
-
- envctrl.terminate = 1;
- kill_proc(pid, SIGKILL, 1);
-
- schedule();
-
- remove_wait_queue(&envctrl.kenvd_wait, &wait);
- current->state = TASK_RUNNING;
- }
-
- t = envctrl.thermistors;
- while (t) {
- envctrl.thermistors = t->next;
- kfree(t);
- t = envctrl.thermistors;
- }
-
- f = envctrl.fans;
- while (f) {
- envctrl.fans = f->next;
- kfree(f);
- f = envctrl.fans;
- }
-
- if (envctrl.cpu_temp_table)
- kfree(envctrl.cpu_temp_table);
-
- if (envctrl.cpu_fan_speeds)
- kfree(envctrl.cpu_fan_speeds);
-
- if (envctrl.ps_temp_table)
- kfree(envctrl.ps_temp_table);
-
- if (envctrl.ps_fan_speeds)
- kfree(envctrl.ps_fan_speeds);
-}
-
-
-static unsigned char
-axi_get_temperature(struct thermistor *t)
-{
- unsigned char value;
-
- if (read_8591(t->regs.addr, t->regs.port, &value) < 0)
- return MAX_TEMPERATURE;
- if (t->regs.port == AXI_THERM_PORT_CPU)
- return axi_cpu_temp_table[value];
- else
- return axi_mod_temp_table[value];
+ return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type,
+ pchild->tblprop_array[i].scale,
+ tbl, bufdata);
}
-static unsigned char
-axi_get_fan_speed(struct thermistor *t)
+/* Function Description: Read noncpu-related data such as motherboard
+ * temperature.
+ * Return: Number of read bytes. Data is stored in bufdata in ascii format.
+ */
+static int envctrl_read_noncpu_info(struct i2c_child_t *pchild,
+ char mon_type, unsigned char *bufdata)
{
- unsigned char temp;
-
- temp = t->temperature(t);
- if (temp >= MAX_TEMPERATURE)
- return MAX_FAN_SPEED;
-
- return axi_fan_speeds[temp];
-}
+ unsigned char data;
+ int i;
+ char *tbl = NULL;
-static int
-axi_set_fan_speed(struct fan *f, unsigned char value)
-{
- if (value != f->value) {
- if (write_8444(f->regs.addr, f->regs.port, value))
- return -1;
- f->value = value;
+ for (i = 0; i < PCF8584_MAX_CHANNELS; i++) {
+ if (pchild->mon_type[i] == mon_type)
+ break;
}
- return 0;
-}
-static void
-axi_toggle_i2c_int(struct environment *env)
-{
- unsigned char data;
+ if (i >= PCF8584_MAX_CHANNELS)
+ return 0;
- if (i2c_read(AXI_PIO_ADDR, &data, 1, 0) != 1)
- return;
+ /* Read data from address and port. */
+ data = envctrl_i2c_read_8591((unsigned char)pchild->addr,
+ (unsigned char)pchild->chnl_array[i].chnl_no);
- data &= ~(0x08);
- if (i2c_write(AXI_PIO_ADDR, &data, 1, 0) != 1)
- return;
- mdelay(1);
+ /* Find decoding table. */
+ tbl = pchild->tables + pchild->tblprop_array[i].offset;
- data |= 0x08;
- if (i2c_write(AXI_PIO_ADDR, &data, 1, 0) != 1)
- return;
- mdelay(1);
+ return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type,
+ pchild->tblprop_array[i].scale,
+ tbl, bufdata);
}
-
-static int
-rasctrl_setup(int node)
+/* Function Description: Read fan status.
+ * Return : Always 1 byte. Status stored in bufdata.
+ */
+static int envctrl_i2c_fan_status(struct i2c_child_t *pchild,
+ unsigned char data,
+ char *bufdata)
{
- struct thermistor *t, **tlast;
- struct fan *f, **flast;
- char tmp[32];
- int monitor;
- int shutdown;
- int warning;
- int i;
+ unsigned char tmp, ret = 0;
+ int i, j = 0;
- prom_getstring(prom_root_node, "name", tmp, sizeof(tmp));
- if (strcmp(tmp, "SUNW,UltraSPARC-IIi-Engine")) {
- printk("SUNW,rasctrl will work only on Ultra AXi\n");
- return -ENODEV;
- }
+ tmp = data & pchild->fan_mask;
- monitor = prom_getintdefault(node, "env-monitor", 0);
- if (monitor == 0)
- return -ENODEV;
+ if (tmp == pchild->fan_mask) {
+ /* All bits are on. All fans are functioning. */
+ ret = ENVCTRL_ALL_FANS_GOOD;
+ } else if (tmp == 0) {
+ /* No bits are on. No fans are functioning. */
+ ret = ENVCTRL_ALL_FANS_BAD;
+ } else {
+ /* Go through all channels, mark 'on' the matched bits.
+ * Notice that fan_mask may have discontiguous bits but
+ * return mask are always contiguous. For example if we
+ * monitor 4 fans at channels 0,1,2,4, the return mask
+ * should be 00010000 if only fan at channel 4 is working.
+ */
+ for (i = 0; i < PCF8584_MAX_CHANNELS;i++) {
+ if (pchild->fan_mask & chnls_mask[i]) {
+ if (!(chnls_mask[i] & tmp))
+ ret |= chnls_mask[j];
- envctrl.interval = prom_getintdefault(node, "env-mon-interval", 60);
- warning = prom_getintdefault(node, "warning-temp", 55);
- shutdown = prom_getintdefault(node, "shutdown-temp", 58);
-
- tlast = &envctrl.thermistors;
- for (i = 0; i < 4; i++) {
- t = kmalloc(sizeof(struct thermistor), GFP_KERNEL);
- if (!t)
- goto out;
- memset(t, 0, sizeof(struct thermistor));
-
- t->regs.addr = AXI_THERM_ADDR;
- t->regs.port = i;
- t->regs.warning = warning;
- t->regs.shutdown = shutdown;
-
- switch (i) {
- case AXI_THERM_PORT_CPU:
- sprintf(t->name, "%.7s", "CPU");
- break;
- case AXI_THERM_PORT_MOD:
- sprintf(t->name, "%.7s", "MOD");
- break;
- case AXI_THERM_PORT_PCI:
- sprintf(t->name, "%.7s", "PCI");
- break;
- case AXI_THERM_PORT_DISK:
- sprintf(t->name, "%.7s", "DISK");
- break;
+ j++;
+ }
}
+ }
- t->temperature = axi_get_temperature;
- t->fan_speed = axi_get_fan_speed;
+ bufdata[0] = ret;
+ return 1;
+}
- if (!i2c_find_device(t->regs.addr)) {
- printk("envctrl: `%s': i2c device %02x not found\n",
- t->name, t->regs.addr);
- kfree(t);
- continue;
+/* Function Description: Read voltage and power supply status.
+ * Return : Always 1 byte. Status stored in bufdata.
+ */
+static unsigned char envctrl_i2c_voltage_status(struct i2c_child_t *pchild,
+ unsigned char data,
+ char *bufdata)
+{
+ unsigned char tmp, ret = 0;
+ int i, j = 0;
+
+ tmp = data & pchild->voltage_mask;
+
+ /* Two channels are used to monitor voltage and power supply. */
+ if (tmp == pchild->voltage_mask) {
+ /* All bits are on. Voltage and power supply are okay. */
+ ret = ENVCTRL_VOLTAGE_POWERSUPPLY_GOOD;
+ } else if (tmp == 0) {
+ /* All bits are off. Voltage and power supply are bad */
+ ret = ENVCTRL_VOLTAGE_POWERSUPPLY_BAD;
+ } else {
+ /* Either voltage or power supply has problem. */
+ for (i = 0; i < PCF8584_MAX_CHANNELS; i++) {
+ if (pchild->voltage_mask & chnls_mask[i]) {
+ j++;
+
+ /* Break out when there is a mismatch. */
+ if (!(chnls_mask[i] & tmp))
+ break;
+ }
}
- *tlast = t;
- tlast = &t->next;
+ /* Make a wish that hardware will always use the
+ * first channel for voltage and the second for
+ * power supply.
+ */
+ if (j == 1)
+ ret = ENVCTRL_VOLTAGE_BAD;
+ else
+ ret = ENVCTRL_POWERSUPPLY_BAD;
}
- flast = &envctrl.fans;
- for (i = 0; i < 2; i++) {
- f = kmalloc(sizeof(struct fan), GFP_KERNEL);
- if (!f)
- goto out;
- memset(f, 0, sizeof(struct fan));
-
- f->regs.addr = AXI_FAN_ADDR;
- f->regs.port = i;
-
- switch (i) {
- case AXI_FAN_PORT_FRONT:
- sprintf(f->name, "%.7s", "FRONT");
- t = NULL;
- while ((t = find_thermistor("CPU", t))) {
- t->chain = f->monitor;
- f->monitor = t;
- }
- break;
- case AXI_FAN_PORT_BACK:
- sprintf(f->name, "%.7s", "BACK");
- t = NULL;
- while ((t = find_thermistor("PCI", t))) {
- t->chain = f->monitor;
- f->monitor = t;
- }
- break;
- }
+ bufdata[0] = ret;
+ return 1;
+}
- if (!f->monitor) {
- kfree(f);
- continue;
- }
+/* Function Description: Read a byte from /dev/envctrl. Mapped to user read().
+ * Return: Number of read bytes. 0 for error.
+ */
+static ssize_t
+envctrl_read(struct file *file, char *buf, size_t count, loff_t *ppos)
+{
+ struct i2c_child_t *pchild;
+ unsigned char data[10];
+ int ret = 0;
+
+ /* Get the type of read as decided in ioctl() call.
+ * Find the appropriate i2c child.
+ * Get the data and put back to the user buffer.
+ */
+
+ switch ((int)(long)file->private_data) {
+ case ENVCTRL_RD_WARNING_TEMPERATURE:
+ if (warning_temperature == 0)
+ return 0;
+
+ data[0] = (unsigned char)(warning_temperature);
+ ret = 1;
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_SHUTDOWN_TEMPERATURE:
+ if (shutdown_temperature == 0)
+ return 0;
+
+ data[0] = (unsigned char)(shutdown_temperature);
+ ret = 1;
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_MTHRBD_TEMPERATURE:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_MTHRBDTEMP_MON)))
+ return 0;
+ ret = envctrl_read_noncpu_info(pchild, ENVCTRL_MTHRBDTEMP_MON, data);
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_CPU_TEMPERATURE:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON)))
+ return 0;
+ ret = envctrl_read_cpu_info(pchild, ENVCTRL_CPUTEMP_MON, data);
+
+ /* Reset cpu to the default cpu0. */
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_CPU_VOLTAGE:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUVOLTAGE_MON)))
+ return 0;
+ ret = envctrl_read_cpu_info(pchild, ENVCTRL_CPUVOLTAGE_MON, data);
+
+ /* Reset cpu to the default cpu0. */
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_SCSI_TEMPERATURE:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_SCSITEMP_MON)))
+ return 0;
+ ret = envctrl_read_noncpu_info(pchild, ENVCTRL_SCSITEMP_MON, data);
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_ETHERNET_TEMPERATURE:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_ETHERTEMP_MON)))
+ return 0;
+ ret = envctrl_read_noncpu_info(pchild, ENVCTRL_ETHERTEMP_MON, data);
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_FAN_STATUS:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_FANSTAT_MON)))
+ return 0;
+ data[0] = envctrl_i2c_read_8574(pchild->addr);
+ ret = envctrl_i2c_fan_status(pchild,data[0], data);
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ case ENVCTRL_RD_VOLTAGE_STATUS:
+ if (!(pchild = envctrl_get_i2c_child(ENVCTRL_VOLTAGESTAT_MON)))
+ return 0;
+ data[0] = envctrl_i2c_read_8574(pchild->addr);
+ ret = envctrl_i2c_voltage_status(pchild, data[0], data);
+ copy_to_user((unsigned char *)buf, data, ret);
+ break;
+
+ default:
+ break;
+
+ };
+
+ return ret;
+}
+
+/* Function Description: Command what to read. Mapped to user ioctl().
+ * Return: Gives 0 for implemented commands, -EINVAL otherwise.
+ */
+static int
+envctrl_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ char *infobuf;
- if (!i2c_find_device(f->regs.addr)) {
- printk("envctrl: `%s': i2c device %02x not found\n",
- f->name, f->regs.addr);
- kfree(f);
- continue;
+ switch (cmd) {
+ case ENVCTRL_RD_WARNING_TEMPERATURE:
+ case ENVCTRL_RD_SHUTDOWN_TEMPERATURE:
+ case ENVCTRL_RD_MTHRBD_TEMPERATURE:
+ case ENVCTRL_RD_FAN_STATUS:
+ case ENVCTRL_RD_VOLTAGE_STATUS:
+ case ENVCTRL_RD_ETHERNET_TEMPERATURE:
+ case ENVCTRL_RD_SCSI_TEMPERATURE:
+ file->private_data = (void *)(long)cmd;
+ break;
+
+ case ENVCTRL_RD_CPU_TEMPERATURE:
+ case ENVCTRL_RD_CPU_VOLTAGE:
+ /* Check to see if application passes in any cpu number,
+ * the default is cpu0.
+ */
+ infobuf = (char *) arg;
+ if (infobuf == NULL) {
+ read_cpu = 0;
+ }else {
+ get_user(read_cpu, infobuf);
}
- *flast = f;
- flast = &f->next;
+ /* Save the command for use when reading. */
+ file->private_data = (void *)(long)cmd;
+ break;
- f->check_failure = NULL;
- f->set_speed = axi_set_fan_speed;
- }
-
- envctrl.enable = axi_toggle_i2c_int;
- envctrl.disable = envctrl_fans_blast;
+ default:
+ return -EINVAL;
+ };
-#ifdef DEBUG
- printk("Warn: %d C, Shutdown %d C, Interval %d s, Monitor %d\n",
- warning, shutdown, envctrl.interval, monitor);
-#endif
return 0;
-
-out:
- return -ENODEV;
-}
-
-
-#ifdef U450_SUPPORT
-
-static unsigned char
-envctrl_get_temperature(struct thermistor *t)
-{
- unsigned char value;
-
- if (read_8591(t->regs.addr, t->regs.port, &value) < 0)
- return MAX_TEMPERATURE;
- if (!strncmp(t->name, "CPU", 3))
- return envctrl.cpu_temp_table[value];
- else
- return envctrl.ps_temp_table[value];
}
-static unsigned char
-envctrl_get_fan_speed(struct thermistor *t)
+/* Function Description: open device. Mapped to user open().
+ * Return: Always 0.
+ */
+static int
+envctrl_open(struct inode *inode, struct file *file)
{
- unsigned char temp;
-
- temp = t->temperature(t);
- if (temp >= MAX_TEMPERATURE)
- return MAX_FAN_SPEED;
-
- if (!strncmp(t->name, "CPU", 3))
- return envctrl.cpu_fan_speeds[temp];
- else
- return envctrl.ps_fan_speeds[temp];
+ file->private_data = 0;
+ MOD_INC_USE_COUNT;
+ return 0;
}
+/* Function Description: Open device. Mapped to user close().
+ * Return: Always 0.
+ */
static int
-envctrl_set_fan_speed(struct fan *f, unsigned char value)
+envctrl_release(struct inode *inode, struct file *file)
{
- if (value != f->value) {
- if (write_8444(f->regs.addr, f->regs.port, value))
- return -1;
- f->value = value;
- }
-
+ MOD_DEC_USE_COUNT;
return 0;
}
-static unsigned char u450_default_thermisters[] =
-{
- /* CPU0 */
- 0x00, 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x30, 0x00,
- /* CPU1 */
- 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x31, 0x00,
- /* CPU2 */
- 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x32, 0x00,
- /* CPU3 */
- 0x00, 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46,
- 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x43, 0x50, 0x55, 0x33, 0x00,
- /* PS0 */
- 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x30, 0x00,
- /* PS1 */
- 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x31, 0x00,
- /* PS2 */
- 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x5a,
- 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x50, 0x53, 0x32, 0x00,
- /* AMB */
- 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x28,
- 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0x00, 0x00, 0x01, 0x41, 0x4d, 0x42, 0x00
-};
-
-static unsigned char u450_default_cpu_temp_factors[] =
-{
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x94, 0x92, 0x90, 0x8f, 0x8e, 0x8d, 0x8c,
- 0x8a, 0x88, 0x87, 0x86, 0x85, 0x84, 0x83, 0x82,
- 0x81, 0x80, 0x7f, 0x7e, 0x7d, 0x7c, 0x7b, 0x7a,
- 0x79, 0x79, 0x78, 0x78, 0x77, 0x76, 0x75, 0x74,
- 0x73, 0x72, 0x71, 0x70, 0x70, 0x6f, 0x6f, 0x6e,
- 0x6e, 0x6e, 0x6d, 0x6d, 0x6c, 0x6b, 0x6a, 0x6a,
- 0x69, 0x69, 0x68, 0x67, 0x66, 0x65, 0x65, 0x64,
- 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61, 0x61,
- 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5e, 0x5d, 0x5d,
- 0x5c, 0x5c, 0x5b, 0x5b, 0x5b, 0x5a, 0x5a, 0x5a,
- 0x59, 0x59, 0x58, 0x58, 0x57, 0x57, 0x56, 0x56,
- 0x55, 0x55, 0x54, 0x54, 0x53, 0x53, 0x52, 0x52,
- 0x52, 0x51, 0x51, 0x50, 0x50, 0x50, 0x50, 0x4f,
- 0x4f, 0x4f, 0x4e, 0x4e, 0x4e, 0x4d, 0x4d, 0x4d,
- 0x4c, 0x4c, 0x4c, 0x4b, 0x4b, 0x4b, 0x4a, 0x4a,
- 0x4a, 0x49, 0x49, 0x49, 0x48, 0x48, 0x48, 0x47,
- 0x47, 0x47, 0x46, 0x46, 0x46, 0x46, 0x45, 0x45,
- 0x45, 0x44, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43,
- 0x43, 0x42, 0x42, 0x42, 0x42, 0x41, 0x41, 0x41,
- 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e, 0x3e,
- 0x3e, 0x3d, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
- 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37, 0x37,
- 0x37, 0x37, 0x36, 0x36, 0x36, 0x35, 0x35, 0x35,
- 0x34, 0x34, 0x34, 0x33, 0x33, 0x33, 0x33, 0x32,
- 0x32, 0x32, 0x31, 0x31, 0x31, 0x30, 0x30, 0x30,
- 0x2f, 0x2f, 0x2f, 0x2e, 0x2e, 0x2e, 0x2d, 0x2d,
- 0x2d, 0x2c, 0x2c, 0x2c, 0x2b, 0x2b, 0x2b, 0x2a,
- 0x2a, 0x2a, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28
-};
-
-static unsigned char u450_default_cpu_fan_speeds[] =
-{
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x27, 0x28, 0x2a, 0x2b, 0x2d,
- 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
-};
-
-static unsigned char u450_default_ps_temp_factors[] =
-{
- 0x9a, 0x96, 0x82, 0x7d, 0x78, 0x73, 0x6e, 0x6b,
- 0x69, 0x67, 0x64, 0x5f, 0x5a, 0x57, 0x55, 0x53,
- 0x51, 0x50, 0x4e, 0x4d, 0x4c, 0x4b, 0x49, 0x47,
- 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 0x40, 0x3f,
- 0x3e, 0x3d, 0x3c, 0x3c, 0x3b, 0x3a, 0x39, 0x39,
- 0x38, 0x37, 0x37, 0x36, 0x35, 0x35, 0x34, 0x33,
- 0x32, 0x32, 0x32, 0x31, 0x31, 0x30, 0x30, 0x2f,
- 0x2f, 0x2e, 0x2e, 0x2d, 0x2d, 0x2c, 0x2c, 0x2b,
- 0x2a, 0x2a, 0x29, 0x29, 0x28, 0x28, 0x27, 0x27,
- 0x26, 0x26, 0x25, 0x25, 0x25, 0x25, 0x24, 0x24,
- 0x23, 0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21,
- 0x21, 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e,
- 0x1e, 0x1d, 0x1d, 0x1d, 0x1d, 0x1c, 0x1c, 0x1c,
- 0x1b, 0x1b, 0x1b, 0x1a, 0x1a, 0x1a, 0x19, 0x19,
- 0x19, 0x18, 0x18, 0x18, 0x18, 0x17, 0x17, 0x17,
- 0x17, 0x16, 0x16, 0x16, 0x16, 0x15, 0x15, 0x15,
- 0x14, 0x14, 0x14, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x12, 0x12, 0x12, 0x12, 0x11, 0x11, 0x11, 0x11,
- 0x10, 0x10, 0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
+static struct file_operations envctrl_fops = {
+ owner: THIS_MODULE,
+ read: envctrl_read,
+ ioctl: envctrl_ioctl,
+ open: envctrl_open,
+ release: envctrl_release,
+};
-static unsigned char u450_default_ps_fan_speeds[] =
-{
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x21, 0x22, 0x23,
- 0x24, 0x25, 0x26, 0x26, 0x27, 0x28, 0x29, 0x2a,
- 0x2b, 0x2d, 0x2e, 0x2f, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f
+static struct miscdevice envctrl_dev = {
+ ENVCTRL_MINOR,
+ "envctrl",
+ &envctrl_fops
};
-static void
-u450_toggle_i2c_int(struct environment *env)
+/* Function Description: Set monitor type based on firmware description.
+ * Return: None.
+ */
+static void envctrl_set_mon(struct i2c_child_t *pchild,
+ char *chnl_desc,
+ int chnl_no)
+{
+ /* Firmware only has temperature type. It does not distinguish
+ * different kinds of temperatures. We use channel description
+ * to disinguish them.
+ */
+ if (!(strcmp(chnl_desc,"temp,cpu")) ||
+ !(strcmp(chnl_desc,"temp,cpu0")) ||
+ !(strcmp(chnl_desc,"temp,cpu1")) ||
+ !(strcmp(chnl_desc,"temp,cpu2")) ||
+ !(strcmp(chnl_desc,"temp,cpu3")))
+ pchild->mon_type[chnl_no] = ENVCTRL_CPUTEMP_MON;
+
+ if (!(strcmp(chnl_desc,"vddcore,cpu0")) ||
+ !(strcmp(chnl_desc,"vddcore,cpu1")) ||
+ !(strcmp(chnl_desc,"vddcore,cpu2")) ||
+ !(strcmp(chnl_desc,"vddcore,cpu3")))
+ pchild->mon_type[chnl_no] = ENVCTRL_CPUVOLTAGE_MON;
+
+ if (!(strcmp(chnl_desc,"temp,motherboard")))
+ pchild->mon_type[chnl_no] = ENVCTRL_MTHRBDTEMP_MON;
+
+ if (!(strcmp(chnl_desc,"temp,scsi")))
+ pchild->mon_type[chnl_no] = ENVCTRL_SCSITEMP_MON;
+
+ if (!(strcmp(chnl_desc,"temp,ethernet")))
+ pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON;
+
+ if (!(strcmp(chnl_desc,"temp,ethernet")))
+ pchild->mon_type[chnl_no] = ENVCTRL_ETHERTEMP_MON;
+}
+
+/* Function Description: Initialize monitor channel with channel desc,
+ * decoding tables, monitor type, optional properties.
+ * Return: None.
+ */
+static void envctrl_init_adc(struct i2c_child_t *pchild, int node)
+{
+ char chnls_desc[CHANNEL_DESC_SZ];
+ int i, len, j = 0;
+ char *ptr;
+
+ /* Firmware describe channels into a stream separated by a '\0'.
+ * Replace all '\0' with a space.
+ */
+ len = prom_getproperty(node, "channels-description", chnls_desc,
+ CHANNEL_DESC_SZ);
+ for (i = 0; i < len; i++) {
+ if (chnls_desc[i] == '\0')
+ chnls_desc[i] = ' ';
+ }
+
+ ptr = strtok(chnls_desc, " ");
+ while (ptr != NULL) {
+ envctrl_set_mon(pchild, ptr, j);
+ ptr = strtok(NULL, " ");
+ j++;
+ }
+
+ /* Get optional properties. */
+ len = prom_getproperty(node, "warning-temp", (char *)&warning_temperature,
+ sizeof(warning_temperature));
+ len = prom_getproperty(node, "shutdown-temp", (char *)&shutdown_temperature,
+ sizeof(shutdown_temperature));
+}
+
+/* Function Description: Initialize child device monitoring fan status.
+ * Return: None.
+ */
+static void envctrl_init_fanstat(struct i2c_child_t *pchild)
{
- unsigned char tmp[80];
- unsigned char data;
- int i, n;
+ int i;
- write_8583(U450_TIMER_ADDR, 0, 0x84);
- write_8583(U450_TIMER_ADDR, 8, 0x0a);
- write_8583(U450_TIMER_ADDR, 7, 0x00);
- write_8583(U450_TIMER_ADDR, 0, 0x04);
+ /* Go through all channels and set up the mask. */
+ for (i = 0; i < pchild->total_chnls; i++)
+ pchild->fan_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no];
- n = sprintf(tmp, "envctrl: PCF8583:");
- for (i = 0; i < 16; i++) {
- if (read_8583(U450_TIMER_ADDR, i, &data) < 0) {
- printk("envctrl: error reading PCF8583\n");
- break;
- }
- n += sprintf(tmp+n, " %02x", data);
- }
- printk("%s\n", tmp);
-
-#if 1
- data = 0x70;
- if (i2c_write(U450_PIO_ADDR, &data, 1, 0) != 1)
- return;
- mdelay(1);
-
- data = 0x78;
- if (i2c_write(U450_PIO_ADDR, &data, 1, 0) != 1)
- return;
- mdelay(1);
-#endif
+ /* We only need to know if this child has fan status monitored.
+ * We dont care which channels since we have the mask already.
+ */
+ pchild->mon_type[0] = ENVCTRL_FANSTAT_MON;
}
-static void
-u450_set_egg_timer(struct environment *env)
+/* Initialize child device monitoring voltage status. */
+static void envctrl_init_voltage_status(struct i2c_child_t *pchild)
{
- unsigned char value;
-
-#if 0
- write_8583(U450_TIMER_ADDR, 0x00, 0x84);
- read_8583(U450_TIMER_ADDR, 0x07, &value);
- write_8583(U450_TIMER_ADDR, 0x07, 0x00);
- write_8583(U450_TIMER_ADDR, 0x00, 0x04);
-#else
- read_8583(U450_TIMER_ADDR, 0x07, &value);
- printk("envctrl: TIMER [%02x:07]: %02x\n", U450_TIMER_ADDR, value);
- read_8583(U450_TIMER_ADDR, 0x00, &value);
- printk("envctrl: TIMER [%02x:00]: %02x\n", U450_TIMER_ADDR, value);
-#endif
-}
+ int i;
-static int
-envctrl_setup(int node)
-{
- struct thermistor *t, **tlast;
- struct fan *f, **flast;
- unsigned char *tmp = NULL, *p;
- int len, n, err;
- int defaults = 0;
-
- len = prom_getproplen(node, "thermisters");
- if (len <= 0) {
- printk("envctrl: no property `thermisters', using defaults\n");
- defaults++;
- len = sizeof(u450_default_thermisters);
- }
+ /* Go through all channels and set up the mask. */
+ for (i = 0; i < pchild->total_chnls; i++)
+ pchild->voltage_mask |= chnls_mask[(pchild->chnl_array[i]).chnl_no];
- tmp = (unsigned char *)kmalloc(len, GFP_KERNEL);
- if (!tmp) {
- printk("envctrl: can't allocate property buffer\n");
- return -ENODEV;
- }
+ /* We only need to know if this child has voltage status monitored.
+ * We dont care which channels since we have the mask already.
+ */
+ pchild->mon_type[0] = ENVCTRL_VOLTAGESTAT_MON;
+}
- if (defaults) {
- memcpy(tmp, u450_default_thermisters, len);
- } else {
- err = prom_getproperty(node, "thermisters", tmp, len);
- if (err < 0) {
- printk("envctrl: error reading property `thermisters'\n");
- kfree(tmp);
- return -ENODEV;
+/* Function Description: Initialize i2c child device.
+ * Return: None.
+ */
+static void envctrl_init_i2c_child(struct linux_ebus_child *edev_child,
+ struct i2c_child_t *pchild)
+{
+ int node, len, i, tbls_size = 0;
+
+ node = edev_child->prom_node;
+
+ /* Get device address. */
+ len = prom_getproperty(node, "reg",
+ (char *) &(pchild->addr),
+ sizeof(pchild->addr));
+
+ /* Get tables property. Read firmware temperature tables. */
+ len = prom_getproperty(node, "translation",
+ (char *) pchild->tblprop_array,
+ (PCF8584_MAX_CHANNELS *
+ sizeof(struct pcf8584_tblprop)));
+ if (len > 0) {
+ pchild->total_tbls = len / sizeof(struct pcf8584_tblprop);
+ for (i = 0; i < pchild->total_tbls; i++) {
+ if ((pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset) > tbls_size) {
+ tbls_size = pchild->tblprop_array[i].size + pchild->tblprop_array[i].offset;
+ }
}
- }
-
- p = tmp;
- err = -ENOMEM;
- tlast = &envctrl.thermistors;
- while (len > sizeof(struct therm_regs)) {
- t = kmalloc(sizeof(struct thermistor), GFP_KERNEL);
- if (!t) {
- printk("envctrl: can't allocate thermistor struct\n");
- goto out;
- }
- memset(t, 0, sizeof(struct thermistor));
-
- memcpy(&t->regs, p, sizeof(struct therm_regs));
- p += sizeof(struct therm_regs);
- len -= sizeof(struct therm_regs);
-
- n = strlen(p) + 1;
- strncpy(t->name, p, 7);
- p += n;
- len -= n;
-
- if (!i2c_find_device(t->regs.addr)) {
- printk("envctrl: `%s': i2c device %02x not found\n",
- t->name, t->regs.addr);
- kfree(t);
- continue;
+ pchild->tables = kmalloc(tbls_size, GFP_KERNEL);
+ len = prom_getproperty(node, "tables",
+ (char *) pchild->tables, tbls_size);
+ if (len <= 0) {
+ printk("envctrl: Failed to get table.\n");
+ return;
}
+ }
- t->temperature = envctrl_get_temperature;
- t->fan_speed = envctrl_get_fan_speed;
+ /* Get the monitor channels. */
+ len = prom_getproperty(node, "channels-in-use",
+ (char *) pchild->chnl_array,
+ (PCF8584_MAX_CHANNELS *
+ sizeof(struct pcf8584_channel)));
+ pchild->total_chnls = len / sizeof(struct pcf8584_channel);
- *tlast = t;
- tlast = &t->next;
- }
+ for (i = 0; i < pchild->total_chnls; i++) {
+ switch (pchild->chnl_array[i].type) {
+ case PCF8584_TEMP_TYPE:
+ envctrl_init_adc(pchild, node);
+ break;
- flast = &envctrl.fans;
- for (n = 0; n < 2; n++) {
- f = kmalloc(sizeof(struct fan), GFP_KERNEL);
- if (!f)
- goto out;
- memset(f, 0, sizeof(struct fan));
-
- f->regs.addr = U450_FAN_ADDR;
- f->regs.port = n;
-
- switch (n) {
- case U450_FAN_PORT_CPU:
- sprintf(f->name, "%.7s", "CPU");
- t = NULL;
- while ((t = find_thermistor("CPU", t))) {
- t->chain = f->monitor;
- f->monitor = t;
- }
+ case PCF8584_FANSTAT_TYPE:
+ envctrl_init_fanstat(pchild);
+ i = pchild->total_chnls;
break;
- case U450_FAN_PORT_PS:
- sprintf(f->name, "%.7s", "PS");
- t = NULL;
- while ((t = find_thermistor("PS", t))) {
- t->chain = f->monitor;
- f->monitor = t;
+
+ case PCF8584_VOLTAGE_TYPE:
+ if (pchild->i2ctype == I2C_ADC) {
+ envctrl_init_adc(pchild,node);
+ } else {
+ envctrl_init_voltage_status(pchild);
}
+ i = pchild->total_chnls;
break;
- }
-
- if (!f->monitor) {
- kfree(f);
- continue;
- }
-
- if (!i2c_find_device(f->regs.addr)) {
- printk("envctrl: `%s': i2c device %02x not found\n",
- f->name, f->regs.addr);
- kfree(f);
- continue;
- }
-
- *flast = f;
- flast = &f->next;
- f->check_failure = NULL;
- f->set_speed = envctrl_set_fan_speed;
- }
-
- envctrl.cpu_temp_table = kmalloc(256, GFP_KERNEL);
- if (!envctrl.cpu_temp_table) {
- printk("envctrl: can't allocate temperature table\n");
- goto out;
- }
- if (defaults) {
- memcpy(envctrl.cpu_temp_table,
- u450_default_cpu_temp_factors, 256);
- } else {
- err = prom_getproperty(node, "cpu-temp-factors",
- envctrl.cpu_temp_table, 256);
- if (err < 0) {
- printk("envctrl: can't read `cpu-temp-factors'\n");
- goto out;
- }
- }
-
- envctrl.cpu_fan_speeds = kmalloc(112, GFP_KERNEL);
- if (!envctrl.cpu_fan_speeds) {
- printk("envctrl: can't allocate fan speed table\n");
- goto out;
- }
- if (defaults) {
- memcpy(envctrl.cpu_fan_speeds,
- u450_default_cpu_fan_speeds, 112);
- } else {
- err = prom_getproperty(node, "cpu-fan-speeds",
- envctrl.cpu_fan_speeds, 112);
- if (err < 0) {
- printk("envctrl: can't read `cpu-fan-speeds'\n");
- goto out;
- }
- }
-
- envctrl.ps_temp_table = kmalloc(256, GFP_KERNEL);
- if (!envctrl.ps_temp_table) {
- printk("envctrl: can't allocate temperature table\n");
- goto out;
- }
- if (defaults) {
- memcpy(envctrl.ps_temp_table,
- u450_default_ps_temp_factors, 256);
- } else {
- err = prom_getproperty(node, "ps-temp-factors",
- envctrl.ps_temp_table, 256);
- if (err < 0) {
- printk("envctrl: can't read `ps-temp-factors'\n");
- goto out;
- }
- }
-
- envctrl.ps_fan_speeds = kmalloc(112, GFP_KERNEL);
- if (!envctrl.ps_fan_speeds) {
- printk("envctrl: can't allocate fan speed table\n");
- goto out;
- }
- if (defaults) {
- memcpy(envctrl.ps_fan_speeds,
- u450_default_ps_fan_speeds, 112);
- } else {
- err = prom_getproperty(node, "ps-fan-speeds",
- envctrl.ps_fan_speeds, 112);
- if (err < 0) {
- printk("envctrl: can't read `ps-fan-speeds'\n");
- goto out;
- }
+ default:
+ break;
+ };
}
-
- envctrl.enable = u450_toggle_i2c_int;
- envctrl.keep_alive = u450_set_egg_timer;
- envctrl.disable = envctrl_fans_blast;
- envctrl.interval = 60;
-
- kfree(tmp);
- return 0;
-
-out:
- if (tmp)
- kfree(tmp);
- return err;
-}
-#endif /* U450_SUPPORT */
-
-
-
-static loff_t
-envctrl_llseek(struct file *file, loff_t offset, int type)
-{
- return -ESPIPE;
-}
-
-static ssize_t
-envctrl_read(struct file *file, char *buf, size_t count, loff_t *ppos)
-{
- unsigned long addr = (unsigned long)file->private_data;
-
- return i2c_read(addr, buf, count, 1);
-}
-
-static ssize_t
-envctrl_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
-{
- unsigned long addr = (unsigned long)file->private_data;
-
- return i2c_write(addr, buf, count, 1);
}
-static int
-envctrl_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg)
+/* Function Description: Search the child device list for a device.
+ * Return : The i2c child if found. NULL otherwise.
+ */
+static struct i2c_child_t *envctrl_get_i2c_child(unsigned char mon_type)
{
- unsigned long data;
- int addr;
+ int i, j;
- switch (cmd) {
- case I2CIOCSADR:
- if (get_user(addr, (int *)arg))
- return -EFAULT;
- data = addr & 0xfe;
- if (!i2c_find_device(addr & 0xfe))
- return -ENODEV;
- file->private_data = (void *)data;
- break;
- case I2CIOCGADR:
- addr = (unsigned long)file->private_data;
- if (put_user(addr, (int *)arg))
- return -EFAULT;
- break;
- default:
- return -EINVAL;
+ for (i = 0; i < ENVCTRL_MAX_CPU*2; i++) {
+ for (j = 0; j < PCF8584_MAX_CHANNELS; j++) {
+ if (i2c_childlist[i].mon_type[j] == mon_type) {
+ return (struct i2c_child_t*)(&(i2c_childlist[i]));
+ }
+ }
}
- return 0;
+ return NULL;
}
-static int
-envctrl_open(struct inode *inode, struct file *file)
-{
- file->private_data = 0;
- return 0;
-}
-
-static struct file_operations envctrl_fops = {
- owner: THIS_MODULE,
- llseek: envctrl_llseek,
- read: envctrl_read,
- write: envctrl_write,
- ioctl: envctrl_ioctl,
- open: envctrl_open,
-};
-
-static struct miscdevice envctrl_dev = {
- ENVCTRL_MINOR,
- "envctrl",
- &envctrl_fops
-};
-
-#ifdef MODULE
-int init_module(void)
-#else
-int __init envctrl_init(void)
-#endif
+static int __init envctrl_init(void)
{
#ifdef CONFIG_PCI
- struct linux_ebus *ebus;
- struct linux_ebus_device *edev = 0;
- pid_t pid;
- int err;
-
+ struct linux_ebus *ebus = NULL;
+ struct linux_ebus_device *edev = NULL;
+ struct linux_ebus_child *edev_child = NULL;
+ int i = 0;
+
+ /* Traverse through ebus and ebus device list for i2c device and
+ * adc and gpio nodes.
+ */
for_each_ebus(ebus) {
for_each_ebusdev(edev, ebus) {
- if (!strcmp(edev->prom_name, "SUNW,envctrl"))
- goto ebus_done;
- if (!strcmp(edev->prom_name, "SUNW,rasctrl"))
- goto ebus_done;
+ if (!strcmp(edev->prom_name, "i2c")) {
+ i2c = ioremap( edev->resource[0].start,
+ sizeof(struct pcf8584_reg));
+ for_each_edevchild(edev, edev_child) {
+ if (!strcmp("gpio", edev_child->prom_name)) {
+ i2c_childlist[i].i2ctype = I2C_GPIO;
+ envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
+ }
+ if (!strcmp("adc", edev_child->prom_name)) {
+ i2c_childlist[i].i2ctype = I2C_ADC;
+ envctrl_init_i2c_child(edev_child, &(i2c_childlist[i++]));
+ }
+ }
+ goto done;
+ }
}
}
-ebus_done:
- if (!edev) {
- printk("%s: ebus device not found\n", __FUNCTION__);
- return -ENODEV;
- }
-
- i2c_regs = (unsigned long) ioremap(edev->resource[0].start, I2C_REG_SIZE);
- writeb(CONTROL_PIN, i2c_regs + I2C_CSR);
- writeb(PCF8584_ADDRESS >> 1, i2c_regs + I2C_DATA);
- writeb(CONTROL_PIN | CONTROL_ES1, i2c_regs + I2C_CSR);
- writeb(CLK_4_43 | BUS_CLK_90, i2c_regs + I2C_DATA);
- writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, i2c_regs + I2C_CSR);
- mdelay(10);
- if (misc_register(&envctrl_dev)) {
- printk("%s: unable to get misc minor %d\n",
- __FUNCTION__, envctrl_dev.minor);
+done:
+ if (!edev) {
+ printk("envctrl: I2C device not found.\n");
return -ENODEV;
}
- err = i2c_scan_bus();
- if (err) {
- i2c_free_devices();
- misc_deregister(&envctrl_dev);
- return err;
- }
+ /* Set device address. */
+ envctrl_writeb(CONTROL_PIN, &i2c->csr);
+ envctrl_writeb(PCF8584_ADDRESS, &i2c->data);
- memset(&envctrl, 0, sizeof(struct environment));
+ /* Set system clock and SCL frequencies. */
+ envctrl_writeb(CONTROL_PIN | CONTROL_ES1, &i2c->csr);
+ envctrl_writeb(CLK_4_43 | BUS_CLK_90, &i2c->data);
- err = -ENODEV;
- if (!strcmp(edev->prom_name, "SUNW,rasctrl"))
- err = rasctrl_setup(edev->prom_node);
-#ifdef U450_SUPPORT
- else if (!strcmp(edev->prom_name, "SUNW,envctrl"))
- err = envctrl_setup(edev->prom_node);
-#endif
+ /* Enable serial interface. */
+ envctrl_writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, &i2c->csr);
+ udelay(200);
- if (err) {
- envctrl_stop();
- i2c_free_devices();
- misc_deregister(&envctrl_dev);
- return err;
+ /* Register the device as a minor miscellaneous device. */
+ if (misc_register(&envctrl_dev)) {
+ printk("envctrl: Unable to get misc minor %d\n",
+ envctrl_dev.minor);
}
- init_waitqueue_head(&envctrl.kenvd_wait);
-
- pid = kernel_thread(kenvd, (void *)&envctrl, CLONE_FS);
- if (pid < 0) {
- envctrl_stop();
- i2c_free_devices();
- misc_deregister(&envctrl_dev);
- return -ENODEV;
+ /* Note above traversal routine post-incremented 'i' to accomodate
+ * a next child device, so we decrement before reverse-traversal of
+ * child devices.
+ */
+ printk("envctrl: initialized ");
+ for(--i; i >= 0; --i)
+ {
+ printk("[%s 0x%lx]%s",
+ (I2C_ADC == i2c_childlist[i].i2ctype) ? ("adc") :
+ ((I2C_GPIO == i2c_childlist[i].i2ctype) ? ("gpio") : ("unknown")),
+ i2c_childlist[i].addr, (0 == i) ? ("\n") : (" "));
}
return 0;
@@ -1605,13 +946,18 @@ ebus_done:
#endif
}
-
-#ifdef MODULE
-void cleanup_module(void)
+static void __exit envctrl_cleanup(void)
{
- envctrl_stop();
- i2c_free_devices();
- iounmap(i2c_regs);
+ int i;
+
+ iounmap(i2c);
misc_deregister(&envctrl_dev);
+
+ for (i = 0; i < ENVCTRL_MAX_CPU * 2; i++) {
+ if (i2c_childlist[i].tables)
+ kfree(i2c_childlist[i].tables);
+ }
}
-#endif
+
+module_init(envctrl_init);
+module_exit(envctrl_cleanup);
diff --git a/drivers/sbus/char/sab82532.c b/drivers/sbus/char/sab82532.c
index 7d010f035..ae7ba7ac1 100644
--- a/drivers/sbus/char/sab82532.c
+++ b/drivers/sbus/char/sab82532.c
@@ -1,4 +1,4 @@
-/* $Id: sab82532.c,v 1.51 2000/09/04 19:41:26 ecd Exp $
+/* $Id: sab82532.c,v 1.52 2000/10/14 10:09:04 davem Exp $
* sab82532.c: ASYNC Driver for the SIEMENS SAB82532 DUSCC.
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -2133,7 +2133,7 @@ static void __init sab82532_kgdb_hook(int line)
static inline void __init show_serial_version(void)
{
- char *revision = "$Revision: 1.51 $";
+ char *revision = "$Revision: 1.52 $";
char *version, *p;
version = strchr(revision, ' ');
@@ -2596,17 +2596,13 @@ sab82532_console_setup(struct console *con, char *options)
}
static struct console sab82532_console = {
- "ttyS",
- sab82532_console_write,
- NULL,
- sab82532_console_device,
- sab82532_console_wait_key,
- NULL,
- sab82532_console_setup,
- CON_PRINTBUFFER,
- -1,
- 0,
- NULL
+ name: "ttyS",
+ write: sab82532_console_write,
+ device: sab82532_console_device,
+ wait_key: sab82532_console_wait_key,
+ setup: sab82532_console_setup,
+ flags: CON_PRINTBUFFER,
+ index: -1,
};
int __init sab82532_console_init(void)
diff --git a/drivers/sbus/char/su.c b/drivers/sbus/char/su.c
index c6e90328e..1fd2d6fbf 100644
--- a/drivers/sbus/char/su.c
+++ b/drivers/sbus/char/su.c
@@ -1,4 +1,4 @@
-/* $Id: su.c,v 1.41 2000/09/04 19:41:27 ecd Exp $
+/* $Id: su.c,v 1.42 2000/10/14 10:09:04 davem Exp $
* su.c: Small serial driver for keyboard/mouse interface on sparc32/PCI
*
* Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
@@ -2219,7 +2219,7 @@ done:
*/
static __inline__ void __init show_su_version(void)
{
- char *revision = "$Revision: 1.41 $";
+ char *revision = "$Revision: 1.42 $";
char *version, *p;
version = strchr(revision, ' ');
@@ -2938,17 +2938,13 @@ static int __init serial_console_setup(struct console *co, char *options)
}
static struct console sercons = {
- "ttyS",
- serial_console_write,
- NULL,
- serial_console_device,
- serial_console_wait_key,
- NULL,
- serial_console_setup,
- CON_PRINTBUFFER,
- -1,
- 0,
- NULL
+ name: "ttyS",
+ write: serial_console_write,
+ device: serial_console_device,
+ wait_key: serial_console_wait_key,
+ setup: serial_console_setup,
+ flags: CON_PRINTBUFFER,
+ index: -1,
};
int su_console_registered = 0;
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index 5540e734b..f34c12250 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -80,7 +80,7 @@ extern void reset_vc(unsigned int new_console);
extern void scrollback(int);
extern void scrollfront(int);
-struct l1a_kbd_state l1a_state = { 0, 0 };
+struct l1a_kbd_state l1a_state;
#ifndef CONFIG_PCI
DECLARE_WAIT_QUEUE_HEAD(keypress_wait);
@@ -101,30 +101,30 @@ static spinlock_t sunkbd_lock = SPIN_LOCK_UNLOCKED;
*/
/* shift state counters.. */
-static unsigned char k_down[NR_SHIFT] = {0, };
+static unsigned char k_down[NR_SHIFT];
/* keyboard key bitmap */
-static unsigned long key_down[256/BITS_PER_LONG] = { 0, };
+static unsigned long key_down[256/BITS_PER_LONG];
void push_kbd (int scan);
-int kbd_redirected = 0;
+int kbd_redirected;
-static int dead_key_next = 0;
+static int dead_key_next;
/*
* In order to retrieve the shift_state (for the mouse server), either
* the variable must be global, or a new procedure must be created to
* return the value. I chose the former way.
*/
#ifndef CONFIG_PCI
-/*static*/ int shift_state = 0;
+/*static*/ int shift_state;
#endif
static int npadch = -1; /* -1 or number assembled on pad */
-static unsigned char diacr = 0;
-static char rep = 0; /* flag telling character repeat */
+static unsigned char diacr;
+static char rep; /* flag telling character repeat */
struct kbd_struct kbd_table[MAX_NR_CONSOLES];
static struct tty_struct **ttytab;
static struct kbd_struct * kbd = kbd_table;
-static struct tty_struct * tty = NULL;
-static int compose_led_on = 0;
+static struct tty_struct * tty;
+static int compose_led_on;
static int kbd_delay_ticks = HZ / 5;
static int kbd_rate_ticks = HZ / 20;
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 77b849ef0..73158f351 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -43,7 +43,7 @@
#include <asm/vfc_ioctls.h>
static struct file_operations vfc_fops;
-static devfs_handle_t devfs_handle = NULL; /* For the directory */
+static devfs_handle_t devfs_handle; /* For the directory */
struct vfc_dev **vfc_dev_lst;
static char vfcstr[]="vfc";
static unsigned char saa9051_init_array[VFC_SAA9051_NR] = {
diff --git a/drivers/sbus/char/zs.c b/drivers/sbus/char/zs.c
index 7acfb2aba..67ef24fd3 100644
--- a/drivers/sbus/char/zs.c
+++ b/drivers/sbus/char/zs.c
@@ -1,4 +1,4 @@
-/* $Id: zs.c,v 1.59 2000/08/29 07:01:55 davem Exp $
+/* $Id: zs.c,v 1.60 2000/10/14 10:09:04 davem Exp $
* zs.c: Zilog serial port driver for the Sparc.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1913,7 +1913,7 @@ int zs_open(struct tty_struct *tty, struct file * filp)
static void show_serial_version(void)
{
- char *revision = "$Revision: 1.59 $";
+ char *revision = "$Revision: 1.60 $";
char *version, *p;
version = strchr(revision, ' ');
@@ -2830,17 +2830,13 @@ static int __init zs_console_setup(struct console *con, char *options)
}
static struct console zs_console = {
- "ttyS",
- zs_console_write,
- NULL,
- zs_console_device,
- zs_console_wait_key,
- NULL,
- zs_console_setup,
- CON_PRINTBUFFER,
- -1,
- 0,
- NULL
+ name: "ttyS",
+ write: zs_console_write,
+ device: zs_console_device,
+ wait_key: zs_console_wait_key,
+ setup: zs_console_setup,
+ flags: CON_PRINTBUFFER,
+ index: -1,
};
static int __init zs_console_init(void)