diff options
Diffstat (limited to 'ANDROID_3.4.5/drivers/sbus')
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/Makefile | 5 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/Kconfig | 75 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/Makefile | 18 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/bbc_envctrl.c | 595 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.c | 421 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.h | 85 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/display7seg.c | 278 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/envctrl.c | 1143 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/flash.c | 220 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/jsflash.c | 636 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/max1617.h | 27 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/openprom.c | 762 | ||||
-rw-r--r-- | ANDROID_3.4.5/drivers/sbus/char/uctrl.c | 439 |
13 files changed, 0 insertions, 4704 deletions
diff --git a/ANDROID_3.4.5/drivers/sbus/Makefile b/ANDROID_3.4.5/drivers/sbus/Makefile deleted file mode 100644 index e94dc258..00000000 --- a/ANDROID_3.4.5/drivers/sbus/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the linux kernel. -# - -obj-$(CONFIG_SBUSCHAR) += char/ diff --git a/ANDROID_3.4.5/drivers/sbus/char/Kconfig b/ANDROID_3.4.5/drivers/sbus/char/Kconfig deleted file mode 100644 index 73cde85d..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/Kconfig +++ /dev/null @@ -1,75 +0,0 @@ - -menu "Misc Linux/SPARC drivers" - -config SUN_OPENPROMIO - tristate "/dev/openprom device support" - help - This driver provides user programs with an interface to the SPARC - PROM device tree. The driver implements a SunOS-compatible - interface and a NetBSD-compatible interface. - - To compile this driver as a module, choose M here: the - module will be called openprom. - - If unsure, say Y. - -config OBP_FLASH - tristate "OBP Flash Device support" - depends on SPARC64 - help - The OpenBoot PROM on Ultra systems is flashable. If you want to be - able to upgrade the OBP firmware, say Y here. - -config TADPOLE_TS102_UCTRL - tristate "Tadpole TS102 Microcontroller support (EXPERIMENTAL)" - depends on EXPERIMENTAL - help - Say Y here to directly support the TS102 Microcontroller interface - on the Tadpole Sparcbook 3. This device handles power-management - events, and can also notice the attachment/detachment of external - monitors and mice. - -config SUN_JSFLASH - tristate "JavaStation OS Flash SIMM (EXPERIMENTAL)" - depends on EXPERIMENTAL && SPARC32 - help - If you say Y here, you will be able to boot from your JavaStation's - Flash memory. - -config BBC_I2C - tristate "UltraSPARC-III bootbus i2c controller driver" - depends on PCI && SPARC64 - help - The BBC devices on the UltraSPARC III have two I2C controllers. The - first I2C controller connects mainly to configuration PROMs (NVRAM, - CPU configuration, DIMM types, etc.). The second I2C controller - connects to environmental control devices such as fans and - temperature sensors. The second controller also connects to the - smartcard reader, if present. Say Y to enable support for these. - -config ENVCTRL - tristate "SUNW, envctrl support" - depends on PCI && SPARC64 - help - Kernel support for temperature and fan monitoring on Sun SME - machines. - - To compile this driver as a module, choose M here: the - module will be called envctrl. - -config DISPLAY7SEG - tristate "7-Segment Display support" - depends on PCI && SPARC64 - ---help--- - This is the driver for the 7-segment display and LED present on - Sun Microsystems CompactPCI models CP1400 and CP1500. - - To compile this driver as a module, choose M here: the - module will be called display7seg. - - If you do not have a CompactPCI model CP1400 or CP1500, or - another UltraSPARC-IIi-cEngine boardset with a 7-segment display, - you should say N to this option. - -endmenu - diff --git a/ANDROID_3.4.5/drivers/sbus/char/Makefile b/ANDROID_3.4.5/drivers/sbus/char/Makefile deleted file mode 100644 index 78b6183c..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# -# Makefile for the kernel miscellaneous SPARC device drivers. -# -# Dave Redman Frame Buffer tuning support. -# -# 7 October 2000, Bartlomiej Zolnierkiewicz <bkz@linux-ide.org> -# Rewritten to use lists instead of if-statements. -# - -bbc-objs := bbc_i2c.o bbc_envctrl.o - -obj-$(CONFIG_ENVCTRL) += envctrl.o -obj-$(CONFIG_DISPLAY7SEG) += display7seg.o -obj-$(CONFIG_OBP_FLASH) += flash.o -obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o -obj-$(CONFIG_TADPOLE_TS102_UCTRL) += uctrl.o -obj-$(CONFIG_SUN_JSFLASH) += jsflash.o -obj-$(CONFIG_BBC_I2C) += bbc.o diff --git a/ANDROID_3.4.5/drivers/sbus/char/bbc_envctrl.c b/ANDROID_3.4.5/drivers/sbus/char/bbc_envctrl.c deleted file mode 100644 index 160e7510..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/bbc_envctrl.c +++ /dev/null @@ -1,595 +0,0 @@ -/* bbc_envctrl.c: UltraSPARC-III environment control driver. - * - * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net) - */ - -#include <linux/kthread.h> -#include <linux/delay.h> -#include <linux/kmod.h> -#include <linux/reboot.h> -#include <linux/of.h> -#include <linux/slab.h> -#include <linux/of_device.h> -#include <asm/oplib.h> - -#include "bbc_i2c.h" -#include "max1617.h" - -#undef ENVCTRL_TRACE - -/* WARNING: Making changes to this driver is very dangerous. - * If you misprogram the sensor chips they can - * cut the power on you instantly. - */ - -/* Two temperature sensors exist in the SunBLADE-1000 enclosure. - * Both are implemented using max1617 i2c devices. Each max1617 - * monitors 2 temperatures, one for one of the cpu dies and the other - * for the ambient temperature. - * - * The max1617 is capable of being programmed with power-off - * temperature values, one low limit and one high limit. These - * can be controlled independently for the cpu or ambient temperature. - * If a limit is violated, the power is simply shut off. The frequency - * with which the max1617 does temperature sampling can be controlled - * as well. - * - * Three fans exist inside the machine, all three are controlled with - * an i2c digital to analog converter. There is a fan directed at the - * two processor slots, another for the rest of the enclosure, and the - * third is for the power supply. The first two fans may be speed - * controlled by changing the voltage fed to them. The third fan may - * only be completely off or on. The third fan is meant to only be - * disabled/enabled when entering/exiting the lowest power-saving - * mode of the machine. - * - * An environmental control kernel thread periodically monitors all - * temperature sensors. Based upon the samples it will adjust the - * fan speeds to try and keep the system within a certain temperature - * range (the goal being to make the fans as quiet as possible without - * allowing the system to get too hot). - * - * If the temperature begins to rise/fall outside of the acceptable - * operating range, a periodic warning will be sent to the kernel log. - * The fans will be put on full blast to attempt to deal with this - * situation. After exceeding the acceptable operating range by a - * certain threshold, the kernel thread will shut down the system. - * Here, the thread is attempting to shut the machine down cleanly - * before the hardware based power-off event is triggered. - */ - -/* These settings are in Celsius. We use these defaults only - * if we cannot interrogate the cpu-fru SEEPROM. - */ -struct temp_limits { - s8 high_pwroff, high_shutdown, high_warn; - s8 low_warn, low_shutdown, low_pwroff; -}; - -static struct temp_limits cpu_temp_limits[2] = { - { 100, 85, 80, 5, -5, -10 }, - { 100, 85, 80, 5, -5, -10 }, -}; - -static struct temp_limits amb_temp_limits[2] = { - { 65, 55, 40, 5, -5, -10 }, - { 65, 55, 40, 5, -5, -10 }, -}; - -static LIST_HEAD(all_temps); -static LIST_HEAD(all_fans); - -#define CPU_FAN_REG 0xf0 -#define SYS_FAN_REG 0xf2 -#define PSUPPLY_FAN_REG 0xf4 - -#define FAN_SPEED_MIN 0x0c -#define FAN_SPEED_MAX 0x3f - -#define PSUPPLY_FAN_ON 0x1f -#define PSUPPLY_FAN_OFF 0x00 - -static void set_fan_speeds(struct bbc_fan_control *fp) -{ - /* Put temperatures into range so we don't mis-program - * the hardware. - */ - if (fp->cpu_fan_speed < FAN_SPEED_MIN) - fp->cpu_fan_speed = FAN_SPEED_MIN; - if (fp->cpu_fan_speed > FAN_SPEED_MAX) - fp->cpu_fan_speed = FAN_SPEED_MAX; - if (fp->system_fan_speed < FAN_SPEED_MIN) - fp->system_fan_speed = FAN_SPEED_MIN; - if (fp->system_fan_speed > FAN_SPEED_MAX) - fp->system_fan_speed = FAN_SPEED_MAX; -#ifdef ENVCTRL_TRACE - printk("fan%d: Changed fan speed to cpu(%02x) sys(%02x)\n", - fp->index, - fp->cpu_fan_speed, fp->system_fan_speed); -#endif - - bbc_i2c_writeb(fp->client, fp->cpu_fan_speed, CPU_FAN_REG); - bbc_i2c_writeb(fp->client, fp->system_fan_speed, SYS_FAN_REG); - bbc_i2c_writeb(fp->client, - (fp->psupply_fan_on ? - PSUPPLY_FAN_ON : PSUPPLY_FAN_OFF), - PSUPPLY_FAN_REG); -} - -static void get_current_temps(struct bbc_cpu_temperature *tp) -{ - tp->prev_amb_temp = tp->curr_amb_temp; - bbc_i2c_readb(tp->client, - (unsigned char *) &tp->curr_amb_temp, - MAX1617_AMB_TEMP); - tp->prev_cpu_temp = tp->curr_cpu_temp; - bbc_i2c_readb(tp->client, - (unsigned char *) &tp->curr_cpu_temp, - MAX1617_CPU_TEMP); -#ifdef ENVCTRL_TRACE - printk("temp%d: cpu(%d C) amb(%d C)\n", - tp->index, - (int) tp->curr_cpu_temp, (int) tp->curr_amb_temp); -#endif -} - - -static void do_envctrl_shutdown(struct bbc_cpu_temperature *tp) -{ - static int shutting_down = 0; - char *type = "???"; - s8 val = -1; - - if (shutting_down != 0) - return; - - if (tp->curr_amb_temp >= amb_temp_limits[tp->index].high_shutdown || - tp->curr_amb_temp < amb_temp_limits[tp->index].low_shutdown) { - type = "ambient"; - val = tp->curr_amb_temp; - } else if (tp->curr_cpu_temp >= cpu_temp_limits[tp->index].high_shutdown || - tp->curr_cpu_temp < cpu_temp_limits[tp->index].low_shutdown) { - type = "CPU"; - val = tp->curr_cpu_temp; - } - - printk(KERN_CRIT "temp%d: Outside of safe %s " - "operating temperature, %d C.\n", - tp->index, type, val); - - printk(KERN_CRIT "kenvctrld: Shutting down the system now.\n"); - - shutting_down = 1; - if (orderly_poweroff(true) < 0) - printk(KERN_CRIT "envctrl: shutdown execution failed\n"); -} - -#define WARN_INTERVAL (30 * HZ) - -static void analyze_ambient_temp(struct bbc_cpu_temperature *tp, unsigned long *last_warn, int tick) -{ - int ret = 0; - - if (time_after(jiffies, (*last_warn + WARN_INTERVAL))) { - if (tp->curr_amb_temp >= - amb_temp_limits[tp->index].high_warn) { - printk(KERN_WARNING "temp%d: " - "Above safe ambient operating temperature, %d C.\n", - tp->index, (int) tp->curr_amb_temp); - ret = 1; - } else if (tp->curr_amb_temp < - amb_temp_limits[tp->index].low_warn) { - printk(KERN_WARNING "temp%d: " - "Below safe ambient operating temperature, %d C.\n", - tp->index, (int) tp->curr_amb_temp); - ret = 1; - } - if (ret) - *last_warn = jiffies; - } else if (tp->curr_amb_temp >= amb_temp_limits[tp->index].high_warn || - tp->curr_amb_temp < amb_temp_limits[tp->index].low_warn) - ret = 1; - - /* Now check the shutdown limits. */ - if (tp->curr_amb_temp >= amb_temp_limits[tp->index].high_shutdown || - tp->curr_amb_temp < amb_temp_limits[tp->index].low_shutdown) { - do_envctrl_shutdown(tp); - ret = 1; - } - - if (ret) { - tp->fan_todo[FAN_AMBIENT] = FAN_FULLBLAST; - } else if ((tick & (8 - 1)) == 0) { - s8 amb_goal_hi = amb_temp_limits[tp->index].high_warn - 10; - s8 amb_goal_lo; - - amb_goal_lo = amb_goal_hi - 3; - - /* We do not try to avoid 'too cold' events. Basically we - * only try to deal with over-heating and fan noise reduction. - */ - if (tp->avg_amb_temp < amb_goal_hi) { - if (tp->avg_amb_temp >= amb_goal_lo) - tp->fan_todo[FAN_AMBIENT] = FAN_SAME; - else - tp->fan_todo[FAN_AMBIENT] = FAN_SLOWER; - } else { - tp->fan_todo[FAN_AMBIENT] = FAN_FASTER; - } - } else { - tp->fan_todo[FAN_AMBIENT] = FAN_SAME; - } -} - -static void analyze_cpu_temp(struct bbc_cpu_temperature *tp, unsigned long *last_warn, int tick) -{ - int ret = 0; - - if (time_after(jiffies, (*last_warn + WARN_INTERVAL))) { - if (tp->curr_cpu_temp >= - cpu_temp_limits[tp->index].high_warn) { - printk(KERN_WARNING "temp%d: " - "Above safe CPU operating temperature, %d C.\n", - tp->index, (int) tp->curr_cpu_temp); - ret = 1; - } else if (tp->curr_cpu_temp < - cpu_temp_limits[tp->index].low_warn) { - printk(KERN_WARNING "temp%d: " - "Below safe CPU operating temperature, %d C.\n", - tp->index, (int) tp->curr_cpu_temp); - ret = 1; - } - if (ret) - *last_warn = jiffies; - } else if (tp->curr_cpu_temp >= cpu_temp_limits[tp->index].high_warn || - tp->curr_cpu_temp < cpu_temp_limits[tp->index].low_warn) - ret = 1; - - /* Now check the shutdown limits. */ - if (tp->curr_cpu_temp >= cpu_temp_limits[tp->index].high_shutdown || - tp->curr_cpu_temp < cpu_temp_limits[tp->index].low_shutdown) { - do_envctrl_shutdown(tp); - ret = 1; - } - - if (ret) { - tp->fan_todo[FAN_CPU] = FAN_FULLBLAST; - } else if ((tick & (8 - 1)) == 0) { - s8 cpu_goal_hi = cpu_temp_limits[tp->index].high_warn - 10; - s8 cpu_goal_lo; - - cpu_goal_lo = cpu_goal_hi - 3; - - /* We do not try to avoid 'too cold' events. Basically we - * only try to deal with over-heating and fan noise reduction. - */ - if (tp->avg_cpu_temp < cpu_goal_hi) { - if (tp->avg_cpu_temp >= cpu_goal_lo) - tp->fan_todo[FAN_CPU] = FAN_SAME; - else - tp->fan_todo[FAN_CPU] = FAN_SLOWER; - } else { - tp->fan_todo[FAN_CPU] = FAN_FASTER; - } - } else { - tp->fan_todo[FAN_CPU] = FAN_SAME; - } -} - -static void analyze_temps(struct bbc_cpu_temperature *tp, unsigned long *last_warn) -{ - tp->avg_amb_temp = (s8)((int)((int)tp->avg_amb_temp + (int)tp->curr_amb_temp) / 2); - tp->avg_cpu_temp = (s8)((int)((int)tp->avg_cpu_temp + (int)tp->curr_cpu_temp) / 2); - - analyze_ambient_temp(tp, last_warn, tp->sample_tick); - analyze_cpu_temp(tp, last_warn, tp->sample_tick); - - tp->sample_tick++; -} - -static enum fan_action prioritize_fan_action(int which_fan) -{ - struct bbc_cpu_temperature *tp; - enum fan_action decision = FAN_STATE_MAX; - - /* Basically, prioritize what the temperature sensors - * recommend we do, and perform that action on all the - * fans. - */ - list_for_each_entry(tp, &all_temps, glob_list) { - if (tp->fan_todo[which_fan] == FAN_FULLBLAST) { - decision = FAN_FULLBLAST; - break; - } - if (tp->fan_todo[which_fan] == FAN_SAME && - decision != FAN_FASTER) - decision = FAN_SAME; - else if (tp->fan_todo[which_fan] == FAN_FASTER) - decision = FAN_FASTER; - else if (decision != FAN_FASTER && - decision != FAN_SAME && - tp->fan_todo[which_fan] == FAN_SLOWER) - decision = FAN_SLOWER; - } - if (decision == FAN_STATE_MAX) - decision = FAN_SAME; - - return decision; -} - -static int maybe_new_ambient_fan_speed(struct bbc_fan_control *fp) -{ - enum fan_action decision = prioritize_fan_action(FAN_AMBIENT); - int ret; - - if (decision == FAN_SAME) - return 0; - - ret = 1; - if (decision == FAN_FULLBLAST) { - if (fp->system_fan_speed >= FAN_SPEED_MAX) - ret = 0; - else - fp->system_fan_speed = FAN_SPEED_MAX; - } else { - if (decision == FAN_FASTER) { - if (fp->system_fan_speed >= FAN_SPEED_MAX) - ret = 0; - else - fp->system_fan_speed += 2; - } else { - int orig_speed = fp->system_fan_speed; - - if (orig_speed <= FAN_SPEED_MIN || - orig_speed <= (fp->cpu_fan_speed - 3)) - ret = 0; - else - fp->system_fan_speed -= 1; - } - } - - return ret; -} - -static int maybe_new_cpu_fan_speed(struct bbc_fan_control *fp) -{ - enum fan_action decision = prioritize_fan_action(FAN_CPU); - int ret; - - if (decision == FAN_SAME) - return 0; - - ret = 1; - if (decision == FAN_FULLBLAST) { - if (fp->cpu_fan_speed >= FAN_SPEED_MAX) - ret = 0; - else - fp->cpu_fan_speed = FAN_SPEED_MAX; - } else { - if (decision == FAN_FASTER) { - if (fp->cpu_fan_speed >= FAN_SPEED_MAX) - ret = 0; - else { - fp->cpu_fan_speed += 2; - if (fp->system_fan_speed < - (fp->cpu_fan_speed - 3)) - fp->system_fan_speed = - fp->cpu_fan_speed - 3; - } - } else { - if (fp->cpu_fan_speed <= FAN_SPEED_MIN) - ret = 0; - else - fp->cpu_fan_speed -= 1; - } - } - - return ret; -} - -static void maybe_new_fan_speeds(struct bbc_fan_control *fp) -{ - int new; - - new = maybe_new_ambient_fan_speed(fp); - new |= maybe_new_cpu_fan_speed(fp); - - if (new) - set_fan_speeds(fp); -} - -static void fans_full_blast(void) -{ - struct bbc_fan_control *fp; - - /* Since we will not be monitoring things anymore, put - * the fans on full blast. - */ - list_for_each_entry(fp, &all_fans, glob_list) { - fp->cpu_fan_speed = FAN_SPEED_MAX; - fp->system_fan_speed = FAN_SPEED_MAX; - fp->psupply_fan_on = 1; - set_fan_speeds(fp); - } -} - -#define POLL_INTERVAL (5 * 1000) -static unsigned long last_warning_jiffies; -static struct task_struct *kenvctrld_task; - -static int kenvctrld(void *__unused) -{ - printk(KERN_INFO "bbc_envctrl: kenvctrld starting...\n"); - last_warning_jiffies = jiffies - WARN_INTERVAL; - for (;;) { - struct bbc_cpu_temperature *tp; - struct bbc_fan_control *fp; - - msleep_interruptible(POLL_INTERVAL); - if (kthread_should_stop()) - break; - - list_for_each_entry(tp, &all_temps, glob_list) { - get_current_temps(tp); - analyze_temps(tp, &last_warning_jiffies); - } - list_for_each_entry(fp, &all_fans, glob_list) - maybe_new_fan_speeds(fp); - } - printk(KERN_INFO "bbc_envctrl: kenvctrld exiting...\n"); - - fans_full_blast(); - - return 0; -} - -static void attach_one_temp(struct bbc_i2c_bus *bp, struct platform_device *op, - int temp_idx) -{ - struct bbc_cpu_temperature *tp; - - tp = kzalloc(sizeof(*tp), GFP_KERNEL); - if (!tp) - return; - - tp->client = bbc_i2c_attach(bp, op); - if (!tp->client) { - kfree(tp); - return; - } - - - tp->index = temp_idx; - - list_add(&tp->glob_list, &all_temps); - list_add(&tp->bp_list, &bp->temps); - - /* Tell it to convert once every 5 seconds, clear all cfg - * bits. - */ - bbc_i2c_writeb(tp->client, 0x00, MAX1617_WR_CFG_BYTE); - bbc_i2c_writeb(tp->client, 0x02, MAX1617_WR_CVRATE_BYTE); - - /* Program the hard temperature limits into the chip. */ - bbc_i2c_writeb(tp->client, amb_temp_limits[tp->index].high_pwroff, - MAX1617_WR_AMB_HIGHLIM); - bbc_i2c_writeb(tp->client, amb_temp_limits[tp->index].low_pwroff, - MAX1617_WR_AMB_LOWLIM); - bbc_i2c_writeb(tp->client, cpu_temp_limits[tp->index].high_pwroff, - MAX1617_WR_CPU_HIGHLIM); - bbc_i2c_writeb(tp->client, cpu_temp_limits[tp->index].low_pwroff, - MAX1617_WR_CPU_LOWLIM); - - get_current_temps(tp); - tp->prev_cpu_temp = tp->avg_cpu_temp = tp->curr_cpu_temp; - tp->prev_amb_temp = tp->avg_amb_temp = tp->curr_amb_temp; - - tp->fan_todo[FAN_AMBIENT] = FAN_SAME; - tp->fan_todo[FAN_CPU] = FAN_SAME; -} - -static void attach_one_fan(struct bbc_i2c_bus *bp, struct platform_device *op, - int fan_idx) -{ - struct bbc_fan_control *fp; - - fp = kzalloc(sizeof(*fp), GFP_KERNEL); - if (!fp) - return; - - fp->client = bbc_i2c_attach(bp, op); - if (!fp->client) { - kfree(fp); - return; - } - - fp->index = fan_idx; - - list_add(&fp->glob_list, &all_fans); - list_add(&fp->bp_list, &bp->fans); - - /* The i2c device controlling the fans is write-only. - * So the only way to keep track of the current power - * level fed to the fans is via software. Choose half - * power for cpu/system and 'on' fo the powersupply fan - * and set it now. - */ - fp->psupply_fan_on = 1; - fp->cpu_fan_speed = (FAN_SPEED_MAX - FAN_SPEED_MIN) / 2; - fp->cpu_fan_speed += FAN_SPEED_MIN; - fp->system_fan_speed = (FAN_SPEED_MAX - FAN_SPEED_MIN) / 2; - fp->system_fan_speed += FAN_SPEED_MIN; - - set_fan_speeds(fp); -} - -static void destroy_one_temp(struct bbc_cpu_temperature *tp) -{ - bbc_i2c_detach(tp->client); - kfree(tp); -} - -static void destroy_all_temps(struct bbc_i2c_bus *bp) -{ - struct bbc_cpu_temperature *tp, *tpos; - - list_for_each_entry_safe(tp, tpos, &bp->temps, bp_list) { - list_del(&tp->bp_list); - list_del(&tp->glob_list); - destroy_one_temp(tp); - } -} - -static void destroy_one_fan(struct bbc_fan_control *fp) -{ - bbc_i2c_detach(fp->client); - kfree(fp); -} - -static void destroy_all_fans(struct bbc_i2c_bus *bp) -{ - struct bbc_fan_control *fp, *fpos; - - list_for_each_entry_safe(fp, fpos, &bp->fans, bp_list) { - list_del(&fp->bp_list); - list_del(&fp->glob_list); - destroy_one_fan(fp); - } -} - -int bbc_envctrl_init(struct bbc_i2c_bus *bp) -{ - struct platform_device *op; - int temp_index = 0; - int fan_index = 0; - int devidx = 0; - - while ((op = bbc_i2c_getdev(bp, devidx++)) != NULL) { - if (!strcmp(op->dev.of_node->name, "temperature")) - attach_one_temp(bp, op, temp_index++); - if (!strcmp(op->dev.of_node->name, "fan-control")) - attach_one_fan(bp, op, fan_index++); - } - if (temp_index != 0 && fan_index != 0) { - kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); - if (IS_ERR(kenvctrld_task)) { - int err = PTR_ERR(kenvctrld_task); - - kenvctrld_task = NULL; - destroy_all_temps(bp); - destroy_all_fans(bp); - return err; - } - } - - return 0; -} - -void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp) -{ - if (kenvctrld_task) - kthread_stop(kenvctrld_task); - - destroy_all_temps(bp); - destroy_all_fans(bp); -} diff --git a/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.c b/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.c deleted file mode 100644 index 54266829..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.c +++ /dev/null @@ -1,421 +0,0 @@ -/* bbc_i2c.c: I2C low-level driver for BBC device on UltraSPARC-III - * platforms. - * - * Copyright (C) 2001, 2008 David S. Miller (davem@davemloft.net) - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/sched.h> -#include <linux/wait.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <asm/bbc.h> -#include <asm/io.h> - -#include "bbc_i2c.h" - -/* Convert this driver to use i2c bus layer someday... */ -#define I2C_PCF_PIN 0x80 -#define I2C_PCF_ESO 0x40 -#define I2C_PCF_ES1 0x20 -#define I2C_PCF_ES2 0x10 -#define I2C_PCF_ENI 0x08 -#define I2C_PCF_STA 0x04 -#define I2C_PCF_STO 0x02 -#define I2C_PCF_ACK 0x01 - -#define I2C_PCF_START (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ENI | I2C_PCF_STA | I2C_PCF_ACK) -#define I2C_PCF_STOP (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_STO | I2C_PCF_ACK) -#define I2C_PCF_REPSTART ( I2C_PCF_ESO | I2C_PCF_STA | I2C_PCF_ACK) -#define I2C_PCF_IDLE (I2C_PCF_PIN | I2C_PCF_ESO | I2C_PCF_ACK) - -#define I2C_PCF_INI 0x40 /* 1 if not initialized */ -#define I2C_PCF_STS 0x20 -#define I2C_PCF_BER 0x10 -#define I2C_PCF_AD0 0x08 -#define I2C_PCF_LRB 0x08 -#define I2C_PCF_AAS 0x04 -#define I2C_PCF_LAB 0x02 -#define I2C_PCF_BB 0x01 - -/* The BBC devices have two I2C controllers. The first I2C controller - * connects mainly to configuration proms (NVRAM, cpu configuration, - * dimm types, etc.). Whereas the second I2C controller connects to - * environmental control devices such as fans and temperature sensors. - * The second controller also connects to the smartcard reader, if present. - */ - -static void set_device_claimage(struct bbc_i2c_bus *bp, struct platform_device *op, int val) -{ - int i; - - for (i = 0; i < NUM_CHILDREN; i++) { - if (bp->devs[i].device == op) { - bp->devs[i].client_claimed = val; - return; - } - } -} - -#define claim_device(BP,ECHILD) set_device_claimage(BP,ECHILD,1) -#define release_device(BP,ECHILD) set_device_claimage(BP,ECHILD,0) - -struct platform_device *bbc_i2c_getdev(struct bbc_i2c_bus *bp, int index) -{ - struct platform_device *op = NULL; - int curidx = 0, i; - - for (i = 0; i < NUM_CHILDREN; i++) { - if (!(op = bp->devs[i].device)) - break; - if (curidx == index) - goto out; - op = NULL; - curidx++; - } - -out: - if (curidx == index) - return op; - return NULL; -} - -struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct platform_device *op) -{ - struct bbc_i2c_client *client; - const u32 *reg; - - client = kzalloc(sizeof(*client), GFP_KERNEL); - if (!client) - return NULL; - client->bp = bp; - client->op = op; - - reg = of_get_property(op->dev.of_node, "reg", NULL); - if (!reg) { - kfree(client); - return NULL; - } - - client->bus = reg[0]; - client->address = reg[1]; - - claim_device(bp, op); - - return client; -} - -void bbc_i2c_detach(struct bbc_i2c_client *client) -{ - struct bbc_i2c_bus *bp = client->bp; - struct platform_device *op = client->op; - - release_device(bp, op); - kfree(client); -} - -static int wait_for_pin(struct bbc_i2c_bus *bp, u8 *status) -{ - DECLARE_WAITQUEUE(wait, current); - int limit = 32; - int ret = 1; - - bp->waiting = 1; - add_wait_queue(&bp->wq, &wait); - while (limit-- > 0) { - long val; - - val = wait_event_interruptible_timeout( - bp->wq, - (((*status = readb(bp->i2c_control_regs + 0)) - & I2C_PCF_PIN) == 0), - msecs_to_jiffies(250)); - if (val > 0) { - ret = 0; - break; - } - } - remove_wait_queue(&bp->wq, &wait); - bp->waiting = 0; - - return ret; -} - -int bbc_i2c_writeb(struct bbc_i2c_client *client, unsigned char val, int off) -{ - struct bbc_i2c_bus *bp = client->bp; - int address = client->address; - u8 status; - int ret = -1; - - if (bp->i2c_bussel_reg != NULL) - writeb(client->bus, bp->i2c_bussel_reg); - - writeb(address, bp->i2c_control_regs + 0x1); - writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0); - if (wait_for_pin(bp, &status)) - goto out; - - writeb(off, bp->i2c_control_regs + 0x1); - if (wait_for_pin(bp, &status) || - (status & I2C_PCF_LRB) != 0) - goto out; - - writeb(val, bp->i2c_control_regs + 0x1); - if (wait_for_pin(bp, &status)) - goto out; - - ret = 0; - -out: - writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0); - return ret; -} - -int bbc_i2c_readb(struct bbc_i2c_client *client, unsigned char *byte, int off) -{ - struct bbc_i2c_bus *bp = client->bp; - unsigned char address = client->address, status; - int ret = -1; - - if (bp->i2c_bussel_reg != NULL) - writeb(client->bus, bp->i2c_bussel_reg); - - writeb(address, bp->i2c_control_regs + 0x1); - writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0); - if (wait_for_pin(bp, &status)) - goto out; - - writeb(off, bp->i2c_control_regs + 0x1); - if (wait_for_pin(bp, &status) || - (status & I2C_PCF_LRB) != 0) - goto out; - - writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0); - - address |= 0x1; /* READ */ - - writeb(address, bp->i2c_control_regs + 0x1); - writeb(I2C_PCF_START, bp->i2c_control_regs + 0x0); - if (wait_for_pin(bp, &status)) - goto out; - - /* Set PIN back to one so the device sends the first - * byte. - */ - (void) readb(bp->i2c_control_regs + 0x1); - if (wait_for_pin(bp, &status)) - goto out; - - writeb(I2C_PCF_ESO | I2C_PCF_ENI, bp->i2c_control_regs + 0x0); - *byte = readb(bp->i2c_control_regs + 0x1); - if (wait_for_pin(bp, &status)) - goto out; - - ret = 0; - -out: - writeb(I2C_PCF_STOP, bp->i2c_control_regs + 0x0); - (void) readb(bp->i2c_control_regs + 0x1); - - return ret; -} - -int bbc_i2c_write_buf(struct bbc_i2c_client *client, - char *buf, int len, int off) -{ - int ret = 0; - - while (len > 0) { - ret = bbc_i2c_writeb(client, *buf, off); - if (ret < 0) - break; - len--; - buf++; - off++; - } - return ret; -} - -int bbc_i2c_read_buf(struct bbc_i2c_client *client, - char *buf, int len, int off) -{ - int ret = 0; - - while (len > 0) { - ret = bbc_i2c_readb(client, buf, off); - if (ret < 0) - break; - len--; - buf++; - off++; - } - - return ret; -} - -EXPORT_SYMBOL(bbc_i2c_getdev); -EXPORT_SYMBOL(bbc_i2c_attach); -EXPORT_SYMBOL(bbc_i2c_detach); -EXPORT_SYMBOL(bbc_i2c_writeb); -EXPORT_SYMBOL(bbc_i2c_readb); -EXPORT_SYMBOL(bbc_i2c_write_buf); -EXPORT_SYMBOL(bbc_i2c_read_buf); - -static irqreturn_t bbc_i2c_interrupt(int irq, void *dev_id) -{ - struct bbc_i2c_bus *bp = dev_id; - - /* PIN going from set to clear is the only event which - * makes the i2c assert an interrupt. - */ - if (bp->waiting && - !(readb(bp->i2c_control_regs + 0x0) & I2C_PCF_PIN)) - wake_up_interruptible(&bp->wq); - - return IRQ_HANDLED; -} - -static void __init reset_one_i2c(struct bbc_i2c_bus *bp) -{ - writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0); - writeb(bp->own, bp->i2c_control_regs + 0x1); - writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0); - writeb(bp->clock, bp->i2c_control_regs + 0x1); - writeb(I2C_PCF_IDLE, bp->i2c_control_regs + 0x0); -} - -static struct bbc_i2c_bus * __init attach_one_i2c(struct platform_device *op, int index) -{ - struct bbc_i2c_bus *bp; - struct device_node *dp; - int entry; - - bp = kzalloc(sizeof(*bp), GFP_KERNEL); - if (!bp) - return NULL; - - bp->i2c_control_regs = of_ioremap(&op->resource[0], 0, 0x2, "bbc_i2c_regs"); - if (!bp->i2c_control_regs) - goto fail; - - bp->i2c_bussel_reg = of_ioremap(&op->resource[1], 0, 0x1, "bbc_i2c_bussel"); - if (!bp->i2c_bussel_reg) - goto fail; - - bp->waiting = 0; - init_waitqueue_head(&bp->wq); - if (request_irq(op->archdata.irqs[0], bbc_i2c_interrupt, - IRQF_SHARED, "bbc_i2c", bp)) - goto fail; - - bp->index = index; - bp->op = op; - - spin_lock_init(&bp->lock); - - entry = 0; - for (dp = op->dev.of_node->child; - dp && entry < 8; - dp = dp->sibling, entry++) { - struct platform_device *child_op; - - child_op = of_find_device_by_node(dp); - bp->devs[entry].device = child_op; - bp->devs[entry].client_claimed = 0; - } - - writeb(I2C_PCF_PIN, bp->i2c_control_regs + 0x0); - bp->own = readb(bp->i2c_control_regs + 0x01); - writeb(I2C_PCF_PIN | I2C_PCF_ES1, bp->i2c_control_regs + 0x0); - bp->clock = readb(bp->i2c_control_regs + 0x01); - - printk(KERN_INFO "i2c-%d: Regs at %p, %d devices, own %02x, clock %02x.\n", - bp->index, bp->i2c_control_regs, entry, bp->own, bp->clock); - - reset_one_i2c(bp); - - return bp; - -fail: - if (bp->i2c_bussel_reg) - of_iounmap(&op->resource[1], bp->i2c_bussel_reg, 1); - if (bp->i2c_control_regs) - of_iounmap(&op->resource[0], bp->i2c_control_regs, 2); - kfree(bp); - return NULL; -} - -extern int bbc_envctrl_init(struct bbc_i2c_bus *bp); -extern void bbc_envctrl_cleanup(struct bbc_i2c_bus *bp); - -static int __devinit bbc_i2c_probe(struct platform_device *op) -{ - struct bbc_i2c_bus *bp; - int err, index = 0; - - bp = attach_one_i2c(op, index); - if (!bp) - return -EINVAL; - - err = bbc_envctrl_init(bp); - if (err) { - free_irq(op->archdata.irqs[0], bp); - if (bp->i2c_bussel_reg) - of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1); - if (bp->i2c_control_regs) - of_iounmap(&op->resource[1], bp->i2c_control_regs, 2); - kfree(bp); - } else { - dev_set_drvdata(&op->dev, bp); - } - - return err; -} - -static int __devexit bbc_i2c_remove(struct platform_device *op) -{ - struct bbc_i2c_bus *bp = dev_get_drvdata(&op->dev); - - bbc_envctrl_cleanup(bp); - - free_irq(op->archdata.irqs[0], bp); - - if (bp->i2c_bussel_reg) - of_iounmap(&op->resource[0], bp->i2c_bussel_reg, 1); - if (bp->i2c_control_regs) - of_iounmap(&op->resource[1], bp->i2c_control_regs, 2); - - kfree(bp); - - return 0; -} - -static const struct of_device_id bbc_i2c_match[] = { - { - .name = "i2c", - .compatible = "SUNW,bbc-i2c", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, bbc_i2c_match); - -static struct platform_driver bbc_i2c_driver = { - .driver = { - .name = "bbc_i2c", - .owner = THIS_MODULE, - .of_match_table = bbc_i2c_match, - }, - .probe = bbc_i2c_probe, - .remove = __devexit_p(bbc_i2c_remove), -}; - -module_platform_driver(bbc_i2c_driver); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.h b/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.h deleted file mode 100644 index 4b453106..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/bbc_i2c.h +++ /dev/null @@ -1,85 +0,0 @@ -#ifndef _BBC_I2C_H -#define _BBC_I2C_H - -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/list.h> - -struct bbc_i2c_client { - struct bbc_i2c_bus *bp; - struct platform_device *op; - int bus; - int address; -}; - -enum fan_action { FAN_SLOWER, FAN_SAME, FAN_FASTER, FAN_FULLBLAST, FAN_STATE_MAX }; - -struct bbc_cpu_temperature { - struct list_head bp_list; - struct list_head glob_list; - - struct bbc_i2c_client *client; - int index; - - /* Current readings, and history. */ - s8 curr_cpu_temp; - s8 curr_amb_temp; - s8 prev_cpu_temp; - s8 prev_amb_temp; - s8 avg_cpu_temp; - s8 avg_amb_temp; - - int sample_tick; - - enum fan_action fan_todo[2]; -#define FAN_AMBIENT 0 -#define FAN_CPU 1 -}; - -struct bbc_fan_control { - struct list_head bp_list; - struct list_head glob_list; - - struct bbc_i2c_client *client; - int index; - - int psupply_fan_on; - int cpu_fan_speed; - int system_fan_speed; -}; - -#define NUM_CHILDREN 8 - -struct bbc_i2c_bus { - struct bbc_i2c_bus *next; - int index; - spinlock_t lock; - void __iomem *i2c_bussel_reg; - void __iomem *i2c_control_regs; - unsigned char own, clock; - - wait_queue_head_t wq; - volatile int waiting; - - struct list_head temps; - struct list_head fans; - - struct platform_device *op; - struct { - struct platform_device *device; - int client_claimed; - } devs[NUM_CHILDREN]; -}; - -/* Probing and attachment. */ -extern struct platform_device *bbc_i2c_getdev(struct bbc_i2c_bus *, int); -extern struct bbc_i2c_client *bbc_i2c_attach(struct bbc_i2c_bus *bp, struct platform_device *); -extern void bbc_i2c_detach(struct bbc_i2c_client *); - -/* Register read/write. NOTE: Blocking! */ -extern int bbc_i2c_writeb(struct bbc_i2c_client *, unsigned char val, int off); -extern int bbc_i2c_readb(struct bbc_i2c_client *, unsigned char *byte, int off); -extern int bbc_i2c_write_buf(struct bbc_i2c_client *, char *buf, int len, int off); -extern int bbc_i2c_read_buf(struct bbc_i2c_client *, char *buf, int len, int off); - -#endif /* _BBC_I2C_H */ diff --git a/ANDROID_3.4.5/drivers/sbus/char/display7seg.c b/ANDROID_3.4.5/drivers/sbus/char/display7seg.c deleted file mode 100644 index 4b993972..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/display7seg.c +++ /dev/null @@ -1,278 +0,0 @@ -/* display7seg.c - Driver implementation for the 7-segment display - * present on Sun Microsystems CP1400 and CP1500 - * - * Copyright (c) 2000 Eric Brower (ebrower@usa.net) - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/major.h> -#include <linux/init.h> -#include <linux/miscdevice.h> -#include <linux/ioport.h> /* request_region */ -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/of.h> -#include <linux/of_device.h> -#include <linux/atomic.h> -#include <asm/uaccess.h> /* put_/get_user */ -#include <asm/io.h> - -#include <asm/display7seg.h> - -#define D7S_MINOR 193 -#define DRIVER_NAME "d7s" -#define PFX DRIVER_NAME ": " - -static DEFINE_MUTEX(d7s_mutex); -static int sol_compat = 0; /* Solaris compatibility mode */ - -/* Solaris compatibility flag - - * The Solaris implementation omits support for several - * documented driver features (ref Sun doc 806-0180-03). - * By default, this module supports the documented driver - * abilities, rather than the Solaris implementation: - * - * 1) Device ALWAYS reverts to OBP-specified FLIPPED mode - * upon closure of device or module unload. - * 2) Device ioctls D7SIOCRD/D7SIOCWR honor toggling of - * FLIP bit - * - * If you wish the device to operate as under Solaris, - * omitting above features, set this parameter to non-zero. - */ -module_param(sol_compat, int, 0); -MODULE_PARM_DESC(sol_compat, - "Disables documented functionality omitted from Solaris driver"); - -MODULE_AUTHOR("Eric Brower <ebrower@usa.net>"); -MODULE_DESCRIPTION("7-Segment Display driver for Sun Microsystems CP1400/1500"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("d7s"); - -struct d7s { - void __iomem *regs; - bool flipped; -}; -struct d7s *d7s_device; - -/* - * Register block address- see header for details - * ----------------------------------------- - * | DP | ALARM | FLIP | 4 | 3 | 2 | 1 | 0 | - * ----------------------------------------- - * - * DP - Toggles decimal point on/off - * ALARM - Toggles "Alarm" LED green/red - * FLIP - Inverts display for upside-down mounted board - * bits 0-4 - 7-segment display contents - */ -static atomic_t d7s_users = ATOMIC_INIT(0); - -static int d7s_open(struct inode *inode, struct file *f) -{ - if (D7S_MINOR != iminor(inode)) - return -ENODEV; - atomic_inc(&d7s_users); - return 0; -} - -static int d7s_release(struct inode *inode, struct file *f) -{ - /* Reset flipped state to OBP default only if - * no other users have the device open and we - * are not operating in solaris-compat mode - */ - if (atomic_dec_and_test(&d7s_users) && !sol_compat) { - struct d7s *p = d7s_device; - u8 regval = 0; - - regval = readb(p->regs); - if (p->flipped) - regval |= D7S_FLIP; - else - regval &= ~D7S_FLIP; - writeb(regval, p->regs); - } - - return 0; -} - -static long d7s_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct d7s *p = d7s_device; - u8 regs = readb(p->regs); - int error = 0; - u8 ireg = 0; - - if (D7S_MINOR != iminor(file->f_path.dentry->d_inode)) - return -ENODEV; - - mutex_lock(&d7s_mutex); - switch (cmd) { - case D7SIOCWR: - /* assign device register values we mask-out D7S_FLIP - * if in sol_compat mode - */ - if (get_user(ireg, (int __user *) arg)) { - error = -EFAULT; - break; - } - if (sol_compat) { - if (regs & D7S_FLIP) - ireg |= D7S_FLIP; - else - ireg &= ~D7S_FLIP; - } - writeb(ireg, p->regs); - break; - - case D7SIOCRD: - /* retrieve device register values - * NOTE: Solaris implementation returns D7S_FLIP bit - * as toggled by user, even though it does not honor it. - * This driver will not misinform you about the state - * of your hardware while in sol_compat mode - */ - if (put_user(regs, (int __user *) arg)) { - error = -EFAULT; - break; - } - break; - - case D7SIOCTM: - /* toggle device mode-- flip display orientation */ - if (regs & D7S_FLIP) - regs &= ~D7S_FLIP; - else - regs |= D7S_FLIP; - writeb(regs, p->regs); - break; - }; - mutex_unlock(&d7s_mutex); - - return error; -} - -static const struct file_operations d7s_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = d7s_ioctl, - .compat_ioctl = d7s_ioctl, - .open = d7s_open, - .release = d7s_release, - .llseek = noop_llseek, -}; - -static struct miscdevice d7s_miscdev = { - .minor = D7S_MINOR, - .name = DRIVER_NAME, - .fops = &d7s_fops -}; - -static int __devinit d7s_probe(struct platform_device *op) -{ - struct device_node *opts; - int err = -EINVAL; - struct d7s *p; - u8 regs; - - if (d7s_device) - goto out; - - p = kzalloc(sizeof(*p), GFP_KERNEL); - err = -ENOMEM; - if (!p) - goto out; - - p->regs = of_ioremap(&op->resource[0], 0, sizeof(u8), "d7s"); - if (!p->regs) { - printk(KERN_ERR PFX "Cannot map chip registers\n"); - goto out_free; - } - - err = misc_register(&d7s_miscdev); - if (err) { - printk(KERN_ERR PFX "Unable to acquire miscdevice minor %i\n", - D7S_MINOR); - goto out_iounmap; - } - - /* OBP option "d7s-flipped?" is honored as default for the - * device, and reset default when detached - */ - regs = readb(p->regs); - opts = of_find_node_by_path("/options"); - if (opts && - of_get_property(opts, "d7s-flipped?", NULL)) - p->flipped = true; - - if (p->flipped) - regs |= D7S_FLIP; - else - regs &= ~D7S_FLIP; - - writeb(regs, p->regs); - - printk(KERN_INFO PFX "7-Segment Display%s at [%s:0x%llx] %s\n", - op->dev.of_node->full_name, - (regs & D7S_FLIP) ? " (FLIPPED)" : "", - op->resource[0].start, - sol_compat ? "in sol_compat mode" : ""); - - dev_set_drvdata(&op->dev, p); - d7s_device = p; - err = 0; - -out: - return err; - -out_iounmap: - of_iounmap(&op->resource[0], p->regs, sizeof(u8)); - -out_free: - kfree(p); - goto out; -} - -static int __devexit d7s_remove(struct platform_device *op) -{ - struct d7s *p = dev_get_drvdata(&op->dev); - u8 regs = readb(p->regs); - - /* Honor OBP d7s-flipped? unless operating in solaris-compat mode */ - if (sol_compat) { - if (p->flipped) - regs |= D7S_FLIP; - else - regs &= ~D7S_FLIP; - writeb(regs, p->regs); - } - - misc_deregister(&d7s_miscdev); - of_iounmap(&op->resource[0], p->regs, sizeof(u8)); - kfree(p); - - return 0; -} - -static const struct of_device_id d7s_match[] = { - { - .name = "display7seg", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, d7s_match); - -static struct platform_driver d7s_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = d7s_match, - }, - .probe = d7s_probe, - .remove = __devexit_p(d7s_remove), -}; - -module_platform_driver(d7s_driver); diff --git a/ANDROID_3.4.5/drivers/sbus/char/envctrl.c b/ANDROID_3.4.5/drivers/sbus/char/envctrl.c deleted file mode 100644 index 339fd6f6..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/envctrl.c +++ /dev/null @@ -1,1143 +0,0 @@ -/* 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 - * - * EB - Added support for CP1500 Global Address and PS/Voltage monitoring. - * Eric Brower <ebrower@usa.net> - * - * DB - Audit every copy_to_user in envctrl_read. - * Daniele Bellucci <bellucda@tiscali.it> - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/kthread.h> -#include <linux/delay.h> -#include <linux/ioport.h> -#include <linux/miscdevice.h> -#include <linux/kmod.h> -#include <linux/reboot.h> -#include <linux/slab.h> -#include <linux/of.h> -#include <linux/of_device.h> - -#include <asm/uaccess.h> -#include <asm/envctrl.h> -#include <asm/io.h> - -#define DRIVER_NAME "envctrl" -#define PFX DRIVER_NAME ": " - -#define ENVCTRL_MINOR 162 - -#define PCF8584_ADDRESS 0x55 - -#define CONTROL_PIN 0x80 -#define CONTROL_ES0 0x40 -#define CONTROL_ES1 0x20 -#define CONTROL_ES2 0x10 -#define CONTROL_ENI 0x08 -#define CONTROL_STA 0x04 -#define CONTROL_STO 0x02 -#define CONTROL_ACK 0x01 - -#define STATUS_PIN 0x80 -#define STATUS_STS 0x20 -#define STATUS_BER 0x10 -#define STATUS_LRB 0x08 -#define STATUS_AD0 0x08 -#define STATUS_AAB 0x04 -#define STATUS_LAB 0x02 -#define STATUS_BB 0x01 - -/* - * CLK Mode Register. - */ -#define BUS_CLK_90 0x00 -#define BUS_CLK_45 0x01 -#define BUS_CLK_11 0x02 -#define BUS_CLK_1_5 0x03 - -#define CLK_3 0x00 -#define CLK_4_43 0x10 -#define CLK_6 0x14 -#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 */ - -/* Monitor type of i2c child device. - * Firmware definitions. - */ -#define PCF8584_MAX_CHANNELS 8 -#define PCF8584_GLOBALADDR_TYPE 6 /* global address monitor */ -#define PCF8584_FANSTAT_TYPE 3 /* fan status monitor */ -#define PCF8584_VOLTAGE_TYPE 2 /* voltage monitor */ -#define PCF8584_TEMP_TYPE 1 /* temperature monitor*/ - -/* Monitor type of i2c child device. - * Driver definitions. - */ -#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 temperature */ - /* monitor */ -#define ENVCTRL_VOLTAGESTAT_MON 5 /* voltage status monitor */ -#define ENVCTRL_MTHRBDTEMP_MON 6 /* motherboard temperature */ -#define ENVCTRL_SCSITEMP_MON 7 /* scsi temperature */ -#define ENVCTRL_GLOBALADDR_MON 8 /* global address */ - -/* Child device type. - * Driver definitions. - */ -#define I2C_ADC 0 /* pcf8591 */ -#define I2C_GPIO 1 /* pcf8571 */ - -/* 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 - -/* Mask values for combined GlobalAddress/PowerStatus node */ -#define ENVCTRL_GLOBALADDR_ADDR_MASK 0x1F -#define ENVCTRL_GLOBALADDR_PSTAT_MASK 0x60 - -/* Node 0x70 ignored on CompactPCI CP1400/1500 platforms - * (see envctrl_init_i2c_child) - */ -#define ENVCTRL_CPCI_IGNORED_NODE 0x70 - -#define PCF8584_DATA 0x00 -#define PCF8584_CSR 0x01 - -/* 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; -}; - -/* 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; -}; - -/* 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]; -}; - -static void __iomem *i2c; -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; - -/* Forward declarations. */ -static struct i2c_child_t *envctrl_get_i2c_child(unsigned char); - -/* 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) -{ - int limit = 1000000; - - while (--limit > 0) { - if (!(readb(i2c + PCF8584_CSR) & STATUS_PIN)) - break; - udelay(1); - } - - if (limit <= 0) - printk(KERN_INFO PFX "Pin status will not clear.\n"); -} - -/* Function Description: Test busy bit. - * Return : None. - */ -static void envctrl_i2c_test_bb(void) -{ - int limit = 1000000; - - while (--limit > 0) { - /* Busy bit 0 means busy. */ - if (readb(i2c + PCF8584_CSR) & STATUS_BB) - break; - udelay(1); - } - - if (limit <= 0) - printk(KERN_INFO PFX "Busy bit will not clear.\n"); -} - -/* Function Description: Send the address for a read access. - * Return : 0 if not acknowledged, otherwise acknowledged. - */ -static int envctrl_i2c_read_addr(unsigned char addr) -{ - envctrl_i2c_test_bb(); - - /* Load address. */ - writeb(addr + 1, i2c + PCF8584_DATA); - - envctrl_i2c_test_bb(); - - writeb(OBD_SEND_START, i2c + PCF8584_CSR); - - /* Wait for PIN. */ - envtrl_i2c_test_pin(); - - /* CSR 0 means acknowledged. */ - if (!(readb(i2c + PCF8584_CSR) & STATUS_LRB)) { - return readb(i2c + PCF8584_DATA); - } else { - writeb(OBD_SEND_STOP, i2c + PCF8584_CSR); - return 0; - } -} - -/* Function Description: Send the address for write mode. - * Return : None. - */ -static void envctrl_i2c_write_addr(unsigned char addr) -{ - envctrl_i2c_test_bb(); - writeb(addr, i2c + PCF8584_DATA); - - /* Generate Start condition. */ - writeb(OBD_SEND_START, i2c + PCF8584_CSR); -} - -/* 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) -{ - envtrl_i2c_test_pin(); - writeb(CONTROL_ES0, i2c + PCF8584_CSR); /* Send neg ack. */ - return readb(i2c + PCF8584_DATA); -} - -/* Function Description: Instruct the device which port to read data from. - * Return : None. - */ -static void envctrl_i2c_write_data(unsigned char port) -{ - envtrl_i2c_test_pin(); - writeb(port, i2c + PCF8584_DATA); -} - -/* Function Description: Generate Stop condition after last byte is sent. - * Return : None. - */ -static void envctrl_i2c_stop(void) -{ - envtrl_i2c_test_pin(); - writeb(OBD_SEND_STOP, i2c + PCF8584_CSR); -} - -/* Function Description: Read adc device. - * Return : Data at address and port. - */ -static unsigned char envctrl_i2c_read_8591(unsigned char addr, unsigned char port) -{ - /* Send address. */ - envctrl_i2c_write_addr(addr); - - /* Setup port to read. */ - envctrl_i2c_write_data(port); - envctrl_i2c_stop(); - - /* Read port. */ - envctrl_i2c_read_addr(addr); - - /* Do a single byte read and send stop. */ - envctrl_i2c_read_data(); - envctrl_i2c_stop(); - - return readb(i2c + PCF8584_DATA); -} - -/* Function Description: Read gpio device. - * Return : Data at address. - */ -static unsigned char envctrl_i2c_read_8574(unsigned char addr) -{ - unsigned char rd; - - envctrl_i2c_read_addr(addr); - - /* Do a single byte read and send stop. */ - rd = envctrl_i2c_read_data(); - envctrl_i2c_stop(); - return rd; -} - -/* 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) -{ - int len = 0; - - switch (translate_type) { - case ENVCTRL_TRANSLATE_NO: - /* No decode necessary. */ - len = 1; - bufdata[0] = data; - break; - - case ENVCTRL_TRANSLATE_FULL: - /* Decode this way: data = table[data]. */ - len = 1; - bufdata[0] = tbl[data]; - break; - - 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; - - default: - break; - }; - - return len; -} - -/* 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(int cpu, struct i2c_child_t *pchild, - char mon_type, unsigned char *bufdata) -{ - unsigned char data; - int i; - char *tbl, j = -1; - - /* Find the right monitor type and channel. */ - for (i = 0; i < PCF8584_MAX_CHANNELS; i++) { - if (pchild->mon_type[i] == mon_type) { - if (++j == cpu) { - break; - } - } - } - - if (j != cpu) - return 0; - - /* Read data from address and port. */ - data = envctrl_i2c_read_8591((unsigned char)pchild->addr, - (unsigned char)pchild->chnl_array[i].chnl_no); - - /* Find decoding table. */ - tbl = pchild->tables + pchild->tblprop_array[i].offset; - - return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type, - pchild->tblprop_array[i].scale, - tbl, bufdata); -} - -/* 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 data; - int i; - char *tbl = NULL; - - for (i = 0; i < PCF8584_MAX_CHANNELS; i++) { - if (pchild->mon_type[i] == mon_type) - break; - } - - if (i >= PCF8584_MAX_CHANNELS) - return 0; - - /* Read data from address and port. */ - data = envctrl_i2c_read_8591((unsigned char)pchild->addr, - (unsigned char)pchild->chnl_array[i].chnl_no); - - /* Find decoding table. */ - tbl = pchild->tables + pchild->tblprop_array[i].offset; - - return envctrl_i2c_data_translate(data, pchild->tblprop_array[i].type, - pchild->tblprop_array[i].scale, - tbl, bufdata); -} - -/* 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) -{ - unsigned char tmp, ret = 0; - int i, j = 0; - - tmp = data & pchild->fan_mask; - - 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]; - - j++; - } - } - } - - bufdata[0] = ret; - return 1; -} - -/* Function Description: Read global addressing line. - * Return : Always 1 byte. Status stored in bufdata. - */ -static int envctrl_i2c_globaladdr(struct i2c_child_t *pchild, - unsigned char data, - char *bufdata) -{ - /* Translatation table is not necessary, as global - * addr is the integer value of the GA# bits. - * - * NOTE: MSB is documented as zero, but I see it as '1' always.... - * - * ----------------------------------------------- - * | 0 | FAL | DEG | GA4 | GA3 | GA2 | GA1 | GA0 | - * ----------------------------------------------- - * GA0 - GA4 integer value of Global Address (backplane slot#) - * DEG 0 = cPCI Power supply output is starting to degrade - * 1 = cPCI Power supply output is OK - * FAL 0 = cPCI Power supply has failed - * 1 = cPCI Power supply output is OK - */ - bufdata[0] = (data & ENVCTRL_GLOBALADDR_ADDR_MASK); - return 1; -} - -/* Function Description: Read standard 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; - } - } - - /* 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; - } - - bufdata[0] = ret; - return 1; -} - -/* 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 __user *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; - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - case ENVCTRL_RD_SHUTDOWN_TEMPERATURE: - if (shutdown_temperature == 0) - return 0; - - data[0] = (unsigned char)(shutdown_temperature); - ret = 1; - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - 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); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - case ENVCTRL_RD_CPU_TEMPERATURE: - if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) - return 0; - ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUTEMP_MON, data); - - /* Reset cpu to the default cpu0. */ - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - case ENVCTRL_RD_CPU_VOLTAGE: - if (!(pchild = envctrl_get_i2c_child(ENVCTRL_CPUVOLTAGE_MON))) - return 0; - ret = envctrl_read_cpu_info(read_cpu, pchild, ENVCTRL_CPUVOLTAGE_MON, data); - - /* Reset cpu to the default cpu0. */ - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - 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); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - 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); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - 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); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - case ENVCTRL_RD_GLOBALADDRESS: - if (!(pchild = envctrl_get_i2c_child(ENVCTRL_GLOBALADDR_MON))) - return 0; - data[0] = envctrl_i2c_read_8574(pchild->addr); - ret = envctrl_i2c_globaladdr(pchild, data[0], data); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - case ENVCTRL_RD_VOLTAGE_STATUS: - if (!(pchild = envctrl_get_i2c_child(ENVCTRL_VOLTAGESTAT_MON))) - /* If voltage monitor not present, check for CPCI equivalent */ - if (!(pchild = envctrl_get_i2c_child(ENVCTRL_GLOBALADDR_MON))) - return 0; - data[0] = envctrl_i2c_read_8574(pchild->addr); - ret = envctrl_i2c_voltage_status(pchild, data[0], data); - if (copy_to_user(buf, data, ret)) - ret = -EFAULT; - break; - - default: - break; - - }; - - return ret; -} - -/* Function Description: Command what to read. Mapped to user ioctl(). - * Return: Gives 0 for implemented commands, -EINVAL otherwise. - */ -static long -envctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - char __user *infobuf; - - 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: - case ENVCTRL_RD_GLOBALADDRESS: - 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 __user *) arg; - if (infobuf == NULL) { - read_cpu = 0; - }else { - get_user(read_cpu, infobuf); - } - - /* Save the command for use when reading. */ - file->private_data = (void *)(long)cmd; - break; - - default: - return -EINVAL; - }; - - return 0; -} - -/* Function Description: open device. Mapped to user open(). - * Return: Always 0. - */ -static int -envctrl_open(struct inode *inode, struct file *file) -{ - file->private_data = NULL; - return 0; -} - -/* Function Description: Open device. Mapped to user close(). - * Return: Always 0. - */ -static int -envctrl_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static const struct file_operations envctrl_fops = { - .owner = THIS_MODULE, - .read = envctrl_read, - .unlocked_ioctl = envctrl_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = envctrl_ioctl, -#endif - .open = envctrl_open, - .release = envctrl_release, - .llseek = noop_llseek, -}; - -static struct miscdevice envctrl_dev = { - ENVCTRL_MINOR, - "envctrl", - &envctrl_fops -}; - -/* Function Description: Set monitor type based on firmware description. - * Return: None. - */ -static void envctrl_set_mon(struct i2c_child_t *pchild, - const 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; -} - -/* 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, struct device_node *dp) -{ - int i = 0, len; - const char *pos; - const unsigned int *pval; - - /* Firmware describe channels into a stream separated by a '\0'. */ - pos = of_get_property(dp, "channels-description", &len); - - while (len > 0) { - int l = strlen(pos) + 1; - envctrl_set_mon(pchild, pos, i++); - len -= l; - pos += l; - } - - /* Get optional properties. */ - pval = of_get_property(dp, "warning-temp", NULL); - if (pval) - warning_temperature = *pval; - - pval = of_get_property(dp, "shutdown-temp", NULL); - if (pval) - shutdown_temperature = *pval; -} - -/* Function Description: Initialize child device monitoring fan status. - * Return: None. - */ -static void envctrl_init_fanstat(struct i2c_child_t *pchild) -{ - int i; - - /* 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]; - - /* We only need to know if this child has fan status monitored. - * We don't care which channels since we have the mask already. - */ - pchild->mon_type[0] = ENVCTRL_FANSTAT_MON; -} - -/* Function Description: Initialize child device for global addressing line. - * Return: None. - */ -static void envctrl_init_globaladdr(struct i2c_child_t *pchild) -{ - int i; - - /* Voltage/PowerSupply monitoring is piggybacked - * with Global Address on CompactPCI. See comments - * within envctrl_i2c_globaladdr for bit assignments. - * - * The mask is created here by assigning mask bits to each - * bit position that represents PCF8584_VOLTAGE_TYPE data. - * Channel numbers are not consecutive within the globaladdr - * node (why?), so we use the actual counter value as chnls_mask - * index instead of the chnl_array[x].chnl_no value. - * - * NOTE: This loop could be replaced with a constant representing - * a mask of bits 5&6 (ENVCTRL_GLOBALADDR_PSTAT_MASK). - */ - for (i = 0; i < pchild->total_chnls; i++) { - if (PCF8584_VOLTAGE_TYPE == pchild->chnl_array[i].type) { - pchild->voltage_mask |= chnls_mask[i]; - } - } - - /* We only need to know if this child has global addressing - * line monitored. We don't care which channels since we know - * the mask already (ENVCTRL_GLOBALADDR_ADDR_MASK). - */ - pchild->mon_type[0] = ENVCTRL_GLOBALADDR_MON; -} - -/* Initialize child device monitoring voltage status. */ -static void envctrl_init_voltage_status(struct i2c_child_t *pchild) -{ - int i; - - /* 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]; - - /* We only need to know if this child has voltage status monitored. - * We don't care which channels since we have the mask already. - */ - pchild->mon_type[0] = ENVCTRL_VOLTAGESTAT_MON; -} - -/* Function Description: Initialize i2c child device. - * Return: None. - */ -static void envctrl_init_i2c_child(struct device_node *dp, - struct i2c_child_t *pchild) -{ - int len, i, tbls_size = 0; - const void *pval; - - /* Get device address. */ - pval = of_get_property(dp, "reg", &len); - memcpy(&pchild->addr, pval, len); - - /* Get tables property. Read firmware temperature tables. */ - pval = of_get_property(dp, "translation", &len); - if (pval && len > 0) { - memcpy(pchild->tblprop_array, pval, len); - 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; - } - } - - pchild->tables = kmalloc(tbls_size, GFP_KERNEL); - if (pchild->tables == NULL){ - printk(KERN_ERR PFX "Failed to allocate table.\n"); - return; - } - pval = of_get_property(dp, "tables", &len); - if (!pval || len <= 0) { - printk(KERN_ERR PFX "Failed to get table.\n"); - return; - } - memcpy(pchild->tables, pval, len); - } - - /* SPARCengine ASM Reference Manual (ref. SMI doc 805-7581-04) - * sections 2.5, 3.5, 4.5 state node 0x70 for CP1400/1500 is - * "For Factory Use Only." - * - * We ignore the node on these platforms by assigning the - * 'NULL' monitor type. - */ - if (ENVCTRL_CPCI_IGNORED_NODE == pchild->addr) { - struct device_node *root_node; - int len; - - root_node = of_find_node_by_path("/"); - if (!strcmp(root_node->name, "SUNW,UltraSPARC-IIi-cEngine")) { - for (len = 0; len < PCF8584_MAX_CHANNELS; ++len) { - pchild->mon_type[len] = ENVCTRL_NOMON; - } - return; - } - } - - /* Get the monitor channels. */ - pval = of_get_property(dp, "channels-in-use", &len); - memcpy(pchild->chnl_array, pval, len); - pchild->total_chnls = len / sizeof(struct pcf8584_channel); - - for (i = 0; i < pchild->total_chnls; i++) { - switch (pchild->chnl_array[i].type) { - case PCF8584_TEMP_TYPE: - envctrl_init_adc(pchild, dp); - break; - - case PCF8584_GLOBALADDR_TYPE: - envctrl_init_globaladdr(pchild); - i = pchild->total_chnls; - break; - - case PCF8584_FANSTAT_TYPE: - envctrl_init_fanstat(pchild); - i = pchild->total_chnls; - break; - - case PCF8584_VOLTAGE_TYPE: - if (pchild->i2ctype == I2C_ADC) { - envctrl_init_adc(pchild,dp); - } else { - envctrl_init_voltage_status(pchild); - } - i = pchild->total_chnls; - break; - - default: - break; - }; - } -} - -/* 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) -{ - int i, j; - - 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 NULL; -} - -static void envctrl_do_shutdown(void) -{ - static int inprog = 0; - int ret; - - if (inprog != 0) - return; - - inprog = 1; - printk(KERN_CRIT "kenvctrld: WARNING: Shutting down the system now.\n"); - ret = orderly_poweroff(true); - if (ret < 0) { - printk(KERN_CRIT "kenvctrld: WARNING: system shutdown failed!\n"); - inprog = 0; /* unlikely to succeed, but we could try again */ - } -} - -static struct task_struct *kenvctrld_task; - -static int kenvctrld(void *__unused) -{ - int poll_interval; - int whichcpu; - char tempbuf[10]; - struct i2c_child_t *cputemp; - - if (NULL == (cputemp = envctrl_get_i2c_child(ENVCTRL_CPUTEMP_MON))) { - printk(KERN_ERR PFX - "kenvctrld unable to monitor CPU temp-- exiting\n"); - return -ENODEV; - } - - poll_interval = 5000; /* TODO env_mon_interval */ - - printk(KERN_INFO PFX "%s starting...\n", current->comm); - for (;;) { - msleep_interruptible(poll_interval); - - if (kthread_should_stop()) - break; - - for (whichcpu = 0; whichcpu < ENVCTRL_MAX_CPU; ++whichcpu) { - if (0 < envctrl_read_cpu_info(whichcpu, cputemp, - ENVCTRL_CPUTEMP_MON, - tempbuf)) { - if (tempbuf[0] >= shutdown_temperature) { - printk(KERN_CRIT - "%s: WARNING: CPU%i temperature %i C meets or exceeds "\ - "shutdown threshold %i C\n", - current->comm, whichcpu, - tempbuf[0], shutdown_temperature); - envctrl_do_shutdown(); - } - } - } - } - printk(KERN_INFO PFX "%s exiting...\n", current->comm); - return 0; -} - -static int __devinit envctrl_probe(struct platform_device *op) -{ - struct device_node *dp; - int index, err; - - if (i2c) - return -EINVAL; - - i2c = of_ioremap(&op->resource[0], 0, 0x2, DRIVER_NAME); - if (!i2c) - return -ENOMEM; - - index = 0; - dp = op->dev.of_node->child; - while (dp) { - if (!strcmp(dp->name, "gpio")) { - i2c_childlist[index].i2ctype = I2C_GPIO; - envctrl_init_i2c_child(dp, &(i2c_childlist[index++])); - } else if (!strcmp(dp->name, "adc")) { - i2c_childlist[index].i2ctype = I2C_ADC; - envctrl_init_i2c_child(dp, &(i2c_childlist[index++])); - } - - dp = dp->sibling; - } - - /* Set device address. */ - writeb(CONTROL_PIN, i2c + PCF8584_CSR); - writeb(PCF8584_ADDRESS, i2c + PCF8584_DATA); - - /* Set system clock and SCL frequencies. */ - writeb(CONTROL_PIN | CONTROL_ES1, i2c + PCF8584_CSR); - writeb(CLK_4_43 | BUS_CLK_90, i2c + PCF8584_DATA); - - /* Enable serial interface. */ - writeb(CONTROL_PIN | CONTROL_ES0 | CONTROL_ACK, i2c + PCF8584_CSR); - udelay(200); - - /* Register the device as a minor miscellaneous device. */ - err = misc_register(&envctrl_dev); - if (err) { - printk(KERN_ERR PFX "Unable to get misc minor %d\n", - envctrl_dev.minor); - goto out_iounmap; - } - - /* Note above traversal routine post-incremented 'i' to accommodate - * a next child device, so we decrement before reverse-traversal of - * child devices. - */ - printk(KERN_INFO PFX "Initialized "); - for (--index; index >= 0; --index) { - printk("[%s 0x%lx]%s", - (I2C_ADC == i2c_childlist[index].i2ctype) ? "adc" : - ((I2C_GPIO == i2c_childlist[index].i2ctype) ? "gpio" : "unknown"), - i2c_childlist[index].addr, (0 == index) ? "\n" : " "); - } - - kenvctrld_task = kthread_run(kenvctrld, NULL, "kenvctrld"); - if (IS_ERR(kenvctrld_task)) { - err = PTR_ERR(kenvctrld_task); - goto out_deregister; - } - - return 0; - -out_deregister: - misc_deregister(&envctrl_dev); -out_iounmap: - of_iounmap(&op->resource[0], i2c, 0x2); - for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++) - kfree(i2c_childlist[index].tables); - - return err; -} - -static int __devexit envctrl_remove(struct platform_device *op) -{ - int index; - - kthread_stop(kenvctrld_task); - - of_iounmap(&op->resource[0], i2c, 0x2); - misc_deregister(&envctrl_dev); - - for (index = 0; index < ENVCTRL_MAX_CPU * 2; index++) - kfree(i2c_childlist[index].tables); - - return 0; -} - -static const struct of_device_id envctrl_match[] = { - { - .name = "i2c", - .compatible = "i2cpcf,8584", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, envctrl_match); - -static struct platform_driver envctrl_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = envctrl_match, - }, - .probe = envctrl_probe, - .remove = __devexit_p(envctrl_remove), -}; - -module_platform_driver(envctrl_driver); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/sbus/char/flash.c b/ANDROID_3.4.5/drivers/sbus/char/flash.c deleted file mode 100644 index 327657e2..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/flash.c +++ /dev/null @@ -1,220 +0,0 @@ -/* flash.c: Allow mmap access to the OBP Flash, for OBP updates. - * - * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) - */ - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/miscdevice.h> -#include <linux/fcntl.h> -#include <linux/poll.h> -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/spinlock.h> -#include <linux/mm.h> -#include <linux/of.h> -#include <linux/of_device.h> - -#include <asm/uaccess.h> -#include <asm/pgtable.h> -#include <asm/io.h> -#include <asm/upa.h> - -static DEFINE_MUTEX(flash_mutex); -static DEFINE_SPINLOCK(flash_lock); -static struct { - unsigned long read_base; /* Physical read address */ - unsigned long write_base; /* Physical write address */ - unsigned long read_size; /* Size of read area */ - unsigned long write_size; /* Size of write area */ - unsigned long busy; /* In use? */ -} flash; - -#define FLASH_MINOR 152 - -static int -flash_mmap(struct file *file, struct vm_area_struct *vma) -{ - unsigned long addr; - unsigned long size; - - spin_lock(&flash_lock); - if (flash.read_base == flash.write_base) { - addr = flash.read_base; - size = flash.read_size; - } else { - if ((vma->vm_flags & VM_READ) && - (vma->vm_flags & VM_WRITE)) { - spin_unlock(&flash_lock); - return -EINVAL; - } - if (vma->vm_flags & VM_READ) { - addr = flash.read_base; - size = flash.read_size; - } else if (vma->vm_flags & VM_WRITE) { - addr = flash.write_base; - size = flash.write_size; - } else { - spin_unlock(&flash_lock); - return -ENXIO; - } - } - spin_unlock(&flash_lock); - - if ((vma->vm_pgoff << PAGE_SHIFT) > size) - return -ENXIO; - addr = vma->vm_pgoff + (addr >> PAGE_SHIFT); - - if (vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)) > size) - size = vma->vm_end - (vma->vm_start + (vma->vm_pgoff << PAGE_SHIFT)); - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - - if (io_remap_pfn_range(vma, vma->vm_start, addr, size, vma->vm_page_prot)) - return -EAGAIN; - - return 0; -} - -static long long -flash_llseek(struct file *file, long long offset, int origin) -{ - mutex_lock(&flash_mutex); - switch (origin) { - case 0: - file->f_pos = offset; - break; - case 1: - file->f_pos += offset; - if (file->f_pos > flash.read_size) - file->f_pos = flash.read_size; - break; - case 2: - file->f_pos = flash.read_size; - break; - default: - mutex_unlock(&flash_mutex); - return -EINVAL; - } - mutex_unlock(&flash_mutex); - return file->f_pos; -} - -static ssize_t -flash_read(struct file * file, char __user * buf, - size_t count, loff_t *ppos) -{ - loff_t p = *ppos; - int i; - - if (count > flash.read_size - p) - count = flash.read_size - p; - - for (i = 0; i < count; i++) { - u8 data = upa_readb(flash.read_base + p + i); - if (put_user(data, buf)) - return -EFAULT; - buf++; - } - - *ppos += count; - return count; -} - -static int -flash_open(struct inode *inode, struct file *file) -{ - mutex_lock(&flash_mutex); - if (test_and_set_bit(0, (void *)&flash.busy) != 0) { - mutex_unlock(&flash_mutex); - return -EBUSY; - } - - mutex_unlock(&flash_mutex); - return 0; -} - -static int -flash_release(struct inode *inode, struct file *file) -{ - spin_lock(&flash_lock); - flash.busy = 0; - spin_unlock(&flash_lock); - - return 0; -} - -static const struct file_operations flash_fops = { - /* no write to the Flash, use mmap - * and play flash dependent tricks. - */ - .owner = THIS_MODULE, - .llseek = flash_llseek, - .read = flash_read, - .mmap = flash_mmap, - .open = flash_open, - .release = flash_release, -}; - -static struct miscdevice flash_dev = { FLASH_MINOR, "flash", &flash_fops }; - -static int __devinit flash_probe(struct platform_device *op) -{ - struct device_node *dp = op->dev.of_node; - struct device_node *parent; - - parent = dp->parent; - - if (strcmp(parent->name, "sbus") && - strcmp(parent->name, "sbi") && - strcmp(parent->name, "ebus")) - return -ENODEV; - - flash.read_base = op->resource[0].start; - flash.read_size = resource_size(&op->resource[0]); - if (op->resource[1].flags) { - flash.write_base = op->resource[1].start; - flash.write_size = resource_size(&op->resource[1]); - } else { - flash.write_base = op->resource[0].start; - flash.write_size = resource_size(&op->resource[0]); - } - flash.busy = 0; - - printk(KERN_INFO "%s: OBP Flash, RD %lx[%lx] WR %lx[%lx]\n", - op->dev.of_node->full_name, - flash.read_base, flash.read_size, - flash.write_base, flash.write_size); - - return misc_register(&flash_dev); -} - -static int __devexit flash_remove(struct platform_device *op) -{ - misc_deregister(&flash_dev); - - return 0; -} - -static const struct of_device_id flash_match[] = { - { - .name = "flashprom", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, flash_match); - -static struct platform_driver flash_driver = { - .driver = { - .name = "flash", - .owner = THIS_MODULE, - .of_match_table = flash_match, - }, - .probe = flash_probe, - .remove = __devexit_p(flash_remove), -}; - -module_platform_driver(flash_driver); - -MODULE_LICENSE("GPL"); diff --git a/ANDROID_3.4.5/drivers/sbus/char/jsflash.c b/ANDROID_3.4.5/drivers/sbus/char/jsflash.c deleted file mode 100644 index 6b4678a7..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/jsflash.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * drivers/sbus/char/jsflash.c - * - * Copyright (C) 1991, 1992 Linus Torvalds (drivers/char/mem.c) - * Copyright (C) 1997 Eddie C. Dost (drivers/sbus/char/flash.c) - * Copyright (C) 1997-2000 Pavel Machek <pavel@ucw.cz> (drivers/block/nbd.c) - * Copyright (C) 1999-2000 Pete Zaitcev - * - * This driver is used to program OS into a Flash SIMM on - * Krups and Espresso platforms. - * - * TODO: do not allow erase/programming if file systems are mounted. - * TODO: Erase/program both banks of a 8MB SIMM. - * - * It is anticipated that programming an OS Flash will be a routine - * procedure. In the same time it is exceedingly dangerous because - * a user can program its OBP flash with OS image and effectively - * kill the machine. - * - * This driver uses an interface different from Eddie's flash.c - * as a silly safeguard. - * - * XXX The flash.c manipulates page caching characteristics in a certain - * dubious way; also it assumes that remap_pfn_range() can remap - * PCI bus locations, which may be false. ioremap() must be used - * instead. We should discuss this. - */ - -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/miscdevice.h> -#include <linux/fcntl.h> -#include <linux/poll.h> -#include <linux/init.h> -#include <linux/string.h> -#include <linux/genhd.h> -#include <linux/blkdev.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> -#include <asm/io.h> -#include <asm/pcic.h> -#include <asm/oplib.h> - -#include <asm/jsflash.h> /* ioctl arguments. <linux/> ?? */ -#define JSFIDSZ (sizeof(struct jsflash_ident_arg)) -#define JSFPRGSZ (sizeof(struct jsflash_program_arg)) - -/* - * Our device numbers have no business in system headers. - * The only thing a user knows is the device name /dev/jsflash. - * - * Block devices are laid out like this: - * minor+0 - Bootstrap, for 8MB SIMM 0x20400000[0x800000] - * minor+1 - Filesystem to mount, normally 0x20400400[0x7ffc00] - * minor+2 - Whole flash area for any case... 0x20000000[0x01000000] - * Total 3 minors per flash device. - * - * It is easier to have static size vectors, so we define - * a total minor range JSF_MAX, which must cover all minors. - */ -/* character device */ -#define JSF_MINOR 178 /* 178 is registered with hpa */ -/* block device */ -#define JSF_MAX 3 /* 3 minors wasted total so far. */ -#define JSF_NPART 3 /* 3 minors per flash device */ -#define JSF_PART_BITS 2 /* 2 bits of minors to cover JSF_NPART */ -#define JSF_PART_MASK 0x3 /* 2 bits mask */ - -static DEFINE_MUTEX(jsf_mutex); - -/* - * Access functions. - * We could ioremap(), but it's easier this way. - */ -static unsigned int jsf_inl(unsigned long addr) -{ - unsigned long retval; - - __asm__ __volatile__("lda [%1] %2, %0\n\t" : - "=r" (retval) : - "r" (addr), "i" (ASI_M_BYPASS)); - return retval; -} - -static void jsf_outl(unsigned long addr, __u32 data) -{ - - __asm__ __volatile__("sta %0, [%1] %2\n\t" : : - "r" (data), "r" (addr), "i" (ASI_M_BYPASS) : - "memory"); -} - -/* - * soft carrier - */ - -struct jsfd_part { - unsigned long dbase; - unsigned long dsize; -}; - -struct jsflash { - unsigned long base; - unsigned long size; - unsigned long busy; /* In use? */ - struct jsflash_ident_arg id; - /* int mbase; */ /* Minor base, typically zero */ - struct jsfd_part dv[JSF_NPART]; -}; - -/* - * We do not map normal memory or obio as a safety precaution. - * But offsets are real, for ease of userland programming. - */ -#define JSF_BASE_TOP 0x30000000 -#define JSF_BASE_ALL 0x20000000 - -#define JSF_BASE_JK 0x20400000 - -/* - */ -static struct gendisk *jsfd_disk[JSF_MAX]; - -/* - * Let's pretend we may have several of these... - */ -static struct jsflash jsf0; - -/* - * Wait for AMD to finish its embedded algorithm. - * We use the Toggle bit DQ6 (0x40) because it does not - * depend on the data value as /DATA bit DQ7 does. - * - * XXX Do we need any timeout here? So far it never hanged, beware broken hw. - */ -static void jsf_wait(unsigned long p) { - unsigned int x1, x2; - - for (;;) { - x1 = jsf_inl(p); - x2 = jsf_inl(p); - if ((x1 & 0x40404040) == (x2 & 0x40404040)) return; - } -} - -/* - * Programming will only work if Flash is clean, - * we leave it to the programmer application. - * - * AMD must be programmed one byte at a time; - * thus, Simple Tech SIMM must be written 4 bytes at a time. - * - * Write waits for the chip to become ready after the write - * was finished. This is done so that application would read - * consistent data after the write is done. - */ -static void jsf_write4(unsigned long fa, u32 data) { - - jsf_outl(fa, 0xAAAAAAAA); /* Unlock 1 Write 1 */ - jsf_outl(fa, 0x55555555); /* Unlock 1 Write 2 */ - jsf_outl(fa, 0xA0A0A0A0); /* Byte Program */ - jsf_outl(fa, data); - - jsf_wait(fa); -} - -/* - */ -static void jsfd_read(char *buf, unsigned long p, size_t togo) { - union byte4 { - char s[4]; - unsigned int n; - } b; - - while (togo >= 4) { - togo -= 4; - b.n = jsf_inl(p); - memcpy(buf, b.s, 4); - p += 4; - buf += 4; - } -} - -static void jsfd_do_request(struct request_queue *q) -{ - struct request *req; - - req = blk_fetch_request(q); - while (req) { - struct jsfd_part *jdp = req->rq_disk->private_data; - unsigned long offset = blk_rq_pos(req) << 9; - size_t len = blk_rq_cur_bytes(req); - int err = -EIO; - - if ((offset + len) > jdp->dsize) - goto end; - - if (rq_data_dir(req) != READ) { - printk(KERN_ERR "jsfd: write\n"); - goto end; - } - - if ((jdp->dbase & 0xff000000) != 0x20000000) { - printk(KERN_ERR "jsfd: bad base %x\n", (int)jdp->dbase); - goto end; - } - - jsfd_read(req->buffer, jdp->dbase + offset, len); - err = 0; - end: - if (!__blk_end_request_cur(req, err)) - req = blk_fetch_request(q); - } -} - -/* - * The memory devices use the full 32/64 bits of the offset, and so we cannot - * check against negative addresses: they are ok. The return value is weird, - * though, in that case (0). - * - * also note that seeking relative to the "end of file" isn't supported: - * it has no meaning, so it returns -EINVAL. - */ -static loff_t jsf_lseek(struct file * file, loff_t offset, int orig) -{ - loff_t ret; - - mutex_lock(&jsf_mutex); - switch (orig) { - case 0: - file->f_pos = offset; - ret = file->f_pos; - break; - case 1: - file->f_pos += offset; - ret = file->f_pos; - break; - default: - ret = -EINVAL; - } - mutex_unlock(&jsf_mutex); - return ret; -} - -/* - * OS SIMM Cannot be read in other size but a 32bits word. - */ -static ssize_t jsf_read(struct file * file, char __user * buf, - size_t togo, loff_t *ppos) -{ - unsigned long p = *ppos; - char __user *tmp = buf; - - union byte4 { - char s[4]; - unsigned int n; - } b; - - if (p < JSF_BASE_ALL || p >= JSF_BASE_TOP) { - return 0; - } - - if ((p + togo) < p /* wrap */ - || (p + togo) >= JSF_BASE_TOP) { - togo = JSF_BASE_TOP - p; - } - - if (p < JSF_BASE_ALL && togo != 0) { -#if 0 /* __bzero XXX */ - size_t x = JSF_BASE_ALL - p; - if (x > togo) x = togo; - clear_user(tmp, x); - tmp += x; - p += x; - togo -= x; -#else - /* - * Implementation of clear_user() calls __bzero - * without regard to modversions, - * so we cannot build a module. - */ - return 0; -#endif - } - - while (togo >= 4) { - togo -= 4; - b.n = jsf_inl(p); - if (copy_to_user(tmp, b.s, 4)) - return -EFAULT; - tmp += 4; - p += 4; - } - - /* - * XXX Small togo may remain if 1 byte is ordered. - * It would be nice if we did a word size read and unpacked it. - */ - - *ppos = p; - return tmp-buf; -} - -static ssize_t jsf_write(struct file * file, const char __user * buf, - size_t count, loff_t *ppos) -{ - return -ENOSPC; -} - -/* - */ -static int jsf_ioctl_erase(unsigned long arg) -{ - unsigned long p; - - /* p = jsf0.base; hits wrong bank */ - p = 0x20400000; - - jsf_outl(p, 0xAAAAAAAA); /* Unlock 1 Write 1 */ - jsf_outl(p, 0x55555555); /* Unlock 1 Write 2 */ - jsf_outl(p, 0x80808080); /* Erase setup */ - jsf_outl(p, 0xAAAAAAAA); /* Unlock 2 Write 1 */ - jsf_outl(p, 0x55555555); /* Unlock 2 Write 2 */ - jsf_outl(p, 0x10101010); /* Chip erase */ - -#if 0 - /* - * This code is ok, except that counter based timeout - * has no place in this world. Let's just drop timeouts... - */ - { - int i; - __u32 x; - for (i = 0; i < 1000000; i++) { - x = jsf_inl(p); - if ((x & 0x80808080) == 0x80808080) break; - } - if ((x & 0x80808080) != 0x80808080) { - printk("jsf0: erase timeout with 0x%08x\n", x); - } else { - printk("jsf0: erase done with 0x%08x\n", x); - } - } -#else - jsf_wait(p); -#endif - - return 0; -} - -/* - * Program a block of flash. - * Very simple because we can do it byte by byte anyway. - */ -static int jsf_ioctl_program(void __user *arg) -{ - struct jsflash_program_arg abuf; - char __user *uptr; - unsigned long p; - unsigned int togo; - union { - unsigned int n; - char s[4]; - } b; - - if (copy_from_user(&abuf, arg, JSFPRGSZ)) - return -EFAULT; - p = abuf.off; - togo = abuf.size; - if ((togo & 3) || (p & 3)) return -EINVAL; - - uptr = (char __user *) (unsigned long) abuf.data; - while (togo != 0) { - togo -= 4; - if (copy_from_user(&b.s[0], uptr, 4)) - return -EFAULT; - jsf_write4(p, b.n); - p += 4; - uptr += 4; - } - - return 0; -} - -static long jsf_ioctl(struct file *f, unsigned int cmd, unsigned long arg) -{ - mutex_lock(&jsf_mutex); - int error = -ENOTTY; - void __user *argp = (void __user *)arg; - - if (!capable(CAP_SYS_ADMIN)) { - mutex_unlock(&jsf_mutex); - return -EPERM; - } - switch (cmd) { - case JSFLASH_IDENT: - if (copy_to_user(argp, &jsf0.id, JSFIDSZ)) { - mutex_unlock(&jsf_mutex); - return -EFAULT; - } - break; - case JSFLASH_ERASE: - error = jsf_ioctl_erase(arg); - break; - case JSFLASH_PROGRAM: - error = jsf_ioctl_program(argp); - break; - } - - mutex_unlock(&jsf_mutex); - return error; -} - -static int jsf_mmap(struct file * file, struct vm_area_struct * vma) -{ - return -ENXIO; -} - -static int jsf_open(struct inode * inode, struct file * filp) -{ - mutex_lock(&jsf_mutex); - if (jsf0.base == 0) { - mutex_unlock(&jsf_mutex); - return -ENXIO; - } - if (test_and_set_bit(0, (void *)&jsf0.busy) != 0) { - mutex_unlock(&jsf_mutex); - return -EBUSY; - } - - mutex_unlock(&jsf_mutex); - return 0; /* XXX What security? */ -} - -static int jsf_release(struct inode *inode, struct file *file) -{ - jsf0.busy = 0; - return 0; -} - -static const struct file_operations jsf_fops = { - .owner = THIS_MODULE, - .llseek = jsf_lseek, - .read = jsf_read, - .write = jsf_write, - .unlocked_ioctl = jsf_ioctl, - .mmap = jsf_mmap, - .open = jsf_open, - .release = jsf_release, -}; - -static struct miscdevice jsf_dev = { JSF_MINOR, "jsflash", &jsf_fops }; - -static const struct block_device_operations jsfd_fops = { - .owner = THIS_MODULE, -}; - -static int jsflash_init(void) -{ - int rc; - struct jsflash *jsf; - phandle node; - char banner[128]; - struct linux_prom_registers reg0; - - node = prom_getchild(prom_root_node); - node = prom_searchsiblings(node, "flash-memory"); - if (node != 0 && (s32)node != -1) { - if (prom_getproperty(node, "reg", - (char *)®0, sizeof(reg0)) == -1) { - printk("jsflash: no \"reg\" property\n"); - return -ENXIO; - } - if (reg0.which_io != 0) { - printk("jsflash: bus number nonzero: 0x%x:%x\n", - reg0.which_io, reg0.phys_addr); - return -ENXIO; - } - /* - * Flash may be somewhere else, for instance on Ebus. - * So, don't do the following check for IIep flash space. - */ -#if 0 - if ((reg0.phys_addr >> 24) != 0x20) { - printk("jsflash: suspicious address: 0x%x:%x\n", - reg0.which_io, reg0.phys_addr); - return -ENXIO; - } -#endif - if ((int)reg0.reg_size <= 0) { - printk("jsflash: bad size 0x%x\n", (int)reg0.reg_size); - return -ENXIO; - } - } else { - /* XXX Remove this code once PROLL ID12 got widespread */ - printk("jsflash: no /flash-memory node, use PROLL >= 12\n"); - prom_getproperty(prom_root_node, "banner-name", banner, 128); - if (strcmp (banner, "JavaStation-NC") != 0 && - strcmp (banner, "JavaStation-E") != 0) { - return -ENXIO; - } - reg0.which_io = 0; - reg0.phys_addr = 0x20400000; - reg0.reg_size = 0x00800000; - } - - /* Let us be really paranoid for modifications to probing code. */ - /* extern enum sparc_cpu sparc_cpu_model; */ /* in <asm/system.h> */ - if (sparc_cpu_model != sun4m) { - /* We must be on sun4m because we use MMU Bypass ASI. */ - return -ENXIO; - } - - if (jsf0.base == 0) { - jsf = &jsf0; - - jsf->base = reg0.phys_addr; - jsf->size = reg0.reg_size; - - /* XXX Redo the userland interface. */ - jsf->id.off = JSF_BASE_ALL; - jsf->id.size = 0x01000000; /* 16M - all segments */ - strcpy(jsf->id.name, "Krups_all"); - - jsf->dv[0].dbase = jsf->base; - jsf->dv[0].dsize = jsf->size; - jsf->dv[1].dbase = jsf->base + 1024; - jsf->dv[1].dsize = jsf->size - 1024; - jsf->dv[2].dbase = JSF_BASE_ALL; - jsf->dv[2].dsize = 0x01000000; - - printk("Espresso Flash @0x%lx [%d MB]\n", jsf->base, - (int) (jsf->size / (1024*1024))); - } - - if ((rc = misc_register(&jsf_dev)) != 0) { - printk(KERN_ERR "jsf: unable to get misc minor %d\n", - JSF_MINOR); - jsf0.base = 0; - return rc; - } - - return 0; -} - -static struct request_queue *jsf_queue; - -static int jsfd_init(void) -{ - static DEFINE_SPINLOCK(lock); - struct jsflash *jsf; - struct jsfd_part *jdp; - int err; - int i; - - if (jsf0.base == 0) - return -ENXIO; - - err = -ENOMEM; - for (i = 0; i < JSF_MAX; i++) { - struct gendisk *disk = alloc_disk(1); - if (!disk) - goto out; - jsfd_disk[i] = disk; - } - - if (register_blkdev(JSFD_MAJOR, "jsfd")) { - err = -EIO; - goto out; - } - - jsf_queue = blk_init_queue(jsfd_do_request, &lock); - if (!jsf_queue) { - err = -ENOMEM; - unregister_blkdev(JSFD_MAJOR, "jsfd"); - goto out; - } - - for (i = 0; i < JSF_MAX; i++) { - struct gendisk *disk = jsfd_disk[i]; - if ((i & JSF_PART_MASK) >= JSF_NPART) continue; - jsf = &jsf0; /* actually, &jsfv[i >> JSF_PART_BITS] */ - jdp = &jsf->dv[i&JSF_PART_MASK]; - - disk->major = JSFD_MAJOR; - disk->first_minor = i; - sprintf(disk->disk_name, "jsfd%d", i); - disk->fops = &jsfd_fops; - set_capacity(disk, jdp->dsize >> 9); - disk->private_data = jdp; - disk->queue = jsf_queue; - add_disk(disk); - set_disk_ro(disk, 1); - } - return 0; -out: - while (i--) - put_disk(jsfd_disk[i]); - return err; -} - -MODULE_LICENSE("GPL"); - -static int __init jsflash_init_module(void) { - int rc; - - if ((rc = jsflash_init()) == 0) { - jsfd_init(); - return 0; - } - return rc; -} - -static void __exit jsflash_cleanup_module(void) -{ - int i; - - for (i = 0; i < JSF_MAX; i++) { - if ((i & JSF_PART_MASK) >= JSF_NPART) continue; - del_gendisk(jsfd_disk[i]); - put_disk(jsfd_disk[i]); - } - if (jsf0.busy) - printk("jsf0: cleaning busy unit\n"); - jsf0.base = 0; - jsf0.busy = 0; - - misc_deregister(&jsf_dev); - unregister_blkdev(JSFD_MAJOR, "jsfd"); - blk_cleanup_queue(jsf_queue); -} - -module_init(jsflash_init_module); -module_exit(jsflash_cleanup_module); diff --git a/ANDROID_3.4.5/drivers/sbus/char/max1617.h b/ANDROID_3.4.5/drivers/sbus/char/max1617.h deleted file mode 100644 index cd30819a..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/max1617.h +++ /dev/null @@ -1,27 +0,0 @@ -/* $Id: max1617.h,v 1.1 2001/04/02 09:59:08 davem Exp $ */ -#ifndef _MAX1617_H -#define _MAX1617_H - -#define MAX1617_AMB_TEMP 0x00 /* Ambient temp in C */ -#define MAX1617_CPU_TEMP 0x01 /* Processor die temp in C */ -#define MAX1617_STATUS 0x02 /* Chip status bits */ - -/* Read-only versions of changeable registers. */ -#define MAX1617_RD_CFG_BYTE 0x03 /* Config register */ -#define MAX1617_RD_CVRATE_BYTE 0x04 /* Temp conversion rate */ -#define MAX1617_RD_AMB_HIGHLIM 0x05 /* Ambient high limit */ -#define MAX1617_RD_AMB_LOWLIM 0x06 /* Ambient low limit */ -#define MAX1617_RD_CPU_HIGHLIM 0x07 /* Processor high limit */ -#define MAX1617_RD_CPU_LOWLIM 0x08 /* Processor low limit */ - -/* Write-only versions of the same. */ -#define MAX1617_WR_CFG_BYTE 0x09 -#define MAX1617_WR_CVRATE_BYTE 0x0a -#define MAX1617_WR_AMB_HIGHLIM 0x0b -#define MAX1617_WR_AMB_LOWLIM 0x0c -#define MAX1617_WR_CPU_HIGHLIM 0x0d -#define MAX1617_WR_CPU_LOWLIM 0x0e - -#define MAX1617_ONESHOT 0x0f - -#endif /* _MAX1617_H */ diff --git a/ANDROID_3.4.5/drivers/sbus/char/openprom.c b/ANDROID_3.4.5/drivers/sbus/char/openprom.c deleted file mode 100644 index 2236aea3..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/openprom.c +++ /dev/null @@ -1,762 +0,0 @@ -/* - * Linux/SPARC PROM Configuration Driver - * Copyright (C) 1996 Thomas K. Dyas (tdyas@noc.rutgers.edu) - * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) - * - * This character device driver allows user programs to access the - * PROM device tree. It is compatible with the SunOS /dev/openprom - * driver and the NetBSD /dev/openprom driver. The SunOS eeprom - * utility works without any modifications. - * - * The driver uses a minor number under the misc device major. The - * file read/write mode determines the type of access to the PROM. - * Interrupts are disabled whenever the driver calls into the PROM for - * sanity's sake. - */ - -/* This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/string.h> -#include <linux/miscdevice.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <asm/oplib.h> -#include <asm/prom.h> -#include <asm/uaccess.h> -#include <asm/openpromio.h> -#ifdef CONFIG_PCI -#include <linux/pci.h> -#endif - -MODULE_AUTHOR("Thomas K. Dyas (tdyas@noc.rutgers.edu) and Eddie C. Dost (ecd@skynet.be)"); -MODULE_DESCRIPTION("OPENPROM Configuration Driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); -MODULE_ALIAS_MISCDEV(SUN_OPENPROM_MINOR); - -/* Private data kept by the driver for each descriptor. */ -typedef struct openprom_private_data -{ - struct device_node *current_node; /* Current node for SunOS ioctls. */ - struct device_node *lastnode; /* Last valid node used by BSD ioctls. */ -} DATA; - -/* ID of the PROM node containing all of the EEPROM options. */ -static DEFINE_MUTEX(openprom_mutex); -static struct device_node *options_node; - -/* - * Copy an openpromio structure into kernel space from user space. - * This routine does error checking to make sure that all memory - * accesses are within bounds. A pointer to the allocated openpromio - * structure will be placed in "*opp_p". Return value is the length - * of the user supplied buffer. - */ -static int copyin(struct openpromio __user *info, struct openpromio **opp_p) -{ - unsigned int bufsize; - - if (!info || !opp_p) - return -EFAULT; - - if (get_user(bufsize, &info->oprom_size)) - return -EFAULT; - - if (bufsize == 0) - return -EINVAL; - - /* If the bufsize is too large, just limit it. - * Fix from Jason Rappleye. - */ - if (bufsize > OPROMMAXPARAM) - bufsize = OPROMMAXPARAM; - - if (!(*opp_p = kzalloc(sizeof(int) + bufsize + 1, GFP_KERNEL))) - return -ENOMEM; - - if (copy_from_user(&(*opp_p)->oprom_array, - &info->oprom_array, bufsize)) { - kfree(*opp_p); - return -EFAULT; - } - return bufsize; -} - -static int getstrings(struct openpromio __user *info, struct openpromio **opp_p) -{ - int n, bufsize; - char c; - - if (!info || !opp_p) - return -EFAULT; - - if (!(*opp_p = kzalloc(sizeof(int) + OPROMMAXPARAM + 1, GFP_KERNEL))) - return -ENOMEM; - - (*opp_p)->oprom_size = 0; - - n = bufsize = 0; - while ((n < 2) && (bufsize < OPROMMAXPARAM)) { - if (get_user(c, &info->oprom_array[bufsize])) { - kfree(*opp_p); - return -EFAULT; - } - if (c == '\0') - n++; - (*opp_p)->oprom_array[bufsize++] = c; - } - if (!n) { - kfree(*opp_p); - return -EINVAL; - } - return bufsize; -} - -/* - * Copy an openpromio structure in kernel space back to user space. - */ -static int copyout(void __user *info, struct openpromio *opp, int len) -{ - if (copy_to_user(info, opp, len)) - return -EFAULT; - return 0; -} - -static int opromgetprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) -{ - const void *pval; - int len; - - if (!dp || - !(pval = of_get_property(dp, op->oprom_array, &len)) || - len <= 0 || len > bufsize) - return copyout(argp, op, sizeof(int)); - - memcpy(op->oprom_array, pval, len); - op->oprom_array[len] = '\0'; - op->oprom_size = len; - - return copyout(argp, op, sizeof(int) + bufsize); -} - -static int opromnxtprop(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize) -{ - struct property *prop; - int len; - - if (!dp) - return copyout(argp, op, sizeof(int)); - if (op->oprom_array[0] == '\0') { - prop = dp->properties; - if (!prop) - return copyout(argp, op, sizeof(int)); - len = strlen(prop->name); - } else { - prop = of_find_property(dp, op->oprom_array, NULL); - - if (!prop || - !prop->next || - (len = strlen(prop->next->name)) + 1 > bufsize) - return copyout(argp, op, sizeof(int)); - - prop = prop->next; - } - - memcpy(op->oprom_array, prop->name, len); - op->oprom_array[len] = '\0'; - op->oprom_size = ++len; - - return copyout(argp, op, sizeof(int) + bufsize); -} - -static int opromsetopt(struct device_node *dp, struct openpromio *op, int bufsize) -{ - char *buf = op->oprom_array + strlen(op->oprom_array) + 1; - int len = op->oprom_array + bufsize - buf; - - return of_set_property(options_node, op->oprom_array, buf, len); -} - -static int opromnext(void __user *argp, unsigned int cmd, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - phandle ph; - - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - - if (bufsize < sizeof(phandle)) - return -EINVAL; - - ph = *((int *) op->oprom_array); - if (ph) { - dp = of_find_node_by_phandle(ph); - if (!dp) - return -EINVAL; - - switch (cmd) { - case OPROMNEXT: - dp = dp->sibling; - break; - - case OPROMCHILD: - dp = dp->child; - break; - - case OPROMSETCUR: - default: - break; - }; - } else { - /* Sibling of node zero is the root node. */ - if (cmd != OPROMNEXT) - return -EINVAL; - - dp = of_find_node_by_path("/"); - } - - ph = 0; - if (dp) - ph = dp->phandle; - - data->current_node = dp; - *((int *) op->oprom_array) = ph; - op->oprom_size = sizeof(phandle); - - return copyout(argp, op, bufsize + sizeof(int)); -} - -static int oprompci2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - int err = -EINVAL; - - if (bufsize >= 2*sizeof(int)) { -#ifdef CONFIG_PCI - struct pci_dev *pdev; - struct device_node *dp; - - pdev = pci_get_bus_and_slot (((int *) op->oprom_array)[0], - ((int *) op->oprom_array)[1]); - - dp = pci_device_to_OF_node(pdev); - data->current_node = dp; - *((int *)op->oprom_array) = dp->phandle; - op->oprom_size = sizeof(int); - err = copyout(argp, op, bufsize + sizeof(int)); - - pci_dev_put(pdev); -#endif - } - - return err; -} - -static int oprompath2node(void __user *argp, struct device_node *dp, struct openpromio *op, int bufsize, DATA *data) -{ - phandle ph = 0; - - dp = of_find_node_by_path(op->oprom_array); - if (dp) - ph = dp->phandle; - data->current_node = dp; - *((int *)op->oprom_array) = ph; - op->oprom_size = sizeof(int); - - return copyout(argp, op, bufsize + sizeof(int)); -} - -static int opromgetbootargs(void __user *argp, struct openpromio *op, int bufsize) -{ - char *buf = saved_command_line; - int len = strlen(buf); - - if (len > bufsize) - return -EINVAL; - - strcpy(op->oprom_array, buf); - op->oprom_size = len; - - return copyout(argp, op, bufsize + sizeof(int)); -} - -/* - * SunOS and Solaris /dev/openprom ioctl calls. - */ -static long openprom_sunos_ioctl(struct file * file, - unsigned int cmd, unsigned long arg, - struct device_node *dp) -{ - DATA *data = file->private_data; - struct openpromio *opp = NULL; - int bufsize, error = 0; - static int cnt; - void __user *argp = (void __user *)arg; - - if (cmd == OPROMSETOPT) - bufsize = getstrings(argp, &opp); - else - bufsize = copyin(argp, &opp); - - if (bufsize < 0) - return bufsize; - - mutex_lock(&openprom_mutex); - - switch (cmd) { - case OPROMGETOPT: - case OPROMGETPROP: - error = opromgetprop(argp, dp, opp, bufsize); - break; - - case OPROMNXTOPT: - case OPROMNXTPROP: - error = opromnxtprop(argp, dp, opp, bufsize); - break; - - case OPROMSETOPT: - case OPROMSETOPT2: - error = opromsetopt(dp, opp, bufsize); - break; - - case OPROMNEXT: - case OPROMCHILD: - case OPROMSETCUR: - error = opromnext(argp, cmd, dp, opp, bufsize, data); - break; - - case OPROMPCI2NODE: - error = oprompci2node(argp, dp, opp, bufsize, data); - break; - - case OPROMPATH2NODE: - error = oprompath2node(argp, dp, opp, bufsize, data); - break; - - case OPROMGETBOOTARGS: - error = opromgetbootargs(argp, opp, bufsize); - break; - - case OPROMU2P: - case OPROMGETCONS: - case OPROMGETFBNAME: - if (cnt++ < 10) - printk(KERN_INFO "openprom_sunos_ioctl: unimplemented ioctl\n"); - error = -EINVAL; - break; - default: - if (cnt++ < 10) - printk(KERN_INFO "openprom_sunos_ioctl: cmd 0x%X, arg 0x%lX\n", cmd, arg); - error = -EINVAL; - break; - } - - kfree(opp); - mutex_unlock(&openprom_mutex); - - return error; -} - -static struct device_node *get_node(phandle n, DATA *data) -{ - struct device_node *dp = of_find_node_by_phandle(n); - - if (dp) - data->lastnode = dp; - - return dp; -} - -/* Copy in a whole string from userspace into kernelspace. */ -static int copyin_string(char __user *user, size_t len, char **ptr) -{ - char *tmp; - - if ((ssize_t)len < 0 || (ssize_t)(len + 1) < 0) - return -EINVAL; - - tmp = kmalloc(len + 1, GFP_KERNEL); - if (!tmp) - return -ENOMEM; - - if (copy_from_user(tmp, user, len)) { - kfree(tmp); - return -EFAULT; - } - - tmp[len] = '\0'; - - *ptr = tmp; - - return 0; -} - -/* - * NetBSD /dev/openprom ioctl calls. - */ -static int opiocget(void __user *argp, DATA *data) -{ - struct opiocdesc op; - struct device_node *dp; - char *str; - const void *pval; - int err, len; - - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; - - dp = get_node(op.op_nodeid, data); - - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; - - pval = of_get_property(dp, str, &len); - err = 0; - if (!pval || len > op.op_buflen) { - err = -EINVAL; - } else { - op.op_buflen = len; - if (copy_to_user(argp, &op, sizeof(op)) || - copy_to_user(op.op_buf, pval, len)) - err = -EFAULT; - } - kfree(str); - - return err; -} - -static int opiocnextprop(void __user *argp, DATA *data) -{ - struct opiocdesc op; - struct device_node *dp; - struct property *prop; - char *str; - int err, len; - - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; - - dp = get_node(op.op_nodeid, data); - if (!dp) - return -EINVAL; - - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; - - if (str[0] == '\0') { - prop = dp->properties; - } else { - prop = of_find_property(dp, str, NULL); - if (prop) - prop = prop->next; - } - kfree(str); - - if (!prop) - len = 0; - else - len = prop->length; - - if (len > op.op_buflen) - len = op.op_buflen; - - if (copy_to_user(argp, &op, sizeof(op))) - return -EFAULT; - - if (len && - copy_to_user(op.op_buf, prop->value, len)) - return -EFAULT; - - return 0; -} - -static int opiocset(void __user *argp, DATA *data) -{ - struct opiocdesc op; - struct device_node *dp; - char *str, *tmp; - int err; - - if (copy_from_user(&op, argp, sizeof(op))) - return -EFAULT; - - dp = get_node(op.op_nodeid, data); - if (!dp) - return -EINVAL; - - err = copyin_string(op.op_name, op.op_namelen, &str); - if (err) - return err; - - err = copyin_string(op.op_buf, op.op_buflen, &tmp); - if (err) { - kfree(str); - return err; - } - - err = of_set_property(dp, str, tmp, op.op_buflen); - - kfree(str); - kfree(tmp); - - return err; -} - -static int opiocgetnext(unsigned int cmd, void __user *argp) -{ - struct device_node *dp; - phandle nd; - - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - - if (copy_from_user(&nd, argp, sizeof(phandle))) - return -EFAULT; - - if (nd == 0) { - if (cmd != OPIOCGETNEXT) - return -EINVAL; - dp = of_find_node_by_path("/"); - } else { - dp = of_find_node_by_phandle(nd); - nd = 0; - if (dp) { - if (cmd == OPIOCGETNEXT) - dp = dp->sibling; - else - dp = dp->child; - } - } - if (dp) - nd = dp->phandle; - if (copy_to_user(argp, &nd, sizeof(phandle))) - return -EFAULT; - - return 0; -} - -static int openprom_bsd_ioctl(struct file * file, - unsigned int cmd, unsigned long arg) -{ - DATA *data = file->private_data; - void __user *argp = (void __user *)arg; - int err; - - mutex_lock(&openprom_mutex); - switch (cmd) { - case OPIOCGET: - err = opiocget(argp, data); - break; - - case OPIOCNEXTPROP: - err = opiocnextprop(argp, data); - break; - - case OPIOCSET: - err = opiocset(argp, data); - break; - - case OPIOCGETOPTNODE: - BUILD_BUG_ON(sizeof(phandle) != sizeof(int)); - - err = 0; - if (copy_to_user(argp, &options_node->phandle, sizeof(phandle))) - err = -EFAULT; - break; - - case OPIOCGETNEXT: - case OPIOCGETCHILD: - err = opiocgetnext(cmd, argp); - break; - - default: - err = -EINVAL; - break; - }; - mutex_unlock(&openprom_mutex); - - return err; -} - - -/* - * Handoff control to the correct ioctl handler. - */ -static long openprom_ioctl(struct file * file, - unsigned int cmd, unsigned long arg) -{ - DATA *data = file->private_data; - - switch (cmd) { - case OPROMGETOPT: - case OPROMNXTOPT: - if ((file->f_mode & FMODE_READ) == 0) - return -EPERM; - return openprom_sunos_ioctl(file, cmd, arg, - options_node); - - case OPROMSETOPT: - case OPROMSETOPT2: - if ((file->f_mode & FMODE_WRITE) == 0) - return -EPERM; - return openprom_sunos_ioctl(file, cmd, arg, - options_node); - - case OPROMNEXT: - case OPROMCHILD: - case OPROMGETPROP: - case OPROMNXTPROP: - if ((file->f_mode & FMODE_READ) == 0) - return -EPERM; - return openprom_sunos_ioctl(file, cmd, arg, - data->current_node); - - case OPROMU2P: - case OPROMGETCONS: - case OPROMGETFBNAME: - case OPROMGETBOOTARGS: - case OPROMSETCUR: - case OPROMPCI2NODE: - case OPROMPATH2NODE: - if ((file->f_mode & FMODE_READ) == 0) - return -EPERM; - return openprom_sunos_ioctl(file, cmd, arg, NULL); - - case OPIOCGET: - case OPIOCNEXTPROP: - case OPIOCGETOPTNODE: - case OPIOCGETNEXT: - case OPIOCGETCHILD: - if ((file->f_mode & FMODE_READ) == 0) - return -EBADF; - return openprom_bsd_ioctl(file,cmd,arg); - - case OPIOCSET: - if ((file->f_mode & FMODE_WRITE) == 0) - return -EBADF; - return openprom_bsd_ioctl(file,cmd,arg); - - default: - return -EINVAL; - }; -} - -static long openprom_compat_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) -{ - long rval = -ENOTTY; - - /* - * SunOS/Solaris only, the NetBSD one's have embedded pointers in - * the arg which we'd need to clean up... - */ - switch (cmd) { - case OPROMGETOPT: - case OPROMSETOPT: - case OPROMNXTOPT: - case OPROMSETOPT2: - case OPROMNEXT: - case OPROMCHILD: - case OPROMGETPROP: - case OPROMNXTPROP: - case OPROMU2P: - case OPROMGETCONS: - case OPROMGETFBNAME: - case OPROMGETBOOTARGS: - case OPROMSETCUR: - case OPROMPCI2NODE: - case OPROMPATH2NODE: - rval = openprom_ioctl(file, cmd, arg); - break; - } - - return rval; -} - -static int openprom_open(struct inode * inode, struct file * file) -{ - DATA *data; - - data = kmalloc(sizeof(DATA), GFP_KERNEL); - if (!data) - return -ENOMEM; - - mutex_lock(&openprom_mutex); - data->current_node = of_find_node_by_path("/"); - data->lastnode = data->current_node; - file->private_data = (void *) data; - mutex_unlock(&openprom_mutex); - - return 0; -} - -static int openprom_release(struct inode * inode, struct file * file) -{ - kfree(file->private_data); - return 0; -} - -static const struct file_operations openprom_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .unlocked_ioctl = openprom_ioctl, - .compat_ioctl = openprom_compat_ioctl, - .open = openprom_open, - .release = openprom_release, -}; - -static struct miscdevice openprom_dev = { - .minor = SUN_OPENPROM_MINOR, - .name = "openprom", - .fops = &openprom_fops, -}; - -static int __init openprom_init(void) -{ - struct device_node *dp; - int err; - - err = misc_register(&openprom_dev); - if (err) - return err; - - dp = of_find_node_by_path("/"); - dp = dp->child; - while (dp) { - if (!strcmp(dp->name, "options")) - break; - dp = dp->sibling; - } - options_node = dp; - - if (!options_node) { - misc_deregister(&openprom_dev); - return -EIO; - } - - return 0; -} - -static void __exit openprom_cleanup(void) -{ - misc_deregister(&openprom_dev); -} - -module_init(openprom_init); -module_exit(openprom_cleanup); diff --git a/ANDROID_3.4.5/drivers/sbus/char/uctrl.c b/ANDROID_3.4.5/drivers/sbus/char/uctrl.c deleted file mode 100644 index a9e468cc..00000000 --- a/ANDROID_3.4.5/drivers/sbus/char/uctrl.c +++ /dev/null @@ -1,439 +0,0 @@ -/* uctrl.c: TS102 Microcontroller interface on Tadpole Sparcbook 3 - * - * Copyright 1999 Derrick J Brashear (shadow@dementia.org) - * Copyright 2008 David S. Miller (davem@davemloft.net) - */ - -#include <linux/module.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/interrupt.h> -#include <linux/slab.h> -#include <linux/mutex.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/miscdevice.h> -#include <linux/mm.h> -#include <linux/of.h> -#include <linux/of_device.h> - -#include <asm/openprom.h> -#include <asm/oplib.h> -#include <asm/irq.h> -#include <asm/io.h> -#include <asm/pgtable.h> - -#define UCTRL_MINOR 174 - -#define DEBUG 1 -#ifdef DEBUG -#define dprintk(x) printk x -#else -#define dprintk(x) -#endif - -struct uctrl_regs { - u32 uctrl_intr; - u32 uctrl_data; - u32 uctrl_stat; - u32 uctrl_xxx[5]; -}; - -struct ts102_regs { - u32 card_a_intr; - u32 card_a_stat; - u32 card_a_ctrl; - u32 card_a_xxx; - u32 card_b_intr; - u32 card_b_stat; - u32 card_b_ctrl; - u32 card_b_xxx; - u32 uctrl_intr; - u32 uctrl_data; - u32 uctrl_stat; - u32 uctrl_xxx; - u32 ts102_xxx[4]; -}; - -/* Bits for uctrl_intr register */ -#define UCTRL_INTR_TXE_REQ 0x01 /* transmit FIFO empty int req */ -#define UCTRL_INTR_TXNF_REQ 0x02 /* transmit FIFO not full int req */ -#define UCTRL_INTR_RXNE_REQ 0x04 /* receive FIFO not empty int req */ -#define UCTRL_INTR_RXO_REQ 0x08 /* receive FIFO overflow int req */ -#define UCTRL_INTR_TXE_MSK 0x10 /* transmit FIFO empty mask */ -#define UCTRL_INTR_TXNF_MSK 0x20 /* transmit FIFO not full mask */ -#define UCTRL_INTR_RXNE_MSK 0x40 /* receive FIFO not empty mask */ -#define UCTRL_INTR_RXO_MSK 0x80 /* receive FIFO overflow mask */ - -/* Bits for uctrl_stat register */ -#define UCTRL_STAT_TXE_STA 0x01 /* transmit FIFO empty status */ -#define UCTRL_STAT_TXNF_STA 0x02 /* transmit FIFO not full status */ -#define UCTRL_STAT_RXNE_STA 0x04 /* receive FIFO not empty status */ -#define UCTRL_STAT_RXO_STA 0x08 /* receive FIFO overflow status */ - -static DEFINE_MUTEX(uctrl_mutex); -static const char *uctrl_extstatus[16] = { - "main power available", - "internal battery attached", - "external battery attached", - "external VGA attached", - "external keyboard attached", - "external mouse attached", - "lid down", - "internal battery currently charging", - "external battery currently charging", - "internal battery currently discharging", - "external battery currently discharging", -}; - -/* Everything required for one transaction with the uctrl */ -struct uctrl_txn { - u8 opcode; - u8 inbits; - u8 outbits; - u8 *inbuf; - u8 *outbuf; -}; - -struct uctrl_status { - u8 current_temp; /* 0x07 */ - u8 reset_status; /* 0x0b */ - u16 event_status; /* 0x0c */ - u16 error_status; /* 0x10 */ - u16 external_status; /* 0x11, 0x1b */ - u8 internal_charge; /* 0x18 */ - u8 external_charge; /* 0x19 */ - u16 control_lcd; /* 0x20 */ - u8 control_bitport; /* 0x21 */ - u8 speaker_volume; /* 0x23 */ - u8 control_tft_brightness; /* 0x24 */ - u8 control_kbd_repeat_delay; /* 0x28 */ - u8 control_kbd_repeat_period; /* 0x29 */ - u8 control_screen_contrast; /* 0x2F */ -}; - -enum uctrl_opcode { - READ_SERIAL_NUMBER=0x1, - READ_ETHERNET_ADDRESS=0x2, - READ_HARDWARE_VERSION=0x3, - READ_MICROCONTROLLER_VERSION=0x4, - READ_MAX_TEMPERATURE=0x5, - READ_MIN_TEMPERATURE=0x6, - READ_CURRENT_TEMPERATURE=0x7, - READ_SYSTEM_VARIANT=0x8, - READ_POWERON_CYCLES=0x9, - READ_POWERON_SECONDS=0xA, - READ_RESET_STATUS=0xB, - READ_EVENT_STATUS=0xC, - READ_REAL_TIME_CLOCK=0xD, - READ_EXTERNAL_VGA_PORT=0xE, - READ_MICROCONTROLLER_ROM_CHECKSUM=0xF, - READ_ERROR_STATUS=0x10, - READ_EXTERNAL_STATUS=0x11, - READ_USER_CONFIGURATION_AREA=0x12, - READ_MICROCONTROLLER_VOLTAGE=0x13, - READ_INTERNAL_BATTERY_VOLTAGE=0x14, - READ_DCIN_VOLTAGE=0x15, - READ_HORIZONTAL_POINTER_VOLTAGE=0x16, - READ_VERTICAL_POINTER_VOLTAGE=0x17, - READ_INTERNAL_BATTERY_CHARGE_LEVEL=0x18, - READ_EXTERNAL_BATTERY_CHARGE_LEVEL=0x19, - READ_REAL_TIME_CLOCK_ALARM=0x1A, - READ_EVENT_STATUS_NO_RESET=0x1B, - READ_INTERNAL_KEYBOARD_LAYOUT=0x1C, - READ_EXTERNAL_KEYBOARD_LAYOUT=0x1D, - READ_EEPROM_STATUS=0x1E, - CONTROL_LCD=0x20, - CONTROL_BITPORT=0x21, - SPEAKER_VOLUME=0x23, - CONTROL_TFT_BRIGHTNESS=0x24, - CONTROL_WATCHDOG=0x25, - CONTROL_FACTORY_EEPROM_AREA=0x26, - CONTROL_KBD_TIME_UNTIL_REPEAT=0x28, - CONTROL_KBD_TIME_BETWEEN_REPEATS=0x29, - CONTROL_TIMEZONE=0x2A, - CONTROL_MARK_SPACE_RATIO=0x2B, - CONTROL_DIAGNOSTIC_MODE=0x2E, - CONTROL_SCREEN_CONTRAST=0x2F, - RING_BELL=0x30, - SET_DIAGNOSTIC_STATUS=0x32, - CLEAR_KEY_COMBINATION_TABLE=0x33, - PERFORM_SOFTWARE_RESET=0x34, - SET_REAL_TIME_CLOCK=0x35, - RECALIBRATE_POINTING_STICK=0x36, - SET_BELL_FREQUENCY=0x37, - SET_INTERNAL_BATTERY_CHARGE_RATE=0x39, - SET_EXTERNAL_BATTERY_CHARGE_RATE=0x3A, - SET_REAL_TIME_CLOCK_ALARM=0x3B, - READ_EEPROM=0x40, - WRITE_EEPROM=0x41, - WRITE_TO_STATUS_DISPLAY=0x42, - DEFINE_SPECIAL_CHARACTER=0x43, - DEFINE_KEY_COMBINATION_ENTRY=0x50, - DEFINE_STRING_TABLE_ENTRY=0x51, - DEFINE_STATUS_SCREEN_DISPLAY=0x52, - PERFORM_EMU_COMMANDS=0x64, - READ_EMU_REGISTER=0x65, - WRITE_EMU_REGISTER=0x66, - READ_EMU_RAM=0x67, - WRITE_EMU_RAM=0x68, - READ_BQ_REGISTER=0x69, - WRITE_BQ_REGISTER=0x6A, - SET_USER_PASSWORD=0x70, - VERIFY_USER_PASSWORD=0x71, - GET_SYSTEM_PASSWORD_KEY=0x72, - VERIFY_SYSTEM_PASSWORD=0x73, - POWER_OFF=0x82, - POWER_RESTART=0x83, -}; - -static struct uctrl_driver { - struct uctrl_regs __iomem *regs; - int irq; - int pending; - struct uctrl_status status; -} *global_driver; - -static void uctrl_get_event_status(struct uctrl_driver *); -static void uctrl_get_external_status(struct uctrl_driver *); - -static long -uctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - default: - return -EINVAL; - } - return 0; -} - -static int -uctrl_open(struct inode *inode, struct file *file) -{ - mutex_lock(&uctrl_mutex); - uctrl_get_event_status(global_driver); - uctrl_get_external_status(global_driver); - mutex_unlock(&uctrl_mutex); - return 0; -} - -static irqreturn_t uctrl_interrupt(int irq, void *dev_id) -{ - return IRQ_HANDLED; -} - -static const struct file_operations uctrl_fops = { - .owner = THIS_MODULE, - .llseek = no_llseek, - .unlocked_ioctl = uctrl_ioctl, - .open = uctrl_open, -}; - -static struct miscdevice uctrl_dev = { - UCTRL_MINOR, - "uctrl", - &uctrl_fops -}; - -/* Wait for space to write, then write to it */ -#define WRITEUCTLDATA(value) \ -{ \ - unsigned int i; \ - for (i = 0; i < 10000; i++) { \ - if (UCTRL_STAT_TXNF_STA & sbus_readl(&driver->regs->uctrl_stat)) \ - break; \ - } \ - dprintk(("write data 0x%02x\n", value)); \ - sbus_writel(value, &driver->regs->uctrl_data); \ -} - -/* Wait for something to read, read it, then clear the bit */ -#define READUCTLDATA(value) \ -{ \ - unsigned int i; \ - value = 0; \ - for (i = 0; i < 10000; i++) { \ - if ((UCTRL_STAT_RXNE_STA & sbus_readl(&driver->regs->uctrl_stat)) == 0) \ - break; \ - udelay(1); \ - } \ - value = sbus_readl(&driver->regs->uctrl_data); \ - dprintk(("read data 0x%02x\n", value)); \ - sbus_writel(UCTRL_STAT_RXNE_STA, &driver->regs->uctrl_stat); \ -} - -static void uctrl_do_txn(struct uctrl_driver *driver, struct uctrl_txn *txn) -{ - int stat, incnt, outcnt, bytecnt, intr; - u32 byte; - - stat = sbus_readl(&driver->regs->uctrl_stat); - intr = sbus_readl(&driver->regs->uctrl_intr); - sbus_writel(stat, &driver->regs->uctrl_stat); - - dprintk(("interrupt stat 0x%x int 0x%x\n", stat, intr)); - - incnt = txn->inbits; - outcnt = txn->outbits; - byte = (txn->opcode << 8); - WRITEUCTLDATA(byte); - - bytecnt = 0; - while (incnt > 0) { - byte = (txn->inbuf[bytecnt] << 8); - WRITEUCTLDATA(byte); - incnt--; - bytecnt++; - } - - /* Get the ack */ - READUCTLDATA(byte); - dprintk(("ack was %x\n", (byte >> 8))); - - bytecnt = 0; - while (outcnt > 0) { - READUCTLDATA(byte); - txn->outbuf[bytecnt] = (byte >> 8); - dprintk(("set byte to %02x\n", byte)); - outcnt--; - bytecnt++; - } -} - -static void uctrl_get_event_status(struct uctrl_driver *driver) -{ - struct uctrl_txn txn; - u8 outbits[2]; - - txn.opcode = READ_EVENT_STATUS; - txn.inbits = 0; - txn.outbits = 2; - txn.inbuf = NULL; - txn.outbuf = outbits; - - uctrl_do_txn(driver, &txn); - - dprintk(("bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff))); - driver->status.event_status = - ((outbits[0] & 0xff) << 8) | (outbits[1] & 0xff); - dprintk(("ev is %x\n", driver->status.event_status)); -} - -static void uctrl_get_external_status(struct uctrl_driver *driver) -{ - struct uctrl_txn txn; - u8 outbits[2]; - int i, v; - - txn.opcode = READ_EXTERNAL_STATUS; - txn.inbits = 0; - txn.outbits = 2; - txn.inbuf = NULL; - txn.outbuf = outbits; - - uctrl_do_txn(driver, &txn); - - dprintk(("bytes %x %x\n", (outbits[0] & 0xff), (outbits[1] & 0xff))); - driver->status.external_status = - ((outbits[0] * 256) + (outbits[1])); - dprintk(("ex is %x\n", driver->status.external_status)); - v = driver->status.external_status; - for (i = 0; v != 0; i++, v >>= 1) { - if (v & 1) { - dprintk(("%s%s", " ", uctrl_extstatus[i])); - } - } - dprintk(("\n")); - -} - -static int __devinit uctrl_probe(struct platform_device *op) -{ - struct uctrl_driver *p; - int err = -ENOMEM; - - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) { - printk(KERN_ERR "uctrl: Unable to allocate device struct.\n"); - goto out; - } - - p->regs = of_ioremap(&op->resource[0], 0, - resource_size(&op->resource[0]), - "uctrl"); - if (!p->regs) { - printk(KERN_ERR "uctrl: Unable to map registers.\n"); - goto out_free; - } - - p->irq = op->archdata.irqs[0]; - err = request_irq(p->irq, uctrl_interrupt, 0, "uctrl", p); - if (err) { - printk(KERN_ERR "uctrl: Unable to register irq.\n"); - goto out_iounmap; - } - - err = misc_register(&uctrl_dev); - if (err) { - printk(KERN_ERR "uctrl: Unable to register misc device.\n"); - goto out_free_irq; - } - - sbus_writel(UCTRL_INTR_RXNE_REQ|UCTRL_INTR_RXNE_MSK, &p->regs->uctrl_intr); - printk(KERN_INFO "%s: uctrl regs[0x%p] (irq %d)\n", - op->dev.of_node->full_name, p->regs, p->irq); - uctrl_get_event_status(p); - uctrl_get_external_status(p); - - dev_set_drvdata(&op->dev, p); - global_driver = p; - -out: - return err; - -out_free_irq: - free_irq(p->irq, p); - -out_iounmap: - of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0])); - -out_free: - kfree(p); - goto out; -} - -static int __devexit uctrl_remove(struct platform_device *op) -{ - struct uctrl_driver *p = dev_get_drvdata(&op->dev); - - if (p) { - misc_deregister(&uctrl_dev); - free_irq(p->irq, p); - of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0])); - kfree(p); - } - return 0; -} - -static const struct of_device_id uctrl_match[] = { - { - .name = "uctrl", - }, - {}, -}; -MODULE_DEVICE_TABLE(of, uctrl_match); - -static struct platform_driver uctrl_driver = { - .driver = { - .name = "uctrl", - .owner = THIS_MODULE, - .of_match_table = uctrl_match, - }, - .probe = uctrl_probe, - .remove = __devexit_p(uctrl_remove), -}; - - -module_platform_driver(uctrl_driver); - -MODULE_LICENSE("GPL"); |