summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/arch/powerpc/platforms/powermac
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /ANDROID_3.4.5/arch/powerpc/platforms/powermac
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2
FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized. Changes are basically to make it look like kernel structure.
Diffstat (limited to 'ANDROID_3.4.5/arch/powerpc/platforms/powermac')
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/Kconfig30
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/Makefile21
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/backlight.c220
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/bootx_init.c595
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/cache.S358
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_32.c718
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_64.c747
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/feature.c3053
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/low_i2c.c1514
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/nvram.c652
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/pci.c1357
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_base.c409
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_core.c1022
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/pic.c656
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/pmac.h42
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/setup.c685
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/sleep.S397
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/smp.c1037
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/time.c334
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_adb.c219
-rw-r--r--ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_scc.c184
21 files changed, 0 insertions, 14250 deletions
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Kconfig b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Kconfig
deleted file mode 100644
index 1afd10f6..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Kconfig
+++ /dev/null
@@ -1,30 +0,0 @@
-config PPC_PMAC
- bool "Apple PowerMac based machines"
- depends on PPC_BOOK3S
- select MPIC
- select PCI
- select PPC_INDIRECT_PCI if PPC32
- select PPC_MPC106 if PPC32
- select PPC_NATIVE
- default y
-
-config PPC_PMAC64
- bool
- depends on PPC_PMAC && POWER4
- select MPIC
- select U3_DART
- select MPIC_U3_HT_IRQS
- select GENERIC_TBSYNC
- select PPC_970_NAP
- default y
-
-config PPC_PMAC32_PSURGE
- bool "Support for powersurge upgrade cards" if EXPERT
- depends on SMP && PPC32 && PPC_PMAC
- select PPC_SMP_MUXED_IPI
- default y
- help
- The powersurge cpu boards can be used in the generation
- of powermacs that have a socket for an upgradeable cpu card,
- including the 7500, 8500, 9500, 9600. Support exists for
- both dual and quad socket upgrade cards.
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Makefile b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Makefile
deleted file mode 100644
index ea47df66..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/Makefile
+++ /dev/null
@@ -1,21 +0,0 @@
-CFLAGS_bootx_init.o += -fPIC
-
-ifdef CONFIG_FUNCTION_TRACER
-# Do not trace early boot code
-CFLAGS_REMOVE_bootx_init.o = -pg -mno-sched-epilog
-endif
-
-obj-y += pic.o setup.o time.o feature.o pci.o \
- sleep.o low_i2c.o cache.o pfunc_core.o \
- pfunc_base.o udbg_scc.o udbg_adb.o
-obj-$(CONFIG_PMAC_BACKLIGHT) += backlight.o
-obj-$(CONFIG_CPU_FREQ_PMAC) += cpufreq_32.o
-obj-$(CONFIG_CPU_FREQ_PMAC64) += cpufreq_64.o
-# CONFIG_NVRAM is an arch. independent tristate symbol, for pmac32 we really
-# need this to be a bool. Cheat here and pretend CONFIG_NVRAM=m is really
-# CONFIG_NVRAM=y
-obj-$(CONFIG_NVRAM:m=y) += nvram.o
-# ppc64 pmac doesn't define CONFIG_NVRAM but needs nvram stuff
-obj-$(CONFIG_PPC64) += nvram.o
-obj-$(CONFIG_PPC32) += bootx_init.o
-obj-$(CONFIG_SMP) += smp.o
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/backlight.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/backlight.c
deleted file mode 100644
index a00096b1..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/backlight.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Miscellaneous procedures for dealing with the PowerMac hardware.
- * Contains support for the backlight.
- *
- * Copyright (C) 2000 Benjamin Herrenschmidt
- * Copyright (C) 2006 Michael Hanselmann <linux-kernel@hansmi.ch>
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/atomic.h>
-#include <linux/export.h>
-#include <asm/prom.h>
-#include <asm/backlight.h>
-
-#define OLD_BACKLIGHT_MAX 15
-
-static void pmac_backlight_key_worker(struct work_struct *work);
-static void pmac_backlight_set_legacy_worker(struct work_struct *work);
-
-static DECLARE_WORK(pmac_backlight_key_work, pmac_backlight_key_worker);
-static DECLARE_WORK(pmac_backlight_set_legacy_work, pmac_backlight_set_legacy_worker);
-
-/* Although these variables are used in interrupt context, it makes no sense to
- * protect them. No user is able to produce enough key events per second and
- * notice the errors that might happen.
- */
-static int pmac_backlight_key_queued;
-static int pmac_backlight_set_legacy_queued;
-
-/* The via-pmu code allows the backlight to be grabbed, in which case the
- * in-kernel control of the brightness needs to be disabled. This should
- * only be used by really old PowerBooks.
- */
-static atomic_t kernel_backlight_disabled = ATOMIC_INIT(0);
-
-/* Protect the pmac_backlight variable below.
- You should hold this lock when using the pmac_backlight pointer to
- prevent its potential removal. */
-DEFINE_MUTEX(pmac_backlight_mutex);
-
-/* Main backlight storage
- *
- * Backlight drivers in this variable are required to have the "ops"
- * attribute set and to have an update_status function.
- *
- * We can only store one backlight here, but since Apple laptops have only one
- * internal display, it doesn't matter. Other backlight drivers can be used
- * independently.
- *
- */
-struct backlight_device *pmac_backlight;
-
-int pmac_has_backlight_type(const char *type)
-{
- struct device_node* bk_node = of_find_node_by_name(NULL, "backlight");
-
- if (bk_node) {
- const char *prop = of_get_property(bk_node,
- "backlight-control", NULL);
- if (prop && strncmp(prop, type, strlen(type)) == 0) {
- of_node_put(bk_node);
- return 1;
- }
- of_node_put(bk_node);
- }
-
- return 0;
-}
-
-int pmac_backlight_curve_lookup(struct fb_info *info, int value)
-{
- int level = (FB_BACKLIGHT_LEVELS - 1);
-
- if (info && info->bl_dev) {
- int i, max = 0;
-
- /* Look for biggest value */
- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++)
- max = max((int)info->bl_curve[i], max);
-
- /* Look for nearest value */
- for (i = 0; i < FB_BACKLIGHT_LEVELS; i++) {
- int diff = abs(info->bl_curve[i] - value);
- if (diff < max) {
- max = diff;
- level = i;
- }
- }
-
- }
-
- return level;
-}
-
-static void pmac_backlight_key_worker(struct work_struct *work)
-{
- if (atomic_read(&kernel_backlight_disabled))
- return;
-
- mutex_lock(&pmac_backlight_mutex);
- if (pmac_backlight) {
- struct backlight_properties *props;
- int brightness;
-
- props = &pmac_backlight->props;
-
- brightness = props->brightness +
- ((pmac_backlight_key_queued?-1:1) *
- (props->max_brightness / 15));
-
- if (brightness < 0)
- brightness = 0;
- else if (brightness > props->max_brightness)
- brightness = props->max_brightness;
-
- props->brightness = brightness;
- backlight_update_status(pmac_backlight);
- }
- mutex_unlock(&pmac_backlight_mutex);
-}
-
-/* This function is called in interrupt context */
-void pmac_backlight_key(int direction)
-{
- if (atomic_read(&kernel_backlight_disabled))
- return;
-
- /* we can receive multiple interrupts here, but the scheduled work
- * will run only once, with the last value
- */
- pmac_backlight_key_queued = direction;
- schedule_work(&pmac_backlight_key_work);
-}
-
-static int __pmac_backlight_set_legacy_brightness(int brightness)
-{
- int error = -ENXIO;
-
- mutex_lock(&pmac_backlight_mutex);
- if (pmac_backlight) {
- struct backlight_properties *props;
-
- props = &pmac_backlight->props;
- props->brightness = brightness *
- (props->max_brightness + 1) /
- (OLD_BACKLIGHT_MAX + 1);
-
- if (props->brightness > props->max_brightness)
- props->brightness = props->max_brightness;
- else if (props->brightness < 0)
- props->brightness = 0;
-
- backlight_update_status(pmac_backlight);
-
- error = 0;
- }
- mutex_unlock(&pmac_backlight_mutex);
-
- return error;
-}
-
-static void pmac_backlight_set_legacy_worker(struct work_struct *work)
-{
- if (atomic_read(&kernel_backlight_disabled))
- return;
-
- __pmac_backlight_set_legacy_brightness(pmac_backlight_set_legacy_queued);
-}
-
-/* This function is called in interrupt context */
-void pmac_backlight_set_legacy_brightness_pmu(int brightness) {
- if (atomic_read(&kernel_backlight_disabled))
- return;
-
- pmac_backlight_set_legacy_queued = brightness;
- schedule_work(&pmac_backlight_set_legacy_work);
-}
-
-int pmac_backlight_set_legacy_brightness(int brightness)
-{
- return __pmac_backlight_set_legacy_brightness(brightness);
-}
-
-int pmac_backlight_get_legacy_brightness()
-{
- int result = -ENXIO;
-
- mutex_lock(&pmac_backlight_mutex);
- if (pmac_backlight) {
- struct backlight_properties *props;
-
- props = &pmac_backlight->props;
-
- result = props->brightness *
- (OLD_BACKLIGHT_MAX + 1) /
- (props->max_brightness + 1);
- }
- mutex_unlock(&pmac_backlight_mutex);
-
- return result;
-}
-
-void pmac_backlight_disable()
-{
- atomic_inc(&kernel_backlight_disabled);
-}
-
-void pmac_backlight_enable()
-{
- atomic_dec(&kernel_backlight_disabled);
-}
-
-EXPORT_SYMBOL_GPL(pmac_backlight);
-EXPORT_SYMBOL_GPL(pmac_backlight_mutex);
-EXPORT_SYMBOL_GPL(pmac_has_backlight_type);
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/bootx_init.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/bootx_init.c
deleted file mode 100644
index 3e91ef53..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/bootx_init.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*
- * Early boot support code for BootX bootloader
- *
- * Copyright (C) 2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <generated/utsrelease.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/page.h>
-#include <asm/bootx.h>
-#include <asm/btext.h>
-#include <asm/io.h>
-#include <asm/setup.h>
-
-#undef DEBUG
-#define SET_BOOT_BAT
-
-#ifdef DEBUG
-#define DBG(fmt...) do { bootx_printf(fmt); } while(0)
-#else
-#define DBG(fmt...) do { } while(0)
-#endif
-
-extern void __start(unsigned long r3, unsigned long r4, unsigned long r5);
-
-static unsigned long __initdata bootx_dt_strbase;
-static unsigned long __initdata bootx_dt_strend;
-static unsigned long __initdata bootx_node_chosen;
-static boot_infos_t * __initdata bootx_info;
-static char __initdata bootx_disp_path[256];
-
-/* Is boot-info compatible ? */
-#define BOOT_INFO_IS_COMPATIBLE(bi) \
- ((bi)->compatible_version <= BOOT_INFO_VERSION)
-#define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2)
-#define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4)
-
-#ifdef CONFIG_BOOTX_TEXT
-static void __init bootx_printf(const char *format, ...)
-{
- const char *p, *q, *s;
- va_list args;
- unsigned long v;
-
- va_start(args, format);
- for (p = format; *p != 0; p = q) {
- for (q = p; *q != 0 && *q != '\n' && *q != '%'; ++q)
- ;
- if (q > p)
- btext_drawtext(p, q - p);
- if (*q == 0)
- break;
- if (*q == '\n') {
- ++q;
- btext_flushline();
- btext_drawstring("\r\n");
- btext_flushline();
- continue;
- }
- ++q;
- if (*q == 0)
- break;
- switch (*q) {
- case 's':
- ++q;
- s = va_arg(args, const char *);
- if (s == NULL)
- s = "<NULL>";
- btext_drawstring(s);
- break;
- case 'x':
- ++q;
- v = va_arg(args, unsigned long);
- btext_drawhex(v);
- break;
- }
- }
-}
-#else /* CONFIG_BOOTX_TEXT */
-static void __init bootx_printf(const char *format, ...) {}
-#endif /* CONFIG_BOOTX_TEXT */
-
-static void * __init bootx_early_getprop(unsigned long base,
- unsigned long node,
- char *prop)
-{
- struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
- u32 *ppp = &np->properties;
-
- while(*ppp) {
- struct bootx_dt_prop *pp =
- (struct bootx_dt_prop *)(base + *ppp);
-
- if (strcmp((char *)((unsigned long)pp->name + base),
- prop) == 0) {
- return (void *)((unsigned long)pp->value + base);
- }
- ppp = &pp->next;
- }
- return NULL;
-}
-
-#define dt_push_token(token, mem) \
- do { \
- *(mem) = _ALIGN_UP(*(mem),4); \
- *((u32 *)*(mem)) = token; \
- *(mem) += 4; \
- } while(0)
-
-static unsigned long __init bootx_dt_find_string(char *str)
-{
- char *s, *os;
-
- s = os = (char *)bootx_dt_strbase;
- s += 4;
- while (s < (char *)bootx_dt_strend) {
- if (strcmp(s, str) == 0)
- return s - os;
- s += strlen(s) + 1;
- }
- return 0;
-}
-
-static void __init bootx_dt_add_prop(char *name, void *data, int size,
- unsigned long *mem_end)
-{
- unsigned long soff = bootx_dt_find_string(name);
- if (data == NULL)
- size = 0;
- if (soff == 0) {
- bootx_printf("WARNING: Can't find string index for <%s>\n",
- name);
- return;
- }
- if (size > 0x20000) {
- bootx_printf("WARNING: ignoring large property ");
- bootx_printf("%s length 0x%x\n", name, size);
- return;
- }
- dt_push_token(OF_DT_PROP, mem_end);
- dt_push_token(size, mem_end);
- dt_push_token(soff, mem_end);
-
- /* push property content */
- if (size && data) {
- memcpy((void *)*mem_end, data, size);
- *mem_end = _ALIGN_UP(*mem_end + size, 4);
- }
-}
-
-static void __init bootx_add_chosen_props(unsigned long base,
- unsigned long *mem_end)
-{
- u32 val;
-
- bootx_dt_add_prop("linux,bootx", NULL, 0, mem_end);
-
- if (bootx_info->kernelParamsOffset) {
- char *args = (char *)((unsigned long)bootx_info) +
- bootx_info->kernelParamsOffset;
- bootx_dt_add_prop("bootargs", args, strlen(args) + 1, mem_end);
- }
- if (bootx_info->ramDisk) {
- val = ((unsigned long)bootx_info) + bootx_info->ramDisk;
- bootx_dt_add_prop("linux,initrd-start", &val, 4, mem_end);
- val += bootx_info->ramDiskSize;
- bootx_dt_add_prop("linux,initrd-end", &val, 4, mem_end);
- }
- if (strlen(bootx_disp_path))
- bootx_dt_add_prop("linux,stdout-path", bootx_disp_path,
- strlen(bootx_disp_path) + 1, mem_end);
-}
-
-static void __init bootx_add_display_props(unsigned long base,
- unsigned long *mem_end,
- int has_real_node)
-{
- boot_infos_t *bi = bootx_info;
- u32 tmp;
-
- if (has_real_node) {
- bootx_dt_add_prop("linux,boot-display", NULL, 0, mem_end);
- bootx_dt_add_prop("linux,opened", NULL, 0, mem_end);
- } else
- bootx_dt_add_prop("linux,bootx-noscreen", NULL, 0, mem_end);
-
- tmp = bi->dispDeviceDepth;
- bootx_dt_add_prop("linux,bootx-depth", &tmp, 4, mem_end);
- tmp = bi->dispDeviceRect[2] - bi->dispDeviceRect[0];
- bootx_dt_add_prop("linux,bootx-width", &tmp, 4, mem_end);
- tmp = bi->dispDeviceRect[3] - bi->dispDeviceRect[1];
- bootx_dt_add_prop("linux,bootx-height", &tmp, 4, mem_end);
- tmp = bi->dispDeviceRowBytes;
- bootx_dt_add_prop("linux,bootx-linebytes", &tmp, 4, mem_end);
- tmp = (u32)bi->dispDeviceBase;
- if (tmp == 0)
- tmp = (u32)bi->logicalDisplayBase;
- tmp += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
- tmp += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
- bootx_dt_add_prop("linux,bootx-addr", &tmp, 4, mem_end);
-}
-
-static void __init bootx_dt_add_string(char *s, unsigned long *mem_end)
-{
- unsigned int l = strlen(s) + 1;
- memcpy((void *)*mem_end, s, l);
- bootx_dt_strend = *mem_end = *mem_end + l;
-}
-
-static void __init bootx_scan_dt_build_strings(unsigned long base,
- unsigned long node,
- unsigned long *mem_end)
-{
- struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
- u32 *cpp, *ppp = &np->properties;
- unsigned long soff;
- char *namep;
-
- /* Keep refs to known nodes */
- namep = np->full_name ? (char *)(base + np->full_name) : NULL;
- if (namep == NULL) {
- bootx_printf("Node without a full name !\n");
- namep = "";
- }
- DBG("* strings: %s\n", namep);
-
- if (!strcmp(namep, "/chosen")) {
- DBG(" detected /chosen ! adding properties names !\n");
- bootx_dt_add_string("linux,bootx", mem_end);
- bootx_dt_add_string("linux,stdout-path", mem_end);
- bootx_dt_add_string("linux,initrd-start", mem_end);
- bootx_dt_add_string("linux,initrd-end", mem_end);
- bootx_dt_add_string("bootargs", mem_end);
- bootx_node_chosen = node;
- }
- if (node == bootx_info->dispDeviceRegEntryOffset) {
- DBG(" detected display ! adding properties names !\n");
- bootx_dt_add_string("linux,boot-display", mem_end);
- bootx_dt_add_string("linux,opened", mem_end);
- strncpy(bootx_disp_path, namep, 255);
- }
-
- /* get and store all property names */
- while (*ppp) {
- struct bootx_dt_prop *pp =
- (struct bootx_dt_prop *)(base + *ppp);
-
- namep = pp->name ? (char *)(base + pp->name) : NULL;
- if (namep == NULL || strcmp(namep, "name") == 0)
- goto next;
- /* get/create string entry */
- soff = bootx_dt_find_string(namep);
- if (soff == 0)
- bootx_dt_add_string(namep, mem_end);
- next:
- ppp = &pp->next;
- }
-
- /* do all our children */
- cpp = &np->child;
- while(*cpp) {
- np = (struct bootx_dt_node *)(base + *cpp);
- bootx_scan_dt_build_strings(base, *cpp, mem_end);
- cpp = &np->sibling;
- }
-}
-
-static void __init bootx_scan_dt_build_struct(unsigned long base,
- unsigned long node,
- unsigned long *mem_end)
-{
- struct bootx_dt_node *np = (struct bootx_dt_node *)(base + node);
- u32 *cpp, *ppp = &np->properties;
- char *namep, *p, *ep, *lp;
- int l;
-
- dt_push_token(OF_DT_BEGIN_NODE, mem_end);
-
- /* get the node's full name */
- namep = np->full_name ? (char *)(base + np->full_name) : NULL;
- if (namep == NULL)
- namep = "";
- l = strlen(namep);
-
- DBG("* struct: %s\n", namep);
-
- /* Fixup an Apple bug where they have bogus \0 chars in the
- * middle of the path in some properties, and extract
- * the unit name (everything after the last '/').
- */
- memcpy((void *)*mem_end, namep, l + 1);
- namep = (char *)*mem_end;
- for (lp = p = namep, ep = namep + l; p < ep; p++) {
- if (*p == '/')
- lp = namep;
- else if (*p != 0)
- *lp++ = *p;
- }
- *lp = 0;
- *mem_end = _ALIGN_UP((unsigned long)lp + 1, 4);
-
- /* get and store all properties */
- while (*ppp) {
- struct bootx_dt_prop *pp =
- (struct bootx_dt_prop *)(base + *ppp);
-
- namep = pp->name ? (char *)(base + pp->name) : NULL;
- /* Skip "name" */
- if (namep == NULL || !strcmp(namep, "name"))
- goto next;
- /* Skip "bootargs" in /chosen too as we replace it */
- if (node == bootx_node_chosen && !strcmp(namep, "bootargs"))
- goto next;
-
- /* push property head */
- bootx_dt_add_prop(namep,
- pp->value ? (void *)(base + pp->value): NULL,
- pp->length, mem_end);
- next:
- ppp = &pp->next;
- }
-
- if (node == bootx_node_chosen) {
- bootx_add_chosen_props(base, mem_end);
- if (bootx_info->dispDeviceRegEntryOffset == 0)
- bootx_add_display_props(base, mem_end, 0);
- }
- else if (node == bootx_info->dispDeviceRegEntryOffset)
- bootx_add_display_props(base, mem_end, 1);
-
- /* do all our children */
- cpp = &np->child;
- while(*cpp) {
- np = (struct bootx_dt_node *)(base + *cpp);
- bootx_scan_dt_build_struct(base, *cpp, mem_end);
- cpp = &np->sibling;
- }
-
- dt_push_token(OF_DT_END_NODE, mem_end);
-}
-
-static unsigned long __init bootx_flatten_dt(unsigned long start)
-{
- boot_infos_t *bi = bootx_info;
- unsigned long mem_start, mem_end;
- struct boot_param_header *hdr;
- unsigned long base;
- u64 *rsvmap;
-
- /* Start using memory after the big blob passed by BootX, get
- * some space for the header
- */
- mem_start = mem_end = _ALIGN_UP(((unsigned long)bi) + start, 4);
- DBG("Boot params header at: %x\n", mem_start);
- hdr = (struct boot_param_header *)mem_start;
- mem_end += sizeof(struct boot_param_header);
- rsvmap = (u64 *)(_ALIGN_UP(mem_end, 8));
- hdr->off_mem_rsvmap = ((unsigned long)rsvmap) - mem_start;
- mem_end = ((unsigned long)rsvmap) + 8 * sizeof(u64);
-
- /* Get base of tree */
- base = ((unsigned long)bi) + bi->deviceTreeOffset;
-
- /* Build string array */
- DBG("Building string array at: %x\n", mem_end);
- DBG("Device Tree Base=%x\n", base);
- bootx_dt_strbase = mem_end;
- mem_end += 4;
- bootx_dt_strend = mem_end;
- bootx_scan_dt_build_strings(base, 4, &mem_end);
- /* Add some strings */
- bootx_dt_add_string("linux,bootx-noscreen", &mem_end);
- bootx_dt_add_string("linux,bootx-depth", &mem_end);
- bootx_dt_add_string("linux,bootx-width", &mem_end);
- bootx_dt_add_string("linux,bootx-height", &mem_end);
- bootx_dt_add_string("linux,bootx-linebytes", &mem_end);
- bootx_dt_add_string("linux,bootx-addr", &mem_end);
- /* Wrap up strings */
- hdr->off_dt_strings = bootx_dt_strbase - mem_start;
- hdr->dt_strings_size = bootx_dt_strend - bootx_dt_strbase;
-
- /* Build structure */
- mem_end = _ALIGN(mem_end, 16);
- DBG("Building device tree structure at: %x\n", mem_end);
- hdr->off_dt_struct = mem_end - mem_start;
- bootx_scan_dt_build_struct(base, 4, &mem_end);
- dt_push_token(OF_DT_END, &mem_end);
-
- /* Finish header */
- hdr->boot_cpuid_phys = 0;
- hdr->magic = OF_DT_HEADER;
- hdr->totalsize = mem_end - mem_start;
- hdr->version = OF_DT_VERSION;
- /* Version 16 is not backward compatible */
- hdr->last_comp_version = 0x10;
-
- /* Reserve the whole thing and copy the reserve map in, we
- * also bump mem_reserve_cnt to cause further reservations to
- * fail since it's too late.
- */
- mem_end = _ALIGN(mem_end, PAGE_SIZE);
- DBG("End of boot params: %x\n", mem_end);
- rsvmap[0] = mem_start;
- rsvmap[1] = mem_end;
- if (bootx_info->ramDisk) {
- rsvmap[2] = ((unsigned long)bootx_info) + bootx_info->ramDisk;
- rsvmap[3] = rsvmap[2] + bootx_info->ramDiskSize;
- rsvmap[4] = 0;
- rsvmap[5] = 0;
- } else {
- rsvmap[2] = 0;
- rsvmap[3] = 0;
- }
-
- return (unsigned long)hdr;
-}
-
-
-#ifdef CONFIG_BOOTX_TEXT
-static void __init btext_welcome(boot_infos_t *bi)
-{
- unsigned long flags;
- unsigned long pvr;
-
- bootx_printf("Welcome to Linux, kernel " UTS_RELEASE "\n");
- bootx_printf("\nlinked at : 0x%x", KERNELBASE);
- bootx_printf("\nframe buffer at : 0x%x", bi->dispDeviceBase);
- bootx_printf(" (phys), 0x%x", bi->logicalDisplayBase);
- bootx_printf(" (log)");
- bootx_printf("\nklimit : 0x%x",(unsigned long)klimit);
- bootx_printf("\nboot_info at : 0x%x", bi);
- __asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
- bootx_printf("\nMSR : 0x%x", flags);
- __asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
- bootx_printf("\nPVR : 0x%x", pvr);
- pvr >>= 16;
- if (pvr > 1) {
- __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
- bootx_printf("\nHID0 : 0x%x", flags);
- }
- if (pvr == 8 || pvr == 12 || pvr == 0x800c) {
- __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
- bootx_printf("\nICTC : 0x%x", flags);
- }
-#ifdef DEBUG
- bootx_printf("\n\n");
- bootx_printf("bi->deviceTreeOffset : 0x%x\n",
- bi->deviceTreeOffset);
- bootx_printf("bi->deviceTreeSize : 0x%x\n",
- bi->deviceTreeSize);
-#endif
- bootx_printf("\n\n");
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-void __init bootx_init(unsigned long r3, unsigned long r4)
-{
- boot_infos_t *bi = (boot_infos_t *) r4;
- unsigned long hdr;
- unsigned long space;
- unsigned long ptr, x;
- char *model;
- unsigned long offset = reloc_offset();
-
- reloc_got2(offset);
-
- bootx_info = bi;
-
- /* We haven't cleared any bss at this point, make sure
- * what we need is initialized
- */
- bootx_dt_strbase = bootx_dt_strend = 0;
- bootx_node_chosen = 0;
- bootx_disp_path[0] = 0;
-
- if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
- bi->logicalDisplayBase = bi->dispDeviceBase;
-
- /* Fixup depth 16 -> 15 as that's what MacOS calls 16bpp */
- if (bi->dispDeviceDepth == 16)
- bi->dispDeviceDepth = 15;
-
-
-#ifdef CONFIG_BOOTX_TEXT
- ptr = (unsigned long)bi->logicalDisplayBase;
- ptr += bi->dispDeviceRect[1] * bi->dispDeviceRowBytes;
- ptr += bi->dispDeviceRect[0] * ((bi->dispDeviceDepth + 7) / 8);
- btext_setup_display(bi->dispDeviceRect[2] - bi->dispDeviceRect[0],
- bi->dispDeviceRect[3] - bi->dispDeviceRect[1],
- bi->dispDeviceDepth, bi->dispDeviceRowBytes,
- (unsigned long)bi->logicalDisplayBase);
- btext_clearscreen();
- btext_flushscreen();
-#endif /* CONFIG_BOOTX_TEXT */
-
- /*
- * Test if boot-info is compatible. Done only in config
- * CONFIG_BOOTX_TEXT since there is nothing much we can do
- * with an incompatible version, except display a message
- * and eventually hang the processor...
- *
- * I'll try to keep enough of boot-info compatible in the
- * future to always allow display of this message;
- */
- if (!BOOT_INFO_IS_COMPATIBLE(bi)) {
- bootx_printf(" !!! WARNING - Incompatible version"
- " of BootX !!!\n\n\n");
- for (;;)
- ;
- }
- if (bi->architecture != BOOT_ARCH_PCI) {
- bootx_printf(" !!! WARNING - Usupported machine"
- " architecture !\n");
- for (;;)
- ;
- }
-
-#ifdef CONFIG_BOOTX_TEXT
- btext_welcome(bi);
-#endif
-
- /* New BootX enters kernel with MMU off, i/os are not allowed
- * here. This hack will have been done by the boostrap anyway.
- */
- if (bi->version < 4) {
- /*
- * XXX If this is an iMac, turn off the USB controller.
- */
- model = (char *) bootx_early_getprop(r4 + bi->deviceTreeOffset,
- 4, "model");
- if (model
- && (strcmp(model, "iMac,1") == 0
- || strcmp(model, "PowerMac1,1") == 0)) {
- bootx_printf("iMac,1 detected, shutting down USB\n");
- out_le32((unsigned __iomem *)0x80880008, 1); /* XXX */
- }
- }
-
- /* Get a pointer that points above the device tree, args, ramdisk,
- * etc... to use for generating the flattened tree
- */
- if (bi->version < 5) {
- space = bi->deviceTreeOffset + bi->deviceTreeSize;
- if (bi->ramDisk >= space)
- space = bi->ramDisk + bi->ramDiskSize;
- } else
- space = bi->totalParamsSize;
-
- bootx_printf("Total space used by parameters & ramdisk: 0x%x\n", space);
-
- /* New BootX will have flushed all TLBs and enters kernel with
- * MMU switched OFF, so this should not be useful anymore.
- */
- if (bi->version < 4) {
- bootx_printf("Touching pages...\n");
-
- /*
- * Touch each page to make sure the PTEs for them
- * are in the hash table - the aim is to try to avoid
- * getting DSI exceptions while copying the kernel image.
- */
- for (ptr = ((unsigned long) &_stext) & PAGE_MASK;
- ptr < (unsigned long)bi + space; ptr += PAGE_SIZE)
- x = *(volatile unsigned long *)ptr;
- }
-
- /* Ok, now we need to generate a flattened device-tree to pass
- * to the kernel
- */
- bootx_printf("Preparing boot params...\n");
-
- hdr = bootx_flatten_dt(space);
-
-#ifdef CONFIG_BOOTX_TEXT
-#ifdef SET_BOOT_BAT
- bootx_printf("Preparing BAT...\n");
- btext_prepare_BAT();
-#else
- btext_unmap();
-#endif
-#endif
-
- reloc_got2(-offset);
-
- __start(hdr, KERNELBASE + offset, 0);
-}
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cache.S b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cache.S
deleted file mode 100644
index 6be1a4af..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cache.S
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * This file contains low-level cache management functions
- * used for sleep and CPU speed changes on Apple machines.
- * (In fact the only thing that is Apple-specific is that we assume
- * that we can read from ROM at physical address 0xfff00000.)
- *
- * Copyright (C) 2004 Paul Mackerras (paulus@samba.org) and
- * Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- *
- */
-
-#include <asm/processor.h>
-#include <asm/ppc_asm.h>
-#include <asm/cputable.h>
-
-/*
- * Flush and disable all data caches (dL1, L2, L3). This is used
- * when going to sleep, when doing a PMU based cpufreq transition,
- * or when "offlining" a CPU on SMP machines. This code is over
- * paranoid, but I've had enough issues with various CPU revs and
- * bugs that I decided it was worth beeing over cautious
- */
-
-_GLOBAL(flush_disable_caches)
-#ifndef CONFIG_6xx
- blr
-#else
-BEGIN_FTR_SECTION
- b flush_disable_745x
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-BEGIN_FTR_SECTION
- b flush_disable_75x
-END_FTR_SECTION_IFSET(CPU_FTR_L2CR)
- b __flush_disable_L1
-
-/* This is the code for G3 and 74[01]0 */
-flush_disable_75x:
- mflr r10
-
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop DST streams */
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-
- /* Stop DPM */
- mfspr r8,SPRN_HID0 /* Save SPRN_HID0 in r8 */
- rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */
- sync
- mtspr SPRN_HID0,r4 /* Disable DPM */
- sync
-
- /* Disp-flush L1. We have a weird problem here that I never
- * totally figured out. On 750FX, using the ROM for the flush
- * results in a non-working flush. We use that workaround for
- * now until I finally understand what's going on. --BenH
- */
-
- /* ROM base by default */
- lis r4,0xfff0
- mfpvr r3
- srwi r3,r3,16
- cmplwi cr0,r3,0x7000
- bne+ 1f
- /* RAM base on 750FX */
- li r4,0
-1: li r4,0x4000
- mtctr r4
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* Disable / invalidate / enable L1 data */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,~(HID0_DCE | HID0_ICE)
- mtspr SPRN_HID0,r3
- sync
- isync
- ori r3,r3,(HID0_DCE|HID0_DCI|HID0_ICE|HID0_ICFI)
- sync
- isync
- mtspr SPRN_HID0,r3
- xori r3,r3,(HID0_DCI|HID0_ICFI)
- mtspr SPRN_HID0,r3
- sync
-
- /* Get the current enable bit of the L2CR into r4 */
- mfspr r5,SPRN_L2CR
- /* Set to data-only (pre-745x bit) */
- oris r3,r5,L2CR_L2DO@h
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: /* disp-flush L2. The interesting thing here is that the L2 can be
- * up to 2Mb ... so using the ROM, we'll end up wrapping back to memory
- * but that is probbaly fine. We disp-flush over 4Mb to be safe
- */
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: lwz r0,0(r4)
- addi r4,r4,32
- bdnz 1b
- sync
- isync
- lis r4,2
- mtctr r4
- lis r4,0xfff0
-1: dcbf 0,r4
- addi r4,r4,32
- bdnz 1b
- sync
- isync
-
- /* now disable L2 */
- rlwinm r5,r5,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r5
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- /* Invalidate L2. This is pre-745x, we clear the L2I bit ourselves */
- oris r4,r5,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-
- /* Wait for the invalidation to complete */
-1: mfspr r3,SPRN_L2CR
- rlwinm. r0,r3,0,31,31
- bne 1b
-
- /* Clear L2I */
- xoris r4,r4,L2CR_L2I@h
- sync
- mtspr SPRN_L2CR,r4
- sync
-
- /* now disable the L1 data cache */
- mfspr r0,SPRN_HID0
- rlwinm r0,r0,0,~(HID0_DCE|HID0_ICE)
- mtspr SPRN_HID0,r0
- sync
- isync
-
- /* Restore HID0[DPM] to whatever it was before */
- sync
- mfspr r0,SPRN_HID0
- rlwimi r0,r8,0,11,11 /* Turn back HID0[DPM] */
- mtspr SPRN_HID0,r0
- sync
-
- /* restore DR and EE */
- sync
- mtmsr r11
- isync
-
- mtlr r10
- blr
-
-/* This code is for 745x processors */
-flush_disable_745x:
- /* Turn off EE and DR in MSR */
- mfmsr r11
- rlwinm r0,r11,0,~MSR_EE
- rlwinm r0,r0,0,~MSR_DR
- sync
- mtmsr r0
- isync
-
- /* Stop prefetch streams */
- DSSALL
- sync
-
- /* Disable L2 prefetching */
- mfspr r0,SPRN_MSSCR0
- rlwinm r0,r0,0,0,29
- mtspr SPRN_MSSCR0,r0
- sync
- isync
- lis r4,0
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
- dcbf 0,r4
-
- /* Due to a bug with the HW flush on some CPU revs, we occasionally
- * experience data corruption. I'm adding a displacement flush along
- * with a dcbf loop over a few Mb to "help". The problem isn't totally
- * fixed by this in theory, but at least, in practice, I couldn't reproduce
- * it even with a big hammer...
- */
-
- lis r4,0x0002
- mtctr r4
- li r4,0
-1:
- lwz r0,0(r4)
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
- isync
-
- /* Now, flush the first 4MB of memory */
- lis r4,0x0002
- mtctr r4
- li r4,0
- sync
-1:
- dcbf 0,r4
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
-
- /* Flush and disable the L1 data cache */
- mfspr r6,SPRN_LDSTCR
- lis r3,0xfff0 /* read from ROM for displacement flush */
- li r4,0xfe /* start with only way 0 unlocked */
- li r5,128 /* 128 lines in each way */
-1: mtctr r5
- rlwimi r6,r4,0,24,31
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-2: lwz r0,0(r3) /* touch each cache line */
- addi r3,r3,32
- bdnz 2b
- rlwinm r4,r4,1,24,30 /* move on to the next way */
- ori r4,r4,1
- cmpwi r4,0xff /* all done? */
- bne 1b
- /* now unlock the L1 data cache */
- li r4,0
- rlwimi r6,r4,0,24,31
- sync
- mtspr SPRN_LDSTCR,r6
- sync
- isync
-
- /* Flush the L2 cache using the hardware assist */
- mfspr r3,SPRN_L2CR
- cmpwi r3,0 /* check if it is enabled first */
- bge 4f
- oris r0,r3,(L2CR_L2IO_745x|L2CR_L2DO_745x)@h
- b 2f
- /* When disabling/locking L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r0 /* lock the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- ori r0,r3,L2CR_L2HWF_745x
- sync
- mtspr SPRN_L2CR,r0 /* set the hardware flush bit */
-3: mfspr r0,SPRN_L2CR /* wait for it to go to 0 */
- andi. r0,r0,L2CR_L2HWF_745x
- bne 3b
- sync
- rlwinm r3,r3,0,~L2CR_L2E
- b 2f
- /* When disabling L2, code must be in L1 */
- .balign 32
-1: mtspr SPRN_L2CR,r3 /* disable the L2 cache */
-3: sync
- isync
- b 1f
-2: b 3f
-3: sync
- isync
- b 1b
-1: sync
- isync
- oris r4,r3,L2CR_L2I@h
- mtspr SPRN_L2CR,r4
- sync
- isync
-1: mfspr r4,SPRN_L2CR
- andis. r0,r4,L2CR_L2I@h
- bne 1b
- sync
-
-BEGIN_FTR_SECTION
- /* Flush the L3 cache using the hardware assist */
-4: mfspr r3,SPRN_L3CR
- cmpwi r3,0 /* check if it is enabled */
- bge 6f
- oris r0,r3,L3CR_L3IO@h
- ori r0,r0,L3CR_L3DO
- sync
- mtspr SPRN_L3CR,r0 /* lock the L3 cache */
- sync
- isync
- ori r0,r0,L3CR_L3HWF
- sync
- mtspr SPRN_L3CR,r0 /* set the hardware flush bit */
-5: mfspr r0,SPRN_L3CR /* wait for it to go to zero */
- andi. r0,r0,L3CR_L3HWF
- bne 5b
- rlwinm r3,r3,0,~L3CR_L3E
- sync
- mtspr SPRN_L3CR,r3 /* disable the L3 cache */
- sync
- ori r4,r3,L3CR_L3I
- mtspr SPRN_L3CR,r4
-1: mfspr r4,SPRN_L3CR
- andi. r0,r4,L3CR_L3I
- bne 1b
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_L3CR)
-
-6: mfspr r0,SPRN_HID0 /* now disable the L1 data cache */
- rlwinm r0,r0,0,~HID0_DCE
- mtspr SPRN_HID0,r0
- sync
- isync
- mtmsr r11 /* restore DR and EE */
- isync
- blr
-#endif /* CONFIG_6xx */
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_32.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_32.c
deleted file mode 100644
index 64171198..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_32.c
+++ /dev/null
@@ -1,718 +0,0 @@
-/*
- * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * Copyright (C) 2004 John Steele Scott <toojays@toojays.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * TODO: Need a big cleanup here. Basically, we need to have different
- * cpufreq_driver structures for the different type of HW instead of the
- * current mess. We also need to better deal with the detection of the
- * type of machine.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/hardirq.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/irq.h>
-#include <asm/pmac_feature.h>
-#include <asm/mmu_context.h>
-#include <asm/sections.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/mpic.h>
-#include <asm/keylargo.h>
-#include <asm/switch_to.h>
-
-/* WARNING !!! This will cause calibrate_delay() to be called,
- * but this is an __init function ! So you MUST go edit
- * init/main.c to make it non-init before enabling DEBUG_FREQ
- */
-#undef DEBUG_FREQ
-
-extern void low_choose_7447a_dfs(int dfs);
-extern void low_choose_750fx_pll(int pll);
-extern void low_sleep_handler(void);
-
-/*
- * Currently, PowerMac cpufreq supports only high & low frequencies
- * that are set by the firmware
- */
-static unsigned int low_freq;
-static unsigned int hi_freq;
-static unsigned int cur_freq;
-static unsigned int sleep_freq;
-
-/*
- * Different models uses different mechanisms to switch the frequency
- */
-static int (*set_speed_proc)(int low_speed);
-static unsigned int (*get_speed_proc)(void);
-
-/*
- * Some definitions used by the various speedprocs
- */
-static u32 voltage_gpio;
-static u32 frequency_gpio;
-static u32 slew_done_gpio;
-static int no_schedule;
-static int has_cpu_l2lve;
-static int is_pmu_based;
-
-/* There are only two frequency states for each processor. Values
- * are in kHz for the time being.
- */
-#define CPUFREQ_HIGH 0
-#define CPUFREQ_LOW 1
-
-static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
- {CPUFREQ_HIGH, 0},
- {CPUFREQ_LOW, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* pmac_cpu_freqs_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-static inline void local_delay(unsigned long ms)
-{
- if (no_schedule)
- mdelay(ms);
- else
- msleep(ms);
-}
-
-#ifdef DEBUG_FREQ
-static inline void debug_calc_bogomips(void)
-{
- /* This will cause a recalc of bogomips and display the
- * result. We backup/restore the value to avoid affecting the
- * core cpufreq framework's own calculation.
- */
- unsigned long save_lpj = loops_per_jiffy;
- calibrate_delay();
- loops_per_jiffy = save_lpj;
-}
-#endif /* DEBUG_FREQ */
-
-/* Switch CPU speed under 750FX CPU control
- */
-static int cpu_750fx_cpu_speed(int low_speed)
-{
- u32 hid2;
-
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(10);
-
- /* tweak L2 for high voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 &= ~0x2000;
- mtspr(SPRN_HID2, hid2);
- }
- }
-#ifdef CONFIG_6xx
- low_choose_750fx_pll(low_speed);
-#endif
- if (low_speed == 1) {
- /* tweak L2 for low voltage */
- if (has_cpu_l2lve) {
- hid2 = mfspr(SPRN_HID2);
- hid2 |= 0x2000;
- mtspr(SPRN_HID2, hid2);
- }
-
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(10);
- }
-
- return 0;
-}
-
-static unsigned int cpu_750fx_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_PS)
- return low_freq;
- else
- return hi_freq;
-}
-
-/* Switch CPU speed using DFS */
-static int dfs_set_cpu_speed(int low_speed)
-{
- if (low_speed == 0) {
- /* ramping up, set voltage first */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Make sure we sleep for at least 1ms */
- local_delay(1);
- }
-
- /* set frequency */
-#ifdef CONFIG_6xx
- low_choose_7447a_dfs(low_speed);
-#endif
- udelay(100);
-
- if (low_speed == 1) {
- /* ramping down, set voltage last */
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- local_delay(1);
- }
-
- return 0;
-}
-
-static unsigned int dfs_get_cpu_speed(void)
-{
- if (mfspr(SPRN_HID1) & HID1_DFS)
- return low_freq;
- else
- return hi_freq;
-}
-
-
-/* Switch CPU speed using slewing GPIOs
- */
-static int gpios_set_cpu_speed(int low_speed)
-{
- int gpio, timeout = 0;
-
- /* If ramping up, set voltage first */
- if (low_speed == 0) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x05);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
- /* Set frequency */
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- if (low_speed == ((gpio & 0x01) == 0))
- goto skip;
-
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, frequency_gpio,
- low_speed ? 0x04 : 0x05);
- udelay(200);
- do {
- if (++timeout > 100)
- break;
- local_delay(1);
- gpio = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, slew_done_gpio, 0);
- } while((gpio & 0x02) == 0);
- skip:
- /* If ramping down, set voltage last */
- if (low_speed == 1) {
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, voltage_gpio, 0x04);
- /* Delay is way too big but it's ok, we schedule */
- local_delay(10);
- }
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- return 0;
-}
-
-/* Switch CPU speed under PMU control
- */
-static int pmu_set_cpu_speed(int low_speed)
-{
- struct adb_request req;
- unsigned long save_l2cr;
- unsigned long save_l3cr;
- unsigned int pic_prio;
- unsigned long flags;
-
- preempt_disable();
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
-#endif
- pmu_suspend();
-
- /* Disable all interrupt sources on openpic */
- pic_prio = mpic_cpu_get_priority();
- mpic_cpu_set_priority(0xf);
-
- /* Make sure the decrementer won't interrupt us */
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- /* Make sure any pending DEC interrupt occurring while we did
- * the above didn't re-enable the DEC */
- mb();
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
-
- /* We can now disable MSR_EE */
- local_irq_save(flags);
-
- /* Giveup the FPU & vec */
- enable_kernel_fp();
-
-#ifdef CONFIG_ALTIVEC
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- enable_kernel_altivec();
-#endif /* CONFIG_ALTIVEC */
-
- /* Save & disable L2 and L3 caches */
- save_l3cr = _get_L3CR(); /* (returns -1 if not available) */
- save_l2cr = _get_L2CR(); /* (returns -1 if not available) */
-
- /* Send the new speed command. My assumption is that this command
- * will cause PLL_CFG[0..3] to be changed next time CPU goes to sleep
- */
- pmu_request(&req, NULL, 6, PMU_CPU_SPEED, 'W', 'O', 'O', 'F', low_speed);
- while (!req.complete)
- pmu_poll();
-
- /* Prepare the northbridge for the speed transition */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
-
- /* Call low level code to backup CPU state and recover from
- * hardware reset
- */
- low_sleep_handler();
-
- /* Restore the northbridge */
- pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,0);
-
- /* Restore L2 cache */
- if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
- _set_L2CR(save_l2cr);
- /* Restore L3 cache */
- if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
- _set_L3CR(save_l3cr);
-
- /* Restore userland MMU context */
- switch_mmu_context(NULL, current->active_mm);
-
-#ifdef DEBUG_FREQ
- printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
-#endif
-
- /* Restore low level PMU operations */
- pmu_unlock();
-
- /*
- * Restore decrementer; we'll take a decrementer interrupt
- * as soon as interrupts are re-enabled and the generic
- * clockevents code will reprogram it with the right value.
- */
- set_dec(1);
-
- /* Restore interrupts */
- mpic_cpu_set_priority(pic_prio);
-
- /* Let interrupts flow again ... */
- local_irq_restore(flags);
-
-#ifdef DEBUG_FREQ
- debug_calc_bogomips();
-#endif
-
- pmu_resume();
-
- preempt_enable();
-
- return 0;
-}
-
-static int do_set_cpu_speed(int speed_mode, int notify)
-{
- struct cpufreq_freqs freqs;
- unsigned long l3cr;
- static unsigned long prev_l3cr;
-
- freqs.old = cur_freq;
- freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
- freqs.cpu = smp_processor_id();
-
- if (freqs.old == freqs.new)
- return 0;
-
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- if (speed_mode == CPUFREQ_LOW &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if (l3cr & L3CR_L3E) {
- prev_l3cr = l3cr;
- _set_L3CR(0);
- }
- }
- set_speed_proc(speed_mode == CPUFREQ_LOW);
- if (speed_mode == CPUFREQ_HIGH &&
- cpu_has_feature(CPU_FTR_L3CR)) {
- l3cr = _get_L3CR();
- if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
- _set_L3CR(prev_l3cr);
- }
- if (notify)
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
- cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
-
- return 0;
-}
-
-static unsigned int pmac_cpufreq_get_speed(unsigned int cpu)
-{
- return cur_freq;
-}
-
-static int pmac_cpufreq_verify(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, pmac_cpu_freqs);
-}
-
-static int pmac_cpufreq_target( struct cpufreq_policy *policy,
- unsigned int target_freq,
- unsigned int relation)
-{
- unsigned int newstate = 0;
- int rc;
-
- if (cpufreq_frequency_table_target(policy, pmac_cpu_freqs,
- target_freq, relation, &newstate))
- return -EINVAL;
-
- rc = do_set_cpu_speed(newstate, 1);
-
- ppc_proc_freq = cur_freq * 1000ul;
- return rc;
-}
-
-static int pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- if (policy->cpu != 0)
- return -ENODEV;
-
- policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
- policy->cur = cur_freq;
-
- cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
- return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
-}
-
-static u32 read_gpio(struct device_node *np)
-{
- const u32 *reg = of_get_property(np, "reg", NULL);
- u32 offset;
-
- if (reg == NULL)
- return 0;
- /* That works for all keylargos but shall be fixed properly
- * some day... The problem is that it seems we can't rely
- * on the "reg" property of the GPIO nodes, they are either
- * relative to the base of KeyLargo or to the base of the
- * GPIO space, and the device-tree doesn't help.
- */
- offset = *reg;
- if (offset < KEYLARGO_GPIO_LEVELS0)
- offset += KEYLARGO_GPIO_LEVELS0;
- return offset;
-}
-
-static int pmac_cpufreq_suspend(struct cpufreq_policy *policy)
-{
- /* Ok, this could be made a bit smarter, but let's be robust for now. We
- * always force a speed change to high speed before sleep, to make sure
- * we have appropriate voltage and/or bus speed for the wakeup process,
- * and to make sure our loops_per_jiffies are "good enough", that is will
- * not cause too short delays if we sleep in low speed and wake in high
- * speed..
- */
- no_schedule = 1;
- sleep_freq = cur_freq;
- if (cur_freq == low_freq && !is_pmu_based)
- do_set_cpu_speed(CPUFREQ_HIGH, 0);
- return 0;
-}
-
-static int pmac_cpufreq_resume(struct cpufreq_policy *policy)
-{
- /* If we resume, first check if we have a get() function */
- if (get_speed_proc)
- cur_freq = get_speed_proc();
- else
- cur_freq = 0;
-
- /* We don't, hrm... we don't really know our speed here, best
- * is that we force a switch to whatever it was, which is
- * probably high speed due to our suspend() routine
- */
- do_set_cpu_speed(sleep_freq == low_freq ?
- CPUFREQ_LOW : CPUFREQ_HIGH, 0);
-
- ppc_proc_freq = cur_freq * 1000ul;
-
- no_schedule = 0;
- return 0;
-}
-
-static struct cpufreq_driver pmac_cpufreq_driver = {
- .verify = pmac_cpufreq_verify,
- .target = pmac_cpufreq_target,
- .get = pmac_cpufreq_get_speed,
- .init = pmac_cpufreq_cpu_init,
- .suspend = pmac_cpufreq_suspend,
- .resume = pmac_cpufreq_resume,
- .flags = CPUFREQ_PM_NO_WARN,
- .attr = pmac_cpu_freqs_attr,
- .name = "powermac",
- .owner = THIS_MODULE,
-};
-
-
-static int pmac_cpufreq_init_MacRISC3(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np = of_find_node_by_name(NULL,
- "voltage-gpio");
- struct device_node *freq_gpio_np = of_find_node_by_name(NULL,
- "frequency-gpio");
- struct device_node *slew_done_gpio_np = of_find_node_by_name(NULL,
- "slewing-done");
- const u32 *value;
-
- /*
- * Check to see if it's GPIO driven or PMU only
- *
- * The way we extract the GPIO address is slightly hackish, but it
- * works well enough for now. We need to abstract the whole GPIO
- * stuff sooner or later anyway
- */
-
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (freq_gpio_np)
- frequency_gpio = read_gpio(freq_gpio_np);
- if (slew_done_gpio_np)
- slew_done_gpio = read_gpio(slew_done_gpio_np);
-
- /* If we use the frequency GPIOs, calculate the min/max speeds based
- * on the bus frequencies
- */
- if (frequency_gpio && slew_done_gpio) {
- int lenp, rc;
- const u32 *freqs, *ratio;
-
- freqs = of_get_property(cpunode, "bus-frequencies", &lenp);
- lenp /= sizeof(u32);
- if (freqs == NULL || lenp != 2) {
- printk(KERN_ERR "cpufreq: bus-frequencies incorrect or missing\n");
- return 1;
- }
- ratio = of_get_property(cpunode, "processor-to-bus-ratio*2",
- NULL);
- if (ratio == NULL) {
- printk(KERN_ERR "cpufreq: processor-to-bus-ratio*2 missing\n");
- return 1;
- }
-
- /* Get the min/max bus frequencies */
- low_freq = min(freqs[0], freqs[1]);
- hi_freq = max(freqs[0], freqs[1]);
-
- /* Grrrr.. It _seems_ that the device-tree is lying on the low bus
- * frequency, it claims it to be around 84Mhz on some models while
- * it appears to be approx. 101Mhz on all. Let's hack around here...
- * fortunately, we don't need to be too precise
- */
- if (low_freq < 98000000)
- low_freq = 101000000;
-
- /* Convert those to CPU core clocks */
- low_freq = (low_freq * (*ratio)) / 2000;
- hi_freq = (hi_freq * (*ratio)) / 2000;
-
- /* Now we get the frequencies, we read the GPIO to see what is out current
- * speed
- */
- rc = pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, frequency_gpio, 0);
- cur_freq = (rc & 0x01) ? hi_freq : low_freq;
-
- set_speed_proc = gpios_set_cpu_speed;
- return 1;
- }
-
- /* If we use the PMU, look for the min & max frequencies in the
- * device-tree
- */
- value = of_get_property(cpunode, "min-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
- /* The PowerBook G4 12" (PowerBook6,1) has an error in the device-tree
- * here */
- if (low_freq < 100000)
- low_freq *= 10;
-
- value = of_get_property(cpunode, "max-clock-frequency", NULL);
- if (!value)
- return 1;
- hi_freq = (*value) / 1000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_7447A(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
-
- if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
- if (!voltage_gpio){
- printk(KERN_ERR "cpufreq: missing cpu-vcore-select gpio\n");
- return 1;
- }
-
- /* OF only reports the high frequency */
- hi_freq = cur_freq;
- low_freq = cur_freq/2;
-
- /* Read actual frequency from CPU */
- cur_freq = dfs_get_cpu_speed();
- set_speed_proc = dfs_set_cpu_speed;
- get_speed_proc = dfs_get_cpu_speed;
-
- return 0;
-}
-
-static int pmac_cpufreq_init_750FX(struct device_node *cpunode)
-{
- struct device_node *volt_gpio_np;
- u32 pvr;
- const u32 *value;
-
- if (of_get_property(cpunode, "dynamic-power-step", NULL) == NULL)
- return 1;
-
- hi_freq = cur_freq;
- value = of_get_property(cpunode, "reduced-clock-frequency", NULL);
- if (!value)
- return 1;
- low_freq = (*value) / 1000;
-
- volt_gpio_np = of_find_node_by_name(NULL, "cpu-vcore-select");
- if (volt_gpio_np)
- voltage_gpio = read_gpio(volt_gpio_np);
-
- pvr = mfspr(SPRN_PVR);
- has_cpu_l2lve = !((pvr & 0xf00) == 0x100);
-
- set_speed_proc = cpu_750fx_cpu_speed;
- get_speed_proc = cpu_750fx_get_cpu_speed;
- cur_freq = cpu_750fx_get_cpu_speed();
-
- return 0;
-}
-
-/* Currently, we support the following machines:
- *
- * - Titanium PowerBook 1Ghz (PMU based, 667Mhz & 1Ghz)
- * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
- * - Titanium PowerBook 400 (PMU based, 300Mhz & 400Mhz)
- * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
- * - iBook2 500/600 (PMU based, 400Mhz & 500/600Mhz)
- * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
- * - Recent MacRISC3 laptops
- * - All new machines with 7447A CPUs
- */
-static int __init pmac_cpufreq_setup(void)
-{
- struct device_node *cpunode;
- const u32 *value;
-
- if (strstr(cmd_line, "nocpufreq"))
- return 0;
-
- /* Assume only one CPU */
- cpunode = of_find_node_by_type(NULL, "cpu");
- if (!cpunode)
- goto out;
-
- /* Get current cpu clock freq */
- value = of_get_property(cpunode, "clock-frequency", NULL);
- if (!value)
- goto out;
- cur_freq = (*value) / 1000;
-
- /* Check for 7447A based MacRISC3 */
- if (of_machine_is_compatible("MacRISC3") &&
- of_get_property(cpunode, "dynamic-power-step", NULL) &&
- PVR_VER(mfspr(SPRN_PVR)) == 0x8003) {
- pmac_cpufreq_init_7447A(cpunode);
- /* Check for other MacRISC3 machines */
- } else if (of_machine_is_compatible("PowerBook3,4") ||
- of_machine_is_compatible("PowerBook3,5") ||
- of_machine_is_compatible("MacRISC3")) {
- pmac_cpufreq_init_MacRISC3(cpunode);
- /* Else check for iBook2 500/600 */
- } else if (of_machine_is_compatible("PowerBook4,1")) {
- hi_freq = cur_freq;
- low_freq = 400000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 550 */
- else if (of_machine_is_compatible("PowerBook3,3") && cur_freq == 550000) {
- hi_freq = cur_freq;
- low_freq = 500000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for TiPb 400 & 500 */
- else if (of_machine_is_compatible("PowerBook3,2")) {
- /* We only know about the 400 MHz and the 500Mhz model
- * they both have 300 MHz as low frequency
- */
- if (cur_freq < 350000 || cur_freq > 550000)
- goto out;
- hi_freq = cur_freq;
- low_freq = 300000;
- set_speed_proc = pmu_set_cpu_speed;
- is_pmu_based = 1;
- }
- /* Else check for 750FX */
- else if (PVR_VER(mfspr(SPRN_PVR)) == 0x7000)
- pmac_cpufreq_init_750FX(cpunode);
-out:
- of_node_put(cpunode);
- if (set_speed_proc == NULL)
- return -ENODEV;
-
- pmac_cpu_freqs[CPUFREQ_LOW].frequency = low_freq;
- pmac_cpu_freqs[CPUFREQ_HIGH].frequency = hi_freq;
- ppc_proc_freq = cur_freq * 1000ul;
-
- printk(KERN_INFO "Registering PowerMac CPU frequency driver\n");
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Boot: %d Mhz\n",
- low_freq/1000, hi_freq/1000, cur_freq/1000);
-
- return cpufreq_register_driver(&pmac_cpufreq_driver);
-}
-
-module_init(pmac_cpufreq_setup);
-
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_64.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_64.c
deleted file mode 100644
index 9650c602..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ /dev/null
@@ -1,747 +0,0 @@
-/*
- * Copyright (C) 2002 - 2005 Benjamin Herrenschmidt <benh@kernel.crashing.org>
- * and Markus Demleitner <msdemlei@cl.uni-heidelberg.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This driver adds basic cpufreq support for SMU & 970FX based G5 Macs,
- * that is iMac G5 and latest single CPU desktop.
- */
-
-#undef DEBUG
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/kernel.h>
-#include <linux/delay.h>
-#include <linux/sched.h>
-#include <linux/cpufreq.h>
-#include <linux/init.h>
-#include <linux/completion.h>
-#include <linux/mutex.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/irq.h>
-#include <asm/sections.h>
-#include <asm/cputable.h>
-#include <asm/time.h>
-#include <asm/smu.h>
-#include <asm/pmac_pfunc.h>
-
-#define DBG(fmt...) pr_debug(fmt)
-
-/* see 970FX user manual */
-
-#define SCOM_PCR 0x0aa001 /* PCR scom addr */
-
-#define PCR_HILO_SELECT 0x80000000U /* 1 = PCR, 0 = PCRH */
-#define PCR_SPEED_FULL 0x00000000U /* 1:1 speed value */
-#define PCR_SPEED_HALF 0x00020000U /* 1:2 speed value */
-#define PCR_SPEED_QUARTER 0x00040000U /* 1:4 speed value */
-#define PCR_SPEED_MASK 0x000e0000U /* speed mask */
-#define PCR_SPEED_SHIFT 17
-#define PCR_FREQ_REQ_VALID 0x00010000U /* freq request valid */
-#define PCR_VOLT_REQ_VALID 0x00008000U /* volt request valid */
-#define PCR_TARGET_TIME_MASK 0x00006000U /* target time */
-#define PCR_STATLAT_MASK 0x00001f00U /* STATLAT value */
-#define PCR_SNOOPLAT_MASK 0x000000f0U /* SNOOPLAT value */
-#define PCR_SNOOPACC_MASK 0x0000000fU /* SNOOPACC value */
-
-#define SCOM_PSR 0x408001 /* PSR scom addr */
-/* warning: PSR is a 64 bits register */
-#define PSR_CMD_RECEIVED 0x2000000000000000U /* command received */
-#define PSR_CMD_COMPLETED 0x1000000000000000U /* command completed */
-#define PSR_CUR_SPEED_MASK 0x0300000000000000U /* current speed */
-#define PSR_CUR_SPEED_SHIFT (56)
-
-/*
- * The G5 only supports two frequencies (Quarter speed is not supported)
- */
-#define CPUFREQ_HIGH 0
-#define CPUFREQ_LOW 1
-
-static struct cpufreq_frequency_table g5_cpu_freqs[] = {
- {CPUFREQ_HIGH, 0},
- {CPUFREQ_LOW, 0},
- {0, CPUFREQ_TABLE_END},
-};
-
-static struct freq_attr* g5_cpu_freqs_attr[] = {
- &cpufreq_freq_attr_scaling_available_freqs,
- NULL,
-};
-
-/* Power mode data is an array of the 32 bits PCR values to use for
- * the various frequencies, retrieved from the device-tree
- */
-static int g5_pmode_cur;
-
-static void (*g5_switch_volt)(int speed_mode);
-static int (*g5_switch_freq)(int speed_mode);
-static int (*g5_query_freq)(void);
-
-static DEFINE_MUTEX(g5_switch_mutex);
-
-static unsigned long transition_latency;
-
-#ifdef CONFIG_PMAC_SMU
-
-static const u32 *g5_pmode_data;
-static int g5_pmode_max;
-
-static struct smu_sdbp_fvt *g5_fvt_table; /* table of op. points */
-static int g5_fvt_count; /* number of op. points */
-static int g5_fvt_cur; /* current op. point */
-
-/*
- * SMU based voltage switching for Neo2 platforms
- */
-
-static void g5_smu_switch_volt(int speed_mode)
-{
- struct smu_simple_cmd cmd;
-
- DECLARE_COMPLETION_ONSTACK(comp);
- smu_queue_simple(&cmd, SMU_CMD_POWER_COMMAND, 8, smu_done_complete,
- &comp, 'V', 'S', 'L', 'E', 'W',
- 0xff, g5_fvt_cur+1, speed_mode);
- wait_for_completion(&comp);
-}
-
-/*
- * Platform function based voltage/vdnap switching for Neo2
- */
-
-static struct pmf_function *pfunc_set_vdnap0;
-static struct pmf_function *pfunc_vdnap0_complete;
-
-static void g5_vdnap_switch_volt(int speed_mode)
-{
- struct pmf_args args;
- u32 slew, done = 0;
- unsigned long timeout;
-
- slew = (speed_mode == CPUFREQ_LOW) ? 1 : 0;
- args.count = 1;
- args.u[0].p = &slew;
-
- pmf_call_one(pfunc_set_vdnap0, &args);
-
- /* It's an irq GPIO so we should be able to just block here,
- * I'll do that later after I've properly tested the IRQ code for
- * platform functions
- */
- timeout = jiffies + HZ/10;
- while(!time_after(jiffies, timeout)) {
- args.count = 1;
- args.u[0].p = &done;
- pmf_call_one(pfunc_vdnap0_complete, &args);
- if (done)
- break;
- msleep(1);
- }
- if (done == 0)
- printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
-}
-
-
-/*
- * SCOM based frequency switching for 970FX rev3
- */
-static int g5_scom_switch_freq(int speed_mode)
-{
- unsigned long flags;
- int to;
-
- /* If frequency is going up, first ramp up the voltage */
- if (speed_mode < g5_pmode_cur)
- g5_switch_volt(speed_mode);
-
- local_irq_save(flags);
-
- /* Clear PCR high */
- scom970_write(SCOM_PCR, 0);
- /* Clear PCR low */
- scom970_write(SCOM_PCR, PCR_HILO_SELECT | 0);
- /* Set PCR low */
- scom970_write(SCOM_PCR, PCR_HILO_SELECT |
- g5_pmode_data[speed_mode]);
-
- /* Wait for completion */
- for (to = 0; to < 10; to++) {
- unsigned long psr = scom970_read(SCOM_PSR);
-
- if ((psr & PSR_CMD_RECEIVED) == 0 &&
- (((psr >> PSR_CUR_SPEED_SHIFT) ^
- (g5_pmode_data[speed_mode] >> PCR_SPEED_SHIFT)) & 0x3)
- == 0)
- break;
- if (psr & PSR_CMD_COMPLETED)
- break;
- udelay(100);
- }
-
- local_irq_restore(flags);
-
- /* If frequency is going down, last ramp the voltage */
- if (speed_mode > g5_pmode_cur)
- g5_switch_volt(speed_mode);
-
- g5_pmode_cur = speed_mode;
- ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
-
- return 0;
-}
-
-static int g5_scom_query_freq(void)
-{
- unsigned long psr = scom970_read(SCOM_PSR);
- int i;
-
- for (i = 0; i <= g5_pmode_max; i++)
- if ((((psr >> PSR_CUR_SPEED_SHIFT) ^
- (g5_pmode_data[i] >> PCR_SPEED_SHIFT)) & 0x3) == 0)
- break;
- return i;
-}
-
-/*
- * Fake voltage switching for platforms with missing support
- */
-
-static void g5_dummy_switch_volt(int speed_mode)
-{
-}
-
-#endif /* CONFIG_PMAC_SMU */
-
-/*
- * Platform function based voltage switching for PowerMac7,2 & 7,3
- */
-
-static struct pmf_function *pfunc_cpu0_volt_high;
-static struct pmf_function *pfunc_cpu0_volt_low;
-static struct pmf_function *pfunc_cpu1_volt_high;
-static struct pmf_function *pfunc_cpu1_volt_low;
-
-static void g5_pfunc_switch_volt(int speed_mode)
-{
- if (speed_mode == CPUFREQ_HIGH) {
- if (pfunc_cpu0_volt_high)
- pmf_call_one(pfunc_cpu0_volt_high, NULL);
- if (pfunc_cpu1_volt_high)
- pmf_call_one(pfunc_cpu1_volt_high, NULL);
- } else {
- if (pfunc_cpu0_volt_low)
- pmf_call_one(pfunc_cpu0_volt_low, NULL);
- if (pfunc_cpu1_volt_low)
- pmf_call_one(pfunc_cpu1_volt_low, NULL);
- }
- msleep(10); /* should be faster , to fix */
-}
-
-/*
- * Platform function based frequency switching for PowerMac7,2 & 7,3
- */
-
-static struct pmf_function *pfunc_cpu_setfreq_high;
-static struct pmf_function *pfunc_cpu_setfreq_low;
-static struct pmf_function *pfunc_cpu_getfreq;
-static struct pmf_function *pfunc_slewing_done;
-
-static int g5_pfunc_switch_freq(int speed_mode)
-{
- struct pmf_args args;
- u32 done = 0;
- unsigned long timeout;
- int rc;
-
- DBG("g5_pfunc_switch_freq(%d)\n", speed_mode);
-
- /* If frequency is going up, first ramp up the voltage */
- if (speed_mode < g5_pmode_cur)
- g5_switch_volt(speed_mode);
-
- /* Do it */
- if (speed_mode == CPUFREQ_HIGH)
- rc = pmf_call_one(pfunc_cpu_setfreq_high, NULL);
- else
- rc = pmf_call_one(pfunc_cpu_setfreq_low, NULL);
-
- if (rc)
- printk(KERN_WARNING "cpufreq: pfunc switch error %d\n", rc);
-
- /* It's an irq GPIO so we should be able to just block here,
- * I'll do that later after I've properly tested the IRQ code for
- * platform functions
- */
- timeout = jiffies + HZ/10;
- while(!time_after(jiffies, timeout)) {
- args.count = 1;
- args.u[0].p = &done;
- pmf_call_one(pfunc_slewing_done, &args);
- if (done)
- break;
- msleep(1);
- }
- if (done == 0)
- printk(KERN_WARNING "cpufreq: Timeout in clock slewing !\n");
-
- /* If frequency is going down, last ramp the voltage */
- if (speed_mode > g5_pmode_cur)
- g5_switch_volt(speed_mode);
-
- g5_pmode_cur = speed_mode;
- ppc_proc_freq = g5_cpu_freqs[speed_mode].frequency * 1000ul;
-
- return 0;
-}
-
-static int g5_pfunc_query_freq(void)
-{
- struct pmf_args args;
- u32 val = 0;
-
- args.count = 1;
- args.u[0].p = &val;
- pmf_call_one(pfunc_cpu_getfreq, &args);
- return val ? CPUFREQ_HIGH : CPUFREQ_LOW;
-}
-
-
-/*
- * Common interface to the cpufreq core
- */
-
-static int g5_cpufreq_verify(struct cpufreq_policy *policy)
-{
- return cpufreq_frequency_table_verify(policy, g5_cpu_freqs);
-}
-
-static int g5_cpufreq_target(struct cpufreq_policy *policy,
- unsigned int target_freq, unsigned int relation)
-{
- unsigned int newstate = 0;
- struct cpufreq_freqs freqs;
- int rc;
-
- if (cpufreq_frequency_table_target(policy, g5_cpu_freqs,
- target_freq, relation, &newstate))
- return -EINVAL;
-
- if (g5_pmode_cur == newstate)
- return 0;
-
- mutex_lock(&g5_switch_mutex);
-
- freqs.old = g5_cpu_freqs[g5_pmode_cur].frequency;
- freqs.new = g5_cpu_freqs[newstate].frequency;
- freqs.cpu = 0;
-
- cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
- rc = g5_switch_freq(newstate);
- cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
- mutex_unlock(&g5_switch_mutex);
-
- return rc;
-}
-
-static unsigned int g5_cpufreq_get_speed(unsigned int cpu)
-{
- return g5_cpu_freqs[g5_pmode_cur].frequency;
-}
-
-static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
-{
- policy->cpuinfo.transition_latency = transition_latency;
- policy->cur = g5_cpu_freqs[g5_query_freq()].frequency;
- /* secondary CPUs are tied to the primary one by the
- * cpufreq core if in the secondary policy we tell it that
- * it actually must be one policy together with all others. */
- cpumask_copy(policy->cpus, cpu_online_mask);
- cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
-
- return cpufreq_frequency_table_cpuinfo(policy,
- g5_cpu_freqs);
-}
-
-
-static struct cpufreq_driver g5_cpufreq_driver = {
- .name = "powermac",
- .owner = THIS_MODULE,
- .flags = CPUFREQ_CONST_LOOPS,
- .init = g5_cpufreq_cpu_init,
- .verify = g5_cpufreq_verify,
- .target = g5_cpufreq_target,
- .get = g5_cpufreq_get_speed,
- .attr = g5_cpu_freqs_attr,
-};
-
-
-#ifdef CONFIG_PMAC_SMU
-
-static int __init g5_neo2_cpufreq_init(struct device_node *cpus)
-{
- struct device_node *cpunode;
- unsigned int psize, ssize;
- unsigned long max_freq;
- char *freq_method, *volt_method;
- const u32 *valp;
- u32 pvr_hi;
- int use_volts_vdnap = 0;
- int use_volts_smu = 0;
- int rc = -ENODEV;
-
- /* Check supported platforms */
- if (of_machine_is_compatible("PowerMac8,1") ||
- of_machine_is_compatible("PowerMac8,2") ||
- of_machine_is_compatible("PowerMac9,1"))
- use_volts_smu = 1;
- else if (of_machine_is_compatible("PowerMac11,2"))
- use_volts_vdnap = 1;
- else
- return -ENODEV;
-
- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- const u32 *reg = of_get_property(cpunode, "reg", NULL);
- if (reg == NULL || (*reg) != 0)
- continue;
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU 0 node\n");
- return -ENODEV;
- }
-
- /* Check 970FX for now */
- valp = of_get_property(cpunode, "cpu-version", NULL);
- if (!valp) {
- DBG("No cpu-version property !\n");
- goto bail_noprops;
- }
- pvr_hi = (*valp) >> 16;
- if (pvr_hi != 0x3c && pvr_hi != 0x44) {
- printk(KERN_ERR "cpufreq: Unsupported CPU version\n");
- goto bail_noprops;
- }
-
- /* Look for the powertune data in the device-tree */
- g5_pmode_data = of_get_property(cpunode, "power-mode-data",&psize);
- if (!g5_pmode_data) {
- DBG("No power-mode-data !\n");
- goto bail_noprops;
- }
- g5_pmode_max = psize / sizeof(u32) - 1;
-
- if (use_volts_smu) {
- const struct smu_sdbp_header *shdr;
-
- /* Look for the FVT table */
- shdr = smu_get_sdb_partition(SMU_SDB_FVT_ID, NULL);
- if (!shdr)
- goto bail_noprops;
- g5_fvt_table = (struct smu_sdbp_fvt *)&shdr[1];
- ssize = (shdr->len * sizeof(u32)) -
- sizeof(struct smu_sdbp_header);
- g5_fvt_count = ssize / sizeof(struct smu_sdbp_fvt);
- g5_fvt_cur = 0;
-
- /* Sanity checking */
- if (g5_fvt_count < 1 || g5_pmode_max < 1)
- goto bail_noprops;
-
- g5_switch_volt = g5_smu_switch_volt;
- volt_method = "SMU";
- } else if (use_volts_vdnap) {
- struct device_node *root;
-
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_ERR "cpufreq: Can't find root of "
- "device tree\n");
- goto bail_noprops;
- }
- pfunc_set_vdnap0 = pmf_find_function(root, "set-vdnap0");
- pfunc_vdnap0_complete =
- pmf_find_function(root, "slewing-done");
- if (pfunc_set_vdnap0 == NULL ||
- pfunc_vdnap0_complete == NULL) {
- printk(KERN_ERR "cpufreq: Can't find required "
- "platform function\n");
- goto bail_noprops;
- }
-
- g5_switch_volt = g5_vdnap_switch_volt;
- volt_method = "GPIO";
- } else {
- g5_switch_volt = g5_dummy_switch_volt;
- volt_method = "none";
- }
-
- /*
- * From what I see, clock-frequency is always the maximal frequency.
- * The current driver can not slew sysclk yet, so we really only deal
- * with powertune steps for now. We also only implement full freq and
- * half freq in this version. So far, I haven't yet seen a machine
- * supporting anything else.
- */
- valp = of_get_property(cpunode, "clock-frequency", NULL);
- if (!valp)
- return -ENODEV;
- max_freq = (*valp)/1000;
- g5_cpu_freqs[0].frequency = max_freq;
- g5_cpu_freqs[1].frequency = max_freq/2;
-
- /* Set callbacks */
- transition_latency = 12000;
- g5_switch_freq = g5_scom_switch_freq;
- g5_query_freq = g5_scom_query_freq;
- freq_method = "SCOM";
-
- /* Force apply current frequency to make sure everything is in
- * sync (voltage is right for example). Firmware may leave us with
- * a strange setting ...
- */
- g5_switch_volt(CPUFREQ_HIGH);
- msleep(10);
- g5_pmode_cur = -1;
- g5_switch_freq(g5_query_freq());
-
- printk(KERN_INFO "Registering G5 CPU frequency driver\n");
- printk(KERN_INFO "Frequency method: %s, Voltage method: %s\n",
- freq_method, volt_method);
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
- g5_cpu_freqs[1].frequency/1000,
- g5_cpu_freqs[0].frequency/1000,
- g5_cpu_freqs[g5_pmode_cur].frequency/1000);
-
- rc = cpufreq_register_driver(&g5_cpufreq_driver);
-
- /* We keep the CPU node on hold... hopefully, Apple G5 don't have
- * hotplug CPU with a dynamic device-tree ...
- */
- return rc;
-
- bail_noprops:
- of_node_put(cpunode);
-
- return rc;
-}
-
-#endif /* CONFIG_PMAC_SMU */
-
-
-static int __init g5_pm72_cpufreq_init(struct device_node *cpus)
-{
- struct device_node *cpuid = NULL, *hwclock = NULL, *cpunode = NULL;
- const u8 *eeprom = NULL;
- const u32 *valp;
- u64 max_freq, min_freq, ih, il;
- int has_volt = 1, rc = 0;
-
- DBG("cpufreq: Initializing for PowerMac7,2, PowerMac7,3 and"
- " RackMac3,1...\n");
-
- /* Get first CPU node */
- for (cpunode = NULL;
- (cpunode = of_get_next_child(cpus, cpunode)) != NULL;) {
- if (!strcmp(cpunode->type, "cpu"))
- break;
- }
- if (cpunode == NULL) {
- printk(KERN_ERR "cpufreq: Can't find any CPU node\n");
- return -ENODEV;
- }
-
- /* Lookup the cpuid eeprom node */
- cpuid = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/cpuid@a0");
- if (cpuid != NULL)
- eeprom = of_get_property(cpuid, "cpuid", NULL);
- if (eeprom == NULL) {
- printk(KERN_ERR "cpufreq: Can't find cpuid EEPROM !\n");
- rc = -ENODEV;
- goto bail;
- }
-
- /* Lookup the i2c hwclock */
- for (hwclock = NULL;
- (hwclock = of_find_node_by_name(hwclock, "i2c-hwclock")) != NULL;){
- const char *loc = of_get_property(hwclock,
- "hwctrl-location", NULL);
- if (loc == NULL)
- continue;
- if (strcmp(loc, "CPU CLOCK"))
- continue;
- if (!of_get_property(hwclock, "platform-get-frequency", NULL))
- continue;
- break;
- }
- if (hwclock == NULL) {
- printk(KERN_ERR "cpufreq: Can't find i2c clock chip !\n");
- rc = -ENODEV;
- goto bail;
- }
-
- DBG("cpufreq: i2c clock chip found: %s\n", hwclock->full_name);
-
- /* Now get all the platform functions */
- pfunc_cpu_getfreq =
- pmf_find_function(hwclock, "get-frequency");
- pfunc_cpu_setfreq_high =
- pmf_find_function(hwclock, "set-frequency-high");
- pfunc_cpu_setfreq_low =
- pmf_find_function(hwclock, "set-frequency-low");
- pfunc_slewing_done =
- pmf_find_function(hwclock, "slewing-done");
- pfunc_cpu0_volt_high =
- pmf_find_function(hwclock, "set-voltage-high-0");
- pfunc_cpu0_volt_low =
- pmf_find_function(hwclock, "set-voltage-low-0");
- pfunc_cpu1_volt_high =
- pmf_find_function(hwclock, "set-voltage-high-1");
- pfunc_cpu1_volt_low =
- pmf_find_function(hwclock, "set-voltage-low-1");
-
- /* Check we have minimum requirements */
- if (pfunc_cpu_getfreq == NULL || pfunc_cpu_setfreq_high == NULL ||
- pfunc_cpu_setfreq_low == NULL || pfunc_slewing_done == NULL) {
- printk(KERN_ERR "cpufreq: Can't find platform functions !\n");
- rc = -ENODEV;
- goto bail;
- }
-
- /* Check that we have complete sets */
- if (pfunc_cpu0_volt_high == NULL || pfunc_cpu0_volt_low == NULL) {
- pmf_put_function(pfunc_cpu0_volt_high);
- pmf_put_function(pfunc_cpu0_volt_low);
- pfunc_cpu0_volt_high = pfunc_cpu0_volt_low = NULL;
- has_volt = 0;
- }
- if (!has_volt ||
- pfunc_cpu1_volt_high == NULL || pfunc_cpu1_volt_low == NULL) {
- pmf_put_function(pfunc_cpu1_volt_high);
- pmf_put_function(pfunc_cpu1_volt_low);
- pfunc_cpu1_volt_high = pfunc_cpu1_volt_low = NULL;
- }
-
- /* Note: The device tree also contains a "platform-set-values"
- * function for which I haven't quite figured out the usage. It
- * might have to be called on init and/or wakeup, I'm not too sure
- * but things seem to work fine without it so far ...
- */
-
- /* Get max frequency from device-tree */
- valp = of_get_property(cpunode, "clock-frequency", NULL);
- if (!valp) {
- printk(KERN_ERR "cpufreq: Can't find CPU frequency !\n");
- rc = -ENODEV;
- goto bail;
- }
-
- max_freq = (*valp)/1000;
-
- /* Now calculate reduced frequency by using the cpuid input freq
- * ratio. This requires 64 bits math unless we are willing to lose
- * some precision
- */
- ih = *((u32 *)(eeprom + 0x10));
- il = *((u32 *)(eeprom + 0x20));
-
- /* Check for machines with no useful settings */
- if (il == ih) {
- printk(KERN_WARNING "cpufreq: No low frequency mode available"
- " on this model !\n");
- rc = -ENODEV;
- goto bail;
- }
-
- min_freq = 0;
- if (ih != 0 && il != 0)
- min_freq = (max_freq * il) / ih;
-
- /* Sanity check */
- if (min_freq >= max_freq || min_freq < 1000) {
- printk(KERN_ERR "cpufreq: Can't calculate low frequency !\n");
- rc = -ENXIO;
- goto bail;
- }
- g5_cpu_freqs[0].frequency = max_freq;
- g5_cpu_freqs[1].frequency = min_freq;
-
- /* Set callbacks */
- transition_latency = CPUFREQ_ETERNAL;
- g5_switch_volt = g5_pfunc_switch_volt;
- g5_switch_freq = g5_pfunc_switch_freq;
- g5_query_freq = g5_pfunc_query_freq;
-
- /* Force apply current frequency to make sure everything is in
- * sync (voltage is right for example). Firmware may leave us with
- * a strange setting ...
- */
- g5_switch_volt(CPUFREQ_HIGH);
- msleep(10);
- g5_pmode_cur = -1;
- g5_switch_freq(g5_query_freq());
-
- printk(KERN_INFO "Registering G5 CPU frequency driver\n");
- printk(KERN_INFO "Frequency method: i2c/pfunc, "
- "Voltage method: %s\n", has_volt ? "i2c/pfunc" : "none");
- printk(KERN_INFO "Low: %d Mhz, High: %d Mhz, Cur: %d MHz\n",
- g5_cpu_freqs[1].frequency/1000,
- g5_cpu_freqs[0].frequency/1000,
- g5_cpu_freqs[g5_pmode_cur].frequency/1000);
-
- rc = cpufreq_register_driver(&g5_cpufreq_driver);
- bail:
- if (rc != 0) {
- pmf_put_function(pfunc_cpu_getfreq);
- pmf_put_function(pfunc_cpu_setfreq_high);
- pmf_put_function(pfunc_cpu_setfreq_low);
- pmf_put_function(pfunc_slewing_done);
- pmf_put_function(pfunc_cpu0_volt_high);
- pmf_put_function(pfunc_cpu0_volt_low);
- pmf_put_function(pfunc_cpu1_volt_high);
- pmf_put_function(pfunc_cpu1_volt_low);
- }
- of_node_put(hwclock);
- of_node_put(cpuid);
- of_node_put(cpunode);
-
- return rc;
-}
-
-static int __init g5_cpufreq_init(void)
-{
- struct device_node *cpus;
- int rc = 0;
-
- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL) {
- DBG("No /cpus node !\n");
- return -ENODEV;
- }
-
- if (of_machine_is_compatible("PowerMac7,2") ||
- of_machine_is_compatible("PowerMac7,3") ||
- of_machine_is_compatible("RackMac3,1"))
- rc = g5_pm72_cpufreq_init(cpus);
-#ifdef CONFIG_PMAC_SMU
- else
- rc = g5_neo2_cpufreq_init(cpus);
-#endif /* CONFIG_PMAC_SMU */
-
- of_node_put(cpus);
- return rc;
-}
-
-module_init(g5_cpufreq_init);
-
-
-MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/feature.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/feature.c
deleted file mode 100644
index 63d82bbc..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/feature.c
+++ /dev/null
@@ -1,3053 +0,0 @@
-/*
- * Copyright (C) 1996-2001 Paul Mackerras (paulus@cs.anu.edu.au)
- * Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- *
- * TODO:
- *
- * - Replace mdelay with some schedule loop if possible
- * - Shorten some obfuscated delays on some routines (like modem
- * power)
- * - Refcount some clocks (see darwin)
- * - Split split split...
- *
- */
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/spinlock.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/ioport.h>
-#include <linux/export.h>
-#include <linux/pci.h>
-#include <asm/sections.h>
-#include <asm/errno.h>
-#include <asm/ohare.h>
-#include <asm/heathrow.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/dbdma.h>
-#include <asm/pci-bridge.h>
-#include <asm/pmac_low_i2c.h>
-
-#undef DEBUG_FEATURE
-
-#ifdef DEBUG_FEATURE
-#define DBG(fmt...) printk(KERN_DEBUG fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-#ifdef CONFIG_6xx
-extern int powersave_lowspeed;
-#endif
-
-extern int powersave_nap;
-extern struct device_node *k2_skiplist[2];
-
-/*
- * We use a single global lock to protect accesses. Each driver has
- * to take care of its own locking
- */
-DEFINE_RAW_SPINLOCK(feature_lock);
-
-#define LOCK(flags) raw_spin_lock_irqsave(&feature_lock, flags);
-#define UNLOCK(flags) raw_spin_unlock_irqrestore(&feature_lock, flags);
-
-
-/*
- * Instance of some macio stuffs
- */
-struct macio_chip macio_chips[MAX_MACIO_CHIPS];
-
-struct macio_chip *macio_find(struct device_node *child, int type)
-{
- while(child) {
- int i;
-
- for (i=0; i < MAX_MACIO_CHIPS && macio_chips[i].of_node; i++)
- if (child == macio_chips[i].of_node &&
- (!type || macio_chips[i].type == type))
- return &macio_chips[i];
- child = child->parent;
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(macio_find);
-
-static const char *macio_names[] =
-{
- "Unknown",
- "Grand Central",
- "OHare",
- "OHareII",
- "Heathrow",
- "Gatwick",
- "Paddington",
- "Keylargo",
- "Pangea",
- "Intrepid",
- "K2",
- "Shasta",
-};
-
-
-struct device_node *uninorth_node;
-u32 __iomem *uninorth_base;
-
-static u32 uninorth_rev;
-static int uninorth_maj;
-static void __iomem *u3_ht_base;
-
-/*
- * For each motherboard family, we have a table of functions pointers
- * that handle the various features.
- */
-
-typedef long (*feature_call)(struct device_node *node, long param, long value);
-
-struct feature_table_entry {
- unsigned int selector;
- feature_call function;
-};
-
-struct pmac_mb_def
-{
- const char* model_string;
- const char* model_name;
- int model_id;
- struct feature_table_entry* features;
- unsigned long board_flags;
-};
-static struct pmac_mb_def pmac_mb;
-
-/*
- * Here are the chip specific feature functions
- */
-
-static inline int simple_feature_tweak(struct device_node *node, int type,
- int reg, u32 mask, int value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, type);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- if (value)
- MACIO_BIS(reg, mask);
- else
- MACIO_BIC(reg, mask);
- (void)MACIO_IN32(reg);
- UNLOCK(flags);
-
- return 0;
-}
-
-#ifndef CONFIG_POWER4
-
-static long ohare_htw_scc_enable(struct device_node *node, long param,
- long value)
-{
- struct macio_chip* macio;
- unsigned long chan_mask;
- unsigned long fcr;
- unsigned long flags;
- int htw, trans;
- unsigned long rmask;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- htw = (macio->type == macio_heathrow || macio->type == macio_paddington
- || macio->type == macio_gatwick);
- /* On these machines, the HRW_SCC_TRANS_EN_N bit mustn't be touched */
- trans = (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES);
- if (value) {
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(1);
-#endif /* CONFIG_ADB_PMU */
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- /* Check if scc cell need enabling */
- if (!(fcr & OH_SCC_ENABLE)) {
- fcr |= OH_SCC_ENABLE;
- if (htw) {
- /* Side effect: this will also power up the
- * modem, but it's too messy to figure out on which
- * ports this controls the tranceiver and on which
- * it controls the modem
- */
- if (trans)
- fcr &= ~HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- fcr |= (rmask = HRW_RESET_SCC);
- MACIO_OUT32(OHARE_FCR, fcr);
- } else {
- fcr |= (rmask = OH_SCC_RESET);
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- UNLOCK(flags);
- (void)MACIO_IN32(OHARE_FCR);
- mdelay(15);
- LOCK(flags);
- fcr &= ~rmask;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr |= OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr |= OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- macio->flags |= chan_mask;
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(OHARE_FCR);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~OH_SCCA_IO;
- if (chan_mask & MACIO_FLAG_SCCB_ON)
- fcr &= ~OH_SCCB_IO;
- MACIO_OUT32(OHARE_FCR, fcr);
- if ((fcr & (OH_SCCA_IO | OH_SCCB_IO)) == 0) {
- fcr &= ~OH_SCC_ENABLE;
- if (htw && trans)
- fcr |= HRW_SCC_TRANS_EN_N;
- MACIO_OUT32(OHARE_FCR, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
-#ifdef CONFIG_ADB_PMU
- if ((param & 0xfff) == PMAC_SCC_IRDA)
- pmu_enable_irled(0);
-#endif /* CONFIG_ADB_PMU */
- }
- return 0;
-}
-
-static long ohare_floppy_enable(struct device_node *node, long param,
- long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_FLOPPY_ENABLE, value);
-}
-
-static long ohare_mesh_enable(struct device_node *node, long param, long value)
-{
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_MESH_ENABLE, value);
-}
-
-static long ohare_ide_enable(struct device_node *node, long param, long value)
-{
- switch(param) {
- case 0:
- /* For some reason, setting the bit in set_initial_features()
- * doesn't stick. I'm still investigating... --BenH.
- */
- if (value)
- simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IOBUS_ENABLE, 1);
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long ohare_ide_reset(struct device_node *node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_ohare,
- OHARE_FCR, OH_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long ohare_sleep_state(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio = &macio_chips[0];
-
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- MACIO_BIC(OHARE_FCR, OH_IOBUS_ENABLE);
- } else if (value == 0) {
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
- return 0;
-}
-
-static long heathrow_modem_enable(struct device_node *node, long param,
- long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1;
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- mdelay(250);
- }
- if (pmac_mb.model_id != PMAC_TYPE_YOSEMITE &&
- pmac_mb.model_id != PMAC_TYPE_YIKES) {
- LOCK(flags);
- if (value)
- MACIO_BIC(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- else
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(250);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(HRW_GPIO_MODEM_RESET, gpio | 1);
- (void)MACIO_IN8(HRW_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long heathrow_floppy_enable(struct device_node *node, long param,
- long value)
-{
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR,
- HRW_SWIM_ENABLE|HRW_BAY_FLOPPY_ENABLE,
- value);
-}
-
-static long heathrow_mesh_enable(struct device_node *node, long param,
- long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, macio_unknown);
- if (!macio)
- return -ENODEV;
- LOCK(flags);
- /* Set clear mesh cell enable */
- if (value)
- MACIO_BIS(HEATHROW_FCR, HRW_MESH_ENABLE);
- else
- MACIO_BIC(HEATHROW_FCR, HRW_MESH_ENABLE);
- (void)MACIO_IN32(HEATHROW_FCR);
- udelay(10);
- /* Set/Clear termination power */
- if (value)
- MACIO_BIC(HEATHROW_MBCR, 0x04000000);
- else
- MACIO_BIS(HEATHROW_MBCR, 0x04000000);
- (void)MACIO_IN32(HEATHROW_MBCR);
- udelay(10);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long heathrow_ide_enable(struct device_node *node, long param,
- long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_BAY_IDE_ENABLE, value);
- default:
- return -ENODEV;
- }
-}
-
-static long heathrow_ide_reset(struct device_node *node, long param,
- long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- HEATHROW_FCR, HRW_IDE1_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long heathrow_bmac_enable(struct device_node *node, long param,
- long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- MACIO_BIS(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_RESET);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- mdelay(10);
- } else {
- LOCK(flags);
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long heathrow_sound_enable(struct device_node *node, long param,
- long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- /* B&W G3 and Yikes don't support that properly (the
- * sound appear to never come back after beeing shut down).
- */
- if (pmac_mb.model_id == PMAC_TYPE_YOSEMITE ||
- pmac_mb.model_id == PMAC_TYPE_YIKES)
- return 0;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (value) {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- UNLOCK(flags);
- (void)MACIO_IN32(HEATHROW_FCR);
- } else {
- LOCK(flags);
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static u32 save_fcr[6];
-static u32 save_mbcr;
-static struct dbdma_regs save_dbdma[13];
-static struct dbdma_regs save_alt_dbdma[13];
-
-static void dbdma_save(struct macio_chip *macio, struct dbdma_regs *save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i = 0; i < 13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- save[i].cmdptr_hi = in_le32(&chan->cmdptr_hi);
- save[i].cmdptr = in_le32(&chan->cmdptr);
- save[i].intr_sel = in_le32(&chan->intr_sel);
- save[i].br_sel = in_le32(&chan->br_sel);
- save[i].wait_sel = in_le32(&chan->wait_sel);
- }
-}
-
-static void dbdma_restore(struct macio_chip *macio, struct dbdma_regs *save)
-{
- int i;
-
- /* Save state & config of DBDMA channels */
- for (i = 0; i < 13; i++) {
- volatile struct dbdma_regs __iomem * chan = (void __iomem *)
- (macio->base + ((0x8000+i*0x100)>>2));
- out_le32(&chan->control, (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);
- while (in_le32(&chan->status) & ACTIVE)
- mb();
- out_le32(&chan->cmdptr_hi, save[i].cmdptr_hi);
- out_le32(&chan->cmdptr, save[i].cmdptr);
- out_le32(&chan->intr_sel, save[i].intr_sel);
- out_le32(&chan->br_sel, save[i].br_sel);
- out_le32(&chan->wait_sel, save[i].wait_sel);
- }
-}
-
-static void heathrow_sleep(struct macio_chip *macio, int secondary)
-{
- if (secondary) {
- dbdma_save(macio, save_alt_dbdma);
- save_fcr[2] = MACIO_IN32(0x38);
- save_fcr[3] = MACIO_IN32(0x3c);
- } else {
- dbdma_save(macio, save_dbdma);
- save_fcr[0] = MACIO_IN32(0x38);
- save_fcr[1] = MACIO_IN32(0x3c);
- save_mbcr = MACIO_IN32(0x34);
- /* Make sure sound is shut down */
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_POWER_N);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- /* This seems to be necessary as well or the fan
- * keeps coming up and battery drains fast */
- MACIO_BIC(HEATHROW_FCR, HRW_IOBUS_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_IDE0_RESET_N);
- /* Make sure eth is down even if module or sleep
- * won't work properly */
- MACIO_BIC(HEATHROW_FCR, HRW_BMAC_IO_ENABLE | HRW_BMAC_RESET);
- }
- /* Make sure modem is shut down */
- MACIO_OUT8(HRW_GPIO_MODEM_RESET,
- MACIO_IN8(HRW_GPIO_MODEM_RESET) & ~1);
- MACIO_BIS(HEATHROW_FCR, HRW_SCC_TRANS_EN_N);
- MACIO_BIC(HEATHROW_FCR, OH_SCCA_IO|OH_SCCB_IO|HRW_SCC_ENABLE);
-
- /* Let things settle */
- (void)MACIO_IN32(HEATHROW_FCR);
-}
-
-static void heathrow_wakeup(struct macio_chip *macio, int secondary)
-{
- if (secondary) {
- MACIO_OUT32(0x38, save_fcr[2]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[3]);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_alt_dbdma);
- } else {
- MACIO_OUT32(0x38, save_fcr[0] | HRW_IOBUS_ENABLE);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x3c, save_fcr[1]);
- (void)MACIO_IN32(0x38);
- mdelay(1);
- MACIO_OUT32(0x34, save_mbcr);
- (void)MACIO_IN32(0x38);
- mdelay(10);
- dbdma_restore(macio, save_dbdma);
- }
-}
-
-static long heathrow_sleep_state(struct device_node *node, long param,
- long value)
-{
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
- if (value == 1) {
- if (macio_chips[1].type == macio_gatwick)
- heathrow_sleep(&macio_chips[0], 1);
- heathrow_sleep(&macio_chips[0], 0);
- } else if (value == 0) {
- heathrow_wakeup(&macio_chips[0], 0);
- if (macio_chips[1].type == macio_gatwick)
- heathrow_wakeup(&macio_chips[0], 1);
- }
- return 0;
-}
-
-static long core99_scc_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- unsigned long chan_mask;
- u32 fcr;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- if (!strcmp(node->name, "ch-a"))
- chan_mask = MACIO_FLAG_SCCA_ON;
- else if (!strcmp(node->name, "ch-b"))
- chan_mask = MACIO_FLAG_SCCB_ON;
- else
- return -ENODEV;
-
- if (value) {
- int need_reset_scc = 0;
- int need_reset_irda = 0;
-
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- /* Check if scc cell need enabling */
- if (!(fcr & KL0_SCC_CELL_ENABLE)) {
- fcr |= KL0_SCC_CELL_ENABLE;
- need_reset_scc = 1;
- }
- if (chan_mask & MACIO_FLAG_SCCA_ON) {
- fcr |= KL0_SCCA_ENABLE;
- /* Don't enable line drivers for I2S modem */
- if ((param & 0xfff) == PMAC_SCC_I2S1)
- fcr &= ~KL0_SCC_A_INTF_ENABLE;
- else
- fcr |= KL0_SCC_A_INTF_ENABLE;
- }
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr |= KL0_SCCB_ENABLE;
- /* Perform irda specific inits */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_SCC_B_INTF_ENABLE;
- fcr |= KL0_IRDA_ENABLE;
- fcr |= KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE;
- fcr |= KL0_IRDA_SOURCE1_SEL;
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- need_reset_irda = 1;
- } else
- fcr |= KL0_SCC_B_INTF_ENABLE;
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- macio->flags |= chan_mask;
- if (need_reset_scc) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_SCC_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_SCC_RESET);
- }
- if (need_reset_irda) {
- MACIO_BIS(KEYLARGO_FCR0, KL0_IRDA_RESET);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(15);
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR0, KL0_IRDA_RESET);
- }
- UNLOCK(flags);
- if (param & PMAC_SCC_FLAG_XMON)
- macio->flags |= MACIO_FLAG_SCC_LOCKED;
- } else {
- if (macio->flags & MACIO_FLAG_SCC_LOCKED)
- return -EPERM;
- LOCK(flags);
- fcr = MACIO_IN32(KEYLARGO_FCR0);
- if (chan_mask & MACIO_FLAG_SCCA_ON)
- fcr &= ~KL0_SCCA_ENABLE;
- if (chan_mask & MACIO_FLAG_SCCB_ON) {
- fcr &= ~KL0_SCCB_ENABLE;
- /* Perform irda specific clears */
- if ((param & 0xfff) == PMAC_SCC_IRDA) {
- fcr &= ~KL0_IRDA_ENABLE;
- fcr &= ~(KL0_IRDA_CLK32_ENABLE | KL0_IRDA_CLK19_ENABLE);
- fcr &= ~(KL0_IRDA_FAST_CONNECT|KL0_IRDA_DEFAULT1|KL0_IRDA_DEFAULT0);
- fcr &= ~(KL0_IRDA_SOURCE1_SEL|KL0_IRDA_SOURCE2_SEL|KL0_IRDA_HIGH_BAND);
- }
- }
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- if ((fcr & (KL0_SCCA_ENABLE | KL0_SCCB_ENABLE)) == 0) {
- fcr &= ~KL0_SCC_CELL_ENABLE;
- MACIO_OUT32(KEYLARGO_FCR0, fcr);
- }
- macio->flags &= ~(chan_mask);
- UNLOCK(flags);
- mdelay(10);
- }
- return 0;
-}
-
-static long
-core99_modem_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_keylargo)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_BIC(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-pangea_modem_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio;
- u8 gpio;
- unsigned long flags;
-
- /* Hack for internal USB modem */
- if (node == NULL) {
- if (macio_chips[0].type != macio_pangea &&
- macio_chips[0].type != macio_intrepid)
- return -ENODEV;
- node = macio_chips[0].of_node;
- }
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
- gpio = MACIO_IN8(KL_GPIO_MODEM_RESET);
- gpio |= KEYLARGO_GPIO_OUTPUT_ENABLE;
- gpio &= ~KEYLARGO_GPIO_OUTOUT_DATA;
-
- if (!value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- UNLOCK(flags);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- mdelay(250);
- }
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- mdelay(250);
- } else {
- MACIO_OUT8(KL_GPIO_MODEM_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- }
- if (value) {
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250); LOCK(flags);
- MACIO_OUT8(KL_GPIO_MODEM_RESET, gpio | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(KL_GPIO_MODEM_RESET);
- UNLOCK(flags); mdelay(250);
- }
- return 0;
-}
-
-static long
-core99_ata100_enable(struct device_node *node, long value)
-{
- unsigned long flags;
- struct pci_dev *pdev = NULL;
- u8 pbus, pid;
- int rc;
-
- if (uninorth_rev < 0x24)
- return -ENODEV;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_ATA100);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- if (value) {
- if (pci_device_from_OF_node(node, &pbus, &pid) == 0)
- pdev = pci_get_bus_and_slot(pbus, pid);
- if (pdev == NULL)
- return 0;
- rc = pci_enable_device(pdev);
- if (rc == 0)
- pci_set_master(pdev);
- pci_dev_put(pdev);
- if (rc)
- return rc;
- }
- return 0;
-}
-
-static long
-core99_ide_enable(struct device_node *node, long param, long value)
-{
- /* Bus ID 0 to 2 are KeyLargo based IDE, busID 3 is U2
- * based ata-100
- */
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_ENABLE, value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_ENABLE, value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_ENABLE, value);
- case 3:
- return core99_ata100_enable(node, value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_ide_reset(struct device_node *node, long param, long value)
-{
- switch(param) {
- case 0:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE0_RESET_N, !value);
- case 1:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_EIDE1_RESET_N, !value);
- case 2:
- return simple_feature_tweak(node, macio_unknown,
- KEYLARGO_FCR1, KL1_UIDE_RESET_N, !value);
- default:
- return -ENODEV;
- }
-}
-
-static long
-core99_gmac_enable(struct device_node *node, long param, long value)
-{
- unsigned long flags;
-
- LOCK(flags);
- if (value)
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- else
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- UNLOCK(flags);
- udelay(20);
-
- return 0;
-}
-
-static long
-core99_gmac_phy_reset(struct device_node *node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip *macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_ETH_PHY_RESET);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KL_GPIO_ETH_PHY_RESET, /*KEYLARGO_GPIO_OUTPUT_ENABLE | */
- KEYLARGO_GPIO_OUTOUT_DATA);
- UNLOCK(flags);
- mdelay(10);
-
- return 0;
-}
-
-static long
-core99_sound_chip_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Do a better probe code, screamer G4 desktops &
- * iMacs can do that too, add a recalibrate in
- * the driver as well
- */
- if (pmac_mb.model_id == PMAC_TYPE_PISMO ||
- pmac_mb.model_id == PMAC_TYPE_TITANIUM) {
- LOCK(flags);
- if (value)
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE |
- KEYLARGO_GPIO_OUTOUT_DATA);
- else
- MACIO_OUT8(KL_GPIO_SOUND_POWER,
- KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(KL_GPIO_SOUND_POWER);
- UNLOCK(flags);
- }
- return 0;
-}
-
-static long
-core99_airport_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip* macio;
- unsigned long flags;
- int state;
-
- macio = macio_find(node, 0);
- if (!macio)
- return -ENODEV;
-
- /* Hint: we allow passing of macio itself for the sake of the
- * sleep code
- */
- if (node != macio->of_node &&
- (!node->parent || node->parent != macio->of_node))
- return -ENODEV;
- state = (macio->flags & MACIO_FLAG_AIRPORT_ON) != 0;
- if (value == state)
- return 0;
- if (value) {
- /* This code is a reproduction of OF enable-cardslot
- * and init-wireless methods, slightly hacked until
- * I got it working.
- */
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 5);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
- mdelay(10);
- LOCK(flags);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xf, 4);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xf);
- UNLOCK(flags);
-
- mdelay(10);
-
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xb, 0);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xb);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xa, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xa);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xd, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xd);
- udelay(10);
- MACIO_OUT8(KEYLARGO_GPIO_0+0xe, 0x28);
- (void)MACIO_IN8(KEYLARGO_GPIO_0+0xe);
- UNLOCK(flags);
- udelay(10);
- MACIO_OUT32(0x1c000, 0);
- mdelay(1);
- MACIO_OUT8(0x1a3e0, 0x41);
- (void)MACIO_IN8(0x1a3e0);
- udelay(10);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- UNLOCK(flags);
- mdelay(100);
-
- macio->flags |= MACIO_FLAG_AIRPORT_ON;
- } else {
- LOCK(flags);
- MACIO_BIC(KEYLARGO_FCR2, KL2_CARDSEL_16);
- (void)MACIO_IN32(KEYLARGO_FCR2);
- MACIO_OUT8(KL_GPIO_AIRPORT_0, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_1, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_2, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_3, 0);
- MACIO_OUT8(KL_GPIO_AIRPORT_4, 0);
- (void)MACIO_IN8(KL_GPIO_AIRPORT_4);
- UNLOCK(flags);
-
- macio->flags &= ~MACIO_FLAG_AIRPORT_ON;
- }
- return 0;
-}
-
-#ifdef CONFIG_SMP
-static long
-core99_reset_cpu(struct device_node *node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip *macio;
- struct device_node *np;
- struct device_node *cpus;
- const int dflt_reset_lines[] = { KL_GPIO_RESET_CPU0,
- KL_GPIO_RESET_CPU1,
- KL_GPIO_RESET_CPU2,
- KL_GPIO_RESET_CPU3 };
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo)
- return -ENODEV;
-
- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL)
- return -ENODEV;
- for (np = cpus->child; np != NULL; np = np->sibling) {
- const u32 *num = of_get_property(np, "reg", NULL);
- const u32 *rst = of_get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- of_node_put(cpus);
- if (np == NULL || reset_io == 0)
- reset_io = dflt_reset_lines[param];
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-static long
-core99_usb_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio;
- unsigned long flags;
- const char *prop;
- int number;
- u32 reg;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- prop = of_get_property(node, "AAPL,clock-id", NULL);
- if (!prop)
- return -ENODEV;
- if (strncmp(prop, "usb0u048", 8) == 0)
- number = 0;
- else if (strncmp(prop, "usb1u148", 8) == 0)
- number = 2;
- else if (strncmp(prop, "usb2u248", 8) == 0)
- number = 4;
- else
- return -ENODEV;
-
- /* Sorry for the brute-force locking, but this is only used during
- * sleep and the timing seem to be critical
- */
- LOCK(flags);
- if (value) {
- /* Turn ON */
- if (number == 0) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- UNLOCK(flags);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- } else if (number == 2) {
- MACIO_BIC(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- } else if (number == 4) {
- MACIO_BIC(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- UNLOCK(flags);
- (void)MACIO_IN32(KEYLARGO_FCR1);
- mdelay(1);
- LOCK(flags);
- MACIO_BIS(KEYLARGO_FCR1, KL1_USB2_CELL_ENABLE);
- }
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number));
- reg &= ~(KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1));
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(10);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0));
- reg &= ~(KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1));
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(10);
- }
- if (macio->type == macio_intrepid) {
- /* wait for clock stopped bits to clear */
- u32 test0 = 0, test1 = 0;
- u32 status0, status1;
- int timeout = 1000;
-
- UNLOCK(flags);
- switch (number) {
- case 0:
- test0 = UNI_N_CLOCK_STOPPED_USB0;
- test1 = UNI_N_CLOCK_STOPPED_USB0PCI;
- break;
- case 2:
- test0 = UNI_N_CLOCK_STOPPED_USB1;
- test1 = UNI_N_CLOCK_STOPPED_USB1PCI;
- break;
- case 4:
- test0 = UNI_N_CLOCK_STOPPED_USB2;
- test1 = UNI_N_CLOCK_STOPPED_USB2PCI;
- break;
- }
- do {
- if (--timeout <= 0) {
- printk(KERN_ERR "core99_usb_enable: "
- "Timeout waiting for clocks\n");
- break;
- }
- mdelay(1);
- status0 = UN_IN(UNI_N_CLOCK_STOP_STATUS0);
- status1 = UN_IN(UNI_N_CLOCK_STOP_STATUS1);
- } while ((status0 & test0) | (status1 & test1));
- LOCK(flags);
- }
- } else {
- /* Turn OFF */
- if (number < 4) {
- reg = MACIO_IN32(KEYLARGO_FCR4);
- reg |= KL4_PORT_WAKEUP_ENABLE(number) | KL4_PORT_RESUME_WAKE_EN(number) |
- KL4_PORT_CONNECT_WAKE_EN(number) | KL4_PORT_DISCONNECT_WAKE_EN(number);
- reg |= KL4_PORT_WAKEUP_ENABLE(number+1) | KL4_PORT_RESUME_WAKE_EN(number+1) |
- KL4_PORT_CONNECT_WAKE_EN(number+1) | KL4_PORT_DISCONNECT_WAKE_EN(number+1);
- MACIO_OUT32(KEYLARGO_FCR4, reg);
- (void)MACIO_IN32(KEYLARGO_FCR4);
- udelay(1);
- } else {
- reg = MACIO_IN32(KEYLARGO_FCR3);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(0) | KL3_IT_PORT_RESUME_WAKE_EN(0) |
- KL3_IT_PORT_CONNECT_WAKE_EN(0) | KL3_IT_PORT_DISCONNECT_WAKE_EN(0);
- reg |= KL3_IT_PORT_WAKEUP_ENABLE(1) | KL3_IT_PORT_RESUME_WAKE_EN(1) |
- KL3_IT_PORT_CONNECT_WAKE_EN(1) | KL3_IT_PORT_DISCONNECT_WAKE_EN(1);
- MACIO_OUT32(KEYLARGO_FCR3, reg);
- (void)MACIO_IN32(KEYLARGO_FCR3);
- udelay(1);
- }
- if (number == 0) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB0_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB0_PAD_SUSPEND0 | KL0_USB0_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 2) {
- if (macio->type != macio_intrepid)
- MACIO_BIC(KEYLARGO_FCR0, KL0_USB1_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR0, (KL0_USB1_PAD_SUSPEND0 | KL0_USB1_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR0);
- } else if (number == 4) {
- udelay(1);
- MACIO_BIS(KEYLARGO_FCR1, (KL1_USB2_PAD_SUSPEND0 | KL1_USB2_PAD_SUSPEND1));
- (void)MACIO_IN32(KEYLARGO_FCR1);
- }
- udelay(1);
- }
- UNLOCK(flags);
-
- return 0;
-}
-
-static long
-core99_firewire_enable(struct device_node *node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip *macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- } else {
- UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW);
- (void)UN_IN(UNI_N_CLOCK_CNTL);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-core99_firewire_cable_power(struct device_node *node, long param, long value)
-{
- unsigned long flags;
- struct macio_chip *macio;
-
- /* Trick: we allow NULL node */
- if ((pmac_mb.board_flags & PMAC_MB_HAS_FW_POWER) == 0)
- return -ENODEV;
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
- if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 0);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER);
- udelay(10);
- } else {
- MACIO_OUT8(KL_GPIO_FW_CABLE_POWER , 4);
- MACIO_IN8(KL_GPIO_FW_CABLE_POWER); udelay(10);
- }
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long
-intrepid_aack_delay_enable(struct device_node *node, long param, long value)
-{
- unsigned long flags;
-
- if (uninorth_rev < 0xd2)
- return -ENODEV;
-
- LOCK(flags);
- if (param)
- UN_BIS(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- else
- UN_BIC(UNI_N_AACK_DELAY, UNI_N_AACK_DELAY_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-
-#endif /* CONFIG_POWER4 */
-
-static long
-core99_read_gpio(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio = &macio_chips[0];
-
- return MACIO_IN8(param);
-}
-
-
-static long
-core99_write_gpio(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio = &macio_chips[0];
-
- MACIO_OUT8(param, (u8)(value & 0xff));
- return 0;
-}
-
-#ifdef CONFIG_POWER4
-static long g5_gmac_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- mb();
- k2_skiplist[0] = NULL;
- } else {
- k2_skiplist[0] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_GMAC_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long g5_fw_enable(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio = &macio_chips[0];
- unsigned long flags;
-
- if (node == NULL)
- return -ENODEV;
-
- LOCK(flags);
- if (value) {
- MACIO_BIS(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- mb();
- k2_skiplist[1] = NULL;
- } else {
- k2_skiplist[1] = node;
- mb();
- MACIO_BIC(KEYLARGO_FCR1, K2_FCR1_FW_CLK_ENABLE);
- }
-
- UNLOCK(flags);
- mdelay(1);
-
- return 0;
-}
-
-static long g5_mpic_enable(struct device_node *node, long param, long value)
-{
- unsigned long flags;
- struct device_node *parent = of_get_parent(node);
- int is_u3;
-
- if (parent == NULL)
- return 0;
- is_u3 = strcmp(parent->name, "u3") == 0 ||
- strcmp(parent->name, "u4") == 0;
- of_node_put(parent);
- if (!is_u3)
- return 0;
-
- LOCK(flags);
- UN_BIS(U3_TOGGLE_REG, U3_MPIC_RESET | U3_MPIC_OUTPUT_ENABLE);
- UNLOCK(flags);
-
- return 0;
-}
-
-static long g5_eth_phy_reset(struct device_node *node, long param, long value)
-{
- struct macio_chip *macio = &macio_chips[0];
- struct device_node *phy;
- int need_reset;
-
- /*
- * We must not reset the combo PHYs, only the BCM5221 found in
- * the iMac G5.
- */
- phy = of_get_next_child(node, NULL);
- if (!phy)
- return -ENODEV;
- need_reset = of_device_is_compatible(phy, "B5221");
- of_node_put(phy);
- if (!need_reset)
- return 0;
-
- /* PHY reset is GPIO 29, not in device-tree unfortunately */
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29,
- KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- /* Thankfully, this is now always called at a time when we can
- * schedule by sungem.
- */
- msleep(10);
- MACIO_OUT8(K2_GPIO_EXTINT_0 + 29, 0);
-
- return 0;
-}
-
-static long g5_i2s_enable(struct device_node *node, long param, long value)
-{
- /* Very crude implementation for now */
- struct macio_chip *macio = &macio_chips[0];
- unsigned long flags;
- int cell;
- u32 fcrs[3][3] = {
- { 0,
- K2_FCR1_I2S0_CELL_ENABLE |
- K2_FCR1_I2S0_CLK_ENABLE_BIT | K2_FCR1_I2S0_ENABLE,
- KL3_I2S0_CLK18_ENABLE
- },
- { KL0_SCC_A_INTF_ENABLE,
- K2_FCR1_I2S1_CELL_ENABLE |
- K2_FCR1_I2S1_CLK_ENABLE_BIT | K2_FCR1_I2S1_ENABLE,
- KL3_I2S1_CLK18_ENABLE
- },
- { KL0_SCC_B_INTF_ENABLE,
- SH_FCR1_I2S2_CELL_ENABLE |
- SH_FCR1_I2S2_CLK_ENABLE_BIT | SH_FCR1_I2S2_ENABLE,
- SH_FCR3_I2S2_CLK18_ENABLE
- },
- };
-
- if (macio->type != macio_keylargo2 && macio->type != macio_shasta)
- return -ENODEV;
- if (strncmp(node->name, "i2s-", 4))
- return -ENODEV;
- cell = node->name[4] - 'a';
- switch(cell) {
- case 0:
- case 1:
- break;
- case 2:
- if (macio->type == macio_shasta)
- break;
- default:
- return -ENODEV;
- }
-
- LOCK(flags);
- if (value) {
- MACIO_BIC(KEYLARGO_FCR0, fcrs[cell][0]);
- MACIO_BIS(KEYLARGO_FCR1, fcrs[cell][1]);
- MACIO_BIS(KEYLARGO_FCR3, fcrs[cell][2]);
- } else {
- MACIO_BIC(KEYLARGO_FCR3, fcrs[cell][2]);
- MACIO_BIC(KEYLARGO_FCR1, fcrs[cell][1]);
- MACIO_BIS(KEYLARGO_FCR0, fcrs[cell][0]);
- }
- udelay(10);
- UNLOCK(flags);
-
- return 0;
-}
-
-
-#ifdef CONFIG_SMP
-static long g5_reset_cpu(struct device_node *node, long param, long value)
-{
- unsigned int reset_io = 0;
- unsigned long flags;
- struct macio_chip *macio;
- struct device_node *np;
- struct device_node *cpus;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo2 && macio->type != macio_shasta)
- return -ENODEV;
-
- cpus = of_find_node_by_path("/cpus");
- if (cpus == NULL)
- return -ENODEV;
- for (np = cpus->child; np != NULL; np = np->sibling) {
- const u32 *num = of_get_property(np, "reg", NULL);
- const u32 *rst = of_get_property(np, "soft-reset", NULL);
- if (num == NULL || rst == NULL)
- continue;
- if (param == *num) {
- reset_io = *rst;
- break;
- }
- }
- of_node_put(cpus);
- if (np == NULL || reset_io == 0)
- return -ENODEV;
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, 0);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-#endif /* CONFIG_SMP */
-
-/*
- * This can be called from pmac_smp so isn't static
- *
- * This takes the second CPU off the bus on dual CPU machines
- * running UP
- */
-void g5_phy_disable_cpu1(void)
-{
- if (uninorth_maj == 3)
- UN_OUT(U3_API_PHY_CONFIG_1, 0);
-}
-#endif /* CONFIG_POWER4 */
-
-#ifndef CONFIG_POWER4
-
-
-#ifdef CONFIG_PM
-static u32 save_gpio_levels[2];
-static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
-static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
-static u32 save_unin_clock_ctl;
-
-static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
-{
- u32 temp;
-
- if (sleep_mode) {
- mdelay(1);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(1);
- }
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_IRDA_ENABLE | KL0_IRDA_CLK32_ENABLE |
- KL0_IRDA_CLK19_ENABLE);
-
- MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
- MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
- KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
- KL1_UIDE_ENABLE);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- if (macio->rev >= 2) {
- temp |= KL3_SHUTDOWN_PLL2X;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLL_TOTAL;
- }
-
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- if (sleep_mode)
- temp |= KL3_SHUTDOWN_PLLKW12;
- temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
- | KL3_CLK31_ENABLE | KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void pangea_shutdown(struct macio_chip *macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE |
- KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
- KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_UIDE_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp |= KL3_SHUTDOWN_PLLKW6 | KL3_SHUTDOWN_PLLKW4 |
- KL3_SHUTDOWN_PLLKW35;
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE | KL3_CLK31_ENABLE
- | KL3_I2S0_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_VIA_CLK16_ENABLE | KL3_TIMER_CLK18_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
-}
-
-static void intrepid_shutdown(struct macio_chip *macio, int sleep_mode)
-{
- u32 temp;
-
- MACIO_BIC(KEYLARGO_FCR0,KL0_SCCA_ENABLE | KL0_SCCB_ENABLE |
- KL0_SCC_CELL_ENABLE);
-
- MACIO_BIC(KEYLARGO_FCR1,
- KL1_I2S0_CELL_ENABLE | KL1_I2S0_CLK_ENABLE_BIT |
- KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
- KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
- KL1_EIDE0_ENABLE);
- if (pmac_mb.board_flags & PMAC_MB_MOBILE)
- MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
-
- temp = MACIO_IN32(KEYLARGO_FCR3);
- temp &= ~(KL3_CLK49_ENABLE | KL3_CLK45_ENABLE |
- KL3_I2S1_CLK18_ENABLE | KL3_I2S0_CLK18_ENABLE);
- if (sleep_mode)
- temp &= ~(KL3_TIMER_CLK18_ENABLE | KL3_IT_VIA_CLK32_ENABLE);
- MACIO_OUT32(KEYLARGO_FCR3, temp);
-
- /* Flush posted writes & wait a bit */
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(10);
-}
-
-
-static int
-core99_sleep(void)
-{
- struct macio_chip *macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /* We power off the wireless slot in case it was not done
- * by the driver. We don't power it on automatically however
- */
- if (macio->flags & MACIO_FLAG_AIRPORT_ON)
- core99_airport_enable(macio->of_node, 0, 0);
-
- /* We power off the FW cable. Should be done by the driver... */
- if (macio->flags & MACIO_FLAG_FW_SUPPORTED) {
- core99_firewire_enable(NULL, 0, 0);
- core99_firewire_cable_power(NULL, 0, 0);
- }
-
- /* We make sure int. modem is off (in case driver lost it) */
- if (macio->type == macio_keylargo)
- core99_modem_enable(macio->of_node, 0, 0);
- else
- pangea_modem_enable(macio->of_node, 0, 0);
-
- /* We make sure the sound is off as well */
- core99_sound_chip_enable(macio->of_node, 0, 0);
-
- /*
- * Save various bits of KeyLargo
- */
-
- /* Save the state of the various GPIOs */
- save_gpio_levels[0] = MACIO_IN32(KEYLARGO_GPIO_LEVELS0);
- save_gpio_levels[1] = MACIO_IN32(KEYLARGO_GPIO_LEVELS1);
- for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
- save_gpio_extint[i] = MACIO_IN8(KEYLARGO_GPIO_EXTINT_0+i);
- for (i=0; i<KEYLARGO_GPIO_CNT; i++)
- save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
-
- /* Save the FCRs */
- if (macio->type == macio_keylargo)
- save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
- save_fcr[0] = MACIO_IN32(KEYLARGO_FCR0);
- save_fcr[1] = MACIO_IN32(KEYLARGO_FCR1);
- save_fcr[2] = MACIO_IN32(KEYLARGO_FCR2);
- save_fcr[3] = MACIO_IN32(KEYLARGO_FCR3);
- save_fcr[4] = MACIO_IN32(KEYLARGO_FCR4);
- if (macio->type == macio_pangea || macio->type == macio_intrepid)
- save_fcr[5] = MACIO_IN32(KEYLARGO_FCR5);
-
- /* Save state & config of DBDMA channels */
- dbdma_save(macio, save_dbdma);
-
- /*
- * Turn off as much as we can
- */
- if (macio->type == macio_pangea)
- pangea_shutdown(macio, 1);
- else if (macio->type == macio_intrepid)
- intrepid_shutdown(macio, 1);
- else if (macio->type == macio_keylargo)
- keylargo_shutdown(macio, 1);
-
- /*
- * Put the host bridge to sleep
- */
-
- save_unin_clock_ctl = UN_IN(UNI_N_CLOCK_CNTL);
- /* Note: do not switch GMAC off, driver does it when necessary, WOL must keep it
- * enabled !
- */
- UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl &
- ~(/*UNI_N_CLOCK_CNTL_GMAC|*/UNI_N_CLOCK_CNTL_FW/*|UNI_N_CLOCK_CNTL_PCI*/));
- udelay(100);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_SLEEP);
- mdelay(10);
-
- /*
- * FIXME: A bit of black magic with OpenPIC (don't ask me why)
- */
- if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
- MACIO_BIS(0x506e0, 0x00400000);
- MACIO_BIS(0x506e0, 0x80000000);
- }
- return 0;
-}
-
-static int
-core99_wake_up(void)
-{
- struct macio_chip *macio;
- int i;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea &&
- macio->type != macio_intrepid)
- return -ENODEV;
-
- /*
- * Wakeup the host bridge
- */
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
- udelay(10);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
- udelay(10);
-
- /*
- * Restore KeyLargo
- */
-
- if (macio->type == macio_keylargo) {
- MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
- }
- MACIO_OUT32(KEYLARGO_FCR0, save_fcr[0]);
- (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR1, save_fcr[1]);
- (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR2, save_fcr[2]);
- (void)MACIO_IN32(KEYLARGO_FCR2); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR3, save_fcr[3]);
- (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
- MACIO_OUT32(KEYLARGO_FCR4, save_fcr[4]);
- (void)MACIO_IN32(KEYLARGO_FCR4); udelay(10);
- if (macio->type == macio_pangea || macio->type == macio_intrepid) {
- MACIO_OUT32(KEYLARGO_FCR5, save_fcr[5]);
- (void)MACIO_IN32(KEYLARGO_FCR5); udelay(10);
- }
-
- dbdma_restore(macio, save_dbdma);
-
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS0, save_gpio_levels[0]);
- MACIO_OUT32(KEYLARGO_GPIO_LEVELS1, save_gpio_levels[1]);
- for (i=0; i<KEYLARGO_GPIO_EXTINT_CNT; i++)
- MACIO_OUT8(KEYLARGO_GPIO_EXTINT_0+i, save_gpio_extint[i]);
- for (i=0; i<KEYLARGO_GPIO_CNT; i++)
- MACIO_OUT8(KEYLARGO_GPIO_0+i, save_gpio_normal[i]);
-
- /* FIXME more black magic with OpenPIC ... */
- if (pmac_mb.model_id == PMAC_TYPE_SAWTOOTH) {
- MACIO_BIC(0x506e0, 0x00400000);
- MACIO_BIC(0x506e0, 0x80000000);
- }
-
- UN_OUT(UNI_N_CLOCK_CNTL, save_unin_clock_ctl);
- udelay(100);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-static long
-core99_sleep_state(struct device_node *node, long param, long value)
-{
- /* Param == 1 means to enter the "fake sleep" mode that is
- * used for CPU speed switch
- */
- if (param == 1) {
- if (value == 1) {
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_SLEEPING);
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_IDLE2);
- } else {
- UN_OUT(UNI_N_POWER_MGT, UNI_N_POWER_MGT_NORMAL);
- udelay(10);
- UN_OUT(UNI_N_HWINIT_STATE, UNI_N_HWINIT_STATE_RUNNING);
- udelay(10);
- }
- return 0;
- }
- if ((pmac_mb.board_flags & PMAC_MB_CAN_SLEEP) == 0)
- return -EPERM;
-
-#ifdef CONFIG_PM
- if (value == 1)
- return core99_sleep();
- else if (value == 0)
- return core99_wake_up();
-
-#endif /* CONFIG_PM */
- return 0;
-}
-
-#endif /* CONFIG_POWER4 */
-
-static long
-generic_dev_can_wake(struct device_node *node, long param, long value)
-{
- /* Todo: eventually check we are really dealing with on-board
- * video device ...
- */
-
- if (pmac_mb.board_flags & PMAC_MB_MAY_SLEEP)
- pmac_mb.board_flags |= PMAC_MB_CAN_SLEEP;
- return 0;
-}
-
-static long generic_get_mb_info(struct device_node *node, long param, long value)
-{
- switch(param) {
- case PMAC_MB_INFO_MODEL:
- return pmac_mb.model_id;
- case PMAC_MB_INFO_FLAGS:
- return pmac_mb.board_flags;
- case PMAC_MB_INFO_NAME:
- /* hack hack hack... but should work */
- *((const char **)value) = pmac_mb.model_name;
- return 0;
- }
- return -EINVAL;
-}
-
-
-/*
- * Table definitions
- */
-
-/* Used on any machine
- */
-static struct feature_table_entry any_features[] = {
- { PMAC_FTR_GET_MB_INFO, generic_get_mb_info },
- { PMAC_FTR_DEVICE_CAN_WAKE, generic_dev_can_wake },
- { 0, NULL }
-};
-
-#ifndef CONFIG_POWER4
-
-/* OHare based motherboards. Currently, we only use these on the
- * 2400,3400 and 3500 series powerbooks. Some older desktops seem
- * to have issues with turning on/off those asic cells
- */
-static struct feature_table_entry ohare_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_SWIM3_ENABLE, ohare_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, ohare_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, ohare_ide_enable},
- { PMAC_FTR_IDE_RESET, ohare_ide_reset},
- { PMAC_FTR_SLEEP_STATE, ohare_sleep_state },
- { 0, NULL }
-};
-
-/* Heathrow desktop machines (Beige G3).
- * Separated as some features couldn't be properly tested
- * and the serial port control bits appear to confuse it.
- */
-static struct feature_table_entry heathrow_desktop_features[] = {
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { 0, NULL }
-};
-
-/* Heathrow based laptop, that is the Wallstreet and mainstreet
- * powerbooks.
- */
-static struct feature_table_entry heathrow_laptop_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
- { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
- { 0, NULL }
-};
-
-/* Paddington based machines
- * The lombard (101) powerbook, first iMac models, B&W G3 and Yikes G4.
- */
-static struct feature_table_entry paddington_features[] = {
- { PMAC_FTR_SCC_ENABLE, ohare_htw_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, heathrow_modem_enable },
- { PMAC_FTR_SWIM3_ENABLE, heathrow_floppy_enable },
- { PMAC_FTR_MESH_ENABLE, heathrow_mesh_enable },
- { PMAC_FTR_IDE_ENABLE, heathrow_ide_enable },
- { PMAC_FTR_IDE_RESET, heathrow_ide_reset },
- { PMAC_FTR_BMAC_ENABLE, heathrow_bmac_enable },
- { PMAC_FTR_SOUND_CHIP_ENABLE, heathrow_sound_enable },
- { PMAC_FTR_SLEEP_STATE, heathrow_sleep_state },
- { 0, NULL }
-};
-
-/* Core99 & MacRISC 2 machines (all machines released since the
- * iBook (included), that is all AGP machines, except pangea
- * chipset. The pangea chipset is the "combo" UniNorth/KeyLargo
- * used on iBook2 & iMac "flow power".
- */
-static struct feature_table_entry core99_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, core99_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
-#ifdef CONFIG_PM
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
-#endif
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, core99_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* RackMac
- */
-static struct feature_table_entry rackmac_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, core99_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* Pangea features
- */
-static struct feature_table_entry pangea_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-/* Intrepid features
- */
-static struct feature_table_entry intrepid_features[] = {
- { PMAC_FTR_SCC_ENABLE, core99_scc_enable },
- { PMAC_FTR_MODEM_ENABLE, pangea_modem_enable },
- { PMAC_FTR_IDE_ENABLE, core99_ide_enable },
- { PMAC_FTR_IDE_RESET, core99_ide_reset },
- { PMAC_FTR_GMAC_ENABLE, core99_gmac_enable },
- { PMAC_FTR_GMAC_PHY_RESET, core99_gmac_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, core99_sound_chip_enable },
- { PMAC_FTR_AIRPORT_ENABLE, core99_airport_enable },
- { PMAC_FTR_USB_ENABLE, core99_usb_enable },
- { PMAC_FTR_1394_ENABLE, core99_firewire_enable },
- { PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
- { PMAC_FTR_SLEEP_STATE, core99_sleep_state },
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { PMAC_FTR_AACK_DELAY_ENABLE, intrepid_aack_delay_enable },
- { 0, NULL }
-};
-
-#else /* CONFIG_POWER4 */
-
-/* G5 features
- */
-static struct feature_table_entry g5_features[] = {
- { PMAC_FTR_GMAC_ENABLE, g5_gmac_enable },
- { PMAC_FTR_1394_ENABLE, g5_fw_enable },
- { PMAC_FTR_ENABLE_MPIC, g5_mpic_enable },
- { PMAC_FTR_GMAC_PHY_RESET, g5_eth_phy_reset },
- { PMAC_FTR_SOUND_CHIP_ENABLE, g5_i2s_enable },
-#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, g5_reset_cpu },
-#endif /* CONFIG_SMP */
- { PMAC_FTR_READ_GPIO, core99_read_gpio },
- { PMAC_FTR_WRITE_GPIO, core99_write_gpio },
- { 0, NULL }
-};
-
-#endif /* CONFIG_POWER4 */
-
-static struct pmac_mb_def pmac_mb_defs[] = {
-#ifndef CONFIG_POWER4
- /*
- * Desktops
- */
-
- { "AAPL,8500", "PowerMac 8500/8600",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,9500", "PowerMac 9500/9600",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7200", "PowerMac 7200",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7300", "PowerMac 7200/7300",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,7500", "PowerMac 7500",
- PMAC_TYPE_PSURGE, NULL,
- 0
- },
- { "AAPL,ShinerESB", "Apple Network Server",
- PMAC_TYPE_ANS, NULL,
- 0
- },
- { "AAPL,e407", "Alchemy",
- PMAC_TYPE_ALCHEMY, NULL,
- 0
- },
- { "AAPL,e411", "Gazelle",
- PMAC_TYPE_GAZELLE, NULL,
- 0
- },
- { "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
- PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
- 0
- },
- { "AAPL,PowerMac G3", "PowerMac G3 (Silk)",
- PMAC_TYPE_SILK, heathrow_desktop_features,
- 0
- },
- { "PowerMac1,1", "Blue&White G3",
- PMAC_TYPE_YOSEMITE, paddington_features,
- 0
- },
- { "PowerMac1,2", "PowerMac G4 PCI Graphics",
- PMAC_TYPE_YIKES, paddington_features,
- 0
- },
- { "PowerMac2,1", "iMac FireWire",
- PMAC_TYPE_FW_IMAC, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac2,2", "iMac FireWire",
- PMAC_TYPE_FW_IMAC, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,1", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,2", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,3", "PowerMac G4 AGP Graphics",
- PMAC_TYPE_SAWTOOTH, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac3,4", "PowerMac G4 Silver",
- PMAC_TYPE_QUICKSILVER, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac3,5", "PowerMac G4 Silver",
- PMAC_TYPE_QUICKSILVER, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac3,6", "PowerMac G4 Windtunnel",
- PMAC_TYPE_WINDTUNNEL, core99_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac4,1", "iMac \"Flower Power\"",
- PMAC_TYPE_PANGEA_IMAC, pangea_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac4,2", "Flat panel iMac",
- PMAC_TYPE_FLAT_PANEL_IMAC, pangea_features,
- PMAC_MB_CAN_SLEEP
- },
- { "PowerMac4,4", "eMac",
- PMAC_TYPE_EMAC, core99_features,
- PMAC_MB_MAY_SLEEP
- },
- { "PowerMac5,1", "PowerMac G4 Cube",
- PMAC_TYPE_CUBE, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_OLD_CORE99
- },
- { "PowerMac6,1", "Flat panel iMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac6,3", "Flat panel iMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac6,4", "eMac",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac10,1", "Mac mini",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "PowerMac10,2", "Mac mini (Late 2005)",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP,
- },
- { "iMac,1", "iMac (first generation)",
- PMAC_TYPE_ORIG_IMAC, paddington_features,
- 0
- },
-
- /*
- * Xserve's
- */
-
- { "RackMac1,1", "XServe",
- PMAC_TYPE_RACKMAC, rackmac_features,
- 0,
- },
- { "RackMac1,2", "XServe rev. 2",
- PMAC_TYPE_RACKMAC, rackmac_features,
- 0,
- },
-
- /*
- * Laptops
- */
-
- { "AAPL,3400/2400", "PowerBook 3400",
- PMAC_TYPE_HOOPER, ohare_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "AAPL,3500", "PowerBook 3500",
- PMAC_TYPE_KANGA, ohare_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "AAPL,PowerBook1998", "PowerBook Wallstreet",
- PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "PowerBook1,1", "PowerBook 101 (Lombard)",
- PMAC_TYPE_101_PBOOK, paddington_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
- },
- { "PowerBook2,1", "iBook (first generation)",
- PMAC_TYPE_ORIG_IBOOK, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook2,2", "iBook FireWire",
- PMAC_TYPE_FW_IBOOK, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
- PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook3,1", "PowerBook Pismo",
- PMAC_TYPE_PISMO, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER |
- PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
- },
- { "PowerBook3,2", "PowerBook Titanium",
- PMAC_TYPE_TITANIUM, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,3", "PowerBook Titanium II",
- PMAC_TYPE_TITANIUM2, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,4", "PowerBook Titanium III",
- PMAC_TYPE_TITANIUM3, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook3,5", "PowerBook Titanium IV",
- PMAC_TYPE_TITANIUM4, core99_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,1", "iBook 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,2", "iBook 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook4,3", "iBook 2 rev. 2",
- PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
- },
- { "PowerBook5,1", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,2", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,3", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,4", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,5", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,6", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,7", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook5,8", "PowerBook G4 15\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE,
- },
- { "PowerBook5,9", "PowerBook G4 17\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_MOBILE,
- },
- { "PowerBook6,1", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,2", "PowerBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,3", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,4", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,5", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,7", "iBook G4",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
- { "PowerBook6,8", "PowerBook G4 12\"",
- PMAC_TYPE_UNKNOWN_INTREPID, intrepid_features,
- PMAC_MB_MAY_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE,
- },
-#else /* CONFIG_POWER4 */
- { "PowerMac7,2", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
-#ifdef CONFIG_PPC64
- { "PowerMac7,3", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5, g5_features,
- 0,
- },
- { "PowerMac8,1", "iMac G5",
- PMAC_TYPE_IMAC_G5, g5_features,
- 0,
- },
- { "PowerMac9,1", "PowerMac G5",
- PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
- 0,
- },
- { "PowerMac11,2", "PowerMac G5 Dual Core",
- PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
- 0,
- },
- { "PowerMac12,1", "iMac G5 (iSight)",
- PMAC_TYPE_POWERMAC_G5_U3L, g5_features,
- 0,
- },
- { "RackMac3,1", "XServe G5",
- PMAC_TYPE_XSERVE_G5, g5_features,
- 0,
- },
-#endif /* CONFIG_PPC64 */
-#endif /* CONFIG_POWER4 */
-};
-
-/*
- * The toplevel feature_call callback
- */
-long pmac_do_feature_call(unsigned int selector, ...)
-{
- struct device_node *node;
- long param, value;
- int i;
- feature_call func = NULL;
- va_list args;
-
- if (pmac_mb.features)
- for (i=0; pmac_mb.features[i].function; i++)
- if (pmac_mb.features[i].selector == selector) {
- func = pmac_mb.features[i].function;
- break;
- }
- if (!func)
- for (i=0; any_features[i].function; i++)
- if (any_features[i].selector == selector) {
- func = any_features[i].function;
- break;
- }
- if (!func)
- return -ENODEV;
-
- va_start(args, selector);
- node = (struct device_node*)va_arg(args, void*);
- param = va_arg(args, long);
- value = va_arg(args, long);
- va_end(args);
-
- return func(node, param, value);
-}
-
-static int __init probe_motherboard(void)
-{
- int i;
- struct macio_chip *macio = &macio_chips[0];
- const char *model = NULL;
- struct device_node *dt;
- int ret = 0;
-
- /* Lookup known motherboard type in device-tree. First try an
- * exact match on the "model" property, then try a "compatible"
- * match is none is found.
- */
- dt = of_find_node_by_name(NULL, "device-tree");
- if (dt != NULL)
- model = of_get_property(dt, "model", NULL);
- for(i=0; model && i<ARRAY_SIZE(pmac_mb_defs); i++) {
- if (strcmp(model, pmac_mb_defs[i].model_string) == 0) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
- for(i=0; i<ARRAY_SIZE(pmac_mb_defs); i++) {
- if (of_machine_is_compatible(pmac_mb_defs[i].model_string)) {
- pmac_mb = pmac_mb_defs[i];
- goto found;
- }
- }
-
- /* Fallback to selection depending on mac-io chip type */
- switch(macio->type) {
-#ifndef CONFIG_POWER4
- case macio_grand_central:
- pmac_mb.model_id = PMAC_TYPE_PSURGE;
- pmac_mb.model_name = "Unknown PowerSurge";
- break;
- case macio_ohare:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_OHARE;
- pmac_mb.model_name = "Unknown OHare-based";
- break;
- case macio_heathrow:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_HEATHROW;
- pmac_mb.model_name = "Unknown Heathrow-based";
- pmac_mb.features = heathrow_desktop_features;
- break;
- case macio_paddington:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PADDINGTON;
- pmac_mb.model_name = "Unknown Paddington-based";
- pmac_mb.features = paddington_features;
- break;
- case macio_keylargo:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_CORE99;
- pmac_mb.model_name = "Unknown Keylargo-based";
- pmac_mb.features = core99_features;
- break;
- case macio_pangea:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
- pmac_mb.model_name = "Unknown Pangea-based";
- pmac_mb.features = pangea_features;
- break;
- case macio_intrepid:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_INTREPID;
- pmac_mb.model_name = "Unknown Intrepid-based";
- pmac_mb.features = intrepid_features;
- break;
-#else /* CONFIG_POWER4 */
- case macio_keylargo2:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_K2;
- pmac_mb.model_name = "Unknown K2-based";
- pmac_mb.features = g5_features;
- break;
- case macio_shasta:
- pmac_mb.model_id = PMAC_TYPE_UNKNOWN_SHASTA;
- pmac_mb.model_name = "Unknown Shasta-based";
- pmac_mb.features = g5_features;
- break;
-#endif /* CONFIG_POWER4 */
- default:
- ret = -ENODEV;
- goto done;
- }
-found:
-#ifndef CONFIG_POWER4
- /* Fixup Hooper vs. Comet */
- if (pmac_mb.model_id == PMAC_TYPE_HOOPER) {
- u32 __iomem * mach_id_ptr = ioremap(0xf3000034, 4);
- if (!mach_id_ptr) {
- ret = -ENODEV;
- goto done;
- }
- /* Here, I used to disable the media-bay on comet. It
- * appears this is wrong, the floppy connector is actually
- * a kind of media-bay and works with the current driver.
- */
- if (__raw_readl(mach_id_ptr) & 0x20000000UL)
- pmac_mb.model_id = PMAC_TYPE_COMET;
- iounmap(mach_id_ptr);
- }
-
- /* Set default value of powersave_nap on machines that support it.
- * It appears that uninorth rev 3 has a problem with it, we don't
- * enable it on those. In theory, the flush-on-lock property is
- * supposed to be set when not supported, but I'm not very confident
- * that all Apple OF revs did it properly, I do it the paranoid way.
- */
- while (uninorth_base && uninorth_rev > 3) {
- struct device_node *cpus = of_find_node_by_path("/cpus");
- struct device_node *np;
-
- if (!cpus || !cpus->child) {
- printk(KERN_WARNING "Can't find CPU(s) in device tree !\n");
- of_node_put(cpus);
- break;
- }
- np = cpus->child;
- /* Nap mode not supported on SMP */
- if (np->sibling) {
- of_node_put(cpus);
- break;
- }
- /* Nap mode not supported if flush-on-lock property is present */
- if (of_get_property(np, "flush-on-lock", NULL)) {
- of_node_put(cpus);
- break;
- }
- of_node_put(cpus);
- powersave_nap = 1;
- printk(KERN_DEBUG "Processor NAP mode on idle enabled.\n");
- break;
- }
-
- /* On CPUs that support it (750FX), lowspeed by default during
- * NAP mode
- */
- powersave_lowspeed = 1;
-
-#else /* CONFIG_POWER4 */
- powersave_nap = 1;
-#endif /* CONFIG_POWER4 */
-
- /* Check for "mobile" machine */
- if (model && (strncmp(model, "PowerBook", 9) == 0
- || strncmp(model, "iBook", 5) == 0))
- pmac_mb.board_flags |= PMAC_MB_MOBILE;
-
-
- printk(KERN_INFO "PowerMac motherboard: %s\n", pmac_mb.model_name);
-done:
- of_node_put(dt);
- return ret;
-}
-
-/* Initialize the Core99 UniNorth host bridge and memory controller
- */
-static void __init probe_uninorth(void)
-{
- const u32 *addrp;
- phys_addr_t address;
- unsigned long actrl;
-
- /* Locate core99 Uni-N */
- uninorth_node = of_find_node_by_name(NULL, "uni-n");
- uninorth_maj = 1;
-
- /* Locate G5 u3 */
- if (uninorth_node == NULL) {
- uninorth_node = of_find_node_by_name(NULL, "u3");
- uninorth_maj = 3;
- }
- /* Locate G5 u4 */
- if (uninorth_node == NULL) {
- uninorth_node = of_find_node_by_name(NULL, "u4");
- uninorth_maj = 4;
- }
- if (uninorth_node == NULL) {
- uninorth_maj = 0;
- return;
- }
-
- addrp = of_get_property(uninorth_node, "reg", NULL);
- if (addrp == NULL)
- return;
- address = of_translate_address(uninorth_node, addrp);
- if (address == 0)
- return;
- uninorth_base = ioremap(address, 0x40000);
- if (uninorth_base == NULL)
- return;
- uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
- if (uninorth_maj == 3 || uninorth_maj == 4) {
- u3_ht_base = ioremap(address + U3_HT_CONFIG_BASE, 0x1000);
- if (u3_ht_base == NULL) {
- iounmap(uninorth_base);
- return;
- }
- }
-
- printk(KERN_INFO "Found %s memory controller & host bridge"
- " @ 0x%08x revision: 0x%02x\n", uninorth_maj == 3 ? "U3" :
- uninorth_maj == 4 ? "U4" : "UniNorth",
- (unsigned int)address, uninorth_rev);
- printk(KERN_INFO "Mapped at 0x%08lx\n", (unsigned long)uninorth_base);
-
- /* Set the arbitrer QAck delay according to what Apple does
- */
- if (uninorth_rev < 0x11) {
- actrl = UN_IN(UNI_N_ARB_CTRL) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
- actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 :
- UNI_N_ARB_CTRL_QACK_DELAY) <<
- UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
- UN_OUT(UNI_N_ARB_CTRL, actrl);
- }
-
- /* Some more magic as done by them in recent MacOS X on UniNorth
- * revs 1.5 to 2.O and Pangea. Seem to toggle the UniN Maxbus/PCI
- * memory timeout
- */
- if ((uninorth_rev >= 0x11 && uninorth_rev <= 0x24) ||
- uninorth_rev == 0xc0)
- UN_OUT(0x2160, UN_IN(0x2160) & 0x00ffffff);
-}
-
-static void __init probe_one_macio(const char *name, const char *compat, int type)
-{
- struct device_node* node;
- int i;
- volatile u32 __iomem *base;
- const u32 *addrp, *revp;
- phys_addr_t addr;
- u64 size;
-
- for (node = NULL; (node = of_find_node_by_name(node, name)) != NULL;) {
- if (!compat)
- break;
- if (of_device_is_compatible(node, compat))
- break;
- }
- if (!node)
- return;
- for(i=0; i<MAX_MACIO_CHIPS; i++) {
- if (!macio_chips[i].of_node)
- break;
- if (macio_chips[i].of_node == node)
- return;
- }
-
- if (i >= MAX_MACIO_CHIPS) {
- printk(KERN_ERR "pmac_feature: Please increase MAX_MACIO_CHIPS !\n");
- printk(KERN_ERR "pmac_feature: %s skipped\n", node->full_name);
- return;
- }
- addrp = of_get_pci_address(node, 0, &size, NULL);
- if (addrp == NULL) {
- printk(KERN_ERR "pmac_feature: %s: can't find base !\n",
- node->full_name);
- return;
- }
- addr = of_translate_address(node, addrp);
- if (addr == 0) {
- printk(KERN_ERR "pmac_feature: %s, can't translate base !\n",
- node->full_name);
- return;
- }
- base = ioremap(addr, (unsigned long)size);
- if (!base) {
- printk(KERN_ERR "pmac_feature: %s, can't map mac-io chip !\n",
- node->full_name);
- return;
- }
- if (type == macio_keylargo || type == macio_keylargo2) {
- const u32 *did = of_get_property(node, "device-id", NULL);
- if (*did == 0x00000025)
- type = macio_pangea;
- if (*did == 0x0000003e)
- type = macio_intrepid;
- if (*did == 0x0000004f)
- type = macio_shasta;
- }
- macio_chips[i].of_node = node;
- macio_chips[i].type = type;
- macio_chips[i].base = base;
- macio_chips[i].flags = MACIO_FLAG_SCCA_ON | MACIO_FLAG_SCCB_ON;
- macio_chips[i].name = macio_names[type];
- revp = of_get_property(node, "revision-id", NULL);
- if (revp)
- macio_chips[i].rev = *revp;
- printk(KERN_INFO "Found a %s mac-io controller, rev: %d, mapped at 0x%p\n",
- macio_names[type], macio_chips[i].rev, macio_chips[i].base);
-}
-
-static int __init
-probe_macios(void)
-{
- /* Warning, ordering is important */
- probe_one_macio("gc", NULL, macio_grand_central);
- probe_one_macio("ohare", NULL, macio_ohare);
- probe_one_macio("pci106b,7", NULL, macio_ohareII);
- probe_one_macio("mac-io", "keylargo", macio_keylargo);
- probe_one_macio("mac-io", "paddington", macio_paddington);
- probe_one_macio("mac-io", "gatwick", macio_gatwick);
- probe_one_macio("mac-io", "heathrow", macio_heathrow);
- probe_one_macio("mac-io", "K2-Keylargo", macio_keylargo2);
-
- /* Make sure the "main" macio chip appear first */
- if (macio_chips[0].type == macio_gatwick
- && macio_chips[1].type == macio_heathrow) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- if (macio_chips[0].type == macio_ohareII
- && macio_chips[1].type == macio_ohare) {
- struct macio_chip temp = macio_chips[0];
- macio_chips[0] = macio_chips[1];
- macio_chips[1] = temp;
- }
- macio_chips[0].lbus.index = 0;
- macio_chips[1].lbus.index = 1;
-
- return (macio_chips[0].of_node == NULL) ? -ENODEV : 0;
-}
-
-static void __init
-initial_serial_shutdown(struct device_node *np)
-{
- int len;
- const struct slot_names_prop {
- int count;
- char name[1];
- } *slots;
- const char *conn;
- int port_type = PMAC_SCC_ASYNC;
- int modem = 0;
-
- slots = of_get_property(np, "slot-names", &len);
- conn = of_get_property(np, "AAPL,connector", &len);
- if (conn && (strcmp(conn, "infrared") == 0))
- port_type = PMAC_SCC_IRDA;
- else if (of_device_is_compatible(np, "cobalt"))
- modem = 1;
- else if (slots && slots->count > 0) {
- if (strcmp(slots->name, "IrDA") == 0)
- port_type = PMAC_SCC_IRDA;
- else if (strcmp(slots->name, "Modem") == 0)
- modem = 1;
- }
- if (modem)
- pmac_call_feature(PMAC_FTR_MODEM_ENABLE, np, 0, 0);
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, np, port_type, 0);
-}
-
-static void __init
-set_initial_features(void)
-{
- struct device_node *np;
-
- /* That hack appears to be necessary for some StarMax motherboards
- * but I'm not too sure it was audited for side-effects on other
- * ohare based machines...
- * Since I still have difficulties figuring the right way to
- * differenciate them all and since that hack was there for a long
- * time, I'll keep it around
- */
- if (macio_chips[0].type == macio_ohare) {
- struct macio_chip *macio = &macio_chips[0];
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np)
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- else
- MACIO_OUT32(OHARE_FCR, STARMAX_FEATURES);
- of_node_put(np);
- } else if (macio_chips[1].type == macio_ohare) {
- struct macio_chip *macio = &macio_chips[1];
- MACIO_BIS(OHARE_FCR, OH_IOBUS_ENABLE);
- }
-
-#ifdef CONFIG_POWER4
- if (macio_chips[0].type == macio_keylargo2 ||
- macio_chips[0].type == macio_shasta) {
-#ifndef CONFIG_SMP
- /* On SMP machines running UP, we have the second CPU eating
- * bus cycles. We need to take it off the bus. This is done
- * from pmac_smp for SMP kernels running on one CPU
- */
- np = of_find_node_by_type(NULL, "cpu");
- if (np != NULL)
- np = of_find_node_by_type(np, "cpu");
- if (np != NULL) {
- g5_phy_disable_cpu1();
- of_node_put(np);
- }
-#endif /* CONFIG_SMP */
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (of_device_is_compatible(np, "K2-GMAC"))
- g5_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (of_device_is_compatible(np, "pci106b,5811")) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- g5_fw_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
- }
-#else /* CONFIG_POWER4 */
-
- if (macio_chips[0].type == macio_keylargo ||
- macio_chips[0].type == macio_pangea ||
- macio_chips[0].type == macio_intrepid) {
- /* Enable GMAC for now for PCI probing. It will be disabled
- * later on after PCI probe
- */
- np = of_find_node_by_name(NULL, "ethernet");
- while(np) {
- if (np->parent
- && of_device_is_compatible(np->parent, "uni-north")
- && of_device_is_compatible(np, "gmac"))
- core99_gmac_enable(np, 0, 1);
- np = of_find_node_by_name(np, "ethernet");
- }
-
- /* Enable FW before PCI probe. Will be disabled later on
- * Note: We should have a batter way to check that we are
- * dealing with uninorth internal cell and not a PCI cell
- * on the external PCI. The code below works though.
- */
- np = of_find_node_by_name(NULL, "firewire");
- while(np) {
- if (np->parent
- && of_device_is_compatible(np->parent, "uni-north")
- && (of_device_is_compatible(np, "pci106b,18") ||
- of_device_is_compatible(np, "pci106b,30") ||
- of_device_is_compatible(np, "pci11c1,5811"))) {
- macio_chips[0].flags |= MACIO_FLAG_FW_SUPPORTED;
- core99_firewire_enable(np, 0, 1);
- }
- np = of_find_node_by_name(np, "firewire");
- }
-
- /* Enable ATA-100 before PCI probe. */
- np = of_find_node_by_name(NULL, "ata-6");
- while(np) {
- if (np->parent
- && of_device_is_compatible(np->parent, "uni-north")
- && of_device_is_compatible(np, "kauai-ata")) {
- core99_ata100_enable(np, 1);
- }
- np = of_find_node_by_name(np, "ata-6");
- }
-
- /* Switch airport off */
- for_each_node_by_name(np, "radio") {
- if (np->parent == macio_chips[0].of_node) {
- macio_chips[0].flags |= MACIO_FLAG_AIRPORT_ON;
- core99_airport_enable(np, 0, 0);
- }
- }
- }
-
- /* On all machines that support sound PM, switch sound off */
- if (macio_chips[0].of_node)
- pmac_do_feature_call(PMAC_FTR_SOUND_CHIP_ENABLE,
- macio_chips[0].of_node, 0, 0);
-
- /* While on some desktop G3s, we turn it back on */
- if (macio_chips[0].of_node && macio_chips[0].type == macio_heathrow
- && (pmac_mb.model_id == PMAC_TYPE_GOSSAMER ||
- pmac_mb.model_id == PMAC_TYPE_SILK)) {
- struct macio_chip *macio = &macio_chips[0];
- MACIO_BIS(HEATHROW_FCR, HRW_SOUND_CLK_ENABLE);
- MACIO_BIC(HEATHROW_FCR, HRW_SOUND_POWER_N);
- }
-
-#endif /* CONFIG_POWER4 */
-
- /* On all machines, switch modem & serial ports off */
- for_each_node_by_name(np, "ch-a")
- initial_serial_shutdown(np);
- of_node_put(np);
- for_each_node_by_name(np, "ch-b")
- initial_serial_shutdown(np);
- of_node_put(np);
-}
-
-void __init
-pmac_feature_init(void)
-{
- /* Detect the UniNorth memory controller */
- probe_uninorth();
-
- /* Probe mac-io controllers */
- if (probe_macios()) {
- printk(KERN_WARNING "No mac-io chip found\n");
- return;
- }
-
- /* Probe machine type */
- if (probe_motherboard())
- printk(KERN_WARNING "Unknown PowerMac !\n");
-
- /* Set some initial features (turn off some chips that will
- * be later turned on)
- */
- set_initial_features();
-}
-
-#if 0
-static void dump_HT_speeds(char *name, u32 cfg, u32 frq)
-{
- int freqs[16] = { 200,300,400,500,600,800,1000,0,0,0,0,0,0,0,0,0 };
- int bits[8] = { 8,16,0,32,2,4,0,0 };
- int freq = (frq >> 8) & 0xf;
-
- if (freqs[freq] == 0)
- printk("%s: Unknown HT link frequency %x\n", name, freq);
- else
- printk("%s: %d MHz on main link, (%d in / %d out) bits width\n",
- name, freqs[freq],
- bits[(cfg >> 28) & 0x7], bits[(cfg >> 24) & 0x7]);
-}
-
-void __init pmac_check_ht_link(void)
-{
- u32 ufreq, freq, ucfg, cfg;
- struct device_node *pcix_node;
- u8 px_bus, px_devfn;
- struct pci_controller *px_hose;
-
- (void)in_be32(u3_ht_base + U3_HT_LINK_COMMAND);
- ucfg = cfg = in_be32(u3_ht_base + U3_HT_LINK_CONFIG);
- ufreq = freq = in_be32(u3_ht_base + U3_HT_LINK_FREQ);
- dump_HT_speeds("U3 HyperTransport", cfg, freq);
-
- pcix_node = of_find_compatible_node(NULL, "pci", "pci-x");
- if (pcix_node == NULL) {
- printk("No PCI-X bridge found\n");
- return;
- }
- if (pci_device_from_OF_node(pcix_node, &px_bus, &px_devfn) != 0) {
- printk("PCI-X bridge found but not matched to pci\n");
- return;
- }
- px_hose = pci_find_hose_for_OF_device(pcix_node);
- if (px_hose == NULL) {
- printk("PCI-X bridge found but not matched to host\n");
- return;
- }
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc4, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xcc, &freq);
- dump_HT_speeds("PCI-X HT Uplink", cfg, freq);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xc8, &cfg);
- early_read_config_dword(px_hose, px_bus, px_devfn, 0xd0, &freq);
- dump_HT_speeds("PCI-X HT Downlink", cfg, freq);
-}
-#endif /* 0 */
-
-/*
- * Early video resume hook
- */
-
-static void (*pmac_early_vresume_proc)(void *data);
-static void *pmac_early_vresume_data;
-
-void pmac_set_early_video_resume(void (*proc)(void *data), void *data)
-{
- if (!machine_is(powermac))
- return;
- preempt_disable();
- pmac_early_vresume_proc = proc;
- pmac_early_vresume_data = data;
- preempt_enable();
-}
-EXPORT_SYMBOL(pmac_set_early_video_resume);
-
-void pmac_call_early_video_resume(void)
-{
- if (pmac_early_vresume_proc)
- pmac_early_vresume_proc(pmac_early_vresume_data);
-}
-
-/*
- * AGP related suspend/resume code
- */
-
-static struct pci_dev *pmac_agp_bridge;
-static int (*pmac_agp_suspend)(struct pci_dev *bridge);
-static int (*pmac_agp_resume)(struct pci_dev *bridge);
-
-void pmac_register_agp_pm(struct pci_dev *bridge,
- int (*suspend)(struct pci_dev *bridge),
- int (*resume)(struct pci_dev *bridge))
-{
- if (suspend || resume) {
- pmac_agp_bridge = bridge;
- pmac_agp_suspend = suspend;
- pmac_agp_resume = resume;
- return;
- }
- if (bridge != pmac_agp_bridge)
- return;
- pmac_agp_suspend = pmac_agp_resume = NULL;
- return;
-}
-EXPORT_SYMBOL(pmac_register_agp_pm);
-
-void pmac_suspend_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_suspend == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_suspend(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_suspend_agp_for_card);
-
-void pmac_resume_agp_for_card(struct pci_dev *dev)
-{
- if (pmac_agp_bridge == NULL || pmac_agp_resume == NULL)
- return;
- if (pmac_agp_bridge->bus != dev->bus)
- return;
- pmac_agp_resume(pmac_agp_bridge);
-}
-EXPORT_SYMBOL(pmac_resume_agp_for_card);
-
-int pmac_get_uninorth_variant(void)
-{
- return uninorth_maj;
-}
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/low_i2c.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/low_i2c.c
deleted file mode 100644
index 03685a32..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/low_i2c.c
+++ /dev/null
@@ -1,1514 +0,0 @@
-/*
- * arch/powerpc/platforms/powermac/low_i2c.c
- *
- * Copyright (C) 2003-2005 Ben. Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- *
- * The linux i2c layer isn't completely suitable for our needs for various
- * reasons ranging from too late initialisation to semantics not perfectly
- * matching some requirements of the apple platform functions etc...
- *
- * This file thus provides a simple low level unified i2c interface for
- * powermac that covers the various types of i2c busses used in Apple machines.
- * For now, keywest, PMU and SMU, though we could add Cuda, or other bit
- * banging busses found on older chipstes in earlier machines if we ever need
- * one of them.
- *
- * The drivers in this file are synchronous/blocking. In addition, the
- * keywest one is fairly slow due to the use of msleep instead of interrupts
- * as the interrupt is currently used by i2c-keywest. In the long run, we
- * might want to get rid of those high-level interfaces to linux i2c layer
- * either completely (converting all drivers) or replacing them all with a
- * single stub driver on top of this one. Once done, the interrupt will be
- * available for our use.
- */
-
-#undef DEBUG
-#undef DEBUG_LOW
-
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/export.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/delay.h>
-#include <linux/completion.h>
-#include <linux/platform_device.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/mutex.h>
-#include <linux/i2c.h>
-#include <linux/slab.h>
-#include <asm/keylargo.h>
-#include <asm/uninorth.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/smu.h>
-#include <asm/pmac_pfunc.h>
-#include <asm/pmac_low_i2c.h>
-
-#ifdef DEBUG
-#define DBG(x...) do {\
- printk(KERN_DEBUG "low_i2c:" x); \
- } while(0)
-#else
-#define DBG(x...)
-#endif
-
-#ifdef DEBUG_LOW
-#define DBG_LOW(x...) do {\
- printk(KERN_DEBUG "low_i2c:" x); \
- } while(0)
-#else
-#define DBG_LOW(x...)
-#endif
-
-
-static int pmac_i2c_force_poll = 1;
-
-/*
- * A bus structure. Each bus in the system has such a structure associated.
- */
-struct pmac_i2c_bus
-{
- struct list_head link;
- struct device_node *controller;
- struct device_node *busnode;
- int type;
- int flags;
- struct i2c_adapter adapter;
- void *hostdata;
- int channel; /* some hosts have multiple */
- int mode; /* current mode */
- struct mutex mutex;
- int opened;
- int polled; /* open mode */
- struct platform_device *platform_dev;
-
- /* ops */
- int (*open)(struct pmac_i2c_bus *bus);
- void (*close)(struct pmac_i2c_bus *bus);
- int (*xfer)(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
- u32 subaddr, u8 *data, int len);
-};
-
-static LIST_HEAD(pmac_i2c_busses);
-
-/*
- * Keywest implementation
- */
-
-struct pmac_i2c_host_kw
-{
- struct mutex mutex; /* Access mutex for use by
- * i2c-keywest */
- void __iomem *base; /* register base address */
- int bsteps; /* register stepping */
- int speed; /* speed */
- int irq;
- u8 *data;
- unsigned len;
- int state;
- int rw;
- int polled;
- int result;
- struct completion complete;
- spinlock_t lock;
- struct timer_list timeout_timer;
-};
-
-/* Register indices */
-typedef enum {
- reg_mode = 0,
- reg_control,
- reg_status,
- reg_isr,
- reg_ier,
- reg_addr,
- reg_subaddr,
- reg_data
-} reg_t;
-
-/* The Tumbler audio equalizer can be really slow sometimes */
-#define KW_POLL_TIMEOUT (2*HZ)
-
-/* Mode register */
-#define KW_I2C_MODE_100KHZ 0x00
-#define KW_I2C_MODE_50KHZ 0x01
-#define KW_I2C_MODE_25KHZ 0x02
-#define KW_I2C_MODE_DUMB 0x00
-#define KW_I2C_MODE_STANDARD 0x04
-#define KW_I2C_MODE_STANDARDSUB 0x08
-#define KW_I2C_MODE_COMBINED 0x0C
-#define KW_I2C_MODE_MODE_MASK 0x0C
-#define KW_I2C_MODE_CHAN_MASK 0xF0
-
-/* Control register */
-#define KW_I2C_CTL_AAK 0x01
-#define KW_I2C_CTL_XADDR 0x02
-#define KW_I2C_CTL_STOP 0x04
-#define KW_I2C_CTL_START 0x08
-
-/* Status register */
-#define KW_I2C_STAT_BUSY 0x01
-#define KW_I2C_STAT_LAST_AAK 0x02
-#define KW_I2C_STAT_LAST_RW 0x04
-#define KW_I2C_STAT_SDA 0x08
-#define KW_I2C_STAT_SCL 0x10
-
-/* IER & ISR registers */
-#define KW_I2C_IRQ_DATA 0x01
-#define KW_I2C_IRQ_ADDR 0x02
-#define KW_I2C_IRQ_STOP 0x04
-#define KW_I2C_IRQ_START 0x08
-#define KW_I2C_IRQ_MASK 0x0F
-
-/* State machine states */
-enum {
- state_idle,
- state_addr,
- state_read,
- state_write,
- state_stop,
- state_dead
-};
-
-#define WRONG_STATE(name) do {\
- printk(KERN_DEBUG "KW: wrong state. Got %s, state: %s " \
- "(isr: %02x)\n", \
- name, __kw_state_names[host->state], isr); \
- } while(0)
-
-static const char *__kw_state_names[] = {
- "state_idle",
- "state_addr",
- "state_read",
- "state_write",
- "state_stop",
- "state_dead"
-};
-
-static inline u8 __kw_read_reg(struct pmac_i2c_host_kw *host, reg_t reg)
-{
- return readb(host->base + (((unsigned int)reg) << host->bsteps));
-}
-
-static inline void __kw_write_reg(struct pmac_i2c_host_kw *host,
- reg_t reg, u8 val)
-{
- writeb(val, host->base + (((unsigned)reg) << host->bsteps));
- (void)__kw_read_reg(host, reg_subaddr);
-}
-
-#define kw_write_reg(reg, val) __kw_write_reg(host, reg, val)
-#define kw_read_reg(reg) __kw_read_reg(host, reg)
-
-static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host)
-{
- int i, j;
- u8 isr;
-
- for (i = 0; i < 1000; i++) {
- isr = kw_read_reg(reg_isr) & KW_I2C_IRQ_MASK;
- if (isr != 0)
- return isr;
-
- /* This code is used with the timebase frozen, we cannot rely
- * on udelay nor schedule when in polled mode !
- * For now, just use a bogus loop....
- */
- if (host->polled) {
- for (j = 1; j < 100000; j++)
- mb();
- } else
- msleep(1);
- }
- return isr;
-}
-
-static void kw_i2c_do_stop(struct pmac_i2c_host_kw *host, int result)
-{
- kw_write_reg(reg_control, KW_I2C_CTL_STOP);
- host->state = state_stop;
- host->result = result;
-}
-
-
-static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
-{
- u8 ack;
-
- DBG_LOW("kw_handle_interrupt(%s, isr: %x)\n",
- __kw_state_names[host->state], isr);
-
- if (host->state == state_idle) {
- printk(KERN_WARNING "low_i2c: Keywest got an out of state"
- " interrupt, ignoring\n");
- kw_write_reg(reg_isr, isr);
- return;
- }
-
- if (isr == 0) {
- printk(KERN_WARNING "low_i2c: Timeout in i2c transfer"
- " on keywest !\n");
- if (host->state != state_stop) {
- kw_i2c_do_stop(host, -EIO);
- return;
- }
- ack = kw_read_reg(reg_status);
- if (ack & KW_I2C_STAT_BUSY)
- kw_write_reg(reg_status, 0);
- host->state = state_idle;
- kw_write_reg(reg_ier, 0x00);
- if (!host->polled)
- complete(&host->complete);
- return;
- }
-
- if (isr & KW_I2C_IRQ_ADDR) {
- ack = kw_read_reg(reg_status);
- if (host->state != state_addr) {
- WRONG_STATE("KW_I2C_IRQ_ADDR");
- kw_i2c_do_stop(host, -EIO);
- }
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- host->result = -ENXIO;
- host->state = state_stop;
- DBG_LOW("KW: NAK on address\n");
- } else {
- if (host->len == 0)
- kw_i2c_do_stop(host, 0);
- else if (host->rw) {
- host->state = state_read;
- if (host->len > 1)
- kw_write_reg(reg_control,
- KW_I2C_CTL_AAK);
- } else {
- host->state = state_write;
- kw_write_reg(reg_data, *(host->data++));
- host->len--;
- }
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
- }
-
- if (isr & KW_I2C_IRQ_DATA) {
- if (host->state == state_read) {
- *(host->data++) = kw_read_reg(reg_data);
- host->len--;
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- if (host->len == 0)
- host->state = state_stop;
- else if (host->len == 1)
- kw_write_reg(reg_control, 0);
- } else if (host->state == state_write) {
- ack = kw_read_reg(reg_status);
- if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
- DBG_LOW("KW: nack on data write\n");
- host->result = -EFBIG;
- host->state = state_stop;
- } else if (host->len) {
- kw_write_reg(reg_data, *(host->data++));
- host->len--;
- } else
- kw_i2c_do_stop(host, 0);
- } else {
- WRONG_STATE("KW_I2C_IRQ_DATA");
- if (host->state != state_stop)
- kw_i2c_do_stop(host, -EIO);
- }
- kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
- }
-
- if (isr & KW_I2C_IRQ_STOP) {
- kw_write_reg(reg_isr, KW_I2C_IRQ_STOP);
- if (host->state != state_stop) {
- WRONG_STATE("KW_I2C_IRQ_STOP");
- host->result = -EIO;
- }
- host->state = state_idle;
- if (!host->polled)
- complete(&host->complete);
- }
-
- /* Below should only happen in manual mode which we don't use ... */
- if (isr & KW_I2C_IRQ_START)
- kw_write_reg(reg_isr, KW_I2C_IRQ_START);
-
-}
-
-/* Interrupt handler */
-static irqreturn_t kw_i2c_irq(int irq, void *dev_id)
-{
- struct pmac_i2c_host_kw *host = dev_id;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- del_timer(&host->timeout_timer);
- kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
- if (host->state != state_idle) {
- host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
- add_timer(&host->timeout_timer);
- }
- spin_unlock_irqrestore(&host->lock, flags);
- return IRQ_HANDLED;
-}
-
-static void kw_i2c_timeout(unsigned long data)
-{
- struct pmac_i2c_host_kw *host = (struct pmac_i2c_host_kw *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
-
- /*
- * If the timer is pending, that means we raced with the
- * irq, in which case we just return
- */
- if (timer_pending(&host->timeout_timer))
- goto skip;
-
- kw_i2c_handle_interrupt(host, kw_read_reg(reg_isr));
- if (host->state != state_idle) {
- host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
- add_timer(&host->timeout_timer);
- }
- skip:
- spin_unlock_irqrestore(&host->lock, flags);
-}
-
-static int kw_i2c_open(struct pmac_i2c_bus *bus)
-{
- struct pmac_i2c_host_kw *host = bus->hostdata;
- mutex_lock(&host->mutex);
- return 0;
-}
-
-static void kw_i2c_close(struct pmac_i2c_bus *bus)
-{
- struct pmac_i2c_host_kw *host = bus->hostdata;
- mutex_unlock(&host->mutex);
-}
-
-static int kw_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
- u32 subaddr, u8 *data, int len)
-{
- struct pmac_i2c_host_kw *host = bus->hostdata;
- u8 mode_reg = host->speed;
- int use_irq = host->irq != NO_IRQ && !bus->polled;
-
- /* Setup mode & subaddress if any */
- switch(bus->mode) {
- case pmac_i2c_mode_dumb:
- return -EINVAL;
- case pmac_i2c_mode_std:
- mode_reg |= KW_I2C_MODE_STANDARD;
- if (subsize != 0)
- return -EINVAL;
- break;
- case pmac_i2c_mode_stdsub:
- mode_reg |= KW_I2C_MODE_STANDARDSUB;
- if (subsize != 1)
- return -EINVAL;
- break;
- case pmac_i2c_mode_combined:
- mode_reg |= KW_I2C_MODE_COMBINED;
- if (subsize != 1)
- return -EINVAL;
- break;
- }
-
- /* Setup channel & clear pending irqs */
- kw_write_reg(reg_isr, kw_read_reg(reg_isr));
- kw_write_reg(reg_mode, mode_reg | (bus->channel << 4));
- kw_write_reg(reg_status, 0);
-
- /* Set up address and r/w bit, strip possible stale bus number from
- * address top bits
- */
- kw_write_reg(reg_addr, addrdir & 0xff);
-
- /* Set up the sub address */
- if ((mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_STANDARDSUB
- || (mode_reg & KW_I2C_MODE_MODE_MASK) == KW_I2C_MODE_COMBINED)
- kw_write_reg(reg_subaddr, subaddr);
-
- /* Prepare for async operations */
- host->data = data;
- host->len = len;
- host->state = state_addr;
- host->result = 0;
- host->rw = (addrdir & 1);
- host->polled = bus->polled;
-
- /* Enable interrupt if not using polled mode and interrupt is
- * available
- */
- if (use_irq) {
- /* Clear completion */
- INIT_COMPLETION(host->complete);
- /* Ack stale interrupts */
- kw_write_reg(reg_isr, kw_read_reg(reg_isr));
- /* Arm timeout */
- host->timeout_timer.expires = jiffies + KW_POLL_TIMEOUT;
- add_timer(&host->timeout_timer);
- /* Enable emission */
- kw_write_reg(reg_ier, KW_I2C_IRQ_MASK);
- }
-
- /* Start sending address */
- kw_write_reg(reg_control, KW_I2C_CTL_XADDR);
-
- /* Wait for completion */
- if (use_irq)
- wait_for_completion(&host->complete);
- else {
- while(host->state != state_idle) {
- unsigned long flags;
-
- u8 isr = kw_i2c_wait_interrupt(host);
- spin_lock_irqsave(&host->lock, flags);
- kw_i2c_handle_interrupt(host, isr);
- spin_unlock_irqrestore(&host->lock, flags);
- }
- }
-
- /* Disable emission */
- kw_write_reg(reg_ier, 0);
-
- return host->result;
-}
-
-static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
-{
- struct pmac_i2c_host_kw *host;
- const u32 *psteps, *prate, *addrp;
- u32 steps;
-
- host = kzalloc(sizeof(struct pmac_i2c_host_kw), GFP_KERNEL);
- if (host == NULL) {
- printk(KERN_ERR "low_i2c: Can't allocate host for %s\n",
- np->full_name);
- return NULL;
- }
-
- /* Apple is kind enough to provide a valid AAPL,address property
- * on all i2c keywest nodes so far ... we would have to fallback
- * to macio parsing if that wasn't the case
- */
- addrp = of_get_property(np, "AAPL,address", NULL);
- if (addrp == NULL) {
- printk(KERN_ERR "low_i2c: Can't find address for %s\n",
- np->full_name);
- kfree(host);
- return NULL;
- }
- mutex_init(&host->mutex);
- init_completion(&host->complete);
- spin_lock_init(&host->lock);
- init_timer(&host->timeout_timer);
- host->timeout_timer.function = kw_i2c_timeout;
- host->timeout_timer.data = (unsigned long)host;
-
- psteps = of_get_property(np, "AAPL,address-step", NULL);
- steps = psteps ? (*psteps) : 0x10;
- for (host->bsteps = 0; (steps & 0x01) == 0; host->bsteps++)
- steps >>= 1;
- /* Select interface rate */
- host->speed = KW_I2C_MODE_25KHZ;
- prate = of_get_property(np, "AAPL,i2c-rate", NULL);
- if (prate) switch(*prate) {
- case 100:
- host->speed = KW_I2C_MODE_100KHZ;
- break;
- case 50:
- host->speed = KW_I2C_MODE_50KHZ;
- break;
- case 25:
- host->speed = KW_I2C_MODE_25KHZ;
- break;
- }
- host->irq = irq_of_parse_and_map(np, 0);
- if (host->irq == NO_IRQ)
- printk(KERN_WARNING
- "low_i2c: Failed to map interrupt for %s\n",
- np->full_name);
-
- host->base = ioremap((*addrp), 0x1000);
- if (host->base == NULL) {
- printk(KERN_ERR "low_i2c: Can't map registers for %s\n",
- np->full_name);
- kfree(host);
- return NULL;
- }
-
- /* Make sure IRQ is disabled */
- kw_write_reg(reg_ier, 0);
-
- /* Request chip interrupt. We set IRQF_NO_SUSPEND because we don't
- * want that interrupt disabled between the 2 passes of driver
- * suspend or we'll have issues running the pfuncs
- */
- if (request_irq(host->irq, kw_i2c_irq, IRQF_NO_SUSPEND,
- "keywest i2c", host))
- host->irq = NO_IRQ;
-
- printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
- *addrp, host->irq, np->full_name);
-
- return host;
-}
-
-
-static void __init kw_i2c_add(struct pmac_i2c_host_kw *host,
- struct device_node *controller,
- struct device_node *busnode,
- int channel)
-{
- struct pmac_i2c_bus *bus;
-
- bus = kzalloc(sizeof(struct pmac_i2c_bus), GFP_KERNEL);
- if (bus == NULL)
- return;
-
- bus->controller = of_node_get(controller);
- bus->busnode = of_node_get(busnode);
- bus->type = pmac_i2c_bus_keywest;
- bus->hostdata = host;
- bus->channel = channel;
- bus->mode = pmac_i2c_mode_std;
- bus->open = kw_i2c_open;
- bus->close = kw_i2c_close;
- bus->xfer = kw_i2c_xfer;
- mutex_init(&bus->mutex);
- if (controller == busnode)
- bus->flags = pmac_i2c_multibus;
- list_add(&bus->link, &pmac_i2c_busses);
-
- printk(KERN_INFO " channel %d bus %s\n", channel,
- (controller == busnode) ? "<multibus>" : busnode->full_name);
-}
-
-static void __init kw_i2c_probe(void)
-{
- struct device_node *np, *child, *parent;
-
- /* Probe keywest-i2c busses */
- for_each_compatible_node(np, "i2c","keywest-i2c") {
- struct pmac_i2c_host_kw *host;
- int multibus;
-
- /* Found one, init a host structure */
- host = kw_i2c_host_init(np);
- if (host == NULL)
- continue;
-
- /* Now check if we have a multibus setup (old style) or if we
- * have proper bus nodes. Note that the "new" way (proper bus
- * nodes) might cause us to not create some busses that are
- * kept hidden in the device-tree. In the future, we might
- * want to work around that by creating busses without a node
- * but not for now
- */
- child = of_get_next_child(np, NULL);
- multibus = !child || strcmp(child->name, "i2c-bus");
- of_node_put(child);
-
- /* For a multibus setup, we get the bus count based on the
- * parent type
- */
- if (multibus) {
- int chans, i;
-
- parent = of_get_parent(np);
- if (parent == NULL)
- continue;
- chans = parent->name[0] == 'u' ? 2 : 1;
- for (i = 0; i < chans; i++)
- kw_i2c_add(host, np, np, i);
- } else {
- for (child = NULL;
- (child = of_get_next_child(np, child)) != NULL;) {
- const u32 *reg = of_get_property(child,
- "reg", NULL);
- if (reg == NULL)
- continue;
- kw_i2c_add(host, np, child, *reg);
- }
- }
- }
-}
-
-
-/*
- *
- * PMU implementation
- *
- */
-
-#ifdef CONFIG_ADB_PMU
-
-/*
- * i2c command block to the PMU
- */
-struct pmu_i2c_hdr {
- u8 bus;
- u8 mode;
- u8 bus2;
- u8 address;
- u8 sub_addr;
- u8 comb_addr;
- u8 count;
- u8 data[];
-};
-
-static void pmu_i2c_complete(struct adb_request *req)
-{
- complete(req->arg);
-}
-
-static int pmu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
- u32 subaddr, u8 *data, int len)
-{
- struct adb_request *req = bus->hostdata;
- struct pmu_i2c_hdr *hdr = (struct pmu_i2c_hdr *)&req->data[1];
- struct completion comp;
- int read = addrdir & 1;
- int retry;
- int rc = 0;
-
- /* For now, limit ourselves to 16 bytes transfers */
- if (len > 16)
- return -EINVAL;
-
- init_completion(&comp);
-
- for (retry = 0; retry < 16; retry++) {
- memset(req, 0, sizeof(struct adb_request));
- hdr->bus = bus->channel;
- hdr->count = len;
-
- switch(bus->mode) {
- case pmac_i2c_mode_std:
- if (subsize != 0)
- return -EINVAL;
- hdr->address = addrdir;
- hdr->mode = PMU_I2C_MODE_SIMPLE;
- break;
- case pmac_i2c_mode_stdsub:
- case pmac_i2c_mode_combined:
- if (subsize != 1)
- return -EINVAL;
- hdr->address = addrdir & 0xfe;
- hdr->comb_addr = addrdir;
- hdr->sub_addr = subaddr;
- if (bus->mode == pmac_i2c_mode_stdsub)
- hdr->mode = PMU_I2C_MODE_STDSUB;
- else
- hdr->mode = PMU_I2C_MODE_COMBINED;
- break;
- default:
- return -EINVAL;
- }
-
- INIT_COMPLETION(comp);
- req->data[0] = PMU_I2C_CMD;
- req->reply[0] = 0xff;
- req->nbytes = sizeof(struct pmu_i2c_hdr) + 1;
- req->done = pmu_i2c_complete;
- req->arg = &comp;
- if (!read && len) {
- memcpy(hdr->data, data, len);
- req->nbytes += len;
- }
- rc = pmu_queue_request(req);
- if (rc)
- return rc;
- wait_for_completion(&comp);
- if (req->reply[0] == PMU_I2C_STATUS_OK)
- break;
- msleep(15);
- }
- if (req->reply[0] != PMU_I2C_STATUS_OK)
- return -EIO;
-
- for (retry = 0; retry < 16; retry++) {
- memset(req, 0, sizeof(struct adb_request));
-
- /* I know that looks like a lot, slow as hell, but darwin
- * does it so let's be on the safe side for now
- */
- msleep(15);
-
- hdr->bus = PMU_I2C_BUS_STATUS;
-
- INIT_COMPLETION(comp);
- req->data[0] = PMU_I2C_CMD;
- req->reply[0] = 0xff;
- req->nbytes = 2;
- req->done = pmu_i2c_complete;
- req->arg = &comp;
- rc = pmu_queue_request(req);
- if (rc)
- return rc;
- wait_for_completion(&comp);
-
- if (req->reply[0] == PMU_I2C_STATUS_OK && !read)
- return 0;
- if (req->reply[0] == PMU_I2C_STATUS_DATAREAD && read) {
- int rlen = req->reply_len - 1;
-
- if (rlen != len) {
- printk(KERN_WARNING "low_i2c: PMU returned %d"
- " bytes, expected %d !\n", rlen, len);
- return -EIO;
- }
- if (len)
- memcpy(data, &req->reply[1], len);
- return 0;
- }
- }
- return -EIO;
-}
-
-static void __init pmu_i2c_probe(void)
-{
- struct pmac_i2c_bus *bus;
- struct device_node *busnode;
- int channel, sz;
-
- if (!pmu_present())
- return;
-
- /* There might or might not be a "pmu-i2c" node, we use that
- * or via-pmu itself, whatever we find. I haven't seen a machine
- * with separate bus nodes, so we assume a multibus setup
- */
- busnode = of_find_node_by_name(NULL, "pmu-i2c");
- if (busnode == NULL)
- busnode = of_find_node_by_name(NULL, "via-pmu");
- if (busnode == NULL)
- return;
-
- printk(KERN_INFO "PMU i2c %s\n", busnode->full_name);
-
- /*
- * We add bus 1 and 2 only for now, bus 0 is "special"
- */
- for (channel = 1; channel <= 2; channel++) {
- sz = sizeof(struct pmac_i2c_bus) + sizeof(struct adb_request);
- bus = kzalloc(sz, GFP_KERNEL);
- if (bus == NULL)
- return;
-
- bus->controller = busnode;
- bus->busnode = busnode;
- bus->type = pmac_i2c_bus_pmu;
- bus->channel = channel;
- bus->mode = pmac_i2c_mode_std;
- bus->hostdata = bus + 1;
- bus->xfer = pmu_i2c_xfer;
- mutex_init(&bus->mutex);
- bus->flags = pmac_i2c_multibus;
- list_add(&bus->link, &pmac_i2c_busses);
-
- printk(KERN_INFO " channel %d bus <multibus>\n", channel);
- }
-}
-
-#endif /* CONFIG_ADB_PMU */
-
-
-/*
- *
- * SMU implementation
- *
- */
-
-#ifdef CONFIG_PMAC_SMU
-
-static void smu_i2c_complete(struct smu_i2c_cmd *cmd, void *misc)
-{
- complete(misc);
-}
-
-static int smu_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
- u32 subaddr, u8 *data, int len)
-{
- struct smu_i2c_cmd *cmd = bus->hostdata;
- struct completion comp;
- int read = addrdir & 1;
- int rc = 0;
-
- if ((read && len > SMU_I2C_READ_MAX) ||
- ((!read) && len > SMU_I2C_WRITE_MAX))
- return -EINVAL;
-
- memset(cmd, 0, sizeof(struct smu_i2c_cmd));
- cmd->info.bus = bus->channel;
- cmd->info.devaddr = addrdir;
- cmd->info.datalen = len;
-
- switch(bus->mode) {
- case pmac_i2c_mode_std:
- if (subsize != 0)
- return -EINVAL;
- cmd->info.type = SMU_I2C_TRANSFER_SIMPLE;
- break;
- case pmac_i2c_mode_stdsub:
- case pmac_i2c_mode_combined:
- if (subsize > 3 || subsize < 1)
- return -EINVAL;
- cmd->info.sublen = subsize;
- /* that's big-endian only but heh ! */
- memcpy(&cmd->info.subaddr, ((char *)&subaddr) + (4 - subsize),
- subsize);
- if (bus->mode == pmac_i2c_mode_stdsub)
- cmd->info.type = SMU_I2C_TRANSFER_STDSUB;
- else
- cmd->info.type = SMU_I2C_TRANSFER_COMBINED;
- break;
- default:
- return -EINVAL;
- }
- if (!read && len)
- memcpy(cmd->info.data, data, len);
-
- init_completion(&comp);
- cmd->done = smu_i2c_complete;
- cmd->misc = &comp;
- rc = smu_queue_i2c(cmd);
- if (rc < 0)
- return rc;
- wait_for_completion(&comp);
- rc = cmd->status;
-
- if (read && len)
- memcpy(data, cmd->info.data, len);
- return rc < 0 ? rc : 0;
-}
-
-static void __init smu_i2c_probe(void)
-{
- struct device_node *controller, *busnode;
- struct pmac_i2c_bus *bus;
- const u32 *reg;
- int sz;
-
- if (!smu_present())
- return;
-
- controller = of_find_node_by_name(NULL, "smu-i2c-control");
- if (controller == NULL)
- controller = of_find_node_by_name(NULL, "smu");
- if (controller == NULL)
- return;
-
- printk(KERN_INFO "SMU i2c %s\n", controller->full_name);
-
- /* Look for childs, note that they might not be of the right
- * type as older device trees mix i2c busses and other things
- * at the same level
- */
- for (busnode = NULL;
- (busnode = of_get_next_child(controller, busnode)) != NULL;) {
- if (strcmp(busnode->type, "i2c") &&
- strcmp(busnode->type, "i2c-bus"))
- continue;
- reg = of_get_property(busnode, "reg", NULL);
- if (reg == NULL)
- continue;
-
- sz = sizeof(struct pmac_i2c_bus) + sizeof(struct smu_i2c_cmd);
- bus = kzalloc(sz, GFP_KERNEL);
- if (bus == NULL)
- return;
-
- bus->controller = controller;
- bus->busnode = of_node_get(busnode);
- bus->type = pmac_i2c_bus_smu;
- bus->channel = *reg;
- bus->mode = pmac_i2c_mode_std;
- bus->hostdata = bus + 1;
- bus->xfer = smu_i2c_xfer;
- mutex_init(&bus->mutex);
- bus->flags = 0;
- list_add(&bus->link, &pmac_i2c_busses);
-
- printk(KERN_INFO " channel %x bus %s\n",
- bus->channel, busnode->full_name);
- }
-}
-
-#endif /* CONFIG_PMAC_SMU */
-
-/*
- *
- * Core code
- *
- */
-
-
-struct pmac_i2c_bus *pmac_i2c_find_bus(struct device_node *node)
-{
- struct device_node *p = of_node_get(node);
- struct device_node *prev = NULL;
- struct pmac_i2c_bus *bus;
-
- while(p) {
- list_for_each_entry(bus, &pmac_i2c_busses, link) {
- if (p == bus->busnode) {
- if (prev && bus->flags & pmac_i2c_multibus) {
- const u32 *reg;
- reg = of_get_property(prev, "reg",
- NULL);
- if (!reg)
- continue;
- if (((*reg) >> 8) != bus->channel)
- continue;
- }
- of_node_put(p);
- of_node_put(prev);
- return bus;
- }
- }
- of_node_put(prev);
- prev = p;
- p = of_get_parent(p);
- }
- return NULL;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_find_bus);
-
-u8 pmac_i2c_get_dev_addr(struct device_node *device)
-{
- const u32 *reg = of_get_property(device, "reg", NULL);
-
- if (reg == NULL)
- return 0;
-
- return (*reg) & 0xff;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_dev_addr);
-
-struct device_node *pmac_i2c_get_controller(struct pmac_i2c_bus *bus)
-{
- return bus->controller;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_controller);
-
-struct device_node *pmac_i2c_get_bus_node(struct pmac_i2c_bus *bus)
-{
- return bus->busnode;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_bus_node);
-
-int pmac_i2c_get_type(struct pmac_i2c_bus *bus)
-{
- return bus->type;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_type);
-
-int pmac_i2c_get_flags(struct pmac_i2c_bus *bus)
-{
- return bus->flags;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_flags);
-
-int pmac_i2c_get_channel(struct pmac_i2c_bus *bus)
-{
- return bus->channel;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_channel);
-
-
-struct i2c_adapter *pmac_i2c_get_adapter(struct pmac_i2c_bus *bus)
-{
- return &bus->adapter;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_get_adapter);
-
-struct pmac_i2c_bus *pmac_i2c_adapter_to_bus(struct i2c_adapter *adapter)
-{
- struct pmac_i2c_bus *bus;
-
- list_for_each_entry(bus, &pmac_i2c_busses, link)
- if (&bus->adapter == adapter)
- return bus;
- return NULL;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_adapter_to_bus);
-
-int pmac_i2c_match_adapter(struct device_node *dev, struct i2c_adapter *adapter)
-{
- struct pmac_i2c_bus *bus = pmac_i2c_find_bus(dev);
-
- if (bus == NULL)
- return 0;
- return (&bus->adapter == adapter);
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_match_adapter);
-
-int pmac_low_i2c_lock(struct device_node *np)
-{
- struct pmac_i2c_bus *bus, *found = NULL;
-
- list_for_each_entry(bus, &pmac_i2c_busses, link) {
- if (np == bus->controller) {
- found = bus;
- break;
- }
- }
- if (!found)
- return -ENODEV;
- return pmac_i2c_open(bus, 0);
-}
-EXPORT_SYMBOL_GPL(pmac_low_i2c_lock);
-
-int pmac_low_i2c_unlock(struct device_node *np)
-{
- struct pmac_i2c_bus *bus, *found = NULL;
-
- list_for_each_entry(bus, &pmac_i2c_busses, link) {
- if (np == bus->controller) {
- found = bus;
- break;
- }
- }
- if (!found)
- return -ENODEV;
- pmac_i2c_close(bus);
- return 0;
-}
-EXPORT_SYMBOL_GPL(pmac_low_i2c_unlock);
-
-
-int pmac_i2c_open(struct pmac_i2c_bus *bus, int polled)
-{
- int rc;
-
- mutex_lock(&bus->mutex);
- bus->polled = polled || pmac_i2c_force_poll;
- bus->opened = 1;
- bus->mode = pmac_i2c_mode_std;
- if (bus->open && (rc = bus->open(bus)) != 0) {
- bus->opened = 0;
- mutex_unlock(&bus->mutex);
- return rc;
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_open);
-
-void pmac_i2c_close(struct pmac_i2c_bus *bus)
-{
- WARN_ON(!bus->opened);
- if (bus->close)
- bus->close(bus);
- bus->opened = 0;
- mutex_unlock(&bus->mutex);
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_close);
-
-int pmac_i2c_setmode(struct pmac_i2c_bus *bus, int mode)
-{
- WARN_ON(!bus->opened);
-
- /* Report me if you see the error below as there might be a new
- * "combined4" mode that I need to implement for the SMU bus
- */
- if (mode < pmac_i2c_mode_dumb || mode > pmac_i2c_mode_combined) {
- printk(KERN_ERR "low_i2c: Invalid mode %d requested on"
- " bus %s !\n", mode, bus->busnode->full_name);
- return -EINVAL;
- }
- bus->mode = mode;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_setmode);
-
-int pmac_i2c_xfer(struct pmac_i2c_bus *bus, u8 addrdir, int subsize,
- u32 subaddr, u8 *data, int len)
-{
- int rc;
-
- WARN_ON(!bus->opened);
-
- DBG("xfer() chan=%d, addrdir=0x%x, mode=%d, subsize=%d, subaddr=0x%x,"
- " %d bytes, bus %s\n", bus->channel, addrdir, bus->mode, subsize,
- subaddr, len, bus->busnode->full_name);
-
- rc = bus->xfer(bus, addrdir, subsize, subaddr, data, len);
-
-#ifdef DEBUG
- if (rc)
- DBG("xfer error %d\n", rc);
-#endif
- return rc;
-}
-EXPORT_SYMBOL_GPL(pmac_i2c_xfer);
-
-/* some quirks for platform function decoding */
-enum {
- pmac_i2c_quirk_invmask = 0x00000001u,
- pmac_i2c_quirk_skip = 0x00000002u,
-};
-
-static void pmac_i2c_devscan(void (*callback)(struct device_node *dev,
- int quirks))
-{
- struct pmac_i2c_bus *bus;
- struct device_node *np;
- static struct whitelist_ent {
- char *name;
- char *compatible;
- int quirks;
- } whitelist[] = {
- /* XXX Study device-tree's & apple drivers are get the quirks
- * right !
- */
- /* Workaround: It seems that running the clockspreading
- * properties on the eMac will cause lockups during boot.
- * The machine seems to work fine without that. So for now,
- * let's make sure i2c-hwclock doesn't match about "imic"
- * clocks and we'll figure out if we really need to do
- * something special about those later.
- */
- { "i2c-hwclock", "imic5002", pmac_i2c_quirk_skip },
- { "i2c-hwclock", "imic5003", pmac_i2c_quirk_skip },
- { "i2c-hwclock", NULL, pmac_i2c_quirk_invmask },
- { "i2c-cpu-voltage", NULL, 0},
- { "temp-monitor", NULL, 0 },
- { "supply-monitor", NULL, 0 },
- { NULL, NULL, 0 },
- };
-
- /* Only some devices need to have platform functions instanciated
- * here. For now, we have a table. Others, like 9554 i2c GPIOs used
- * on Xserve, if we ever do a driver for them, will use their own
- * platform function instance
- */
- list_for_each_entry(bus, &pmac_i2c_busses, link) {
- for (np = NULL;
- (np = of_get_next_child(bus->busnode, np)) != NULL;) {
- struct whitelist_ent *p;
- /* If multibus, check if device is on that bus */
- if (bus->flags & pmac_i2c_multibus)
- if (bus != pmac_i2c_find_bus(np))
- continue;
- for (p = whitelist; p->name != NULL; p++) {
- if (strcmp(np->name, p->name))
- continue;
- if (p->compatible &&
- !of_device_is_compatible(np, p->compatible))
- continue;
- if (p->quirks & pmac_i2c_quirk_skip)
- break;
- callback(np, p->quirks);
- break;
- }
- }
- }
-}
-
-#define MAX_I2C_DATA 64
-
-struct pmac_i2c_pf_inst
-{
- struct pmac_i2c_bus *bus;
- u8 addr;
- u8 buffer[MAX_I2C_DATA];
- u8 scratch[MAX_I2C_DATA];
- int bytes;
- int quirks;
-};
-
-static void* pmac_i2c_do_begin(struct pmf_function *func, struct pmf_args *args)
-{
- struct pmac_i2c_pf_inst *inst;
- struct pmac_i2c_bus *bus;
-
- bus = pmac_i2c_find_bus(func->node);
- if (bus == NULL) {
- printk(KERN_ERR "low_i2c: Can't find bus for %s (pfunc)\n",
- func->node->full_name);
- return NULL;
- }
- if (pmac_i2c_open(bus, 0)) {
- printk(KERN_ERR "low_i2c: Can't open i2c bus for %s (pfunc)\n",
- func->node->full_name);
- return NULL;
- }
-
- /* XXX might need GFP_ATOMIC when called during the suspend process,
- * but then, there are already lots of issues with suspending when
- * near OOM that need to be resolved, the allocator itself should
- * probably make GFP_NOIO implicit during suspend
- */
- inst = kzalloc(sizeof(struct pmac_i2c_pf_inst), GFP_KERNEL);
- if (inst == NULL) {
- pmac_i2c_close(bus);
- return NULL;
- }
- inst->bus = bus;
- inst->addr = pmac_i2c_get_dev_addr(func->node);
- inst->quirks = (int)(long)func->driver_data;
- return inst;
-}
-
-static void pmac_i2c_do_end(struct pmf_function *func, void *instdata)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- if (inst == NULL)
- return;
- pmac_i2c_close(inst->bus);
- kfree(inst);
-}
-
-static int pmac_i2c_do_read(PMF_STD_ARGS, u32 len)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- inst->bytes = len;
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 0, 0,
- inst->buffer, len);
-}
-
-static int pmac_i2c_do_write(PMF_STD_ARGS, u32 len, const u8 *data)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
- (u8 *)data, len);
-}
-
-/* This function is used to do the masking & OR'ing for the "rmw" type
- * callbacks. Ze should apply the mask and OR in the values in the
- * buffer before writing back. The problem is that it seems that
- * various darwin drivers implement the mask/or differently, thus
- * we need to check the quirks first
- */
-static void pmac_i2c_do_apply_rmw(struct pmac_i2c_pf_inst *inst,
- u32 len, const u8 *mask, const u8 *val)
-{
- int i;
-
- if (inst->quirks & pmac_i2c_quirk_invmask) {
- for (i = 0; i < len; i ++)
- inst->scratch[i] = (inst->buffer[i] & mask[i]) | val[i];
- } else {
- for (i = 0; i < len; i ++)
- inst->scratch[i] = (inst->buffer[i] & ~mask[i])
- | (val[i] & mask[i]);
- }
-}
-
-static int pmac_i2c_do_rmw(PMF_STD_ARGS, u32 masklen, u32 valuelen,
- u32 totallen, const u8 *maskdata,
- const u8 *valuedata)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- if (masklen > inst->bytes || valuelen > inst->bytes ||
- totallen > inst->bytes || valuelen > masklen)
- return -EINVAL;
-
- pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
-
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 0, 0,
- inst->scratch, totallen);
-}
-
-static int pmac_i2c_do_read_sub(PMF_STD_ARGS, u8 subaddr, u32 len)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- inst->bytes = len;
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_read, 1, subaddr,
- inst->buffer, len);
-}
-
-static int pmac_i2c_do_write_sub(PMF_STD_ARGS, u8 subaddr, u32 len,
- const u8 *data)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
- subaddr, (u8 *)data, len);
-}
-
-static int pmac_i2c_do_set_mode(PMF_STD_ARGS, int mode)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- return pmac_i2c_setmode(inst->bus, mode);
-}
-
-static int pmac_i2c_do_rmw_sub(PMF_STD_ARGS, u8 subaddr, u32 masklen,
- u32 valuelen, u32 totallen, const u8 *maskdata,
- const u8 *valuedata)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
-
- if (masklen > inst->bytes || valuelen > inst->bytes ||
- totallen > inst->bytes || valuelen > masklen)
- return -EINVAL;
-
- pmac_i2c_do_apply_rmw(inst, masklen, maskdata, valuedata);
-
- return pmac_i2c_xfer(inst->bus, inst->addr | pmac_i2c_write, 1,
- subaddr, inst->scratch, totallen);
-}
-
-static int pmac_i2c_do_mask_and_comp(PMF_STD_ARGS, u32 len,
- const u8 *maskdata,
- const u8 *valuedata)
-{
- struct pmac_i2c_pf_inst *inst = instdata;
- int i, match;
-
- /* Get return value pointer, it's assumed to be a u32 */
- if (!args || !args->count || !args->u[0].p)
- return -EINVAL;
-
- /* Check buffer */
- if (len > inst->bytes)
- return -EINVAL;
-
- for (i = 0, match = 1; match && i < len; i ++)
- if ((inst->buffer[i] & maskdata[i]) != valuedata[i])
- match = 0;
- *args->u[0].p = match;
- return 0;
-}
-
-static int pmac_i2c_do_delay(PMF_STD_ARGS, u32 duration)
-{
- msleep((duration + 999) / 1000);
- return 0;
-}
-
-
-static struct pmf_handlers pmac_i2c_pfunc_handlers = {
- .begin = pmac_i2c_do_begin,
- .end = pmac_i2c_do_end,
- .read_i2c = pmac_i2c_do_read,
- .write_i2c = pmac_i2c_do_write,
- .rmw_i2c = pmac_i2c_do_rmw,
- .read_i2c_sub = pmac_i2c_do_read_sub,
- .write_i2c_sub = pmac_i2c_do_write_sub,
- .rmw_i2c_sub = pmac_i2c_do_rmw_sub,
- .set_i2c_mode = pmac_i2c_do_set_mode,
- .mask_and_compare = pmac_i2c_do_mask_and_comp,
- .delay = pmac_i2c_do_delay,
-};
-
-static void __init pmac_i2c_dev_create(struct device_node *np, int quirks)
-{
- DBG("dev_create(%s)\n", np->full_name);
-
- pmf_register_driver(np, &pmac_i2c_pfunc_handlers,
- (void *)(long)quirks);
-}
-
-static void __init pmac_i2c_dev_init(struct device_node *np, int quirks)
-{
- DBG("dev_create(%s)\n", np->full_name);
-
- pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
-}
-
-static void pmac_i2c_dev_suspend(struct device_node *np, int quirks)
-{
- DBG("dev_suspend(%s)\n", np->full_name);
- pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_SLEEP, NULL);
-}
-
-static void pmac_i2c_dev_resume(struct device_node *np, int quirks)
-{
- DBG("dev_resume(%s)\n", np->full_name);
- pmf_do_functions(np, NULL, 0, PMF_FLAGS_ON_WAKE, NULL);
-}
-
-void pmac_pfunc_i2c_suspend(void)
-{
- pmac_i2c_devscan(pmac_i2c_dev_suspend);
-}
-
-void pmac_pfunc_i2c_resume(void)
-{
- pmac_i2c_devscan(pmac_i2c_dev_resume);
-}
-
-/*
- * Initialize us: probe all i2c busses on the machine, instantiate
- * busses and platform functions as needed.
- */
-/* This is non-static as it might be called early by smp code */
-int __init pmac_i2c_init(void)
-{
- static int i2c_inited;
-
- if (i2c_inited)
- return 0;
- i2c_inited = 1;
-
- /* Probe keywest-i2c busses */
- kw_i2c_probe();
-
-#ifdef CONFIG_ADB_PMU
- /* Probe PMU i2c busses */
- pmu_i2c_probe();
-#endif
-
-#ifdef CONFIG_PMAC_SMU
- /* Probe SMU i2c busses */
- smu_i2c_probe();
-#endif
-
- /* Now add plaform functions for some known devices */
- pmac_i2c_devscan(pmac_i2c_dev_create);
-
- return 0;
-}
-machine_arch_initcall(powermac, pmac_i2c_init);
-
-/* Since pmac_i2c_init can be called too early for the platform device
- * registration, we need to do it at a later time. In our case, subsys
- * happens to fit well, though I agree it's a bit of a hack...
- */
-static int __init pmac_i2c_create_platform_devices(void)
-{
- struct pmac_i2c_bus *bus;
- int i = 0;
-
- /* In the case where we are initialized from smp_init(), we must
- * not use the timer (and thus the irq). It's safe from now on
- * though
- */
- pmac_i2c_force_poll = 0;
-
- /* Create platform devices */
- list_for_each_entry(bus, &pmac_i2c_busses, link) {
- bus->platform_dev =
- platform_device_alloc("i2c-powermac", i++);
- if (bus->platform_dev == NULL)
- return -ENOMEM;
- bus->platform_dev->dev.platform_data = bus;
- platform_device_add(bus->platform_dev);
- }
-
- /* Now call platform "init" functions */
- pmac_i2c_devscan(pmac_i2c_dev_init);
-
- return 0;
-}
-machine_subsys_initcall(powermac, pmac_i2c_create_platform_devices);
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/nvram.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/nvram.c
deleted file mode 100644
index 014d06e6..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/nvram.c
+++ /dev/null
@@ -1,652 +0,0 @@
-/*
- * Copyright (C) 2002 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- *
- * Todo: - add support for the OF persistent properties
- */
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/stddef.h>
-#include <linux/string.h>
-#include <linux/nvram.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/bootmem.h>
-#include <linux/completion.h>
-#include <linux/spinlock.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/nvram.h>
-
-#include "pmac.h"
-
-#define DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
-
-#define CORE99_SIGNATURE 0x5a
-#define CORE99_ADLER_START 0x14
-
-/* On Core99, nvram is either a sharp, a micron or an AMD flash */
-#define SM_FLASH_STATUS_DONE 0x80
-#define SM_FLASH_STATUS_ERR 0x38
-
-#define SM_FLASH_CMD_ERASE_CONFIRM 0xd0
-#define SM_FLASH_CMD_ERASE_SETUP 0x20
-#define SM_FLASH_CMD_RESET 0xff
-#define SM_FLASH_CMD_WRITE_SETUP 0x40
-#define SM_FLASH_CMD_CLEAR_STATUS 0x50
-#define SM_FLASH_CMD_READ_STATUS 0x70
-
-/* CHRP NVRAM header */
-struct chrp_header {
- u8 signature;
- u8 cksum;
- u16 len;
- char name[12];
- u8 data[0];
-};
-
-struct core99_header {
- struct chrp_header hdr;
- u32 adler;
- u32 generation;
- u32 reserved[2];
-};
-
-/*
- * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
- */
-static int nvram_naddrs;
-static volatile unsigned char __iomem *nvram_data;
-static int is_core_99;
-static int core99_bank = 0;
-static int nvram_partitions[3];
-// XXX Turn that into a sem
-static DEFINE_RAW_SPINLOCK(nv_lock);
-
-static int (*core99_write_bank)(int bank, u8* datas);
-static int (*core99_erase_bank)(int bank);
-
-static char *nvram_image;
-
-
-static unsigned char core99_nvram_read_byte(int addr)
-{
- if (nvram_image == NULL)
- return 0xff;
- return nvram_image[addr];
-}
-
-static void core99_nvram_write_byte(int addr, unsigned char val)
-{
- if (nvram_image == NULL)
- return;
- nvram_image[addr] = val;
-}
-
-static ssize_t core99_nvram_read(char *buf, size_t count, loff_t *index)
-{
- int i;
-
- if (nvram_image == NULL)
- return -ENODEV;
- if (*index > NVRAM_SIZE)
- return 0;
-
- i = *index;
- if (i + count > NVRAM_SIZE)
- count = NVRAM_SIZE - i;
-
- memcpy(buf, &nvram_image[i], count);
- *index = i + count;
- return count;
-}
-
-static ssize_t core99_nvram_write(char *buf, size_t count, loff_t *index)
-{
- int i;
-
- if (nvram_image == NULL)
- return -ENODEV;
- if (*index > NVRAM_SIZE)
- return 0;
-
- i = *index;
- if (i + count > NVRAM_SIZE)
- count = NVRAM_SIZE - i;
-
- memcpy(&nvram_image[i], buf, count);
- *index = i + count;
- return count;
-}
-
-static ssize_t core99_nvram_size(void)
-{
- if (nvram_image == NULL)
- return -ENODEV;
- return NVRAM_SIZE;
-}
-
-#ifdef CONFIG_PPC32
-static volatile unsigned char __iomem *nvram_addr;
-static int nvram_mult;
-
-static unsigned char direct_nvram_read_byte(int addr)
-{
- return in_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult]);
-}
-
-static void direct_nvram_write_byte(int addr, unsigned char val)
-{
- out_8(&nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult], val);
-}
-
-
-static unsigned char indirect_nvram_read_byte(int addr)
-{
- unsigned char val;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- val = in_8(&nvram_data[(addr & 0x1f) << 4]);
- raw_spin_unlock_irqrestore(&nv_lock, flags);
-
- return val;
-}
-
-static void indirect_nvram_write_byte(int addr, unsigned char val)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&nv_lock, flags);
- out_8(nvram_addr, addr >> 5);
- out_8(&nvram_data[(addr & 0x1f) << 4], val);
- raw_spin_unlock_irqrestore(&nv_lock, flags);
-}
-
-
-#ifdef CONFIG_ADB_PMU
-
-static void pmu_nvram_complete(struct adb_request *req)
-{
- if (req->arg)
- complete((struct completion *)req->arg);
-}
-
-static unsigned char pmu_nvram_read_byte(int addr)
-{
- struct adb_request req;
- DECLARE_COMPLETION_ONSTACK(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff))
- return 0xff;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
- return req.reply[0];
-}
-
-static void pmu_nvram_write_byte(int addr, unsigned char val)
-{
- struct adb_request req;
- DECLARE_COMPLETION_ONSTACK(req_complete);
-
- req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
- if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
- (addr >> 8) & 0xff, addr & 0xff, val))
- return;
- if (system_state == SYSTEM_RUNNING)
- wait_for_completion(&req_complete);
- while (!req.complete)
- pmu_poll();
-}
-
-#endif /* CONFIG_ADB_PMU */
-#endif /* CONFIG_PPC32 */
-
-static u8 chrp_checksum(struct chrp_header* hdr)
-{
- u8 *ptr;
- u16 sum = hdr->signature;
- for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
- sum += *ptr;
- while (sum > 0xFF)
- sum = (sum & 0xFF) + (sum>>8);
- return sum;
-}
-
-static u32 core99_calc_adler(u8 *buffer)
-{
- int cnt;
- u32 low, high;
-
- buffer += CORE99_ADLER_START;
- low = 1;
- high = 0;
- for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
- if ((cnt % 5000) == 0) {
- high %= 65521UL;
- high %= 65521UL;
- }
- low += buffer[cnt];
- high += low;
- }
- low %= 65521UL;
- high %= 65521UL;
-
- return (high << 16) | low;
-}
-
-static u32 core99_check(u8* datas)
-{
- struct core99_header* hdr99 = (struct core99_header*)datas;
-
- if (hdr99->hdr.signature != CORE99_SIGNATURE) {
- DBG("Invalid signature\n");
- return 0;
- }
- if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
- DBG("Invalid checksum\n");
- return 0;
- }
- if (hdr99->adler != core99_calc_adler(datas)) {
- DBG("Invalid adler\n");
- return 0;
- }
- return hdr99->generation;
-}
-
-static int sm_erase_bank(int bank)
-{
- int stat;
- unsigned long timeout;
-
- u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: Sharp/Micron Erasing bank %d...\n", bank);
-
- out_8(base, SM_FLASH_CMD_ERASE_SETUP);
- out_8(base, SM_FLASH_CMD_ERASE_CONFIRM);
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Micron flash erase timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
-
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
-
- if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
- printk(KERN_ERR "nvram: Sharp/Micron flash erase failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int sm_write_bank(int bank, u8* datas)
-{
- int i, stat = 0;
- unsigned long timeout;
-
- u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: Sharp/Micron Writing bank %d...\n", bank);
-
- for (i=0; i<NVRAM_SIZE; i++) {
- out_8(base+i, SM_FLASH_CMD_WRITE_SETUP);
- udelay(1);
- out_8(base+i, datas[i]);
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: Sharp/Micron flash write timeout !\n");
- break;
- }
- out_8(base, SM_FLASH_CMD_READ_STATUS);
- stat = in_8(base);
- } while (!(stat & SM_FLASH_STATUS_DONE));
- if (!(stat & SM_FLASH_STATUS_DONE))
- break;
- }
- out_8(base, SM_FLASH_CMD_CLEAR_STATUS);
- out_8(base, SM_FLASH_CMD_RESET);
- if (memcmp(base, datas, NVRAM_SIZE)) {
- printk(KERN_ERR "nvram: Sharp/Micron flash write failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int amd_erase_bank(int bank)
-{
- int stat = 0;
- unsigned long timeout;
-
- u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: AMD Erasing bank %d...\n", bank);
-
- /* Unlock 1 */
- out_8(base+0x555, 0xaa);
- udelay(1);
- /* Unlock 2 */
- out_8(base+0x2aa, 0x55);
- udelay(1);
-
- /* Sector-Erase */
- out_8(base+0x555, 0x80);
- udelay(1);
- out_8(base+0x555, 0xaa);
- udelay(1);
- out_8(base+0x2aa, 0x55);
- udelay(1);
- out_8(base, 0x30);
- udelay(1);
-
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: AMD flash erase timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- if (memchr_inv(base, 0xff, NVRAM_SIZE)) {
- printk(KERN_ERR "nvram: AMD flash erase failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static int amd_write_bank(int bank, u8* datas)
-{
- int i, stat = 0;
- unsigned long timeout;
-
- u8 __iomem *base = (u8 __iomem *)nvram_data + core99_bank*NVRAM_SIZE;
-
- DBG("nvram: AMD Writing bank %d...\n", bank);
-
- for (i=0; i<NVRAM_SIZE; i++) {
- /* Unlock 1 */
- out_8(base+0x555, 0xaa);
- udelay(1);
- /* Unlock 2 */
- out_8(base+0x2aa, 0x55);
- udelay(1);
-
- /* Write single word */
- out_8(base+0x555, 0xa0);
- udelay(1);
- out_8(base+i, datas[i]);
-
- timeout = 0;
- do {
- if (++timeout > 1000000) {
- printk(KERN_ERR "nvram: AMD flash write timeout !\n");
- break;
- }
- stat = in_8(base) ^ in_8(base);
- } while (stat != 0);
- if (stat != 0)
- break;
- }
-
- /* Reset */
- out_8(base, 0xf0);
- udelay(1);
-
- if (memcmp(base, datas, NVRAM_SIZE)) {
- printk(KERN_ERR "nvram: AMD flash write failed !\n");
- return -ENXIO;
- }
- return 0;
-}
-
-static void __init lookup_partitions(void)
-{
- u8 buffer[17];
- int i, offset;
- struct chrp_header* hdr;
-
- if (pmac_newworld) {
- nvram_partitions[pmac_nvram_OF] = -1;
- nvram_partitions[pmac_nvram_XPRAM] = -1;
- nvram_partitions[pmac_nvram_NR] = -1;
- hdr = (struct chrp_header *)buffer;
-
- offset = 0;
- buffer[16] = 0;
- do {
- for (i=0;i<16;i++)
- buffer[i] = ppc_md.nvram_read_val(offset+i);
- if (!strcmp(hdr->name, "common"))
- nvram_partitions[pmac_nvram_OF] = offset + 0x10;
- if (!strcmp(hdr->name, "APL,MacOS75")) {
- nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
- nvram_partitions[pmac_nvram_NR] = offset + 0x110;
- }
- offset += (hdr->len * 0x10);
- } while(offset < NVRAM_SIZE);
- } else {
- nvram_partitions[pmac_nvram_OF] = 0x1800;
- nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
- nvram_partitions[pmac_nvram_NR] = 0x1400;
- }
- DBG("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
- DBG("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
- DBG("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
-}
-
-static void core99_nvram_sync(void)
-{
- struct core99_header* hdr99;
- unsigned long flags;
-
- if (!is_core_99 || !nvram_data || !nvram_image)
- return;
-
- raw_spin_lock_irqsave(&nv_lock, flags);
- if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
- NVRAM_SIZE))
- goto bail;
-
- DBG("Updating nvram...\n");
-
- hdr99 = (struct core99_header*)nvram_image;
- hdr99->generation++;
- hdr99->hdr.signature = CORE99_SIGNATURE;
- hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
- hdr99->adler = core99_calc_adler(nvram_image);
- core99_bank = core99_bank ? 0 : 1;
- if (core99_erase_bank)
- if (core99_erase_bank(core99_bank)) {
- printk("nvram: Error erasing bank %d\n", core99_bank);
- goto bail;
- }
- if (core99_write_bank)
- if (core99_write_bank(core99_bank, nvram_image))
- printk("nvram: Error writing bank %d\n", core99_bank);
- bail:
- raw_spin_unlock_irqrestore(&nv_lock, flags);
-
-#ifdef DEBUG
- mdelay(2000);
-#endif
-}
-
-static int __init core99_nvram_setup(struct device_node *dp, unsigned long addr)
-{
- int i;
- u32 gen_bank0, gen_bank1;
-
- if (nvram_naddrs < 1) {
- printk(KERN_ERR "nvram: no address\n");
- return -EINVAL;
- }
- nvram_image = alloc_bootmem(NVRAM_SIZE);
- if (nvram_image == NULL) {
- printk(KERN_ERR "nvram: can't allocate ram image\n");
- return -ENOMEM;
- }
- nvram_data = ioremap(addr, NVRAM_SIZE*2);
- nvram_naddrs = 1; /* Make sure we get the correct case */
-
- DBG("nvram: Checking bank 0...\n");
-
- gen_bank0 = core99_check((u8 *)nvram_data);
- gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
- core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
-
- DBG("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
- DBG("nvram: Active bank is: %d\n", core99_bank);
-
- for (i=0; i<NVRAM_SIZE; i++)
- nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
-
- ppc_md.nvram_read_val = core99_nvram_read_byte;
- ppc_md.nvram_write_val = core99_nvram_write_byte;
- ppc_md.nvram_read = core99_nvram_read;
- ppc_md.nvram_write = core99_nvram_write;
- ppc_md.nvram_size = core99_nvram_size;
- ppc_md.nvram_sync = core99_nvram_sync;
- ppc_md.machine_shutdown = core99_nvram_sync;
- /*
- * Maybe we could be smarter here though making an exclusive list
- * of known flash chips is a bit nasty as older OF didn't provide us
- * with a useful "compatible" entry. A solution would be to really
- * identify the chip using flash id commands and base ourselves on
- * a list of known chips IDs
- */
- if (of_device_is_compatible(dp, "amd-0137")) {
- core99_erase_bank = amd_erase_bank;
- core99_write_bank = amd_write_bank;
- } else {
- core99_erase_bank = sm_erase_bank;
- core99_write_bank = sm_write_bank;
- }
- return 0;
-}
-
-int __init pmac_nvram_init(void)
-{
- struct device_node *dp;
- struct resource r1, r2;
- unsigned int s1 = 0, s2 = 0;
- int err = 0;
-
- nvram_naddrs = 0;
-
- dp = of_find_node_by_name(NULL, "nvram");
- if (dp == NULL) {
- printk(KERN_ERR "Can't find NVRAM device\n");
- return -ENODEV;
- }
-
- /* Try to obtain an address */
- if (of_address_to_resource(dp, 0, &r1) == 0) {
- nvram_naddrs = 1;
- s1 = resource_size(&r1);
- if (of_address_to_resource(dp, 1, &r2) == 0) {
- nvram_naddrs = 2;
- s2 = resource_size(&r2);
- }
- }
-
- is_core_99 = of_device_is_compatible(dp, "nvram,flash");
- if (is_core_99) {
- err = core99_nvram_setup(dp, r1.start);
- goto bail;
- }
-
-#ifdef CONFIG_PPC32
- if (machine_is(chrp) && nvram_naddrs == 1) {
- nvram_data = ioremap(r1.start, s1);
- nvram_mult = 1;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 1) {
- nvram_data = ioremap(r1.start, s1);
- nvram_mult = (s1 + NVRAM_SIZE - 1) / NVRAM_SIZE;
- ppc_md.nvram_read_val = direct_nvram_read_byte;
- ppc_md.nvram_write_val = direct_nvram_write_byte;
- } else if (nvram_naddrs == 2) {
- nvram_addr = ioremap(r1.start, s1);
- nvram_data = ioremap(r2.start, s2);
- ppc_md.nvram_read_val = indirect_nvram_read_byte;
- ppc_md.nvram_write_val = indirect_nvram_write_byte;
- } else if (nvram_naddrs == 0 && sys_ctrler == SYS_CTRLER_PMU) {
-#ifdef CONFIG_ADB_PMU
- nvram_naddrs = -1;
- ppc_md.nvram_read_val = pmu_nvram_read_byte;
- ppc_md.nvram_write_val = pmu_nvram_write_byte;
-#endif /* CONFIG_ADB_PMU */
- } else {
- printk(KERN_ERR "Incompatible type of NVRAM\n");
- err = -ENXIO;
- }
-#endif /* CONFIG_PPC32 */
-bail:
- of_node_put(dp);
- if (err == 0)
- lookup_partitions();
- return err;
-}
-
-int pmac_get_partition(int partition)
-{
- return nvram_partitions[partition];
-}
-
-u8 pmac_xpram_read(int xpaddr)
-{
- int offset = pmac_get_partition(pmac_nvram_XPRAM);
-
- if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
- return 0xff;
-
- return ppc_md.nvram_read_val(xpaddr + offset);
-}
-
-void pmac_xpram_write(int xpaddr, u8 data)
-{
- int offset = pmac_get_partition(pmac_nvram_XPRAM);
-
- if (offset < 0 || xpaddr < 0 || xpaddr > 0x100)
- return;
-
- ppc_md.nvram_write_val(xpaddr + offset, data);
-}
-
-EXPORT_SYMBOL(pmac_get_partition);
-EXPORT_SYMBOL(pmac_xpram_read);
-EXPORT_SYMBOL(pmac_xpram_write);
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pci.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pci.c
deleted file mode 100644
index 43bbe1bd..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pci.c
+++ /dev/null
@@ -1,1357 +0,0 @@
-/*
- * Support for PCI bridges found on Power Macintoshes.
- *
- * Copyright (C) 2003-2005 Benjamin Herrenschmuidt (benh@kernel.crashing.org)
- * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
- *
- * 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.
- */
-
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/init.h>
-#include <linux/bootmem.h>
-#include <linux/irq.h>
-#include <linux/of_pci.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/grackle.h>
-#include <asm/ppc-pci.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* XXX Could be per-controller, but I don't think we risk anything by
- * assuming we won't have both UniNorth and Bandit */
-static int has_uninorth;
-#ifdef CONFIG_PPC64
-static struct pci_controller *u3_agp;
-#else
-static int has_second_ohare;
-#endif /* CONFIG_PPC64 */
-
-extern int pcibios_assign_bus_offset;
-
-struct device_node *k2_skiplist[2];
-
-/*
- * Magic constants for enabling cache coherency in the bandit/PSX bridge.
- */
-#define BANDIT_DEVID_2 8
-#define BANDIT_REVID 3
-
-#define BANDIT_DEVNUM 11
-#define BANDIT_MAGIC 0x50
-#define BANDIT_COHERENT 0x40
-
-static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
-{
- for (; node != 0;node = node->sibling) {
- const int * bus_range;
- const unsigned int *class_code;
- int len;
-
- /* For PCI<->PCI bridges or CardBus bridges, we go down */
- class_code = of_get_property(node, "class-code", NULL);
- if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
- (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
- continue;
- bus_range = of_get_property(node, "bus-range", &len);
- if (bus_range != NULL && len > 2 * sizeof(int)) {
- if (bus_range[1] > higher)
- higher = bus_range[1];
- }
- higher = fixup_one_level_bus_range(node->child, higher);
- }
- return higher;
-}
-
-/* This routine fixes the "bus-range" property of all bridges in the
- * system since they tend to have their "last" member wrong on macs
- *
- * Note that the bus numbers manipulated here are OF bus numbers, they
- * are not Linux bus numbers.
- */
-static void __init fixup_bus_range(struct device_node *bridge)
-{
- int *bus_range, len;
- struct property *prop;
-
- /* Lookup the "bus-range" property for the hose */
- prop = of_find_property(bridge, "bus-range", &len);
- if (prop == NULL || prop->length < 2 * sizeof(int))
- return;
-
- bus_range = prop->value;
- bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
-}
-
-/*
- * Apple MacRISC (U3, UniNorth, Bandit, Chaos) PCI controllers.
- *
- * The "Bandit" version is present in all early PCI PowerMacs,
- * and up to the first ones using Grackle. Some machines may
- * have 2 bandit controllers (2 PCI busses).
- *
- * "Chaos" is used in some "Bandit"-type machines as a bridge
- * for the separate display bus. It is accessed the same
- * way as bandit, but cannot be probed for devices. It therefore
- * has its own config access functions.
- *
- * The "UniNorth" version is present in all Core99 machines
- * (iBook, G4, new IMacs, and all the recent Apple machines).
- * It contains 3 controllers in one ASIC.
- *
- * The U3 is the bridge used on G5 machines. It contains an
- * AGP bus which is dealt with the old UniNorth access routines
- * and a HyperTransport bus which uses its own set of access
- * functions.
- */
-
-#define MACRISC_CFA0(devfn, off) \
- ((1 << (unsigned int)PCI_SLOT(dev_fn)) \
- | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \
- | (((unsigned int)(off)) & 0xFCUL))
-
-#define MACRISC_CFA1(bus, devfn, off) \
- ((((unsigned int)(bus)) << 16) \
- |(((unsigned int)(devfn)) << 8) \
- |(((unsigned int)(off)) & 0xFCUL) \
- |1UL)
-
-static volatile void __iomem *macrisc_cfg_access(struct pci_controller* hose,
- u8 bus, u8 dev_fn, u8 offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- if (dev_fn < (11 << 3))
- return NULL;
- caddr = MACRISC_CFA0(dev_fn, offset);
- } else
- caddr = MACRISC_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= has_uninorth ? 0x07 : 0x03;
- return hose->cfg_data + offset;
-}
-
-static int macrisc_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- volatile void __iomem *addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x100)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int macrisc_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- volatile void __iomem *addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x100)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = macrisc_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- break;
- case 2:
- out_le16(addr, val);
- break;
- default:
- out_le32(addr, val);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops macrisc_pci_ops =
-{
- .read = macrisc_read_config,
- .write = macrisc_write_config,
-};
-
-#ifdef CONFIG_PPC32
-/*
- * Verify that a specific (bus, dev_fn) exists on chaos
- */
-static int chaos_validate_dev(struct pci_bus *bus, int devfn, int offset)
-{
- struct device_node *np;
- const u32 *vendor, *device;
-
- if (offset >= 0x100)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- np = of_pci_find_child_device(bus->dev.of_node, devfn);
- if (np == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- vendor = of_get_property(np, "vendor-id", NULL);
- device = of_get_property(np, "device-id", NULL);
- if (vendor == NULL || device == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- if ((*vendor == 0x106b) && (*device == 3) && (offset >= 0x10)
- && (offset != 0x14) && (offset != 0x18) && (offset <= 0x24))
- return PCIBIOS_BAD_REGISTER_NUMBER;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int
-chaos_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 *val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result == PCIBIOS_BAD_REGISTER_NUMBER)
- *val = ~0U;
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_read_config(bus, devfn, offset, len, val);
-}
-
-static int
-chaos_write_config(struct pci_bus *bus, unsigned int devfn, int offset,
- int len, u32 val)
-{
- int result = chaos_validate_dev(bus, devfn, offset);
- if (result != PCIBIOS_SUCCESSFUL)
- return result;
- return macrisc_write_config(bus, devfn, offset, len, val);
-}
-
-static struct pci_ops chaos_pci_ops =
-{
- .read = chaos_read_config,
- .write = chaos_write_config,
-};
-
-static void __init setup_chaos(struct pci_controller *hose,
- struct resource *addr)
-{
- /* assume a `chaos' bridge */
- hose->ops = &chaos_pci_ops;
- hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
-}
-#endif /* CONFIG_PPC32 */
-
-#ifdef CONFIG_PPC64
-/*
- * These versions of U3 HyperTransport config space access ops do not
- * implement self-view of the HT host yet
- */
-
-/*
- * This function deals with some "special cases" devices.
- *
- * 0 -> No special case
- * 1 -> Skip the device but act as if the access was successful
- * (return 0xff's on reads, eventually, cache config space
- * accesses in a later version)
- * -1 -> Hide the device (unsuccessful access)
- */
-static int u3_ht_skip_device(struct pci_controller *hose,
- struct pci_bus *bus, unsigned int devfn)
-{
- struct device_node *busdn, *dn;
- int i;
-
- /* We only allow config cycles to devices that are in OF device-tree
- * as we are apparently having some weird things going on with some
- * revs of K2 on recent G5s, except for the host bridge itself, which
- * is missing from the tree but we know we can probe.
- */
- if (bus->self)
- busdn = pci_device_to_OF_node(bus->self);
- else if (devfn == 0)
- return 0;
- else
- busdn = hose->dn;
- for (dn = busdn->child; dn; dn = dn->sibling)
- if (PCI_DN(dn) && PCI_DN(dn)->devfn == devfn)
- break;
- if (dn == NULL)
- return -1;
-
- /*
- * When a device in K2 is powered down, we die on config
- * cycle accesses. Fix that here.
- */
- for (i=0; i<2; i++)
- if (k2_skiplist[i] == dn)
- return 1;
-
- return 0;
-}
-
-#define U3_HT_CFA0(devfn, off) \
- ((((unsigned int)devfn) << 8) | offset)
-#define U3_HT_CFA1(bus, devfn, off) \
- (U3_HT_CFA0(devfn, off) \
- + (((unsigned int)bus) << 16) \
- + 0x01000000UL)
-
-static void __iomem *u3_ht_cfg_access(struct pci_controller *hose, u8 bus,
- u8 devfn, u8 offset, int *swap)
-{
- *swap = 1;
- if (bus == hose->first_busno) {
- if (devfn != 0)
- return hose->cfg_data + U3_HT_CFA0(devfn, offset);
- *swap = 0;
- return ((void __iomem *)hose->cfg_addr) + (offset << 2);
- } else
- return hose->cfg_data + U3_HT_CFA1(bus, devfn, offset);
-}
-
-static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- void __iomem *addr;
- int swap;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x100)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- switch (len) {
- case 1:
- *val = 0xff; break;
- case 2:
- *val = 0xffff; break;
- default:
- *val = 0xfffffffful; break;
- }
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = swap ? in_le16(addr) : in_be16(addr);
- break;
- default:
- *val = swap ? in_le32(addr) : in_be32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- void __iomem *addr;
- int swap;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x100)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = u3_ht_cfg_access(hose, bus->number, devfn, offset, &swap);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
-
- switch (u3_ht_skip_device(hose, bus, devfn)) {
- case 0:
- break;
- case 1:
- return PCIBIOS_SUCCESSFUL;
- default:
- return PCIBIOS_DEVICE_NOT_FOUND;
- }
-
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- break;
- case 2:
- swap ? out_le16(addr, val) : out_be16(addr, val);
- break;
- default:
- swap ? out_le32(addr, val) : out_be32(addr, val);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u3_ht_pci_ops =
-{
- .read = u3_ht_read_config,
- .write = u3_ht_write_config,
-};
-
-#define U4_PCIE_CFA0(devfn, off) \
- ((1 << ((unsigned int)PCI_SLOT(dev_fn))) \
- | (((unsigned int)PCI_FUNC(dev_fn)) << 8) \
- | ((((unsigned int)(off)) >> 8) << 28) \
- | (((unsigned int)(off)) & 0xfcU))
-
-#define U4_PCIE_CFA1(bus, devfn, off) \
- ((((unsigned int)(bus)) << 16) \
- |(((unsigned int)(devfn)) << 8) \
- | ((((unsigned int)(off)) >> 8) << 28) \
- |(((unsigned int)(off)) & 0xfcU) \
- |1UL)
-
-static volatile void __iomem *u4_pcie_cfg_access(struct pci_controller* hose,
- u8 bus, u8 dev_fn, int offset)
-{
- unsigned int caddr;
-
- if (bus == hose->first_busno) {
- caddr = U4_PCIE_CFA0(dev_fn, offset);
- } else
- caddr = U4_PCIE_CFA1(bus, dev_fn, offset);
-
- /* Uninorth will return garbage if we don't read back the value ! */
- do {
- out_le32(hose->cfg_addr, caddr);
- } while (in_le32(hose->cfg_addr) != caddr);
-
- offset &= 0x03;
- return hose->cfg_data + offset;
-}
-
-static int u4_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 *val)
-{
- struct pci_controller *hose;
- volatile void __iomem *addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x1000)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- *val = in_8(addr);
- break;
- case 2:
- *val = in_le16(addr);
- break;
- default:
- *val = in_le32(addr);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int u4_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
- int offset, int len, u32 val)
-{
- struct pci_controller *hose;
- volatile void __iomem *addr;
-
- hose = pci_bus_to_host(bus);
- if (hose == NULL)
- return PCIBIOS_DEVICE_NOT_FOUND;
- if (offset >= 0x1000)
- return PCIBIOS_BAD_REGISTER_NUMBER;
- addr = u4_pcie_cfg_access(hose, bus->number, devfn, offset);
- if (!addr)
- return PCIBIOS_DEVICE_NOT_FOUND;
- /*
- * Note: the caller has already checked that offset is
- * suitably aligned and that len is 1, 2 or 4.
- */
- switch (len) {
- case 1:
- out_8(addr, val);
- break;
- case 2:
- out_le16(addr, val);
- break;
- default:
- out_le32(addr, val);
- break;
- }
- return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops u4_pcie_pci_ops =
-{
- .read = u4_pcie_read_config,
- .write = u4_pcie_write_config,
-};
-
-static void __devinit pmac_pci_fixup_u4_of_node(struct pci_dev *dev)
-{
- /* Apple's device-tree "hides" the root complex virtual P2P bridge
- * on U4. However, Linux sees it, causing the PCI <-> OF matching
- * code to fail to properly match devices below it. This works around
- * it by setting the node of the bridge to point to the PHB node,
- * which is not entirely correct but fixes the matching code and
- * doesn't break anything else. It's also the simplest possible fix.
- */
- if (dev->dev.of_node == NULL)
- dev->dev.of_node = pcibios_get_phb_of_node(dev->bus);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, 0x5b, pmac_pci_fixup_u4_of_node);
-
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_PPC32
-/*
- * For a bandit bridge, turn on cache coherency if necessary.
- * N.B. we could clean this up using the hose ops directly.
- */
-static void __init init_bandit(struct pci_controller *bp)
-{
- unsigned int vendev, magic;
- int rev;
-
- /* read the word at offset 0 in config space for device 11 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + PCI_VENDOR_ID);
- udelay(2);
- vendev = in_le32(bp->cfg_data);
- if (vendev == (PCI_DEVICE_ID_APPLE_BANDIT << 16) +
- PCI_VENDOR_ID_APPLE) {
- /* read the revision id */
- out_le32(bp->cfg_addr,
- (1UL << BANDIT_DEVNUM) + PCI_REVISION_ID);
- udelay(2);
- rev = in_8(bp->cfg_data);
- if (rev != BANDIT_REVID)
- printk(KERN_WARNING
- "Unknown revision %d for bandit\n", rev);
- } else if (vendev != (BANDIT_DEVID_2 << 16) + PCI_VENDOR_ID_APPLE) {
- printk(KERN_WARNING "bandit isn't? (%x)\n", vendev);
- return;
- }
-
- /* read the word at offset 0x50 */
- out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC);
- udelay(2);
- magic = in_le32(bp->cfg_data);
- if ((magic & BANDIT_COHERENT) != 0)
- return;
- magic |= BANDIT_COHERENT;
- udelay(2);
- out_le32(bp->cfg_data, magic);
- printk(KERN_INFO "Cache coherency enabled for bandit/PSX\n");
-}
-
-/*
- * Tweak the PCI-PCI bridge chip on the blue & white G3s.
- */
-static void __init init_p2pbridge(void)
-{
- struct device_node *p2pbridge;
- struct pci_controller* hose;
- u8 bus, devfn;
- u16 val;
-
- /* XXX it would be better here to identify the specific
- PCI-PCI bridge chip we have. */
- p2pbridge = of_find_node_by_name(NULL, "pci-bridge");
- if (p2pbridge == NULL
- || p2pbridge->parent == NULL
- || strcmp(p2pbridge->parent->name, "pci") != 0)
- goto done;
- if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) {
- DBG("Can't find PCI infos for PCI<->PCI bridge\n");
- goto done;
- }
- /* Warning: At this point, we have not yet renumbered all busses.
- * So we must use OF walking to find out hose
- */
- hose = pci_find_hose_for_OF_device(p2pbridge);
- if (!hose) {
- DBG("Can't find hose for PCI<->PCI bridge\n");
- goto done;
- }
- if (early_read_config_word(hose, bus, devfn,
- PCI_BRIDGE_CONTROL, &val) < 0) {
- printk(KERN_ERR "init_p2pbridge: couldn't read bridge"
- " control\n");
- goto done;
- }
- val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val);
-done:
- of_node_put(p2pbridge);
-}
-
-static void __init init_second_ohare(void)
-{
- struct device_node *np = of_find_node_by_name(NULL, "pci106b,7");
- unsigned char bus, devfn;
- unsigned short cmd;
-
- if (np == NULL)
- return;
-
- /* This must run before we initialize the PICs since the second
- * ohare hosts a PIC that will be accessed there.
- */
- if (pci_device_from_OF_node(np, &bus, &devfn) == 0) {
- struct pci_controller* hose =
- pci_find_hose_for_OF_device(np);
- if (!hose) {
- printk(KERN_ERR "Can't find PCI hose for OHare2 !\n");
- of_node_put(np);
- return;
- }
- early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- cmd &= ~PCI_COMMAND_IO;
- early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd);
- }
- has_second_ohare = 1;
- of_node_put(np);
-}
-
-/*
- * Some Apple desktop machines have a NEC PD720100A USB2 controller
- * on the motherboard. Open Firmware, on these, will disable the
- * EHCI part of it so it behaves like a pair of OHCI's. This fixup
- * code re-enables it ;)
- */
-static void __init fixup_nec_usb2(void)
-{
- struct device_node *nec;
-
- for (nec = NULL; (nec = of_find_node_by_name(nec, "usb")) != NULL;) {
- struct pci_controller *hose;
- u32 data;
- const u32 *prop;
- u8 bus, devfn;
-
- prop = of_get_property(nec, "vendor-id", NULL);
- if (prop == NULL)
- continue;
- if (0x1033 != *prop)
- continue;
- prop = of_get_property(nec, "device-id", NULL);
- if (prop == NULL)
- continue;
- if (0x0035 != *prop)
- continue;
- prop = of_get_property(nec, "reg", NULL);
- if (prop == NULL)
- continue;
- devfn = (prop[0] >> 8) & 0xff;
- bus = (prop[0] >> 16) & 0xff;
- if (PCI_FUNC(devfn) != 0)
- continue;
- hose = pci_find_hose_for_OF_device(nec);
- if (!hose)
- continue;
- early_read_config_dword(hose, bus, devfn, 0xe4, &data);
- if (data & 1UL) {
- printk("Found NEC PD720100A USB2 chip with disabled"
- " EHCI, fixing up...\n");
- data &= ~1UL;
- early_write_config_dword(hose, bus, devfn, 0xe4, data);
- }
- }
-}
-
-static void __init setup_bandit(struct pci_controller *hose,
- struct resource *addr)
-{
- hose->ops = &macrisc_pci_ops;
- hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
- init_bandit(hose);
-}
-
-static int __init setup_uninorth(struct pci_controller *hose,
- struct resource *addr)
-{
- pci_add_flags(PCI_REASSIGN_ALL_BUS);
- has_uninorth = 1;
- hose->ops = &macrisc_pci_ops;
- hose->cfg_addr = ioremap(addr->start + 0x800000, 0x1000);
- hose->cfg_data = ioremap(addr->start + 0xc00000, 0x1000);
- /* We "know" that the bridge at f2000000 has the PCI slots. */
- return addr->start == 0xf2000000;
-}
-#endif /* CONFIG_PPC32 */
-
-#ifdef CONFIG_PPC64
-static void __init setup_u3_agp(struct pci_controller* hose)
-{
- /* On G5, we move AGP up to high bus number so we don't need
- * to reassign bus numbers for HT. If we ever have P2P bridges
- * on AGP, we'll have to move pci_assign_all_busses to the
- * pci_controller structure so we enable it for AGP and not for
- * HT childs.
- * We hard code the address because of the different size of
- * the reg address cell, we shall fix that by killing struct
- * reg_property and using some accessor functions instead
- */
- hose->first_busno = 0xf0;
- hose->last_busno = 0xff;
- has_uninorth = 1;
- hose->ops = &macrisc_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
- u3_agp = hose;
-}
-
-static void __init setup_u4_pcie(struct pci_controller* hose)
-{
- /* We currently only implement the "non-atomic" config space, to
- * be optimised later.
- */
- hose->ops = &u4_pcie_pci_ops;
- hose->cfg_addr = ioremap(0xf0000000 + 0x800000, 0x1000);
- hose->cfg_data = ioremap(0xf0000000 + 0xc00000, 0x1000);
-
- /* The bus contains a bridge from root -> device, we need to
- * make it visible on bus 0 so that we pick the right type
- * of config cycles. If we didn't, we would have to force all
- * config cycles to be type 1. So we override the "bus-range"
- * property here
- */
- hose->first_busno = 0x00;
- hose->last_busno = 0xff;
-}
-
-static void __init parse_region_decode(struct pci_controller *hose,
- u32 decode)
-{
- unsigned long base, end, next = -1;
- int i, cur = -1;
-
- /* Iterate through all bits. We ignore the last bit as this region is
- * reserved for the ROM among other niceties
- */
- for (i = 0; i < 31; i++) {
- if ((decode & (0x80000000 >> i)) == 0)
- continue;
- if (i < 16) {
- base = 0xf0000000 | (((u32)i) << 24);
- end = base + 0x00ffffff;
- } else {
- base = ((u32)i-16) << 28;
- end = base + 0x0fffffff;
- }
- if (base != next) {
- if (++cur >= 3) {
- printk(KERN_WARNING "PCI: Too many ranges !\n");
- break;
- }
- hose->mem_resources[cur].flags = IORESOURCE_MEM;
- hose->mem_resources[cur].name = hose->dn->full_name;
- hose->mem_resources[cur].start = base;
- hose->mem_resources[cur].end = end;
- DBG(" %d: 0x%08lx-0x%08lx\n", cur, base, end);
- } else {
- DBG(" : -0x%08lx\n", end);
- hose->mem_resources[cur].end = end;
- }
- next = end + 1;
- }
-}
-
-static void __init setup_u3_ht(struct pci_controller* hose)
-{
- struct device_node *np = hose->dn;
- struct resource cfg_res, self_res;
- u32 decode;
-
- hose->ops = &u3_ht_pci_ops;
-
- /* Get base addresses from OF tree
- */
- if (of_address_to_resource(np, 0, &cfg_res) ||
- of_address_to_resource(np, 1, &self_res)) {
- printk(KERN_ERR "PCI: Failed to get U3/U4 HT resources !\n");
- return;
- }
-
- /* Map external cfg space access into cfg_data and self registers
- * into cfg_addr
- */
- hose->cfg_data = ioremap(cfg_res.start, 0x02000000);
- hose->cfg_addr = ioremap(self_res.start, resource_size(&self_res));
-
- /*
- * /ht node doesn't expose a "ranges" property, we read the register
- * that controls the decoding logic and use that for memory regions.
- * The IO region is hard coded since it is fixed in HW as well.
- */
- hose->io_base_phys = 0xf4000000;
- hose->pci_io_size = 0x00400000;
- hose->io_resource.name = np->full_name;
- hose->io_resource.start = 0;
- hose->io_resource.end = 0x003fffff;
- hose->io_resource.flags = IORESOURCE_IO;
- hose->pci_mem_offset = 0;
- hose->first_busno = 0;
- hose->last_busno = 0xef;
-
- /* Note: fix offset when cfg_addr becomes a void * */
- decode = in_be32(hose->cfg_addr + 0x80);
-
- DBG("PCI: Apple HT bridge decode register: 0x%08x\n", decode);
-
- /* NOTE: The decode register setup is a bit weird... region
- * 0xf8000000 for example is marked as enabled in there while it's
- & actually the memory controller registers.
- * That means that we are incorrectly attributing it to HT.
- *
- * In a similar vein, region 0xf4000000 is actually the HT IO space but
- * also marked as enabled in here and 0xf9000000 is used by some other
- * internal bits of the northbridge.
- *
- * Unfortunately, we can't just mask out those bit as we would end
- * up with more regions than we can cope (linux can only cope with
- * 3 memory regions for a PHB at this stage).
- *
- * So for now, we just do a little hack. We happen to -know- that
- * Apple firmware doesn't assign things below 0xfa000000 for that
- * bridge anyway so we mask out all bits we don't want.
- */
- decode &= 0x003fffff;
-
- /* Now parse the resulting bits and build resources */
- parse_region_decode(hose, decode);
-}
-#endif /* CONFIG_PPC64 */
-
-/*
- * We assume that if we have a G3 powermac, we have one bridge called
- * "pci" (a MPC106) and no bandit or chaos bridges, and contrariwise,
- * if we have one or more bandit or chaos bridges, we don't have a MPC106.
- */
-static int __init pmac_add_bridge(struct device_node *dev)
-{
- int len;
- struct pci_controller *hose;
- struct resource rsrc;
- char *disp_name;
- const int *bus_range;
- int primary = 1, has_address = 0;
-
- DBG("Adding PCI host bridge %s\n", dev->full_name);
-
- /* Fetch host bridge registers address */
- has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
-
- /* Get bus range if any */
- bus_range = of_get_property(dev, "bus-range", &len);
- if (bus_range == NULL || len < 2 * sizeof(int)) {
- printk(KERN_WARNING "Can't get bus-range for %s, assume"
- " bus 0\n", dev->full_name);
- }
-
- hose = pcibios_alloc_controller(dev);
- if (!hose)
- return -ENOMEM;
- hose->first_busno = bus_range ? bus_range[0] : 0;
- hose->last_busno = bus_range ? bus_range[1] : 0xff;
-
- disp_name = NULL;
-
- /* 64 bits only bridges */
-#ifdef CONFIG_PPC64
- if (of_device_is_compatible(dev, "u3-agp")) {
- setup_u3_agp(hose);
- disp_name = "U3-AGP";
- primary = 0;
- } else if (of_device_is_compatible(dev, "u3-ht")) {
- setup_u3_ht(hose);
- disp_name = "U3-HT";
- primary = 1;
- } else if (of_device_is_compatible(dev, "u4-pcie")) {
- setup_u4_pcie(hose);
- disp_name = "U4-PCIE";
- primary = 0;
- }
- printk(KERN_INFO "Found %s PCI host bridge. Firmware bus number:"
- " %d->%d\n", disp_name, hose->first_busno, hose->last_busno);
-#endif /* CONFIG_PPC64 */
-
- /* 32 bits only bridges */
-#ifdef CONFIG_PPC32
- if (of_device_is_compatible(dev, "uni-north")) {
- primary = setup_uninorth(hose, &rsrc);
- disp_name = "UniNorth";
- } else if (strcmp(dev->name, "pci") == 0) {
- /* XXX assume this is a mpc106 (grackle) */
- setup_grackle(hose);
- disp_name = "Grackle (MPC106)";
- } else if (strcmp(dev->name, "bandit") == 0) {
- setup_bandit(hose, &rsrc);
- disp_name = "Bandit";
- } else if (strcmp(dev->name, "chaos") == 0) {
- setup_chaos(hose, &rsrc);
- disp_name = "Chaos";
- primary = 0;
- }
- printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. "
- "Firmware bus number: %d->%d\n",
- disp_name, (unsigned long long)rsrc.start, hose->first_busno,
- hose->last_busno);
-#endif /* CONFIG_PPC32 */
-
- DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
- hose, hose->cfg_addr, hose->cfg_data);
-
- /* Interpret the "ranges" property */
- /* This also maps the I/O region and sets isa_io/mem_base */
- pci_process_bridge_OF_ranges(hose, dev, primary);
-
- /* Fixup "bus-range" OF property */
- fixup_bus_range(dev);
-
- return 0;
-}
-
-void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
-{
-#ifdef CONFIG_PPC32
- /* Fixup interrupt for the modem/ethernet combo controller.
- * on machines with a second ohare chip.
- * The number in the device tree (27) is bogus (correct for
- * the ethernet-only board but not the combo ethernet/modem
- * board). The real interrupt is 28 on the second controller
- * -> 28+32 = 60.
- */
- if (has_second_ohare &&
- dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
- dev->irq = irq_create_mapping(NULL, 60);
- irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
- }
-#endif /* CONFIG_PPC32 */
-}
-
-void __init pmac_pci_init(void)
-{
- struct device_node *np, *root;
- struct device_node *ht = NULL;
-
- pci_set_flags(PCI_CAN_SKIP_ISA_ALIGN);
-
- root = of_find_node_by_path("/");
- if (root == NULL) {
- printk(KERN_CRIT "pmac_pci_init: can't find root "
- "of device tree\n");
- return;
- }
- for (np = NULL; (np = of_get_next_child(root, np)) != NULL;) {
- if (np->name == NULL)
- continue;
- if (strcmp(np->name, "bandit") == 0
- || strcmp(np->name, "chaos") == 0
- || strcmp(np->name, "pci") == 0) {
- if (pmac_add_bridge(np) == 0)
- of_node_get(np);
- }
- if (strcmp(np->name, "ht") == 0) {
- of_node_get(np);
- ht = np;
- }
- }
- of_node_put(root);
-
-#ifdef CONFIG_PPC64
- /* Probe HT last as it relies on the agp resources to be already
- * setup
- */
- if (ht && pmac_add_bridge(ht) != 0)
- of_node_put(ht);
-
- /* Setup the linkage between OF nodes and PHBs */
- pci_devs_phb_init();
-
- /* Fixup the PCI<->OF mapping for U3 AGP due to bus renumbering. We
- * assume there is no P2P bridge on the AGP bus, which should be a
- * safe assumptions for now. We should do something better in the
- * future though
- */
- if (u3_agp) {
- struct device_node *np = u3_agp->dn;
- PCI_DN(np)->busno = 0xf0;
- for (np = np->child; np; np = np->sibling)
- PCI_DN(np)->busno = 0xf0;
- }
- /* pmac_check_ht_link(); */
-
-#else /* CONFIG_PPC64 */
- init_p2pbridge();
- init_second_ohare();
- fixup_nec_usb2();
-
- /* We are still having some issues with the Xserve G4, enabling
- * some offset between bus number and domains for now when we
- * assign all busses should help for now
- */
- if (pci_has_flag(PCI_REASSIGN_ALL_BUS))
- pcibios_assign_bus_offset = 0x10;
-#endif
-}
-
-#ifdef CONFIG_PPC32
-int pmac_pci_enable_device_hook(struct pci_dev *dev)
-{
- struct device_node* node;
- int updatecfg = 0;
- int uninorth_child;
-
- node = pci_device_to_OF_node(dev);
-
- /* We don't want to enable USB controllers absent from the OF tree
- * (iBook second controller)
- */
- if (dev->vendor == PCI_VENDOR_ID_APPLE
- && dev->class == PCI_CLASS_SERIAL_USB_OHCI
- && !node) {
- printk(KERN_INFO "Apple USB OHCI %s disabled by firmware\n",
- pci_name(dev));
- return -EINVAL;
- }
-
- if (!node)
- return 0;
-
- uninorth_child = node->parent &&
- of_device_is_compatible(node->parent, "uni-north");
-
- /* Firewire & GMAC were disabled after PCI probe, the driver is
- * claiming them, we must re-enable them now.
- */
- if (uninorth_child && !strcmp(node->name, "firewire") &&
- (of_device_is_compatible(node, "pci106b,18") ||
- of_device_is_compatible(node, "pci106b,30") ||
- of_device_is_compatible(node, "pci11c1,5811"))) {
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, node, 0, 1);
- pmac_call_feature(PMAC_FTR_1394_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
- if (uninorth_child && !strcmp(node->name, "ethernet") &&
- of_device_is_compatible(node, "gmac")) {
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, node, 0, 1);
- updatecfg = 1;
- }
-
- /*
- * Fixup various header fields on 32 bits. We don't do that on
- * 64 bits as some of these have strange values behind the HT
- * bridge and we must not, for example, enable MWI or set the
- * cache line size on them.
- */
- if (updatecfg) {
- u16 cmd;
-
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
- | PCI_COMMAND_INVALIDATE;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 16);
-
- pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE,
- L1_CACHE_BYTES >> 2);
- }
-
- return 0;
-}
-
-void __devinit pmac_pci_fixup_ohci(struct pci_dev *dev)
-{
- struct device_node *node = pci_device_to_OF_node(dev);
-
- /* We don't want to assign resources to USB controllers
- * absent from the OF tree (iBook second controller)
- */
- if (dev->class == PCI_CLASS_SERIAL_USB_OHCI && !node)
- dev->resource[0].flags = 0;
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_ANY_ID, pmac_pci_fixup_ohci);
-
-/* We power down some devices after they have been probed. They'll
- * be powered back on later on
- */
-void __init pmac_pcibios_after_init(void)
-{
- struct device_node* nd;
-
- for_each_node_by_name(nd, "firewire") {
- if (nd->parent && (of_device_is_compatible(nd, "pci106b,18") ||
- of_device_is_compatible(nd, "pci106b,30") ||
- of_device_is_compatible(nd, "pci11c1,5811"))
- && of_device_is_compatible(nd->parent, "uni-north")) {
- pmac_call_feature(PMAC_FTR_1394_ENABLE, nd, 0, 0);
- pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, nd, 0, 0);
- }
- }
- for_each_node_by_name(nd, "ethernet") {
- if (nd->parent && of_device_is_compatible(nd, "gmac")
- && of_device_is_compatible(nd->parent, "uni-north"))
- pmac_call_feature(PMAC_FTR_GMAC_ENABLE, nd, 0, 0);
- }
-}
-
-void pmac_pci_fixup_cardbus(struct pci_dev* dev)
-{
- if (!machine_is(powermac))
- return;
- /*
- * Fix the interrupt routing on the various cardbus bridges
- * used on powerbooks
- */
- if (dev->vendor != PCI_VENDOR_ID_TI)
- return;
- if (dev->device == PCI_DEVICE_ID_TI_1130 ||
- dev->device == PCI_DEVICE_ID_TI_1131) {
- u8 val;
- /* Enable PCI interrupt */
- if (pci_read_config_byte(dev, 0x91, &val) == 0)
- pci_write_config_byte(dev, 0x91, val | 0x30);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
- if (dev->device == PCI_DEVICE_ID_TI_1210 ||
- dev->device == PCI_DEVICE_ID_TI_1211 ||
- dev->device == PCI_DEVICE_ID_TI_1410 ||
- dev->device == PCI_DEVICE_ID_TI_1510) {
- u8 val;
- /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA
- signal out the MFUNC0 pin */
- if (pci_read_config_byte(dev, 0x8c, &val) == 0)
- pci_write_config_byte(dev, 0x8c, (val & ~0x0f) | 2);
- /* Disable ISA interrupt mode */
- if (pci_read_config_byte(dev, 0x92, &val) == 0)
- pci_write_config_byte(dev, 0x92, val & ~0x06);
- }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_TI, PCI_ANY_ID, pmac_pci_fixup_cardbus);
-
-void pmac_pci_fixup_pciata(struct pci_dev* dev)
-{
- u8 progif = 0;
-
- /*
- * On PowerMacs, we try to switch any PCI ATA controller to
- * fully native mode
- */
- if (!machine_is(powermac))
- return;
-
- /* Some controllers don't have the class IDE */
- if (dev->vendor == PCI_VENDOR_ID_PROMISE)
- switch(dev->device) {
- case PCI_DEVICE_ID_PROMISE_20246:
- case PCI_DEVICE_ID_PROMISE_20262:
- case PCI_DEVICE_ID_PROMISE_20263:
- case PCI_DEVICE_ID_PROMISE_20265:
- case PCI_DEVICE_ID_PROMISE_20267:
- case PCI_DEVICE_ID_PROMISE_20268:
- case PCI_DEVICE_ID_PROMISE_20269:
- case PCI_DEVICE_ID_PROMISE_20270:
- case PCI_DEVICE_ID_PROMISE_20271:
- case PCI_DEVICE_ID_PROMISE_20275:
- case PCI_DEVICE_ID_PROMISE_20276:
- case PCI_DEVICE_ID_PROMISE_20277:
- goto good;
- }
- /* Others, check PCI class */
- if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
- return;
- good:
- pci_read_config_byte(dev, PCI_CLASS_PROG, &progif);
- if ((progif & 5) != 5) {
- printk(KERN_INFO "PCI: %s Forcing PCI IDE into native mode\n",
- pci_name(dev));
- (void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
- if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
- (progif & 5) != 5)
- printk(KERN_ERR "Rewrite of PROGIF failed !\n");
- else {
- /* Clear IO BARs, they will be reassigned */
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, 0);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, 0);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, 0);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_3, 0);
- }
- }
-}
-DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, pmac_pci_fixup_pciata);
-#endif /* CONFIG_PPC32 */
-
-/*
- * Disable second function on K2-SATA, it's broken
- * and disable IO BARs on first one
- */
-static void fixup_k2_sata(struct pci_dev* dev)
-{
- int i;
- u16 cmd;
-
- if (PCI_FUNC(dev->devfn) > 0) {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 6; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i,
- 0);
- }
- } else {
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_IO;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
- for (i = 0; i < 5; i++) {
- dev->resource[i].start = dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4 * i,
- 0);
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SERVERWORKS, 0x0240, fixup_k2_sata);
-
-/*
- * On U4 (aka CPC945) the PCIe root complex "P2P" bridge resource ranges aren't
- * configured by the firmware. The bridge itself seems to ignore them but it
- * causes problems with Linux which then re-assigns devices below the bridge,
- * thus changing addresses of those devices from what was in the device-tree,
- * which sucks when those are video cards using offb
- *
- * We could just mark it transparent but I prefer fixing up the resources to
- * properly show what's going on here, as I have some doubts about having them
- * badly configured potentially being an issue for DMA.
- *
- * We leave PIO alone, it seems to be fine
- *
- * Oh and there's another funny bug. The OF properties advertize the region
- * 0xf1000000..0xf1ffffff as being forwarded as memory space. But that's
- * actually not true, this region is the memory mapped config space. So we
- * also need to filter it out or we'll map things in the wrong place.
- */
-static void fixup_u4_pcie(struct pci_dev* dev)
-{
- struct pci_controller *host = pci_bus_to_host(dev->bus);
- struct resource *region = NULL;
- u32 reg;
- int i;
-
- /* Only do that on PowerMac */
- if (!machine_is(powermac))
- return;
-
- /* Find the largest MMIO region */
- for (i = 0; i < 3; i++) {
- struct resource *r = &host->mem_resources[i];
- if (!(r->flags & IORESOURCE_MEM))
- continue;
- /* Skip the 0xf0xxxxxx..f2xxxxxx regions, we know they
- * are reserved by HW for other things
- */
- if (r->start >= 0xf0000000 && r->start < 0xf3000000)
- continue;
- if (!region || resource_size(r) > resource_size(region))
- region = r;
- }
- /* Nothing found, bail */
- if (region == 0)
- return;
-
- /* Print things out */
- printk(KERN_INFO "PCI: Fixup U4 PCIe bridge range: %pR\n", region);
-
- /* Fixup bridge config space. We know it's a Mac, resource aren't
- * offset so let's just blast them as-is. We also know that they
- * fit in 32 bits
- */
- reg = ((region->start >> 16) & 0xfff0) | (region->end & 0xfff00000);
- pci_write_config_dword(dev, PCI_MEMORY_BASE, reg);
- pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0);
- pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
- pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0);
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_U4_PCIE, fixup_u4_pcie);
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_base.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_base.c
deleted file mode 100644
index f5e3cda6..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_base.c
+++ /dev/null
@@ -1,409 +0,0 @@
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-
-#include <asm/pmac_feature.h>
-#include <asm/pmac_pfunc.h>
-
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-static irqreturn_t macio_gpio_irq(int irq, void *data)
-{
- pmf_do_irq(data);
-
- return IRQ_HANDLED;
-}
-
-static int macio_do_gpio_irq_enable(struct pmf_function *func)
-{
- unsigned int irq = irq_of_parse_and_map(func->node, 0);
- if (irq == NO_IRQ)
- return -EINVAL;
- return request_irq(irq, macio_gpio_irq, 0, func->node->name, func);
-}
-
-static int macio_do_gpio_irq_disable(struct pmf_function *func)
-{
- unsigned int irq = irq_of_parse_and_map(func->node, 0);
- if (irq == NO_IRQ)
- return -EINVAL;
- free_irq(irq, func);
- return 0;
-}
-
-static int macio_do_gpio_write(PMF_STD_ARGS, u8 value, u8 mask)
-{
- u8 __iomem *addr = (u8 __iomem *)func->driver_data;
- unsigned long flags;
- u8 tmp;
-
- /* Check polarity */
- if (args && args->count && !args->u[0].v)
- value = ~value;
-
- /* Toggle the GPIO */
- raw_spin_lock_irqsave(&feature_lock, flags);
- tmp = readb(addr);
- tmp = (tmp & ~mask) | (value & mask);
- DBG("Do write 0x%02x to GPIO %s (%p)\n",
- tmp, func->node->full_name, addr);
- writeb(tmp, addr);
- raw_spin_unlock_irqrestore(&feature_lock, flags);
-
- return 0;
-}
-
-static int macio_do_gpio_read(PMF_STD_ARGS, u8 mask, int rshift, u8 xor)
-{
- u8 __iomem *addr = (u8 __iomem *)func->driver_data;
- u32 value;
-
- /* Check if we have room for reply */
- if (args == NULL || args->count == 0 || args->u[0].p == NULL)
- return -EINVAL;
-
- value = readb(addr);
- *args->u[0].p = ((value & mask) >> rshift) ^ xor;
-
- return 0;
-}
-
-static int macio_do_delay(PMF_STD_ARGS, u32 duration)
-{
- /* assume we can sleep ! */
- msleep((duration + 999) / 1000);
- return 0;
-}
-
-static struct pmf_handlers macio_gpio_handlers = {
- .irq_enable = macio_do_gpio_irq_enable,
- .irq_disable = macio_do_gpio_irq_disable,
- .write_gpio = macio_do_gpio_write,
- .read_gpio = macio_do_gpio_read,
- .delay = macio_do_delay,
-};
-
-static void macio_gpio_init_one(struct macio_chip *macio)
-{
- struct device_node *gparent, *gp;
-
- /*
- * Find the "gpio" parent node
- */
-
- for (gparent = NULL;
- (gparent = of_get_next_child(macio->of_node, gparent)) != NULL;)
- if (strcmp(gparent->name, "gpio") == 0)
- break;
- if (gparent == NULL)
- return;
-
- DBG("Installing GPIO functions for macio %s\n",
- macio->of_node->full_name);
-
- /*
- * Ok, got one, we dont need anything special to track them down, so
- * we just create them all
- */
- for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;) {
- const u32 *reg = of_get_property(gp, "reg", NULL);
- unsigned long offset;
- if (reg == NULL)
- continue;
- offset = *reg;
- /* Deal with old style device-tree. We can safely hard code the
- * offset for now too even if it's a bit gross ...
- */
- if (offset < 0x50)
- offset += 0x50;
- offset += (unsigned long)macio->base;
- pmf_register_driver(gp, &macio_gpio_handlers, (void *)offset);
- }
-
- DBG("Calling initial GPIO functions for macio %s\n",
- macio->of_node->full_name);
-
- /* And now we run all the init ones */
- for (gp = NULL; (gp = of_get_next_child(gparent, gp)) != NULL;)
- pmf_do_functions(gp, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
-
- /* Note: We do not at this point implement the "at sleep" or "at wake"
- * functions. I yet to find any for GPIOs anyway
- */
-}
-
-static int macio_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
-{
- struct macio_chip *macio = func->driver_data;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&feature_lock, flags);
- MACIO_OUT32(offset, (MACIO_IN32(offset) & ~mask) | (value & mask));
- raw_spin_unlock_irqrestore(&feature_lock, flags);
- return 0;
-}
-
-static int macio_do_read_reg32(PMF_STD_ARGS, u32 offset)
-{
- struct macio_chip *macio = func->driver_data;
-
- /* Check if we have room for reply */
- if (args == NULL || args->count == 0 || args->u[0].p == NULL)
- return -EINVAL;
-
- *args->u[0].p = MACIO_IN32(offset);
- return 0;
-}
-
-static int macio_do_write_reg8(PMF_STD_ARGS, u32 offset, u8 value, u8 mask)
-{
- struct macio_chip *macio = func->driver_data;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&feature_lock, flags);
- MACIO_OUT8(offset, (MACIO_IN8(offset) & ~mask) | (value & mask));
- raw_spin_unlock_irqrestore(&feature_lock, flags);
- return 0;
-}
-
-static int macio_do_read_reg8(PMF_STD_ARGS, u32 offset)
-{
- struct macio_chip *macio = func->driver_data;
-
- /* Check if we have room for reply */
- if (args == NULL || args->count == 0 || args->u[0].p == NULL)
- return -EINVAL;
-
- *((u8 *)(args->u[0].p)) = MACIO_IN8(offset);
- return 0;
-}
-
-static int macio_do_read_reg32_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
- u32 shift, u32 xor)
-{
- struct macio_chip *macio = func->driver_data;
-
- /* Check if we have room for reply */
- if (args == NULL || args->count == 0 || args->u[0].p == NULL)
- return -EINVAL;
-
- *args->u[0].p = ((MACIO_IN32(offset) & mask) >> shift) ^ xor;
- return 0;
-}
-
-static int macio_do_read_reg8_msrx(PMF_STD_ARGS, u32 offset, u32 mask,
- u32 shift, u32 xor)
-{
- struct macio_chip *macio = func->driver_data;
-
- /* Check if we have room for reply */
- if (args == NULL || args->count == 0 || args->u[0].p == NULL)
- return -EINVAL;
-
- *((u8 *)(args->u[0].p)) = ((MACIO_IN8(offset) & mask) >> shift) ^ xor;
- return 0;
-}
-
-static int macio_do_write_reg32_slm(PMF_STD_ARGS, u32 offset, u32 shift,
- u32 mask)
-{
- struct macio_chip *macio = func->driver_data;
- unsigned long flags;
- u32 tmp, val;
-
- /* Check args */
- if (args == NULL || args->count == 0)
- return -EINVAL;
-
- raw_spin_lock_irqsave(&feature_lock, flags);
- tmp = MACIO_IN32(offset);
- val = args->u[0].v << shift;
- tmp = (tmp & ~mask) | (val & mask);
- MACIO_OUT32(offset, tmp);
- raw_spin_unlock_irqrestore(&feature_lock, flags);
- return 0;
-}
-
-static int macio_do_write_reg8_slm(PMF_STD_ARGS, u32 offset, u32 shift,
- u32 mask)
-{
- struct macio_chip *macio = func->driver_data;
- unsigned long flags;
- u32 tmp, val;
-
- /* Check args */
- if (args == NULL || args->count == 0)
- return -EINVAL;
-
- raw_spin_lock_irqsave(&feature_lock, flags);
- tmp = MACIO_IN8(offset);
- val = args->u[0].v << shift;
- tmp = (tmp & ~mask) | (val & mask);
- MACIO_OUT8(offset, tmp);
- raw_spin_unlock_irqrestore(&feature_lock, flags);
- return 0;
-}
-
-static struct pmf_handlers macio_mmio_handlers = {
- .write_reg32 = macio_do_write_reg32,
- .read_reg32 = macio_do_read_reg32,
- .write_reg8 = macio_do_write_reg8,
- .read_reg8 = macio_do_read_reg8,
- .read_reg32_msrx = macio_do_read_reg32_msrx,
- .read_reg8_msrx = macio_do_read_reg8_msrx,
- .write_reg32_slm = macio_do_write_reg32_slm,
- .write_reg8_slm = macio_do_write_reg8_slm,
- .delay = macio_do_delay,
-};
-
-static void macio_mmio_init_one(struct macio_chip *macio)
-{
- DBG("Installing MMIO functions for macio %s\n",
- macio->of_node->full_name);
-
- pmf_register_driver(macio->of_node, &macio_mmio_handlers, macio);
-}
-
-static struct device_node *unin_hwclock;
-
-static int unin_do_write_reg32(PMF_STD_ARGS, u32 offset, u32 value, u32 mask)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&feature_lock, flags);
- /* This is fairly bogus in darwin, but it should work for our needs
- * implemeted that way:
- */
- UN_OUT(offset, (UN_IN(offset) & ~mask) | (value & mask));
- raw_spin_unlock_irqrestore(&feature_lock, flags);
- return 0;
-}
-
-
-static struct pmf_handlers unin_mmio_handlers = {
- .write_reg32 = unin_do_write_reg32,
- .delay = macio_do_delay,
-};
-
-static void uninorth_install_pfunc(void)
-{
- struct device_node *np;
-
- DBG("Installing functions for UniN %s\n",
- uninorth_node->full_name);
-
- /*
- * Install handlers for the bridge itself
- */
- pmf_register_driver(uninorth_node, &unin_mmio_handlers, NULL);
- pmf_do_functions(uninorth_node, NULL, 0, PMF_FLAGS_ON_INIT, NULL);
-
-
- /*
- * Install handlers for the hwclock child if any
- */
- for (np = NULL; (np = of_get_next_child(uninorth_node, np)) != NULL;)
- if (strcmp(np->name, "hw-clock") == 0) {
- unin_hwclock = np;
- break;
- }
- if (unin_hwclock) {
- DBG("Installing functions for UniN clock %s\n",
- unin_hwclock->full_name);
- pmf_register_driver(unin_hwclock, &unin_mmio_handlers, NULL);
- pmf_do_functions(unin_hwclock, NULL, 0, PMF_FLAGS_ON_INIT,
- NULL);
- }
-}
-
-/* We export this as the SMP code might init us early */
-int __init pmac_pfunc_base_install(void)
-{
- static int pfbase_inited;
- int i;
-
- if (pfbase_inited)
- return 0;
- pfbase_inited = 1;
-
- if (!machine_is(powermac))
- return 0;
-
- DBG("Installing base platform functions...\n");
-
- /*
- * Locate mac-io chips and install handlers
- */
- for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
- if (macio_chips[i].of_node) {
- macio_mmio_init_one(&macio_chips[i]);
- macio_gpio_init_one(&macio_chips[i]);
- }
- }
-
- /*
- * Install handlers for northbridge and direct mapped hwclock
- * if any. We do not implement the config space access callback
- * which is only ever used for functions that we do not call in
- * the current driver (enabling/disabling cells in U2, mostly used
- * to restore the PCI settings, we do that differently)
- */
- if (uninorth_node && uninorth_base)
- uninorth_install_pfunc();
-
- DBG("All base functions installed\n");
-
- return 0;
-}
-machine_arch_initcall(powermac, pmac_pfunc_base_install);
-
-#ifdef CONFIG_PM
-
-/* Those can be called by pmac_feature. Ultimately, I should use a sysdev
- * or a device, but for now, that's good enough until I sort out some
- * ordering issues. Also, we do not bother with GPIOs, as so far I yet have
- * to see a case where a GPIO function has the on-suspend or on-resume bit
- */
-void pmac_pfunc_base_suspend(void)
-{
- int i;
-
- for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
- if (macio_chips[i].of_node)
- pmf_do_functions(macio_chips[i].of_node, NULL, 0,
- PMF_FLAGS_ON_SLEEP, NULL);
- }
- if (uninorth_node)
- pmf_do_functions(uninorth_node, NULL, 0,
- PMF_FLAGS_ON_SLEEP, NULL);
- if (unin_hwclock)
- pmf_do_functions(unin_hwclock, NULL, 0,
- PMF_FLAGS_ON_SLEEP, NULL);
-}
-
-void pmac_pfunc_base_resume(void)
-{
- int i;
-
- if (unin_hwclock)
- pmf_do_functions(unin_hwclock, NULL, 0,
- PMF_FLAGS_ON_WAKE, NULL);
- if (uninorth_node)
- pmf_do_functions(uninorth_node, NULL, 0,
- PMF_FLAGS_ON_WAKE, NULL);
- for (i = 0 ; i < MAX_MACIO_CHIPS; i++) {
- if (macio_chips[i].of_node)
- pmf_do_functions(macio_chips[i].of_node, NULL, 0,
- PMF_FLAGS_ON_WAKE, NULL);
- }
-}
-
-#endif /* CONFIG_PM */
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_core.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_core.c
deleted file mode 100644
index b0c37775..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pfunc_core.c
+++ /dev/null
@@ -1,1022 +0,0 @@
-/*
- *
- * FIXME: Properly make this race free with refcounting etc...
- *
- * FIXME: LOCKING !!!
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-
-#include <asm/prom.h>
-#include <asm/pmac_pfunc.h>
-
-/* Debug */
-#define LOG_PARSE(fmt...)
-#define LOG_ERROR(fmt...) printk(fmt)
-#define LOG_BLOB(t,b,c)
-
-#undef DEBUG
-#ifdef DEBUG
-#define DBG(fmt...) printk(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/* Command numbers */
-#define PMF_CMD_LIST 0
-#define PMF_CMD_WRITE_GPIO 1
-#define PMF_CMD_READ_GPIO 2
-#define PMF_CMD_WRITE_REG32 3
-#define PMF_CMD_READ_REG32 4
-#define PMF_CMD_WRITE_REG16 5
-#define PMF_CMD_READ_REG16 6
-#define PMF_CMD_WRITE_REG8 7
-#define PMF_CMD_READ_REG8 8
-#define PMF_CMD_DELAY 9
-#define PMF_CMD_WAIT_REG32 10
-#define PMF_CMD_WAIT_REG16 11
-#define PMF_CMD_WAIT_REG8 12
-#define PMF_CMD_READ_I2C 13
-#define PMF_CMD_WRITE_I2C 14
-#define PMF_CMD_RMW_I2C 15
-#define PMF_CMD_GEN_I2C 16
-#define PMF_CMD_SHIFT_BYTES_RIGHT 17
-#define PMF_CMD_SHIFT_BYTES_LEFT 18
-#define PMF_CMD_READ_CFG 19
-#define PMF_CMD_WRITE_CFG 20
-#define PMF_CMD_RMW_CFG 21
-#define PMF_CMD_READ_I2C_SUBADDR 22
-#define PMF_CMD_WRITE_I2C_SUBADDR 23
-#define PMF_CMD_SET_I2C_MODE 24
-#define PMF_CMD_RMW_I2C_SUBADDR 25
-#define PMF_CMD_READ_REG32_MASK_SHR_XOR 26
-#define PMF_CMD_READ_REG16_MASK_SHR_XOR 27
-#define PMF_CMD_READ_REG8_MASK_SHR_XOR 28
-#define PMF_CMD_WRITE_REG32_SHL_MASK 29
-#define PMF_CMD_WRITE_REG16_SHL_MASK 30
-#define PMF_CMD_WRITE_REG8_SHL_MASK 31
-#define PMF_CMD_MASK_AND_COMPARE 32
-#define PMF_CMD_COUNT 33
-
-/* This structure holds the state of the parser while walking through
- * a function definition
- */
-struct pmf_cmd {
- const void *cmdptr;
- const void *cmdend;
- struct pmf_function *func;
- void *instdata;
- struct pmf_args *args;
- int error;
-};
-
-#if 0
-/* Debug output */
-static void print_blob(const char *title, const void *blob, int bytes)
-{
- printk("%s", title);
- while(bytes--) {
- printk("%02x ", *((u8 *)blob));
- blob += 1;
- }
- printk("\n");
-}
-#endif
-
-/*
- * Parser helpers
- */
-
-static u32 pmf_next32(struct pmf_cmd *cmd)
-{
- u32 value;
- if ((cmd->cmdend - cmd->cmdptr) < 4) {
- cmd->error = 1;
- return 0;
- }
- value = *((u32 *)cmd->cmdptr);
- cmd->cmdptr += 4;
- return value;
-}
-
-static const void* pmf_next_blob(struct pmf_cmd *cmd, int count)
-{
- const void *value;
- if ((cmd->cmdend - cmd->cmdptr) < count) {
- cmd->error = 1;
- return NULL;
- }
- value = cmd->cmdptr;
- cmd->cmdptr += count;
- return value;
-}
-
-/*
- * Individual command parsers
- */
-
-#define PMF_PARSE_CALL(name, cmd, handlers, p...) \
- do { \
- if (cmd->error) \
- return -ENXIO; \
- if (handlers == NULL) \
- return 0; \
- if (handlers->name) \
- return handlers->name(cmd->func, cmd->instdata, \
- cmd->args, p); \
- return -1; \
- } while(0) \
-
-
-static int pmf_parser_write_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u8 value = (u8)pmf_next32(cmd);
- u8 mask = (u8)pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_gpio(value: %02x, mask: %02x)\n", value, mask);
-
- PMF_PARSE_CALL(write_gpio, cmd, h, value, mask);
-}
-
-static int pmf_parser_read_gpio(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u8 mask = (u8)pmf_next32(cmd);
- int rshift = (int)pmf_next32(cmd);
- u8 xor = (u8)pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_gpio(mask: %02x, rshift: %d, xor: %02x)\n",
- mask, rshift, xor);
-
- PMF_PARSE_CALL(read_gpio, cmd, h, mask, rshift, xor);
-}
-
-static int pmf_parser_write_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 value = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg32(offset: %08x, value: %08x, mask: %08x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(write_reg32, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_read_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg32(offset: %08x)\n", offset);
-
- PMF_PARSE_CALL(read_reg32, cmd, h, offset);
-}
-
-
-static int pmf_parser_write_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u16 value = (u16)pmf_next32(cmd);
- u16 mask = (u16)pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg16(offset: %08x, value: %04x, mask: %04x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(write_reg16, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_read_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg16(offset: %08x)\n", offset);
-
- PMF_PARSE_CALL(read_reg16, cmd, h, offset);
-}
-
-
-static int pmf_parser_write_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u8 value = (u16)pmf_next32(cmd);
- u8 mask = (u16)pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg8(offset: %08x, value: %02x, mask: %02x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(write_reg8, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_read_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg8(offset: %08x)\n", offset);
-
- PMF_PARSE_CALL(read_reg8, cmd, h, offset);
-}
-
-static int pmf_parser_delay(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 duration = pmf_next32(cmd);
-
- LOG_PARSE("pmf: delay(duration: %d us)\n", duration);
-
- PMF_PARSE_CALL(delay, cmd, h, duration);
-}
-
-static int pmf_parser_wait_reg32(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 value = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
-
- LOG_PARSE("pmf: wait_reg32(offset: %08x, comp_value: %08x,mask: %08x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(wait_reg32, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_wait_reg16(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u16 value = (u16)pmf_next32(cmd);
- u16 mask = (u16)pmf_next32(cmd);
-
- LOG_PARSE("pmf: wait_reg16(offset: %08x, comp_value: %04x,mask: %04x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(wait_reg16, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_wait_reg8(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u8 value = (u8)pmf_next32(cmd);
- u8 mask = (u8)pmf_next32(cmd);
-
- LOG_PARSE("pmf: wait_reg8(offset: %08x, comp_value: %02x,mask: %02x)\n",
- offset, value, mask);
-
- PMF_PARSE_CALL(wait_reg8, cmd, h, offset, value, mask);
-}
-
-static int pmf_parser_read_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 bytes = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_i2c(bytes: %ud)\n", bytes);
-
- PMF_PARSE_CALL(read_i2c, cmd, h, bytes);
-}
-
-static int pmf_parser_write_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 bytes = pmf_next32(cmd);
- const void *blob = pmf_next_blob(cmd, bytes);
-
- LOG_PARSE("pmf: write_i2c(bytes: %ud) ...\n", bytes);
- LOG_BLOB("pmf: data: \n", blob, bytes);
-
- PMF_PARSE_CALL(write_i2c, cmd, h, bytes, blob);
-}
-
-
-static int pmf_parser_rmw_i2c(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 maskbytes = pmf_next32(cmd);
- u32 valuesbytes = pmf_next32(cmd);
- u32 totalbytes = pmf_next32(cmd);
- const void *maskblob = pmf_next_blob(cmd, maskbytes);
- const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
-
- LOG_PARSE("pmf: rmw_i2c(maskbytes: %ud, valuebytes: %ud, "
- "totalbytes: %d) ...\n",
- maskbytes, valuesbytes, totalbytes);
- LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
- LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
-
- PMF_PARSE_CALL(rmw_i2c, cmd, h, maskbytes, valuesbytes, totalbytes,
- maskblob, valuesblob);
-}
-
-static int pmf_parser_read_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 bytes = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
-
- PMF_PARSE_CALL(read_cfg, cmd, h, offset, bytes);
-}
-
-
-static int pmf_parser_write_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 bytes = pmf_next32(cmd);
- const void *blob = pmf_next_blob(cmd, bytes);
-
- LOG_PARSE("pmf: write_cfg(offset: %x, bytes: %ud)\n", offset, bytes);
- LOG_BLOB("pmf: data: \n", blob, bytes);
-
- PMF_PARSE_CALL(write_cfg, cmd, h, offset, bytes, blob);
-}
-
-static int pmf_parser_rmw_cfg(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 maskbytes = pmf_next32(cmd);
- u32 valuesbytes = pmf_next32(cmd);
- u32 totalbytes = pmf_next32(cmd);
- const void *maskblob = pmf_next_blob(cmd, maskbytes);
- const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
-
- LOG_PARSE("pmf: rmw_cfg(maskbytes: %ud, valuebytes: %ud,"
- " totalbytes: %d) ...\n",
- maskbytes, valuesbytes, totalbytes);
- LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
- LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
-
- PMF_PARSE_CALL(rmw_cfg, cmd, h, offset, maskbytes, valuesbytes,
- totalbytes, maskblob, valuesblob);
-}
-
-
-static int pmf_parser_read_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u8 subaddr = (u8)pmf_next32(cmd);
- u32 bytes = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_i2c_sub(subaddr: %x, bytes: %ud)\n",
- subaddr, bytes);
-
- PMF_PARSE_CALL(read_i2c_sub, cmd, h, subaddr, bytes);
-}
-
-static int pmf_parser_write_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u8 subaddr = (u8)pmf_next32(cmd);
- u32 bytes = pmf_next32(cmd);
- const void *blob = pmf_next_blob(cmd, bytes);
-
- LOG_PARSE("pmf: write_i2c_sub(subaddr: %x, bytes: %ud) ...\n",
- subaddr, bytes);
- LOG_BLOB("pmf: data: \n", blob, bytes);
-
- PMF_PARSE_CALL(write_i2c_sub, cmd, h, subaddr, bytes, blob);
-}
-
-static int pmf_parser_set_i2c_mode(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u32 mode = pmf_next32(cmd);
-
- LOG_PARSE("pmf: set_i2c_mode(mode: %d)\n", mode);
-
- PMF_PARSE_CALL(set_i2c_mode, cmd, h, mode);
-}
-
-
-static int pmf_parser_rmw_i2c_sub(struct pmf_cmd *cmd, struct pmf_handlers *h)
-{
- u8 subaddr = (u8)pmf_next32(cmd);
- u32 maskbytes = pmf_next32(cmd);
- u32 valuesbytes = pmf_next32(cmd);
- u32 totalbytes = pmf_next32(cmd);
- const void *maskblob = pmf_next_blob(cmd, maskbytes);
- const void *valuesblob = pmf_next_blob(cmd, valuesbytes);
-
- LOG_PARSE("pmf: rmw_i2c_sub(subaddr: %x, maskbytes: %ud, valuebytes: %ud"
- ", totalbytes: %d) ...\n",
- subaddr, maskbytes, valuesbytes, totalbytes);
- LOG_BLOB("pmf: mask data: \n", maskblob, maskbytes);
- LOG_BLOB("pmf: values data: \n", valuesblob, valuesbytes);
-
- PMF_PARSE_CALL(rmw_i2c_sub, cmd, h, subaddr, maskbytes, valuesbytes,
- totalbytes, maskblob, valuesblob);
-}
-
-static int pmf_parser_read_reg32_msrx(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 xor = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg32_msrx(offset: %x, mask: %x, shift: %x,"
- " xor: %x\n", offset, mask, shift, xor);
-
- PMF_PARSE_CALL(read_reg32_msrx, cmd, h, offset, mask, shift, xor);
-}
-
-static int pmf_parser_read_reg16_msrx(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 xor = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg16_msrx(offset: %x, mask: %x, shift: %x,"
- " xor: %x\n", offset, mask, shift, xor);
-
- PMF_PARSE_CALL(read_reg16_msrx, cmd, h, offset, mask, shift, xor);
-}
-static int pmf_parser_read_reg8_msrx(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 xor = pmf_next32(cmd);
-
- LOG_PARSE("pmf: read_reg8_msrx(offset: %x, mask: %x, shift: %x,"
- " xor: %x\n", offset, mask, shift, xor);
-
- PMF_PARSE_CALL(read_reg8_msrx, cmd, h, offset, mask, shift, xor);
-}
-
-static int pmf_parser_write_reg32_slm(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg32_slm(offset: %x, shift: %x, mask: %x\n",
- offset, shift, mask);
-
- PMF_PARSE_CALL(write_reg32_slm, cmd, h, offset, shift, mask);
-}
-
-static int pmf_parser_write_reg16_slm(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg16_slm(offset: %x, shift: %x, mask: %x\n",
- offset, shift, mask);
-
- PMF_PARSE_CALL(write_reg16_slm, cmd, h, offset, shift, mask);
-}
-
-static int pmf_parser_write_reg8_slm(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 offset = pmf_next32(cmd);
- u32 shift = pmf_next32(cmd);
- u32 mask = pmf_next32(cmd);
-
- LOG_PARSE("pmf: write_reg8_slm(offset: %x, shift: %x, mask: %x\n",
- offset, shift, mask);
-
- PMF_PARSE_CALL(write_reg8_slm, cmd, h, offset, shift, mask);
-}
-
-static int pmf_parser_mask_and_compare(struct pmf_cmd *cmd,
- struct pmf_handlers *h)
-{
- u32 bytes = pmf_next32(cmd);
- const void *maskblob = pmf_next_blob(cmd, bytes);
- const void *valuesblob = pmf_next_blob(cmd, bytes);
-
- LOG_PARSE("pmf: mask_and_compare(length: %ud ...\n", bytes);
- LOG_BLOB("pmf: mask data: \n", maskblob, bytes);
- LOG_BLOB("pmf: values data: \n", valuesblob, bytes);
-
- PMF_PARSE_CALL(mask_and_compare, cmd, h,
- bytes, maskblob, valuesblob);
-}
-
-
-typedef int (*pmf_cmd_parser_t)(struct pmf_cmd *cmd, struct pmf_handlers *h);
-
-static pmf_cmd_parser_t pmf_parsers[PMF_CMD_COUNT] =
-{
- NULL,
- pmf_parser_write_gpio,
- pmf_parser_read_gpio,
- pmf_parser_write_reg32,
- pmf_parser_read_reg32,
- pmf_parser_write_reg16,
- pmf_parser_read_reg16,
- pmf_parser_write_reg8,
- pmf_parser_read_reg8,
- pmf_parser_delay,
- pmf_parser_wait_reg32,
- pmf_parser_wait_reg16,
- pmf_parser_wait_reg8,
- pmf_parser_read_i2c,
- pmf_parser_write_i2c,
- pmf_parser_rmw_i2c,
- NULL, /* Bogus command */
- NULL, /* Shift bytes right: NYI */
- NULL, /* Shift bytes left: NYI */
- pmf_parser_read_cfg,
- pmf_parser_write_cfg,
- pmf_parser_rmw_cfg,
- pmf_parser_read_i2c_sub,
- pmf_parser_write_i2c_sub,
- pmf_parser_set_i2c_mode,
- pmf_parser_rmw_i2c_sub,
- pmf_parser_read_reg32_msrx,
- pmf_parser_read_reg16_msrx,
- pmf_parser_read_reg8_msrx,
- pmf_parser_write_reg32_slm,
- pmf_parser_write_reg16_slm,
- pmf_parser_write_reg8_slm,
- pmf_parser_mask_and_compare,
-};
-
-struct pmf_device {
- struct list_head link;
- struct device_node *node;
- struct pmf_handlers *handlers;
- struct list_head functions;
- struct kref ref;
-};
-
-static LIST_HEAD(pmf_devices);
-static DEFINE_SPINLOCK(pmf_lock);
-static DEFINE_MUTEX(pmf_irq_mutex);
-
-static void pmf_release_device(struct kref *kref)
-{
- struct pmf_device *dev = container_of(kref, struct pmf_device, ref);
- kfree(dev);
-}
-
-static inline void pmf_put_device(struct pmf_device *dev)
-{
- kref_put(&dev->ref, pmf_release_device);
-}
-
-static inline struct pmf_device *pmf_get_device(struct pmf_device *dev)
-{
- kref_get(&dev->ref);
- return dev;
-}
-
-static inline struct pmf_device *pmf_find_device(struct device_node *np)
-{
- struct pmf_device *dev;
-
- list_for_each_entry(dev, &pmf_devices, link) {
- if (dev->node == np)
- return pmf_get_device(dev);
- }
- return NULL;
-}
-
-static int pmf_parse_one(struct pmf_function *func,
- struct pmf_handlers *handlers,
- void *instdata, struct pmf_args *args)
-{
- struct pmf_cmd cmd;
- u32 ccode;
- int count, rc;
-
- cmd.cmdptr = func->data;
- cmd.cmdend = func->data + func->length;
- cmd.func = func;
- cmd.instdata = instdata;
- cmd.args = args;
- cmd.error = 0;
-
- LOG_PARSE("pmf: func %s, %d bytes, %s...\n",
- func->name, func->length,
- handlers ? "executing" : "parsing");
-
- /* One subcommand to parse for now */
- count = 1;
-
- while(count-- && cmd.cmdptr < cmd.cmdend) {
- /* Get opcode */
- ccode = pmf_next32(&cmd);
- /* Check if we are hitting a command list, fetch new count */
- if (ccode == 0) {
- count = pmf_next32(&cmd) - 1;
- ccode = pmf_next32(&cmd);
- }
- if (cmd.error) {
- LOG_ERROR("pmf: parse error, not enough data\n");
- return -ENXIO;
- }
- if (ccode >= PMF_CMD_COUNT) {
- LOG_ERROR("pmf: command code %d unknown !\n", ccode);
- return -ENXIO;
- }
- if (pmf_parsers[ccode] == NULL) {
- LOG_ERROR("pmf: no parser for command %d !\n", ccode);
- return -ENXIO;
- }
- rc = pmf_parsers[ccode](&cmd, handlers);
- if (rc != 0) {
- LOG_ERROR("pmf: parser for command %d returned"
- " error %d\n", ccode, rc);
- return rc;
- }
- }
-
- /* We are doing an initial parse pass, we need to adjust the size */
- if (handlers == NULL)
- func->length = cmd.cmdptr - func->data;
-
- return 0;
-}
-
-static int pmf_add_function_prop(struct pmf_device *dev, void *driverdata,
- const char *name, u32 *data,
- unsigned int length)
-{
- int count = 0;
- struct pmf_function *func = NULL;
-
- DBG("pmf: Adding functions for platform-do-%s\n", name);
-
- while (length >= 12) {
- /* Allocate a structure */
- func = kzalloc(sizeof(struct pmf_function), GFP_KERNEL);
- if (func == NULL)
- goto bail;
- kref_init(&func->ref);
- INIT_LIST_HEAD(&func->irq_clients);
- func->node = dev->node;
- func->driver_data = driverdata;
- func->name = name;
- func->phandle = data[0];
- func->flags = data[1];
- data += 2;
- length -= 8;
- func->data = data;
- func->length = length;
- func->dev = dev;
- DBG("pmf: idx %d: flags=%08x, phandle=%08x "
- " %d bytes remaining, parsing...\n",
- count+1, func->flags, func->phandle, length);
- if (pmf_parse_one(func, NULL, NULL, NULL)) {
- kfree(func);
- goto bail;
- }
- length -= func->length;
- data = (u32 *)(((u8 *)data) + func->length);
- list_add(&func->link, &dev->functions);
- pmf_get_device(dev);
- count++;
- }
- bail:
- DBG("pmf: Added %d functions\n", count);
-
- return count;
-}
-
-static int pmf_add_functions(struct pmf_device *dev, void *driverdata)
-{
- struct property *pp;
-#define PP_PREFIX "platform-do-"
- const int plen = strlen(PP_PREFIX);
- int count = 0;
-
- for (pp = dev->node->properties; pp != 0; pp = pp->next) {
- char *name;
- if (strncmp(pp->name, PP_PREFIX, plen) != 0)
- continue;
- name = pp->name + plen;
- if (strlen(name) && pp->length >= 12)
- count += pmf_add_function_prop(dev, driverdata, name,
- pp->value, pp->length);
- }
- return count;
-}
-
-
-int pmf_register_driver(struct device_node *np,
- struct pmf_handlers *handlers,
- void *driverdata)
-{
- struct pmf_device *dev;
- unsigned long flags;
- int rc = 0;
-
- if (handlers == NULL)
- return -EINVAL;
-
- DBG("pmf: registering driver for node %s\n", np->full_name);
-
- spin_lock_irqsave(&pmf_lock, flags);
- dev = pmf_find_device(np);
- spin_unlock_irqrestore(&pmf_lock, flags);
- if (dev != NULL) {
- DBG("pmf: already there !\n");
- pmf_put_device(dev);
- return -EBUSY;
- }
-
- dev = kzalloc(sizeof(struct pmf_device), GFP_KERNEL);
- if (dev == NULL) {
- DBG("pmf: no memory !\n");
- return -ENOMEM;
- }
- kref_init(&dev->ref);
- dev->node = of_node_get(np);
- dev->handlers = handlers;
- INIT_LIST_HEAD(&dev->functions);
-
- rc = pmf_add_functions(dev, driverdata);
- if (rc == 0) {
- DBG("pmf: no functions, disposing.. \n");
- of_node_put(np);
- kfree(dev);
- return -ENODEV;
- }
-
- spin_lock_irqsave(&pmf_lock, flags);
- list_add(&dev->link, &pmf_devices);
- spin_unlock_irqrestore(&pmf_lock, flags);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(pmf_register_driver);
-
-struct pmf_function *pmf_get_function(struct pmf_function *func)
-{
- if (!try_module_get(func->dev->handlers->owner))
- return NULL;
- kref_get(&func->ref);
- return func;
-}
-EXPORT_SYMBOL_GPL(pmf_get_function);
-
-static void pmf_release_function(struct kref *kref)
-{
- struct pmf_function *func =
- container_of(kref, struct pmf_function, ref);
- pmf_put_device(func->dev);
- kfree(func);
-}
-
-static inline void __pmf_put_function(struct pmf_function *func)
-{
- kref_put(&func->ref, pmf_release_function);
-}
-
-void pmf_put_function(struct pmf_function *func)
-{
- if (func == NULL)
- return;
- module_put(func->dev->handlers->owner);
- __pmf_put_function(func);
-}
-EXPORT_SYMBOL_GPL(pmf_put_function);
-
-void pmf_unregister_driver(struct device_node *np)
-{
- struct pmf_device *dev;
- unsigned long flags;
-
- DBG("pmf: unregistering driver for node %s\n", np->full_name);
-
- spin_lock_irqsave(&pmf_lock, flags);
- dev = pmf_find_device(np);
- if (dev == NULL) {
- DBG("pmf: not such driver !\n");
- spin_unlock_irqrestore(&pmf_lock, flags);
- return;
- }
- list_del(&dev->link);
-
- while(!list_empty(&dev->functions)) {
- struct pmf_function *func =
- list_entry(dev->functions.next, typeof(*func), link);
- list_del(&func->link);
- __pmf_put_function(func);
- }
-
- pmf_put_device(dev);
- spin_unlock_irqrestore(&pmf_lock, flags);
-}
-EXPORT_SYMBOL_GPL(pmf_unregister_driver);
-
-struct pmf_function *__pmf_find_function(struct device_node *target,
- const char *name, u32 flags)
-{
- struct device_node *actor = of_node_get(target);
- struct pmf_device *dev;
- struct pmf_function *func, *result = NULL;
- char fname[64];
- const u32 *prop;
- u32 ph;
-
- /*
- * Look for a "platform-*" function reference. If we can't find
- * one, then we fallback to a direct call attempt
- */
- snprintf(fname, 63, "platform-%s", name);
- prop = of_get_property(target, fname, NULL);
- if (prop == NULL)
- goto find_it;
- ph = *prop;
- if (ph == 0)
- goto find_it;
-
- /*
- * Ok, now try to find the actor. If we can't find it, we fail,
- * there is no point in falling back there
- */
- of_node_put(actor);
- actor = of_find_node_by_phandle(ph);
- if (actor == NULL)
- return NULL;
- find_it:
- dev = pmf_find_device(actor);
- if (dev == NULL) {
- result = NULL;
- goto out;
- }
-
- list_for_each_entry(func, &dev->functions, link) {
- if (name && strcmp(name, func->name))
- continue;
- if (func->phandle && target->phandle != func->phandle)
- continue;
- if ((func->flags & flags) == 0)
- continue;
- result = func;
- break;
- }
- pmf_put_device(dev);
-out:
- of_node_put(actor);
- return result;
-}
-
-
-int pmf_register_irq_client(struct device_node *target,
- const char *name,
- struct pmf_irq_client *client)
-{
- struct pmf_function *func;
- unsigned long flags;
-
- spin_lock_irqsave(&pmf_lock, flags);
- func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN);
- if (func)
- func = pmf_get_function(func);
- spin_unlock_irqrestore(&pmf_lock, flags);
- if (func == NULL)
- return -ENODEV;
-
- /* guard against manipulations of list */
- mutex_lock(&pmf_irq_mutex);
- if (list_empty(&func->irq_clients))
- func->dev->handlers->irq_enable(func);
-
- /* guard against pmf_do_irq while changing list */
- spin_lock_irqsave(&pmf_lock, flags);
- list_add(&client->link, &func->irq_clients);
- spin_unlock_irqrestore(&pmf_lock, flags);
-
- client->func = func;
- mutex_unlock(&pmf_irq_mutex);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(pmf_register_irq_client);
-
-void pmf_unregister_irq_client(struct pmf_irq_client *client)
-{
- struct pmf_function *func = client->func;
- unsigned long flags;
-
- BUG_ON(func == NULL);
-
- /* guard against manipulations of list */
- mutex_lock(&pmf_irq_mutex);
- client->func = NULL;
-
- /* guard against pmf_do_irq while changing list */
- spin_lock_irqsave(&pmf_lock, flags);
- list_del(&client->link);
- spin_unlock_irqrestore(&pmf_lock, flags);
-
- if (list_empty(&func->irq_clients))
- func->dev->handlers->irq_disable(func);
- mutex_unlock(&pmf_irq_mutex);
- pmf_put_function(func);
-}
-EXPORT_SYMBOL_GPL(pmf_unregister_irq_client);
-
-
-void pmf_do_irq(struct pmf_function *func)
-{
- unsigned long flags;
- struct pmf_irq_client *client;
-
- /* For now, using a spinlock over the whole function. Can be made
- * to drop the lock using 2 lists if necessary
- */
- spin_lock_irqsave(&pmf_lock, flags);
- list_for_each_entry(client, &func->irq_clients, link) {
- if (!try_module_get(client->owner))
- continue;
- client->handler(client->data);
- module_put(client->owner);
- }
- spin_unlock_irqrestore(&pmf_lock, flags);
-}
-EXPORT_SYMBOL_GPL(pmf_do_irq);
-
-
-int pmf_call_one(struct pmf_function *func, struct pmf_args *args)
-{
- struct pmf_device *dev = func->dev;
- void *instdata = NULL;
- int rc = 0;
-
- DBG(" ** pmf_call_one(%s/%s) **\n", dev->node->full_name, func->name);
-
- if (dev->handlers->begin)
- instdata = dev->handlers->begin(func, args);
- rc = pmf_parse_one(func, dev->handlers, instdata, args);
- if (dev->handlers->end)
- dev->handlers->end(func, instdata);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(pmf_call_one);
-
-int pmf_do_functions(struct device_node *np, const char *name,
- u32 phandle, u32 fflags, struct pmf_args *args)
-{
- struct pmf_device *dev;
- struct pmf_function *func, *tmp;
- unsigned long flags;
- int rc = -ENODEV;
-
- spin_lock_irqsave(&pmf_lock, flags);
-
- dev = pmf_find_device(np);
- if (dev == NULL) {
- spin_unlock_irqrestore(&pmf_lock, flags);
- return -ENODEV;
- }
- list_for_each_entry_safe(func, tmp, &dev->functions, link) {
- if (name && strcmp(name, func->name))
- continue;
- if (phandle && func->phandle && phandle != func->phandle)
- continue;
- if ((func->flags & fflags) == 0)
- continue;
- if (pmf_get_function(func) == NULL)
- continue;
- spin_unlock_irqrestore(&pmf_lock, flags);
- rc = pmf_call_one(func, args);
- pmf_put_function(func);
- spin_lock_irqsave(&pmf_lock, flags);
- }
- pmf_put_device(dev);
- spin_unlock_irqrestore(&pmf_lock, flags);
-
- return rc;
-}
-EXPORT_SYMBOL_GPL(pmf_do_functions);
-
-
-struct pmf_function *pmf_find_function(struct device_node *target,
- const char *name)
-{
- struct pmf_function *func;
- unsigned long flags;
-
- spin_lock_irqsave(&pmf_lock, flags);
- func = __pmf_find_function(target, name, PMF_FLAGS_ON_DEMAND);
- if (func)
- func = pmf_get_function(func);
- spin_unlock_irqrestore(&pmf_lock, flags);
- return func;
-}
-EXPORT_SYMBOL_GPL(pmf_find_function);
-
-int pmf_call_function(struct device_node *target, const char *name,
- struct pmf_args *args)
-{
- struct pmf_function *func = pmf_find_function(target, name);
- int rc;
-
- if (func == NULL)
- return -ENODEV;
-
- rc = pmf_call_one(func, args);
- pmf_put_function(func);
- return rc;
-}
-EXPORT_SYMBOL_GPL(pmf_call_function);
-
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pic.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pic.c
deleted file mode 100644
index c4e63057..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pic.c
+++ /dev/null
@@ -1,656 +0,0 @@
-/*
- * Support for the interrupt controllers found on Power Macintosh,
- * currently Apple's "Grand Central" interrupt controller in all
- * it's incarnations. OpenPIC support used on newer machines is
- * in a separate file
- *
- * Copyright (C) 1997 Paul Mackerras (paulus@samba.org)
- * Copyright (C) 2005 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- * IBM, Corp.
- *
- * 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.
- *
- */
-
-#include <linux/stddef.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/signal.h>
-#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/syscore_ops.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/prom.h>
-#include <asm/pci-bridge.h>
-#include <asm/time.h>
-#include <asm/pmac_feature.h>
-#include <asm/mpic.h>
-#include <asm/xmon.h>
-
-#include "pmac.h"
-
-#ifdef CONFIG_PPC32
-struct pmac_irq_hw {
- unsigned int event;
- unsigned int enable;
- unsigned int ack;
- unsigned int level;
-};
-
-/* Workaround flags for 32bit powermac machines */
-unsigned int of_irq_workarounds;
-struct device_node *of_irq_dflt_pic;
-
-/* Default addresses */
-static volatile struct pmac_irq_hw __iomem *pmac_irq_hw[4];
-
-static int max_irqs;
-static int max_real_irqs;
-
-static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
-
-/* The max irq number this driver deals with is 128; see max_irqs */
-static DECLARE_BITMAP(ppc_lost_interrupts, 128);
-static DECLARE_BITMAP(ppc_cached_irq_mask, 128);
-static int pmac_irq_cascade = -1;
-static struct irq_domain *pmac_pic_host;
-
-static void __pmac_retrigger(unsigned int irq_nr)
-{
- if (irq_nr >= max_real_irqs && pmac_irq_cascade > 0) {
- __set_bit(irq_nr, ppc_lost_interrupts);
- irq_nr = pmac_irq_cascade;
- mb();
- }
- if (!__test_and_set_bit(irq_nr, ppc_lost_interrupts)) {
- atomic_inc(&ppc_n_lost_interrupts);
- set_dec(1);
- }
-}
-
-static void pmac_mask_and_ack_irq(struct irq_data *d)
-{
- unsigned int src = irqd_to_hwirq(d);
- unsigned long bit = 1UL << (src & 0x1f);
- int i = src >> 5;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- __clear_bit(src, ppc_cached_irq_mask);
- if (__test_and_clear_bit(src, ppc_lost_interrupts))
- atomic_dec(&ppc_n_lost_interrupts);
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- do {
- /* make sure ack gets to controller before we enable
- interrupts */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static void pmac_ack_irq(struct irq_data *d)
-{
- unsigned int src = irqd_to_hwirq(d);
- unsigned long bit = 1UL << (src & 0x1f);
- int i = src >> 5;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- if (__test_and_clear_bit(src, ppc_lost_interrupts))
- atomic_dec(&ppc_n_lost_interrupts);
- out_le32(&pmac_irq_hw[i]->ack, bit);
- (void)in_le32(&pmac_irq_hw[i]->ack);
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static void __pmac_set_irq_mask(unsigned int irq_nr, int nokicklost)
-{
- unsigned long bit = 1UL << (irq_nr & 0x1f);
- int i = irq_nr >> 5;
-
- if ((unsigned)irq_nr >= max_irqs)
- return;
-
- /* enable unmasked interrupts */
- out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]);
-
- do {
- /* make sure mask gets to controller before we
- return to user */
- mb();
- } while((in_le32(&pmac_irq_hw[i]->enable) & bit)
- != (ppc_cached_irq_mask[i] & bit));
-
- /*
- * Unfortunately, setting the bit in the enable register
- * when the device interrupt is already on *doesn't* set
- * the bit in the flag register or request another interrupt.
- */
- if (bit & ppc_cached_irq_mask[i] & in_le32(&pmac_irq_hw[i]->level))
- __pmac_retrigger(irq_nr);
-}
-
-/* When an irq gets requested for the first client, if it's an
- * edge interrupt, we clear any previous one on the controller
- */
-static unsigned int pmac_startup_irq(struct irq_data *d)
-{
- unsigned long flags;
- unsigned int src = irqd_to_hwirq(d);
- unsigned long bit = 1UL << (src & 0x1f);
- int i = src >> 5;
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- if (!irqd_is_level_type(d))
- out_le32(&pmac_irq_hw[i]->ack, bit);
- __set_bit(src, ppc_cached_irq_mask);
- __pmac_set_irq_mask(src, 0);
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
-
- return 0;
-}
-
-static void pmac_mask_irq(struct irq_data *d)
-{
- unsigned long flags;
- unsigned int src = irqd_to_hwirq(d);
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- __clear_bit(src, ppc_cached_irq_mask);
- __pmac_set_irq_mask(src, 1);
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static void pmac_unmask_irq(struct irq_data *d)
-{
- unsigned long flags;
- unsigned int src = irqd_to_hwirq(d);
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- __set_bit(src, ppc_cached_irq_mask);
- __pmac_set_irq_mask(src, 0);
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
-}
-
-static int pmac_retrigger(struct irq_data *d)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- __pmac_retrigger(irqd_to_hwirq(d));
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
- return 1;
-}
-
-static struct irq_chip pmac_pic = {
- .name = "PMAC-PIC",
- .irq_startup = pmac_startup_irq,
- .irq_mask = pmac_mask_irq,
- .irq_ack = pmac_ack_irq,
- .irq_mask_ack = pmac_mask_and_ack_irq,
- .irq_unmask = pmac_unmask_irq,
- .irq_retrigger = pmac_retrigger,
-};
-
-static irqreturn_t gatwick_action(int cpl, void *dev_id)
-{
- unsigned long flags;
- int irq, bits;
- int rc = IRQ_NONE;
-
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- for (irq = max_irqs; (irq -= 32) >= max_real_irqs; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- bits |= in_le32(&pmac_irq_hw[i]->level);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
- generic_handle_irq(irq);
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- rc = IRQ_HANDLED;
- }
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
- return rc;
-}
-
-static unsigned int pmac_pic_get_irq(void)
-{
- int irq;
- unsigned long bits = 0;
- unsigned long flags;
-
-#ifdef CONFIG_PPC_PMAC32_PSURGE
- /* IPI's are a hack on the powersurge -- Cort */
- if (smp_processor_id() != 0) {
- return psurge_secondary_virq;
- }
-#endif /* CONFIG_PPC_PMAC32_PSURGE */
- raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- for (irq = max_real_irqs; (irq -= 32) >= 0; ) {
- int i = irq >> 5;
- bits = in_le32(&pmac_irq_hw[i]->event) | ppc_lost_interrupts[i];
- bits |= in_le32(&pmac_irq_hw[i]->level);
- bits &= ppc_cached_irq_mask[i];
- if (bits == 0)
- continue;
- irq += __ilog2(bits);
- break;
- }
- raw_spin_unlock_irqrestore(&pmac_pic_lock, flags);
- if (unlikely(irq < 0))
- return NO_IRQ;
- return irq_linear_revmap(pmac_pic_host, irq);
-}
-
-#ifdef CONFIG_XMON
-static struct irqaction xmon_action = {
- .handler = xmon_irq,
- .flags = 0,
- .name = "NMI - XMON"
-};
-#endif
-
-static struct irqaction gatwick_cascade_action = {
- .handler = gatwick_action,
- .name = "cascade",
-};
-
-static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
-{
- /* We match all, we don't always have a node anyway */
- return 1;
-}
-
-static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- if (hw >= max_irqs)
- return -EINVAL;
-
- /* Mark level interrupts, set delayed disable for edge ones and set
- * handlers
- */
- irq_set_status_flags(virq, IRQ_LEVEL);
- irq_set_chip_and_handler(virq, &pmac_pic, handle_level_irq);
- return 0;
-}
-
-static const struct irq_domain_ops pmac_pic_host_ops = {
- .match = pmac_pic_host_match,
- .map = pmac_pic_host_map,
- .xlate = irq_domain_xlate_onecell,
-};
-
-static void __init pmac_pic_probe_oldstyle(void)
-{
- int i;
- struct device_node *master = NULL;
- struct device_node *slave = NULL;
- u8 __iomem *addr;
- struct resource r;
-
- /* Set our get_irq function */
- ppc_md.get_irq = pmac_pic_get_irq;
-
- /*
- * Find the interrupt controller type & node
- */
-
- if ((master = of_find_node_by_name(NULL, "gc")) != NULL) {
- max_irqs = max_real_irqs = 32;
- } else if ((master = of_find_node_by_name(NULL, "ohare")) != NULL) {
- max_irqs = max_real_irqs = 32;
- /* We might have a second cascaded ohare */
- slave = of_find_node_by_name(NULL, "pci106b,7");
- if (slave)
- max_irqs = 64;
- } else if ((master = of_find_node_by_name(NULL, "mac-io")) != NULL) {
- max_irqs = max_real_irqs = 64;
-
- /* We might have a second cascaded heathrow */
- slave = of_find_node_by_name(master, "mac-io");
-
- /* Check ordering of master & slave */
- if (of_device_is_compatible(master, "gatwick")) {
- struct device_node *tmp;
- BUG_ON(slave == NULL);
- tmp = master;
- master = slave;
- slave = tmp;
- }
-
- /* We found a slave */
- if (slave)
- max_irqs = 128;
- }
- BUG_ON(master == NULL);
-
- /*
- * Allocate an irq host
- */
- pmac_pic_host = irq_domain_add_linear(master, max_irqs,
- &pmac_pic_host_ops, NULL);
- BUG_ON(pmac_pic_host == NULL);
- irq_set_default_host(pmac_pic_host);
-
- /* Get addresses of first controller if we have a node for it */
- BUG_ON(of_address_to_resource(master, 0, &r));
-
- /* Map interrupts of primary controller */
- addr = (u8 __iomem *) ioremap(r.start, 0x40);
- i = 0;
- pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
- (addr + 0x20);
- if (max_real_irqs > 32)
- pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
- (addr + 0x10);
- of_node_put(master);
-
- printk(KERN_INFO "irq: Found primary Apple PIC %s for %d irqs\n",
- master->full_name, max_real_irqs);
-
- /* Map interrupts of cascaded controller */
- if (slave && !of_address_to_resource(slave, 0, &r)) {
- addr = (u8 __iomem *)ioremap(r.start, 0x40);
- pmac_irq_hw[i++] = (volatile struct pmac_irq_hw __iomem *)
- (addr + 0x20);
- if (max_irqs > 64)
- pmac_irq_hw[i++] =
- (volatile struct pmac_irq_hw __iomem *)
- (addr + 0x10);
- pmac_irq_cascade = irq_of_parse_and_map(slave, 0);
-
- printk(KERN_INFO "irq: Found slave Apple PIC %s for %d irqs"
- " cascade: %d\n", slave->full_name,
- max_irqs - max_real_irqs, pmac_irq_cascade);
- }
- of_node_put(slave);
-
- /* Disable all interrupts in all controllers */
- for (i = 0; i * 32 < max_irqs; ++i)
- out_le32(&pmac_irq_hw[i]->enable, 0);
-
- /* Hookup cascade irq */
- if (slave && pmac_irq_cascade != NO_IRQ)
- setup_irq(pmac_irq_cascade, &gatwick_cascade_action);
-
- printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs);
-#ifdef CONFIG_XMON
- setup_irq(irq_create_mapping(NULL, 20), &xmon_action);
-#endif
-}
-
-int of_irq_map_oldworld(struct device_node *device, int index,
- struct of_irq *out_irq)
-{
- const u32 *ints = NULL;
- int intlen;
-
- /*
- * Old machines just have a list of interrupt numbers
- * and no interrupt-controller nodes. We also have dodgy
- * cases where the APPL,interrupts property is completely
- * missing behind pci-pci bridges and we have to get it
- * from the parent (the bridge itself, as apple just wired
- * everything together on these)
- */
- while (device) {
- ints = of_get_property(device, "AAPL,interrupts", &intlen);
- if (ints != NULL)
- break;
- device = device->parent;
- if (device && strcmp(device->type, "pci") != 0)
- break;
- }
- if (ints == NULL)
- return -EINVAL;
- intlen /= sizeof(u32);
-
- if (index >= intlen)
- return -EINVAL;
-
- out_irq->controller = NULL;
- out_irq->specifier[0] = ints[index];
- out_irq->size = 1;
-
- return 0;
-}
-#endif /* CONFIG_PPC32 */
-
-static void __init pmac_pic_setup_mpic_nmi(struct mpic *mpic)
-{
-#if defined(CONFIG_XMON) && defined(CONFIG_PPC32)
- struct device_node* pswitch;
- int nmi_irq;
-
- pswitch = of_find_node_by_name(NULL, "programmer-switch");
- if (pswitch) {
- nmi_irq = irq_of_parse_and_map(pswitch, 0);
- if (nmi_irq != NO_IRQ) {
- mpic_irq_set_priority(nmi_irq, 9);
- setup_irq(nmi_irq, &xmon_action);
- }
- of_node_put(pswitch);
- }
-#endif /* defined(CONFIG_XMON) && defined(CONFIG_PPC32) */
-}
-
-static struct mpic * __init pmac_setup_one_mpic(struct device_node *np,
- int master)
-{
- const char *name = master ? " MPIC 1 " : " MPIC 2 ";
- struct mpic *mpic;
- unsigned int flags = master ? 0 : MPIC_SECONDARY;
-
- pmac_call_feature(PMAC_FTR_ENABLE_MPIC, np, 0, 0);
-
- if (of_get_property(np, "big-endian", NULL))
- flags |= MPIC_BIG_ENDIAN;
-
- /* Primary Big Endian means HT interrupts. This is quite dodgy
- * but works until I find a better way
- */
- if (master && (flags & MPIC_BIG_ENDIAN))
- flags |= MPIC_U3_HT_IRQS;
-
- mpic = mpic_alloc(np, 0, flags, 0, 0, name);
- if (mpic == NULL)
- return NULL;
-
- mpic_init(mpic);
-
- return mpic;
- }
-
-static int __init pmac_pic_probe_mpic(void)
-{
- struct mpic *mpic1, *mpic2;
- struct device_node *np, *master = NULL, *slave = NULL;
-
- /* We can have up to 2 MPICs cascaded */
- for (np = NULL; (np = of_find_node_by_type(np, "open-pic"))
- != NULL;) {
- if (master == NULL &&
- of_get_property(np, "interrupts", NULL) == NULL)
- master = of_node_get(np);
- else if (slave == NULL)
- slave = of_node_get(np);
- if (master && slave)
- break;
- }
-
- /* Check for bogus setups */
- if (master == NULL && slave != NULL) {
- master = slave;
- slave = NULL;
- }
-
- /* Not found, default to good old pmac pic */
- if (master == NULL)
- return -ENODEV;
-
- /* Set master handler */
- ppc_md.get_irq = mpic_get_irq;
-
- /* Setup master */
- mpic1 = pmac_setup_one_mpic(master, 1);
- BUG_ON(mpic1 == NULL);
-
- /* Install NMI if any */
- pmac_pic_setup_mpic_nmi(mpic1);
-
- of_node_put(master);
-
- /* Set up a cascaded controller, if present */
- if (slave) {
- mpic2 = pmac_setup_one_mpic(slave, 0);
- if (mpic2 == NULL)
- printk(KERN_ERR "Failed to setup slave MPIC\n");
- of_node_put(slave);
- }
-
- return 0;
-}
-
-
-void __init pmac_pic_init(void)
-{
- /* We configure the OF parsing based on our oldworld vs. newworld
- * platform type and wether we were booted by BootX.
- */
-#ifdef CONFIG_PPC32
- if (!pmac_newworld)
- of_irq_workarounds |= OF_IMAP_OLDWORLD_MAC;
- if (of_get_property(of_chosen, "linux,bootx", NULL) != NULL)
- of_irq_workarounds |= OF_IMAP_NO_PHANDLE;
-
- /* If we don't have phandles on a newworld, then try to locate a
- * default interrupt controller (happens when booting with BootX).
- * We do a first match here, hopefully, that only ever happens on
- * machines with one controller.
- */
- if (pmac_newworld && (of_irq_workarounds & OF_IMAP_NO_PHANDLE)) {
- struct device_node *np;
-
- for_each_node_with_property(np, "interrupt-controller") {
- /* Skip /chosen/interrupt-controller */
- if (strcmp(np->name, "chosen") == 0)
- continue;
- /* It seems like at least one person wants
- * to use BootX on a machine with an AppleKiwi
- * controller which happens to pretend to be an
- * interrupt controller too. */
- if (strcmp(np->name, "AppleKiwi") == 0)
- continue;
- /* I think we found one ! */
- of_irq_dflt_pic = np;
- break;
- }
- }
-#endif /* CONFIG_PPC32 */
-
- /* We first try to detect Apple's new Core99 chipset, since mac-io
- * is quite different on those machines and contains an IBM MPIC2.
- */
- if (pmac_pic_probe_mpic() == 0)
- return;
-
-#ifdef CONFIG_PPC32
- pmac_pic_probe_oldstyle();
-#endif
-}
-
-#if defined(CONFIG_PM) && defined(CONFIG_PPC32)
-/*
- * These procedures are used in implementing sleep on the powerbooks.
- * sleep_save_intrs() saves the states of all interrupt enables
- * and disables all interrupts except for the nominated one.
- * sleep_restore_intrs() restores the states of all interrupt enables.
- */
-unsigned long sleep_save_mask[2];
-
-/* This used to be passed by the PMU driver but that link got
- * broken with the new driver model. We use this tweak for now...
- * We really want to do things differently though...
- */
-static int pmacpic_find_viaint(void)
-{
- int viaint = -1;
-
-#ifdef CONFIG_ADB_PMU
- struct device_node *np;
-
- if (pmu_get_model() != PMU_OHARE_BASED)
- goto not_found;
- np = of_find_node_by_name(NULL, "via-pmu");
- if (np == NULL)
- goto not_found;
- viaint = irq_of_parse_and_map(np, 0);
-
-not_found:
-#endif /* CONFIG_ADB_PMU */
- return viaint;
-}
-
-static int pmacpic_suspend(void)
-{
- int viaint = pmacpic_find_viaint();
-
- sleep_save_mask[0] = ppc_cached_irq_mask[0];
- sleep_save_mask[1] = ppc_cached_irq_mask[1];
- ppc_cached_irq_mask[0] = 0;
- ppc_cached_irq_mask[1] = 0;
- if (viaint > 0)
- set_bit(viaint, ppc_cached_irq_mask);
- out_le32(&pmac_irq_hw[0]->enable, ppc_cached_irq_mask[0]);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, ppc_cached_irq_mask[1]);
- (void)in_le32(&pmac_irq_hw[0]->event);
- /* make sure mask gets to controller before we return to caller */
- mb();
- (void)in_le32(&pmac_irq_hw[0]->enable);
-
- return 0;
-}
-
-static void pmacpic_resume(void)
-{
- int i;
-
- out_le32(&pmac_irq_hw[0]->enable, 0);
- if (max_real_irqs > 32)
- out_le32(&pmac_irq_hw[1]->enable, 0);
- mb();
- for (i = 0; i < max_real_irqs; ++i)
- if (test_bit(i, sleep_save_mask))
- pmac_unmask_irq(irq_get_irq_data(i));
-}
-
-static struct syscore_ops pmacpic_syscore_ops = {
- .suspend = pmacpic_suspend,
- .resume = pmacpic_resume,
-};
-
-static int __init init_pmacpic_syscore(void)
-{
- if (pmac_irq_hw[0])
- register_syscore_ops(&pmacpic_syscore_ops);
- return 0;
-}
-
-machine_subsys_initcall(powermac, init_pmacpic_syscore);
-
-#endif /* CONFIG_PM && CONFIG_PPC32 */
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pmac.h b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pmac.h
deleted file mode 100644
index 8327cce2..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/pmac.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef __PMAC_H__
-#define __PMAC_H__
-
-#include <linux/pci.h>
-#include <linux/irq.h>
-
-/*
- * Declaration for the various functions exported by the
- * pmac_* files. Mostly for use by pmac_setup
- */
-
-struct rtc_time;
-
-extern int pmac_newworld;
-
-extern long pmac_time_init(void);
-extern unsigned long pmac_get_boot_time(void);
-extern void pmac_get_rtc_time(struct rtc_time *);
-extern int pmac_set_rtc_time(struct rtc_time *);
-extern void pmac_read_rtc_time(void);
-extern void pmac_calibrate_decr(void);
-extern void pmac_pci_irq_fixup(struct pci_dev *);
-extern void pmac_pci_init(void);
-
-extern void pmac_nvram_update(void);
-extern unsigned char pmac_nvram_read_byte(int addr);
-extern void pmac_nvram_write_byte(int addr, unsigned char val);
-extern int pmac_pci_enable_device_hook(struct pci_dev *dev);
-extern void pmac_pcibios_after_init(void);
-extern int of_show_percpuinfo(struct seq_file *m, int i);
-
-extern void pmac_setup_pci_dma(void);
-extern void pmac_check_ht_link(void);
-
-extern void pmac_setup_smp(void);
-extern int psurge_secondary_virq;
-extern void low_cpu_die(void) __attribute__((noreturn));
-
-extern int pmac_nvram_init(void);
-extern void pmac_pic_init(void);
-
-#endif /* __PMAC_H__ */
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/setup.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/setup.c
deleted file mode 100644
index 141f8899..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/setup.c
+++ /dev/null
@@ -1,685 +0,0 @@
-/*
- * Powermac setup and early boot code plus other random bits.
- *
- * PowerPC version
- * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
- *
- * Adapted for Power Macintosh by Paul Mackerras
- * Copyright (C) 1996 Paul Mackerras (paulus@samba.org)
- *
- * Derived from "arch/alpha/kernel/setup.c"
- * Copyright (C) 1995 Linus Torvalds
- *
- * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
- *
- * 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.
- *
- */
-
-/*
- * bootup setup stuff..
- */
-
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/stddef.h>
-#include <linux/unistd.h>
-#include <linux/ptrace.h>
-#include <linux/export.h>
-#include <linux/user.h>
-#include <linux/tty.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/major.h>
-#include <linux/initrd.h>
-#include <linux/vt_kern.h>
-#include <linux/console.h>
-#include <linux/pci.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/irq.h>
-#include <linux/seq_file.h>
-#include <linux/root_dev.h>
-#include <linux/bitops.h>
-#include <linux/suspend.h>
-#include <linux/of_device.h>
-#include <linux/of_platform.h>
-#include <linux/memblock.h>
-
-#include <asm/reg.h>
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/pci-bridge.h>
-#include <asm/ohare.h>
-#include <asm/mediabay.h>
-#include <asm/machdep.h>
-#include <asm/dma.h>
-#include <asm/cputable.h>
-#include <asm/btext.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/mmu_context.h>
-#include <asm/iommu.h>
-#include <asm/smu.h>
-#include <asm/pmc.h>
-#include <asm/udbg.h>
-
-#include "pmac.h"
-
-#undef SHOW_GATWICK_IRQS
-
-int ppc_override_l2cr = 0;
-int ppc_override_l2cr_value;
-int has_l2cache = 0;
-
-int pmac_newworld;
-
-static int current_root_goodness = -1;
-
-extern struct machdep_calls pmac_md;
-
-#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */
-
-#ifdef CONFIG_PPC64
-int sccdbg;
-#endif
-
-sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
-EXPORT_SYMBOL(sys_ctrler);
-
-#ifdef CONFIG_PMAC_SMU
-unsigned long smu_cmdbuf_abs;
-EXPORT_SYMBOL(smu_cmdbuf_abs);
-#endif
-
-static void pmac_show_cpuinfo(struct seq_file *m)
-{
- struct device_node *np;
- const char *pp;
- int plen;
- int mbmodel;
- unsigned int mbflags;
- char* mbname;
-
- mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_MODEL, 0);
- mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
- PMAC_MB_INFO_FLAGS, 0);
- if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
- (long) &mbname) != 0)
- mbname = "Unknown";
-
- /* find motherboard type */
- seq_printf(m, "machine\t\t: ");
- np = of_find_node_by_path("/");
- if (np != NULL) {
- pp = of_get_property(np, "model", NULL);
- if (pp != NULL)
- seq_printf(m, "%s\n", pp);
- else
- seq_printf(m, "PowerMac\n");
- pp = of_get_property(np, "compatible", &plen);
- if (pp != NULL) {
- seq_printf(m, "motherboard\t:");
- while (plen > 0) {
- int l = strlen(pp) + 1;
- seq_printf(m, " %s", pp);
- plen -= l;
- pp += l;
- }
- seq_printf(m, "\n");
- }
- of_node_put(np);
- } else
- seq_printf(m, "PowerMac\n");
-
- /* print parsed model */
- seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
- seq_printf(m, "pmac flags\t: %08x\n", mbflags);
-
- /* find l2 cache info */
- np = of_find_node_by_name(NULL, "l2-cache");
- if (np == NULL)
- np = of_find_node_by_type(NULL, "cache");
- if (np != NULL) {
- const unsigned int *ic =
- of_get_property(np, "i-cache-size", NULL);
- const unsigned int *dc =
- of_get_property(np, "d-cache-size", NULL);
- seq_printf(m, "L2 cache\t:");
- has_l2cache = 1;
- if (of_get_property(np, "cache-unified", NULL) != 0 && dc) {
- seq_printf(m, " %dK unified", *dc / 1024);
- } else {
- if (ic)
- seq_printf(m, " %dK instruction", *ic / 1024);
- if (dc)
- seq_printf(m, "%s %dK data",
- (ic? " +": ""), *dc / 1024);
- }
- pp = of_get_property(np, "ram-type", NULL);
- if (pp)
- seq_printf(m, " %s", pp);
- seq_printf(m, "\n");
- of_node_put(np);
- }
-
- /* Indicate newworld/oldworld */
- seq_printf(m, "pmac-generation\t: %s\n",
- pmac_newworld ? "NewWorld" : "OldWorld");
-}
-
-#ifndef CONFIG_ADB_CUDA
-int find_via_cuda(void)
-{
- struct device_node *dn = of_find_node_by_name(NULL, "via-cuda");
-
- if (!dn)
- return 0;
- of_node_put(dn);
- printk("WARNING ! Your machine is CUDA-based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n");
- return 0;
-}
-#endif
-
-#ifndef CONFIG_ADB_PMU
-int find_via_pmu(void)
-{
- struct device_node *dn = of_find_node_by_name(NULL, "via-pmu");
-
- if (!dn)
- return 0;
- of_node_put(dn);
- printk("WARNING ! Your machine is PMU-based but your kernel\n");
- printk(" wasn't compiled with CONFIG_ADB_PMU option !\n");
- return 0;
-}
-#endif
-
-#ifndef CONFIG_PMAC_SMU
-int smu_init(void)
-{
- /* should check and warn if SMU is present */
- return 0;
-}
-#endif
-
-#ifdef CONFIG_PPC32
-static volatile u32 *sysctrl_regs;
-
-static void __init ohare_init(void)
-{
- struct device_node *dn;
-
- /* this area has the CPU identification register
- and some registers used by smp boards */
- sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
-
- /*
- * Turn on the L2 cache.
- * We assume that we have a PSX memory controller iff
- * we have an ohare I/O controller.
- */
- dn = of_find_node_by_name(NULL, "ohare");
- if (dn) {
- of_node_put(dn);
- if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
- if (sysctrl_regs[4] & 0x10)
- sysctrl_regs[4] |= 0x04000020;
- else
- sysctrl_regs[4] |= 0x04000000;
- if(has_l2cache)
- printk(KERN_INFO "Level 2 cache enabled\n");
- }
- }
-}
-
-static void __init l2cr_init(void)
-{
- /* Checks "l2cr-value" property in the registry */
- if (cpu_has_feature(CPU_FTR_L2CR)) {
- struct device_node *np = of_find_node_by_name(NULL, "cpus");
- if (np == 0)
- np = of_find_node_by_type(NULL, "cpu");
- if (np != 0) {
- const unsigned int *l2cr =
- of_get_property(np, "l2cr-value", NULL);
- if (l2cr != 0) {
- ppc_override_l2cr = 1;
- ppc_override_l2cr_value = *l2cr;
- _set_L2CR(0);
- _set_L2CR(ppc_override_l2cr_value);
- }
- of_node_put(np);
- }
- }
-
- if (ppc_override_l2cr)
- printk(KERN_INFO "L2CR overridden (0x%x), "
- "backside cache is %s\n",
- ppc_override_l2cr_value,
- (ppc_override_l2cr_value & 0x80000000)
- ? "enabled" : "disabled");
-}
-#endif
-
-static void __init pmac_setup_arch(void)
-{
- struct device_node *cpu, *ic;
- const int *fp;
- unsigned long pvr;
-
- pvr = PVR_VER(mfspr(SPRN_PVR));
-
- /* Set loops_per_jiffy to a half-way reasonable value,
- for use until calibrate_delay gets called. */
- loops_per_jiffy = 50000000 / HZ;
- cpu = of_find_node_by_type(NULL, "cpu");
- if (cpu != NULL) {
- fp = of_get_property(cpu, "clock-frequency", NULL);
- if (fp != NULL) {
- if (pvr >= 0x30 && pvr < 0x80)
- /* PPC970 etc. */
- loops_per_jiffy = *fp / (3 * HZ);
- else if (pvr == 4 || pvr >= 8)
- /* 604, G3, G4 etc. */
- loops_per_jiffy = *fp / HZ;
- else
- /* 601, 603, etc. */
- loops_per_jiffy = *fp / (2 * HZ);
- }
- of_node_put(cpu);
- }
-
- /* See if newworld or oldworld */
- ic = of_find_node_with_property(NULL, "interrupt-controller");
- if (ic) {
- pmac_newworld = 1;
- of_node_put(ic);
- }
-
- /* Lookup PCI hosts */
- pmac_pci_init();
-
-#ifdef CONFIG_PPC32
- ohare_init();
- l2cr_init();
-#endif /* CONFIG_PPC32 */
-
- find_via_cuda();
- find_via_pmu();
- smu_init();
-
-#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
- defined(CONFIG_PPC64)
- pmac_nvram_init();
-#endif
-
-#ifdef CONFIG_PPC32
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start)
- ROOT_DEV = Root_RAM0;
- else
-#endif
- ROOT_DEV = DEFAULT_ROOT_DEVICE;
-#endif
-
-#ifdef CONFIG_ADB
- if (strstr(cmd_line, "adb_sync")) {
- extern int __adb_probe_sync;
- __adb_probe_sync = 1;
- }
-#endif /* CONFIG_ADB */
-}
-
-#ifdef CONFIG_SCSI
-void note_scsi_host(struct device_node *node, void *host)
-{
-}
-EXPORT_SYMBOL(note_scsi_host);
-#endif
-
-static int initializing = 1;
-
-static int pmac_late_init(void)
-{
- initializing = 0;
- return 0;
-}
-machine_late_initcall(powermac, pmac_late_init);
-
-/*
- * This is __init_refok because we check for "initializing" before
- * touching any of the __init sensitive things and "initializing"
- * will be false after __init time. This can't be __init because it
- * can be called whenever a disk is first accessed.
- */
-void __init_refok note_bootable_part(dev_t dev, int part, int goodness)
-{
- char *p;
-
- if (!initializing)
- return;
- if ((goodness <= current_root_goodness) &&
- ROOT_DEV != DEFAULT_ROOT_DEVICE)
- return;
- p = strstr(boot_command_line, "root=");
- if (p != NULL && (p == boot_command_line || p[-1] == ' '))
- return;
-
- ROOT_DEV = dev + part;
- current_root_goodness = goodness;
-}
-
-#ifdef CONFIG_ADB_CUDA
-static void cuda_restart(void)
-{
- struct adb_request req;
-
- cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
- for (;;)
- cuda_poll();
-}
-
-static void cuda_shutdown(void)
-{
- struct adb_request req;
-
- cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
- for (;;)
- cuda_poll();
-}
-
-#else
-#define cuda_restart()
-#define cuda_shutdown()
-#endif
-
-#ifndef CONFIG_ADB_PMU
-#define pmu_restart()
-#define pmu_shutdown()
-#endif
-
-#ifndef CONFIG_PMAC_SMU
-#define smu_restart()
-#define smu_shutdown()
-#endif
-
-static void pmac_restart(char *cmd)
-{
- switch (sys_ctrler) {
- case SYS_CTRLER_CUDA:
- cuda_restart();
- break;
- case SYS_CTRLER_PMU:
- pmu_restart();
- break;
- case SYS_CTRLER_SMU:
- smu_restart();
- break;
- default: ;
- }
-}
-
-static void pmac_power_off(void)
-{
- switch (sys_ctrler) {
- case SYS_CTRLER_CUDA:
- cuda_shutdown();
- break;
- case SYS_CTRLER_PMU:
- pmu_shutdown();
- break;
- case SYS_CTRLER_SMU:
- smu_shutdown();
- break;
- default: ;
- }
-}
-
-static void
-pmac_halt(void)
-{
- pmac_power_off();
-}
-
-/*
- * Early initialization.
- */
-static void __init pmac_init_early(void)
-{
- /* Enable early btext debug if requested */
- if (strstr(cmd_line, "btextdbg")) {
- udbg_adb_init_early();
- register_early_udbg_console();
- }
-
- /* Probe motherboard chipset */
- pmac_feature_init();
-
- /* Initialize debug stuff */
- udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
- udbg_adb_init(!!strstr(cmd_line, "btextdbg"));
-
-#ifdef CONFIG_PPC64
- iommu_init_early_dart();
-#endif
-
- /* SMP Init has to be done early as we need to patch up
- * cpu_possible_mask before interrupt stacks are allocated
- * or kaboom...
- */
-#ifdef CONFIG_SMP
- pmac_setup_smp();
-#endif
-}
-
-static int __init pmac_declare_of_platform_devices(void)
-{
- struct device_node *np;
-
- if (machine_is(chrp))
- return -1;
-
- np = of_find_node_by_name(NULL, "valkyrie");
- if (np) {
- of_platform_device_create(np, "valkyrie", NULL);
- of_node_put(np);
- }
- np = of_find_node_by_name(NULL, "platinum");
- if (np) {
- of_platform_device_create(np, "platinum", NULL);
- of_node_put(np);
- }
- np = of_find_node_by_type(NULL, "smu");
- if (np) {
- of_platform_device_create(np, "smu", NULL);
- of_node_put(np);
- }
- np = of_find_node_by_type(NULL, "fcu");
- if (np == NULL) {
- /* Some machines have strangely broken device-tree */
- np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e");
- }
- if (np) {
- of_platform_device_create(np, "temperature", NULL);
- of_node_put(np);
- }
-
- return 0;
-}
-machine_device_initcall(powermac, pmac_declare_of_platform_devices);
-
-#ifdef CONFIG_SERIAL_PMACZILOG_CONSOLE
-/*
- * This is called very early, as part of console_init() (typically just after
- * time_init()). This function is respondible for trying to find a good
- * default console on serial ports. It tries to match the open firmware
- * default output with one of the available serial console drivers.
- */
-static int __init check_pmac_serial_console(void)
-{
- struct device_node *prom_stdout = NULL;
- int offset = 0;
- const char *name;
-#ifdef CONFIG_SERIAL_PMACZILOG_TTYS
- char *devname = "ttyS";
-#else
- char *devname = "ttyPZ";
-#endif
-
- pr_debug(" -> check_pmac_serial_console()\n");
-
- /* The user has requested a console so this is already set up. */
- if (strstr(boot_command_line, "console=")) {
- pr_debug(" console was specified !\n");
- return -EBUSY;
- }
-
- if (!of_chosen) {
- pr_debug(" of_chosen is NULL !\n");
- return -ENODEV;
- }
-
- /* We are getting a weird phandle from OF ... */
- /* ... So use the full path instead */
- name = of_get_property(of_chosen, "linux,stdout-path", NULL);
- if (name == NULL) {
- pr_debug(" no linux,stdout-path !\n");
- return -ENODEV;
- }
- prom_stdout = of_find_node_by_path(name);
- if (!prom_stdout) {
- pr_debug(" can't find stdout package %s !\n", name);
- return -ENODEV;
- }
- pr_debug("stdout is %s\n", prom_stdout->full_name);
-
- name = of_get_property(prom_stdout, "name", NULL);
- if (!name) {
- pr_debug(" stdout package has no name !\n");
- goto not_found;
- }
-
- if (strcmp(name, "ch-a") == 0)
- offset = 0;
- else if (strcmp(name, "ch-b") == 0)
- offset = 1;
- else
- goto not_found;
- of_node_put(prom_stdout);
-
- pr_debug("Found serial console at %s%d\n", devname, offset);
-
- return add_preferred_console(devname, offset, NULL);
-
- not_found:
- pr_debug("No preferred console found !\n");
- of_node_put(prom_stdout);
- return -ENODEV;
-}
-console_initcall(check_pmac_serial_console);
-
-#endif /* CONFIG_SERIAL_PMACZILOG_CONSOLE */
-
-/*
- * Called very early, MMU is off, device-tree isn't unflattened
- */
-static int __init pmac_probe(void)
-{
- unsigned long root = of_get_flat_dt_root();
-
- if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
- !of_flat_dt_is_compatible(root, "MacRISC"))
- return 0;
-
-#ifdef CONFIG_PPC64
- /*
- * On U3, the DART (iommu) must be allocated now since it
- * has an impact on htab_initialize (due to the large page it
- * occupies having to be broken up so the DART itself is not
- * part of the cacheable linar mapping
- */
- alloc_dart_table();
-
- hpte_init_native();
-#endif
-
-#ifdef CONFIG_PPC32
- /* isa_io_base gets set in pmac_pci_init */
- ISA_DMA_THRESHOLD = ~0L;
- DMA_MODE_READ = 1;
- DMA_MODE_WRITE = 2;
-#endif /* CONFIG_PPC32 */
-
-#ifdef CONFIG_PMAC_SMU
- /*
- * SMU based G5s need some memory below 2Gb, at least the current
- * driver needs that. We have to allocate it now. We allocate 4k
- * (1 small page) for now.
- */
- smu_cmdbuf_abs = memblock_alloc_base(4096, 4096, 0x80000000UL);
-#endif /* CONFIG_PMAC_SMU */
-
- return 1;
-}
-
-#ifdef CONFIG_PPC64
-/* Move that to pci.c */
-static int pmac_pci_probe_mode(struct pci_bus *bus)
-{
- struct device_node *node = pci_bus_to_OF_node(bus);
-
- /* We need to use normal PCI probing for the AGP bus,
- * since the device for the AGP bridge isn't in the tree.
- * Same for the PCIe host on U4 and the HT host bridge.
- */
- if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
- of_device_is_compatible(node, "u4-pcie") ||
- of_device_is_compatible(node, "u3-ht")))
- return PCI_PROBE_NORMAL;
- return PCI_PROBE_DEVTREE;
-}
-#endif /* CONFIG_PPC64 */
-
-define_machine(powermac) {
- .name = "PowerMac",
- .probe = pmac_probe,
- .setup_arch = pmac_setup_arch,
- .init_early = pmac_init_early,
- .show_cpuinfo = pmac_show_cpuinfo,
- .init_IRQ = pmac_pic_init,
- .get_irq = NULL, /* changed later */
- .pci_irq_fixup = pmac_pci_irq_fixup,
- .restart = pmac_restart,
- .power_off = pmac_power_off,
- .halt = pmac_halt,
- .time_init = pmac_time_init,
- .get_boot_time = pmac_get_boot_time,
- .set_rtc_time = pmac_set_rtc_time,
- .get_rtc_time = pmac_get_rtc_time,
- .calibrate_decr = pmac_calibrate_decr,
- .feature_call = pmac_do_feature_call,
- .progress = udbg_progress,
-#ifdef CONFIG_PPC64
- .pci_probe_mode = pmac_pci_probe_mode,
- .power_save = power4_idle,
- .enable_pmcs = power4_enable_pmcs,
-#endif /* CONFIG_PPC64 */
-#ifdef CONFIG_PPC32
- .pcibios_enable_device_hook = pmac_pci_enable_device_hook,
- .pcibios_after_init = pmac_pcibios_after_init,
- .phys_mem_access_prot = pci_phys_mem_access_prot,
-#endif
-};
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/sleep.S b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/sleep.S
deleted file mode 100644
index 1c2802fa..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/sleep.S
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * This file contains sleep low-level functions for PowerBook G3.
- * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org)
- * and Paul Mackerras (paulus@samba.org).
- *
- * 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.
- *
- */
-
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/ppc_asm.h>
-#include <asm/cputable.h>
-#include <asm/cache.h>
-#include <asm/thread_info.h>
-#include <asm/asm-offsets.h>
-#include <asm/mmu.h>
-
-#define MAGIC 0x4c617273 /* 'Lars' */
-
-/*
- * Structure for storing CPU registers on the stack.
- */
-#define SL_SP 0
-#define SL_PC 4
-#define SL_MSR 8
-#define SL_SDR1 0xc
-#define SL_SPRG0 0x10 /* 4 sprg's */
-#define SL_DBAT0 0x20
-#define SL_IBAT0 0x28
-#define SL_DBAT1 0x30
-#define SL_IBAT1 0x38
-#define SL_DBAT2 0x40
-#define SL_IBAT2 0x48
-#define SL_DBAT3 0x50
-#define SL_IBAT3 0x58
-#define SL_TB 0x60
-#define SL_R2 0x68
-#define SL_CR 0x6c
-#define SL_R12 0x70 /* r12 to r31 */
-#define SL_SIZE (SL_R12 + 80)
-
- .section .text
- .align 5
-
-#if defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ_PMAC) || \
- (defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32))
-
-/* This gets called by via-pmu.c late during the sleep process.
- * The PMU was already send the sleep command and will shut us down
- * soon. We need to save all that is needed and setup the wakeup
- * vector that will be called by the ROM on wakeup
- */
-_GLOBAL(low_sleep_handler)
-#ifndef CONFIG_6xx
- blr
-#else
- mflr r0
- stw r0,4(r1)
- stwu r1,-SL_SIZE(r1)
- mfcr r0
- stw r0,SL_CR(r1)
- stw r2,SL_R2(r1)
- stmw r12,SL_R12(r1)
-
- /* Save MSR & SDR1 */
- mfmsr r4
- stw r4,SL_MSR(r1)
- mfsdr1 r4
- stw r4,SL_SDR1(r1)
-
- /* Get a stable timebase and save it */
-1: mftbu r4
- stw r4,SL_TB(r1)
- mftb r5
- stw r5,SL_TB+4(r1)
- mftbu r3
- cmpw r3,r4
- bne 1b
-
- /* Save SPRGs */
- mfsprg r4,0
- stw r4,SL_SPRG0(r1)
- mfsprg r4,1
- stw r4,SL_SPRG0+4(r1)
- mfsprg r4,2
- stw r4,SL_SPRG0+8(r1)
- mfsprg r4,3
- stw r4,SL_SPRG0+12(r1)
-
- /* Save BATs */
- mfdbatu r4,0
- stw r4,SL_DBAT0(r1)
- mfdbatl r4,0
- stw r4,SL_DBAT0+4(r1)
- mfdbatu r4,1
- stw r4,SL_DBAT1(r1)
- mfdbatl r4,1
- stw r4,SL_DBAT1+4(r1)
- mfdbatu r4,2
- stw r4,SL_DBAT2(r1)
- mfdbatl r4,2
- stw r4,SL_DBAT2+4(r1)
- mfdbatu r4,3
- stw r4,SL_DBAT3(r1)
- mfdbatl r4,3
- stw r4,SL_DBAT3+4(r1)
- mfibatu r4,0
- stw r4,SL_IBAT0(r1)
- mfibatl r4,0
- stw r4,SL_IBAT0+4(r1)
- mfibatu r4,1
- stw r4,SL_IBAT1(r1)
- mfibatl r4,1
- stw r4,SL_IBAT1+4(r1)
- mfibatu r4,2
- stw r4,SL_IBAT2(r1)
- mfibatl r4,2
- stw r4,SL_IBAT2+4(r1)
- mfibatu r4,3
- stw r4,SL_IBAT3(r1)
- mfibatl r4,3
- stw r4,SL_IBAT3+4(r1)
-
- /* Backup various CPU config stuffs */
- bl __save_cpu_setup
-
- /* The ROM can wake us up via 2 different vectors:
- * - On wallstreet & lombard, we must write a magic
- * value 'Lars' at address 4 and a pointer to a
- * memory location containing the PC to resume from
- * at address 0.
- * - On Core99, we must store the wakeup vector at
- * address 0x80 and eventually it's parameters
- * at address 0x84. I've have some trouble with those
- * parameters however and I no longer use them.
- */
- lis r5,grackle_wake_up@ha
- addi r5,r5,grackle_wake_up@l
- tophys(r5,r5)
- stw r5,SL_PC(r1)
- lis r4,KERNELBASE@h
- tophys(r5,r1)
- addi r5,r5,SL_PC
- lis r6,MAGIC@ha
- addi r6,r6,MAGIC@l
- stw r5,0(r4)
- stw r6,4(r4)
- /* Setup stuffs at 0x80-0x84 for Core99 */
- lis r3,core99_wake_up@ha
- addi r3,r3,core99_wake_up@l
- tophys(r3,r3)
- stw r3,0x80(r4)
- stw r5,0x84(r4)
- /* Store a pointer to our backup storage into
- * a kernel global
- */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- stw r5,0(r3)
-
- .globl low_cpu_die
-low_cpu_die:
- /* Flush & disable all caches */
- bl flush_disable_caches
-
- /* Turn off data relocation. */
- mfmsr r3 /* Save MSR in r7 */
- rlwinm r3,r3,0,28,26 /* Turn off DR bit */
- sync
- mtmsr r3
- isync
-
-BEGIN_FTR_SECTION
- /* Flush any pending L2 data prefetches to work around HW bug */
- sync
- lis r3,0xfff0
- lwz r0,0(r3) /* perform cache-inhibited load to ROM */
- sync /* (caches are disabled at this point) */
-END_FTR_SECTION_IFSET(CPU_FTR_SPEC7450)
-
-/*
- * Set the HID0 and MSR for sleep.
- */
- mfspr r2,SPRN_HID0
- rlwinm r2,r2,0,10,7 /* clear doze, nap */
- oris r2,r2,HID0_SLEEP@h
- sync
- isync
- mtspr SPRN_HID0,r2
- sync
-
-/* This loop puts us back to sleep in case we have a spurrious
- * wakeup so that the host bridge properly stays asleep. The
- * CPU will be turned off, either after a known time (about 1
- * second) on wallstreet & lombard, or as soon as the CPU enters
- * SLEEP mode on core99
- */
- mfmsr r2
- oris r2,r2,MSR_POW@h
-1: sync
- mtmsr r2
- isync
- b 1b
-
-/*
- * Here is the resume code.
- */
-
-
-/*
- * Core99 machines resume here
- * r4 has the physical address of SL_PC(sp) (unused)
- */
-_GLOBAL(core99_wake_up)
- /* Make sure HID0 no longer contains any sleep bit and that data cache
- * is disabled
- */
- mfspr r3,SPRN_HID0
- rlwinm r3,r3,0,11,7 /* clear SLEEP, NAP, DOZE bits */
- rlwinm 3,r3,0,18,15 /* clear DCE, ICE */
- mtspr SPRN_HID0,r3
- sync
- isync
-
- /* sanitize MSR */
- mfmsr r3
- ori r3,r3,MSR_EE|MSR_IP
- xori r3,r3,MSR_EE|MSR_IP
- sync
- isync
- mtmsr r3
- sync
- isync
-
- /* Recover sleep storage */
- lis r3,sleep_storage@ha
- addi r3,r3,sleep_storage@l
- tophys(r3,r3)
- lwz r1,0(r3)
-
- /* Pass thru to older resume code ... */
-/*
- * Here is the resume code for older machines.
- * r1 has the physical address of SL_PC(sp).
- */
-
-grackle_wake_up:
-
- /* Restore the kernel's segment registers before
- * we do any r1 memory access as we are not sure they
- * are in a sane state above the first 256Mb region
- */
- li r0,16 /* load up segment register values */
- mtctr r0 /* for context 0 */
- lis r3,0x2000 /* Ku = 1, VSID = 0 */
- li r4,0
-3: mtsrin r3,r4
- addi r3,r3,0x111 /* increment VSID */
- addis r4,r4,0x1000 /* address of next segment */
- bdnz 3b
- sync
- isync
-
- subi r1,r1,SL_PC
-
- /* Restore various CPU config stuffs */
- bl __restore_cpu_setup
-
- /* Make sure all FPRs have been initialized */
- bl reloc_offset
- bl __init_fpu_registers
-
- /* Invalidate & enable L1 cache, we don't care about
- * whatever the ROM may have tried to write to memory
- */
- bl __inval_enable_L1
-
- /* Restore the BATs, and SDR1. Then we can turn on the MMU. */
- lwz r4,SL_SDR1(r1)
- mtsdr1 r4
- lwz r4,SL_SPRG0(r1)
- mtsprg 0,r4
- lwz r4,SL_SPRG0+4(r1)
- mtsprg 1,r4
- lwz r4,SL_SPRG0+8(r1)
- mtsprg 2,r4
- lwz r4,SL_SPRG0+12(r1)
- mtsprg 3,r4
-
- lwz r4,SL_DBAT0(r1)
- mtdbatu 0,r4
- lwz r4,SL_DBAT0+4(r1)
- mtdbatl 0,r4
- lwz r4,SL_DBAT1(r1)
- mtdbatu 1,r4
- lwz r4,SL_DBAT1+4(r1)
- mtdbatl 1,r4
- lwz r4,SL_DBAT2(r1)
- mtdbatu 2,r4
- lwz r4,SL_DBAT2+4(r1)
- mtdbatl 2,r4
- lwz r4,SL_DBAT3(r1)
- mtdbatu 3,r4
- lwz r4,SL_DBAT3+4(r1)
- mtdbatl 3,r4
- lwz r4,SL_IBAT0(r1)
- mtibatu 0,r4
- lwz r4,SL_IBAT0+4(r1)
- mtibatl 0,r4
- lwz r4,SL_IBAT1(r1)
- mtibatu 1,r4
- lwz r4,SL_IBAT1+4(r1)
- mtibatl 1,r4
- lwz r4,SL_IBAT2(r1)
- mtibatu 2,r4
- lwz r4,SL_IBAT2+4(r1)
- mtibatl 2,r4
- lwz r4,SL_IBAT3(r1)
- mtibatu 3,r4
- lwz r4,SL_IBAT3+4(r1)
- mtibatl 3,r4
-
-BEGIN_MMU_FTR_SECTION
- li r4,0
- mtspr SPRN_DBAT4U,r4
- mtspr SPRN_DBAT4L,r4
- mtspr SPRN_DBAT5U,r4
- mtspr SPRN_DBAT5L,r4
- mtspr SPRN_DBAT6U,r4
- mtspr SPRN_DBAT6L,r4
- mtspr SPRN_DBAT7U,r4
- mtspr SPRN_DBAT7L,r4
- mtspr SPRN_IBAT4U,r4
- mtspr SPRN_IBAT4L,r4
- mtspr SPRN_IBAT5U,r4
- mtspr SPRN_IBAT5L,r4
- mtspr SPRN_IBAT6U,r4
- mtspr SPRN_IBAT6L,r4
- mtspr SPRN_IBAT7U,r4
- mtspr SPRN_IBAT7L,r4
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
-
- /* Flush all TLBs */
- lis r4,0x1000
-1: addic. r4,r4,-0x1000
- tlbie r4
- blt 1b
- sync
-
- /* restore the MSR and turn on the MMU */
- lwz r3,SL_MSR(r1)
- bl turn_on_mmu
-
- /* get back the stack pointer */
- tovirt(r1,r1)
-
- /* Restore TB */
- li r3,0
- mttbl r3
- lwz r3,SL_TB(r1)
- lwz r4,SL_TB+4(r1)
- mttbu r3
- mttbl r4
-
- /* Restore the callee-saved registers and return */
- lwz r0,SL_CR(r1)
- mtcr r0
- lwz r2,SL_R2(r1)
- lmw r12,SL_R12(r1)
- addi r1,r1,SL_SIZE
- lwz r0,4(r1)
- mtlr r0
- blr
-
-turn_on_mmu:
- mflr r4
- tovirt(r4,r4)
- mtsrr0 r4
- mtsrr1 r3
- sync
- isync
- rfi
-
-#endif /* defined(CONFIG_PM) || defined(CONFIG_CPU_FREQ) */
-
- .section .data
- .balign L1_CACHE_BYTES
-sleep_storage:
- .long 0
- .balign L1_CACHE_BYTES, 0
-
-#endif /* CONFIG_6xx */
- .section .text
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/smp.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/smp.c
deleted file mode 100644
index b4ddaa3f..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/smp.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * SMP support for power macintosh.
- *
- * We support both the old "powersurge" SMP architecture
- * and the current Core99 (G4 PowerMac) machines.
- *
- * Note that we don't support the very first rev. of
- * Apple/DayStar 2 CPUs board, the one with the funky
- * watchdog. Hopefully, none of these should be there except
- * maybe internally to Apple. I should probably still add some
- * code to detect this card though and disable SMP. --BenH.
- *
- * Support Macintosh G4 SMP by Troy Benjegerdes (hozer@drgw.net)
- * and Ben Herrenschmidt <benh@kernel.crashing.org>.
- *
- * Support for DayStar quad CPU cards
- * Copyright (C) XLR8, Inc. 1994-2000
- *
- * 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.
- */
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
-#include <linux/delay.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/errno.h>
-#include <linux/hardirq.h>
-#include <linux/cpu.h>
-#include <linux/compiler.h>
-
-#include <asm/ptrace.h>
-#include <linux/atomic.h>
-#include <asm/code-patching.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-#include <asm/sections.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/time.h>
-#include <asm/mpic.h>
-#include <asm/cacheflush.h>
-#include <asm/keylargo.h>
-#include <asm/pmac_low_i2c.h>
-#include <asm/pmac_pfunc.h>
-
-#include "pmac.h"
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-extern void __secondary_start_pmac_0(void);
-extern int pmac_pfunc_base_install(void);
-
-static void (*pmac_tb_freeze)(int freeze);
-static u64 timebase;
-static int tb_req;
-
-#ifdef CONFIG_PPC_PMAC32_PSURGE
-
-/*
- * Powersurge (old powermac SMP) support.
- */
-
-/* Addresses for powersurge registers */
-#define HAMMERHEAD_BASE 0xf8000000
-#define HHEAD_CONFIG 0x90
-#define HHEAD_SEC_INTR 0xc0
-
-/* register for interrupting the primary processor on the powersurge */
-/* N.B. this is actually the ethernet ROM! */
-#define PSURGE_PRI_INTR 0xf3019000
-
-/* register for storing the start address for the secondary processor */
-/* N.B. this is the PCI config space address register for the 1st bridge */
-#define PSURGE_START 0xf2800000
-
-/* Daystar/XLR8 4-CPU card */
-#define PSURGE_QUAD_REG_ADDR 0xf8800000
-
-#define PSURGE_QUAD_IRQ_SET 0
-#define PSURGE_QUAD_IRQ_CLR 1
-#define PSURGE_QUAD_IRQ_PRIMARY 2
-#define PSURGE_QUAD_CKSTOP_CTL 3
-#define PSURGE_QUAD_PRIMARY_ARB 4
-#define PSURGE_QUAD_BOARD_ID 6
-#define PSURGE_QUAD_WHICH_CPU 7
-#define PSURGE_QUAD_CKSTOP_RDBK 8
-#define PSURGE_QUAD_RESET_CTL 11
-
-#define PSURGE_QUAD_OUT(r, v) (out_8(quad_base + ((r) << 4) + 4, (v)))
-#define PSURGE_QUAD_IN(r) (in_8(quad_base + ((r) << 4) + 4) & 0x0f)
-#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v)))
-#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v)))
-
-/* virtual addresses for the above */
-static volatile u8 __iomem *hhead_base;
-static volatile u8 __iomem *quad_base;
-static volatile u32 __iomem *psurge_pri_intr;
-static volatile u8 __iomem *psurge_sec_intr;
-static volatile u32 __iomem *psurge_start;
-
-/* values for psurge_type */
-#define PSURGE_NONE -1
-#define PSURGE_DUAL 0
-#define PSURGE_QUAD_OKEE 1
-#define PSURGE_QUAD_COTTON 2
-#define PSURGE_QUAD_ICEGRASS 3
-
-/* what sort of powersurge board we have */
-static int psurge_type = PSURGE_NONE;
-
-/* irq for secondary cpus to report */
-static struct irq_domain *psurge_host;
-int psurge_secondary_virq;
-
-/*
- * Set and clear IPIs for powersurge.
- */
-static inline void psurge_set_ipi(int cpu)
-{
- if (psurge_type == PSURGE_NONE)
- return;
- if (cpu == 0)
- in_be32(psurge_pri_intr);
- else if (psurge_type == PSURGE_DUAL)
- out_8(psurge_sec_intr, 0);
- else
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu);
-}
-
-static inline void psurge_clr_ipi(int cpu)
-{
- if (cpu > 0) {
- switch(psurge_type) {
- case PSURGE_DUAL:
- out_8(psurge_sec_intr, ~0);
- case PSURGE_NONE:
- break;
- default:
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu);
- }
- }
-}
-
-/*
- * On powersurge (old SMP powermac architecture) we don't have
- * separate IPIs for separate messages like openpic does. Instead
- * use the generic demux helpers
- * -- paulus.
- */
-static irqreturn_t psurge_ipi_intr(int irq, void *d)
-{
- psurge_clr_ipi(smp_processor_id());
- smp_ipi_demux();
-
- return IRQ_HANDLED;
-}
-
-static void smp_psurge_cause_ipi(int cpu, unsigned long data)
-{
- psurge_set_ipi(cpu);
-}
-
-static int psurge_host_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
-
- return 0;
-}
-
-static const struct irq_domain_ops psurge_host_ops = {
- .map = psurge_host_map,
-};
-
-static int psurge_secondary_ipi_init(void)
-{
- int rc = -ENOMEM;
-
- psurge_host = irq_domain_add_nomap(NULL, 0, &psurge_host_ops, NULL);
-
- if (psurge_host)
- psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
-
- if (psurge_secondary_virq)
- rc = request_irq(psurge_secondary_virq, psurge_ipi_intr,
- IRQF_PERCPU | IRQF_NO_THREAD, "IPI", NULL);
-
- if (rc)
- pr_err("Failed to setup secondary cpu IPI\n");
-
- return rc;
-}
-
-/*
- * Determine a quad card presence. We read the board ID register, we
- * force the data bus to change to something else, and we read it again.
- * It it's stable, then the register probably exist (ugh !)
- */
-static int __init psurge_quad_probe(void)
-{
- int type;
- unsigned int i;
-
- type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID);
- if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS
- || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
- return PSURGE_DUAL;
-
- /* looks OK, try a slightly more rigorous test */
- /* bogus is not necessarily cacheline-aligned,
- though I don't suppose that really matters. -- paulus */
- for (i = 0; i < 100; i++) {
- volatile u32 bogus[8];
- bogus[(0+i)%8] = 0x00000000;
- bogus[(1+i)%8] = 0x55555555;
- bogus[(2+i)%8] = 0xFFFFFFFF;
- bogus[(3+i)%8] = 0xAAAAAAAA;
- bogus[(4+i)%8] = 0x33333333;
- bogus[(5+i)%8] = 0xCCCCCCCC;
- bogus[(6+i)%8] = 0xCCCCCCCC;
- bogus[(7+i)%8] = 0x33333333;
- wmb();
- asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory");
- mb();
- if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID))
- return PSURGE_DUAL;
- }
- return type;
-}
-
-static void __init psurge_quad_init(void)
-{
- int procbits;
-
- if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351);
- procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU);
- if (psurge_type == PSURGE_QUAD_ICEGRASS)
- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
- else
- PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits);
- mdelay(33);
- out_8(psurge_sec_intr, ~0);
- PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits);
- PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits);
- if (psurge_type != PSURGE_QUAD_ICEGRASS)
- PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits);
- PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits);
- mdelay(33);
- PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits);
- mdelay(33);
- PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits);
- mdelay(33);
-}
-
-static int __init smp_psurge_probe(void)
-{
- int i, ncpus;
- struct device_node *dn;
-
- /* We don't do SMP on the PPC601 -- paulus */
- if (PVR_VER(mfspr(SPRN_PVR)) == 1)
- return 1;
-
- /*
- * The powersurge cpu board can be used in the generation
- * of powermacs that have a socket for an upgradeable cpu card,
- * including the 7500, 8500, 9500, 9600.
- * The device tree doesn't tell you if you have 2 cpus because
- * OF doesn't know anything about the 2nd processor.
- * Instead we look for magic bits in magic registers,
- * in the hammerhead memory controller in the case of the
- * dual-cpu powersurge board. -- paulus.
- */
- dn = of_find_node_by_name(NULL, "hammerhead");
- if (dn == NULL)
- return 1;
- of_node_put(dn);
-
- hhead_base = ioremap(HAMMERHEAD_BASE, 0x800);
- quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024);
- psurge_sec_intr = hhead_base + HHEAD_SEC_INTR;
-
- psurge_type = psurge_quad_probe();
- if (psurge_type != PSURGE_DUAL) {
- psurge_quad_init();
- /* All released cards using this HW design have 4 CPUs */
- ncpus = 4;
- /* No sure how timebase sync works on those, let's use SW */
- smp_ops->give_timebase = smp_generic_give_timebase;
- smp_ops->take_timebase = smp_generic_take_timebase;
- } else {
- iounmap(quad_base);
- if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) {
- /* not a dual-cpu card */
- iounmap(hhead_base);
- psurge_type = PSURGE_NONE;
- return 1;
- }
- ncpus = 2;
- }
-
- if (psurge_secondary_ipi_init())
- return 1;
-
- psurge_start = ioremap(PSURGE_START, 4);
- psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
-
- /* This is necessary because OF doesn't know about the
- * secondary cpu(s), and thus there aren't nodes in the
- * device tree for them, and smp_setup_cpu_maps hasn't
- * set their bits in cpu_present_mask.
- */
- if (ncpus > NR_CPUS)
- ncpus = NR_CPUS;
- for (i = 1; i < ncpus ; ++i)
- set_cpu_present(i, true);
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352);
-
- return ncpus;
-}
-
-static int __init smp_psurge_kick_cpu(int nr)
-{
- unsigned long start = __pa(__secondary_start_pmac_0) + nr * 8;
- unsigned long a, flags;
- int i, j;
-
- /* Defining this here is evil ... but I prefer hiding that
- * crap to avoid giving people ideas that they can do the
- * same.
- */
- extern volatile unsigned int cpu_callin_map[NR_CPUS];
-
- /* may need to flush here if secondary bats aren't setup */
- for (a = KERNELBASE; a < KERNELBASE + 0x800000; a += 32)
- asm volatile("dcbf 0,%0" : : "r" (a) : "memory");
- asm volatile("sync");
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353);
-
- /* This is going to freeze the timeebase, we disable interrupts */
- local_irq_save(flags);
-
- out_be32(psurge_start, start);
- mb();
-
- psurge_set_ipi(nr);
-
- /*
- * We can't use udelay here because the timebase is now frozen.
- */
- for (i = 0; i < 2000; ++i)
- asm volatile("nop" : : : "memory");
- psurge_clr_ipi(nr);
-
- /*
- * Also, because the timebase is frozen, we must not return to the
- * caller which will try to do udelay's etc... Instead, we wait -here-
- * for the CPU to callin.
- */
- for (i = 0; i < 100000 && !cpu_callin_map[nr]; ++i) {
- for (j = 1; j < 10000; j++)
- asm volatile("nop" : : : "memory");
- asm volatile("sync" : : : "memory");
- }
- if (!cpu_callin_map[nr])
- goto stuck;
-
- /* And we do the TB sync here too for standard dual CPU cards */
- if (psurge_type == PSURGE_DUAL) {
- while(!tb_req)
- barrier();
- tb_req = 0;
- mb();
- timebase = get_tb();
- mb();
- while (timebase)
- barrier();
- mb();
- }
- stuck:
- /* now interrupt the secondary, restarting both TBs */
- if (psurge_type == PSURGE_DUAL)
- psurge_set_ipi(1);
-
- if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354);
-
- return 0;
-}
-
-static struct irqaction psurge_irqaction = {
- .handler = psurge_ipi_intr,
- .flags = IRQF_PERCPU | IRQF_NO_THREAD,
- .name = "primary IPI",
-};
-
-static void __init smp_psurge_setup_cpu(int cpu_nr)
-{
- if (cpu_nr != 0 || !psurge_start)
- return;
-
- /* reset the entry point so if we get another intr we won't
- * try to startup again */
- out_be32(psurge_start, 0x100);
- if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction))
- printk(KERN_ERR "Couldn't get primary IPI interrupt");
-}
-
-void __init smp_psurge_take_timebase(void)
-{
- if (psurge_type != PSURGE_DUAL)
- return;
-
- tb_req = 1;
- mb();
- while (!timebase)
- barrier();
- mb();
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- mb();
- set_dec(tb_ticks_per_jiffy/2);
-}
-
-void __init smp_psurge_give_timebase(void)
-{
- /* Nothing to do here */
-}
-
-/* PowerSurge-style Macs */
-struct smp_ops_t psurge_smp_ops = {
- .message_pass = NULL, /* Use smp_muxed_ipi_message_pass */
- .cause_ipi = smp_psurge_cause_ipi,
- .probe = smp_psurge_probe,
- .kick_cpu = smp_psurge_kick_cpu,
- .setup_cpu = smp_psurge_setup_cpu,
- .give_timebase = smp_psurge_give_timebase,
- .take_timebase = smp_psurge_take_timebase,
-};
-#endif /* CONFIG_PPC_PMAC32_PSURGE */
-
-/*
- * Core 99 and later support
- */
-
-
-static void smp_core99_give_timebase(void)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- while(!tb_req)
- barrier();
- tb_req = 0;
- (*pmac_tb_freeze)(1);
- mb();
- timebase = get_tb();
- mb();
- while (timebase)
- barrier();
- mb();
- (*pmac_tb_freeze)(0);
- mb();
-
- local_irq_restore(flags);
-}
-
-
-static void __devinit smp_core99_take_timebase(void)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- tb_req = 1;
- mb();
- while (!timebase)
- barrier();
- mb();
- set_tb(timebase >> 32, timebase & 0xffffffff);
- timebase = 0;
- mb();
-
- local_irq_restore(flags);
-}
-
-#ifdef CONFIG_PPC64
-/*
- * G5s enable/disable the timebase via an i2c-connected clock chip.
- */
-static struct pmac_i2c_bus *pmac_tb_clock_chip_host;
-static u8 pmac_tb_pulsar_addr;
-
-static void smp_core99_cypress_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- /* Strangely, the device-tree says address is 0xd2, but darwin
- * accesses 0xd0 ...
- */
- pmac_i2c_setmode(pmac_tb_clock_chip_host,
- pmac_i2c_mode_combined);
- rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_i2c_read,
- 1, 0x81, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0xf3) | (freeze ? 0x00 : 0x0c);
-
- pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
- rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
- 0xd0 | pmac_i2c_write,
- 1, 0x81, &data, 1);
-
- bail:
- if (rc != 0) {
- printk("Cypress Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-
-static void smp_core99_pulsar_tb_freeze(int freeze)
-{
- u8 data;
- int rc;
-
- pmac_i2c_setmode(pmac_tb_clock_chip_host,
- pmac_i2c_mode_combined);
- rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_i2c_read,
- 1, 0x2e, &data, 1);
- if (rc != 0)
- goto bail;
-
- data = (data & 0x88) | (freeze ? 0x11 : 0x22);
-
- pmac_i2c_setmode(pmac_tb_clock_chip_host, pmac_i2c_mode_stdsub);
- rc = pmac_i2c_xfer(pmac_tb_clock_chip_host,
- pmac_tb_pulsar_addr | pmac_i2c_write,
- 1, 0x2e, &data, 1);
- bail:
- if (rc != 0) {
- printk(KERN_ERR "Pulsar Timebase %s rc: %d\n",
- freeze ? "freeze" : "unfreeze", rc);
- panic("Timebase freeze failed !\n");
- }
-}
-
-static void __init smp_core99_setup_i2c_hwsync(int ncpus)
-{
- struct device_node *cc = NULL;
- struct device_node *p;
- const char *name = NULL;
- const u32 *reg;
- int ok;
-
- /* Look for the clock chip */
- while ((cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL) {
- p = of_get_parent(cc);
- ok = p && of_device_is_compatible(p, "uni-n-i2c");
- of_node_put(p);
- if (!ok)
- continue;
-
- pmac_tb_clock_chip_host = pmac_i2c_find_bus(cc);
- if (pmac_tb_clock_chip_host == NULL)
- continue;
- reg = of_get_property(cc, "reg", NULL);
- if (reg == NULL)
- continue;
- switch (*reg) {
- case 0xd2:
- if (of_device_is_compatible(cc,"pulsar-legacy-slewing")) {
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd2;
- name = "Pulsar";
- } else if (of_device_is_compatible(cc, "cy28508")) {
- pmac_tb_freeze = smp_core99_cypress_tb_freeze;
- name = "Cypress";
- }
- break;
- case 0xd4:
- pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
- pmac_tb_pulsar_addr = 0xd4;
- name = "Pulsar";
- break;
- }
- if (pmac_tb_freeze != NULL)
- break;
- }
- if (pmac_tb_freeze != NULL) {
- /* Open i2c bus for synchronous access */
- if (pmac_i2c_open(pmac_tb_clock_chip_host, 1)) {
- printk(KERN_ERR "Failed top open i2c bus for clock"
- " sync, fallback to software sync !\n");
- goto no_i2c_sync;
- }
- printk(KERN_INFO "Processor timebase sync using %s i2c clock\n",
- name);
- return;
- }
- no_i2c_sync:
- pmac_tb_freeze = NULL;
- pmac_tb_clock_chip_host = NULL;
-}
-
-
-
-/*
- * Newer G5s uses a platform function
- */
-
-static void smp_core99_pfunc_tb_freeze(int freeze)
-{
- struct device_node *cpus;
- struct pmf_args args;
-
- cpus = of_find_node_by_path("/cpus");
- BUG_ON(cpus == NULL);
- args.count = 1;
- args.u[0].v = !freeze;
- pmf_call_function(cpus, "cpu-timebase", &args);
- of_node_put(cpus);
-}
-
-#else /* CONFIG_PPC64 */
-
-/*
- * SMP G4 use a GPIO to enable/disable the timebase.
- */
-
-static unsigned int core99_tb_gpio; /* Timebase freeze GPIO */
-
-static void smp_core99_gpio_tb_freeze(int freeze)
-{
- if (freeze)
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 4);
- else
- pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, core99_tb_gpio, 0);
- pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, core99_tb_gpio, 0);
-}
-
-
-#endif /* !CONFIG_PPC64 */
-
-/* L2 and L3 cache settings to pass from CPU0 to CPU1 on G4 cpus */
-volatile static long int core99_l2_cache;
-volatile static long int core99_l3_cache;
-
-static void __devinit core99_init_caches(int cpu)
-{
-#ifndef CONFIG_PPC64
- if (!cpu_has_feature(CPU_FTR_L2CR))
- return;
-
- if (cpu == 0) {
- core99_l2_cache = _get_L2CR();
- printk("CPU0: L2CR is %lx\n", core99_l2_cache);
- } else {
- printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR());
- _set_L2CR(0);
- _set_L2CR(core99_l2_cache);
- printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache);
- }
-
- if (!cpu_has_feature(CPU_FTR_L3CR))
- return;
-
- if (cpu == 0){
- core99_l3_cache = _get_L3CR();
- printk("CPU0: L3CR is %lx\n", core99_l3_cache);
- } else {
- printk("CPU%d: L3CR was %lx\n", cpu, _get_L3CR());
- _set_L3CR(0);
- _set_L3CR(core99_l3_cache);
- printk("CPU%d: L3CR set to %lx\n", cpu, core99_l3_cache);
- }
-#endif /* !CONFIG_PPC64 */
-}
-
-static void __init smp_core99_setup(int ncpus)
-{
-#ifdef CONFIG_PPC64
-
- /* i2c based HW sync on some G5s */
- if (of_machine_is_compatible("PowerMac7,2") ||
- of_machine_is_compatible("PowerMac7,3") ||
- of_machine_is_compatible("RackMac3,1"))
- smp_core99_setup_i2c_hwsync(ncpus);
-
- /* pfunc based HW sync on recent G5s */
- if (pmac_tb_freeze == NULL) {
- struct device_node *cpus =
- of_find_node_by_path("/cpus");
- if (cpus &&
- of_get_property(cpus, "platform-cpu-timebase", NULL)) {
- pmac_tb_freeze = smp_core99_pfunc_tb_freeze;
- printk(KERN_INFO "Processor timebase sync using"
- " platform function\n");
- }
- }
-
-#else /* CONFIG_PPC64 */
-
- /* GPIO based HW sync on ppc32 Core99 */
- if (pmac_tb_freeze == NULL && !of_machine_is_compatible("MacRISC4")) {
- struct device_node *cpu;
- const u32 *tbprop = NULL;
-
- core99_tb_gpio = KL_GPIO_TB_ENABLE; /* default value */
- cpu = of_find_node_by_type(NULL, "cpu");
- if (cpu != NULL) {
- tbprop = of_get_property(cpu, "timebase-enable", NULL);
- if (tbprop)
- core99_tb_gpio = *tbprop;
- of_node_put(cpu);
- }
- pmac_tb_freeze = smp_core99_gpio_tb_freeze;
- printk(KERN_INFO "Processor timebase sync using"
- " GPIO 0x%02x\n", core99_tb_gpio);
- }
-
-#endif /* CONFIG_PPC64 */
-
- /* No timebase sync, fallback to software */
- if (pmac_tb_freeze == NULL) {
- smp_ops->give_timebase = smp_generic_give_timebase;
- smp_ops->take_timebase = smp_generic_take_timebase;
- printk(KERN_INFO "Processor timebase sync using software\n");
- }
-
-#ifndef CONFIG_PPC64
- {
- int i;
-
- /* XXX should get this from reg properties */
- for (i = 1; i < ncpus; ++i)
- set_hard_smp_processor_id(i, i);
- }
-#endif
-
- /* 32 bits SMP can't NAP */
- if (!of_machine_is_compatible("MacRISC4"))
- powersave_nap = 0;
-}
-
-static int __init smp_core99_probe(void)
-{
- struct device_node *cpus;
- int ncpus = 0;
-
- if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345);
-
- /* Count CPUs in the device-tree */
- for (cpus = NULL; (cpus = of_find_node_by_type(cpus, "cpu")) != NULL;)
- ++ncpus;
-
- printk(KERN_INFO "PowerMac SMP probe found %d cpus\n", ncpus);
-
- /* Nothing more to do if less than 2 of them */
- if (ncpus <= 1)
- return 1;
-
- /* We need to perform some early initialisations before we can start
- * setting up SMP as we are running before initcalls
- */
- pmac_pfunc_base_install();
- pmac_i2c_init();
-
- /* Setup various bits like timebase sync method, ability to nap, ... */
- smp_core99_setup(ncpus);
-
- /* Install IPIs */
- mpic_request_ipis();
-
- /* Collect l2cr and l3cr values from CPU 0 */
- core99_init_caches(0);
-
- return ncpus;
-}
-
-static int __devinit smp_core99_kick_cpu(int nr)
-{
- unsigned int save_vector;
- unsigned long target, flags;
- unsigned int *vector = (unsigned int *)(PAGE_OFFSET+0x100);
-
- if (nr < 0 || nr > 3)
- return -ENOENT;
-
- if (ppc_md.progress)
- ppc_md.progress("smp_core99_kick_cpu", 0x346);
-
- local_irq_save(flags);
-
- /* Save reset vector */
- save_vector = *vector;
-
- /* Setup fake reset vector that does
- * b __secondary_start_pmac_0 + nr*8
- */
- target = (unsigned long) __secondary_start_pmac_0 + nr * 8;
- patch_branch(vector, target, BRANCH_SET_LINK);
-
- /* Put some life in our friend */
- pmac_call_feature(PMAC_FTR_RESET_CPU, NULL, nr, 0);
-
- /* FIXME: We wait a bit for the CPU to take the exception, I should
- * instead wait for the entry code to set something for me. Well,
- * ideally, all that crap will be done in prom.c and the CPU left
- * in a RAM-based wait loop like CHRP.
- */
- mdelay(1);
-
- /* Restore our exception vector */
- *vector = save_vector;
- flush_icache_range((unsigned long) vector, (unsigned long) vector + 4);
-
- local_irq_restore(flags);
- if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu done", 0x347);
-
- return 0;
-}
-
-static void __devinit smp_core99_setup_cpu(int cpu_nr)
-{
- /* Setup L2/L3 */
- if (cpu_nr != 0)
- core99_init_caches(cpu_nr);
-
- /* Setup openpic */
- mpic_setup_this_cpu();
-}
-
-#ifdef CONFIG_PPC64
-#ifdef CONFIG_HOTPLUG_CPU
-static int smp_core99_cpu_notify(struct notifier_block *self,
- unsigned long action, void *hcpu)
-{
- int rc;
-
- switch(action) {
- case CPU_UP_PREPARE:
- case CPU_UP_PREPARE_FROZEN:
- /* Open i2c bus if it was used for tb sync */
- if (pmac_tb_clock_chip_host) {
- rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
- if (rc) {
- pr_err("Failed to open i2c bus for time sync\n");
- return notifier_from_errno(rc);
- }
- }
- break;
- case CPU_ONLINE:
- case CPU_UP_CANCELED:
- /* Close i2c bus if it was used for tb sync */
- if (pmac_tb_clock_chip_host)
- pmac_i2c_close(pmac_tb_clock_chip_host);
- break;
- default:
- break;
- }
- return NOTIFY_OK;
-}
-
-static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
- .notifier_call = smp_core99_cpu_notify,
-};
-#endif /* CONFIG_HOTPLUG_CPU */
-
-static void __init smp_core99_bringup_done(void)
-{
- extern void g5_phy_disable_cpu1(void);
-
- /* Close i2c bus if it was used for tb sync */
- if (pmac_tb_clock_chip_host)
- pmac_i2c_close(pmac_tb_clock_chip_host);
-
- /* If we didn't start the second CPU, we must take
- * it off the bus.
- */
- if (of_machine_is_compatible("MacRISC4") &&
- num_online_cpus() < 2) {
- set_cpu_present(1, false);
- g5_phy_disable_cpu1();
- }
-#ifdef CONFIG_HOTPLUG_CPU
- register_cpu_notifier(&smp_core99_cpu_nb);
-#endif
-
- if (ppc_md.progress)
- ppc_md.progress("smp_core99_bringup_done", 0x349);
-}
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-static int smp_core99_cpu_disable(void)
-{
- int rc = generic_cpu_disable();
- if (rc)
- return rc;
-
- mpic_cpu_set_priority(0xf);
-
- return 0;
-}
-
-#ifdef CONFIG_PPC32
-
-static void pmac_cpu_die(void)
-{
- int cpu = smp_processor_id();
-
- local_irq_disable();
- idle_task_exit();
- pr_debug("CPU%d offline\n", cpu);
- generic_set_cpu_dead(cpu);
- smp_wmb();
- mb();
- low_cpu_die();
-}
-
-#else /* CONFIG_PPC32 */
-
-static void pmac_cpu_die(void)
-{
- int cpu = smp_processor_id();
-
- local_irq_disable();
- idle_task_exit();
-
- /*
- * turn off as much as possible, we'll be
- * kicked out as this will only be invoked
- * on core99 platforms for now ...
- */
-
- printk(KERN_INFO "CPU#%d offline\n", cpu);
- generic_set_cpu_dead(cpu);
- smp_wmb();
-
- /*
- * Re-enable interrupts. The NAP code needs to enable them
- * anyways, do it now so we deal with the case where one already
- * happened while soft-disabled.
- * We shouldn't get any external interrupts, only decrementer, and the
- * decrementer handler is safe for use on offline CPUs
- */
- local_irq_enable();
-
- while (1) {
- /* let's not take timer interrupts too often ... */
- set_dec(0x7fffffff);
-
- /* Enter NAP mode */
- power4_idle();
- }
-}
-
-#endif /* else CONFIG_PPC32 */
-#endif /* CONFIG_HOTPLUG_CPU */
-
-/* Core99 Macs (dual G4s and G5s) */
-struct smp_ops_t core99_smp_ops = {
- .message_pass = smp_mpic_message_pass,
- .probe = smp_core99_probe,
-#ifdef CONFIG_PPC64
- .bringup_done = smp_core99_bringup_done,
-#endif
- .kick_cpu = smp_core99_kick_cpu,
- .setup_cpu = smp_core99_setup_cpu,
- .give_timebase = smp_core99_give_timebase,
- .take_timebase = smp_core99_take_timebase,
-#if defined(CONFIG_HOTPLUG_CPU)
- .cpu_disable = smp_core99_cpu_disable,
- .cpu_die = generic_cpu_die,
-#endif
-};
-
-void __init pmac_setup_smp(void)
-{
- struct device_node *np;
-
- /* Check for Core99 */
- np = of_find_node_by_name(NULL, "uni-n");
- if (!np)
- np = of_find_node_by_name(NULL, "u3");
- if (!np)
- np = of_find_node_by_name(NULL, "u4");
- if (np) {
- of_node_put(np);
- smp_ops = &core99_smp_ops;
- }
-#ifdef CONFIG_PPC_PMAC32_PSURGE
- else {
- /* We have to set bits in cpu_possible_mask here since the
- * secondary CPU(s) aren't in the device tree. Various
- * things won't be initialized for CPUs not in the possible
- * map, so we really need to fix it up here.
- */
- int cpu;
-
- for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
- set_cpu_possible(cpu, true);
- smp_ops = &psurge_smp_ops;
- }
-#endif /* CONFIG_PPC_PMAC32_PSURGE */
-
-#ifdef CONFIG_HOTPLUG_CPU
- ppc_md.cpu_die = pmac_cpu_die;
-#endif
-}
-
-
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/time.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/time.c
deleted file mode 100644
index 8680bb69..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/time.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
- * Support for periodic interrupts (100 per second) and for getting
- * the current time from the RTC on Power Macintoshes.
- *
- * We use the decrementer register for our periodic interrupts.
- *
- * Paul Mackerras August 1996.
- * Copyright (C) 1996 Paul Mackerras.
- * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
- *
- */
-#include <linux/errno.h>
-#include <linux/sched.h>
-#include <linux/kernel.h>
-#include <linux/param.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <linux/time.h>
-#include <linux/adb.h>
-#include <linux/cuda.h>
-#include <linux/pmu.h>
-#include <linux/interrupt.h>
-#include <linux/hardirq.h>
-#include <linux/rtc.h>
-
-#include <asm/sections.h>
-#include <asm/prom.h>
-#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/machdep.h>
-#include <asm/time.h>
-#include <asm/nvram.h>
-#include <asm/smu.h>
-
-#undef DEBUG
-
-#ifdef DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-/* Apparently the RTC stores seconds since 1 Jan 1904 */
-#define RTC_OFFSET 2082844800
-
-/*
- * Calibrate the decrementer frequency with the VIA timer 1.
- */
-#define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
-
-/* VIA registers */
-#define RS 0x200 /* skip between registers */
-#define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
-#define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
-#define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
-#define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
-#define ACR (11*RS) /* Auxiliary control register */
-#define IFR (13*RS) /* Interrupt flag register */
-
-/* Bits in ACR */
-#define T1MODE 0xc0 /* Timer 1 mode */
-#define T1MODE_CONT 0x40 /* continuous interrupts */
-
-/* Bits in IFR and IER */
-#define T1_INT 0x40 /* Timer 1 interrupt */
-
-long __init pmac_time_init(void)
-{
- s32 delta = 0;
-#ifdef CONFIG_NVRAM
- int dst;
-
- delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
- delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
- delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
- if (delta & 0x00800000UL)
- delta |= 0xFF000000UL;
- dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
- printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
- dst ? "on" : "off");
-#endif
- return delta;
-}
-
-#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
-static void to_rtc_time(unsigned long now, struct rtc_time *tm)
-{
- to_tm(now, tm);
- tm->tm_year -= 1900;
- tm->tm_mon -= 1;
-}
-#endif
-
-#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU) || \
- defined(CONFIG_PMAC_SMU)
-static unsigned long from_rtc_time(struct rtc_time *tm)
-{
- return mktime(tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec);
-}
-#endif
-
-#ifdef CONFIG_ADB_CUDA
-static unsigned long cuda_get_time(void)
-{
- struct adb_request req;
- unsigned int now;
-
- if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
- return 0;
- while (!req.complete)
- cuda_poll();
- if (req.reply_len != 7)
- printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
- req.reply_len);
- now = (req.reply[3] << 24) + (req.reply[4] << 16)
- + (req.reply[5] << 8) + req.reply[6];
- return ((unsigned long)now) - RTC_OFFSET;
-}
-
-#define cuda_get_rtc_time(tm) to_rtc_time(cuda_get_time(), (tm))
-
-static int cuda_set_rtc_time(struct rtc_time *tm)
-{
- unsigned int nowtime;
- struct adb_request req;
-
- nowtime = from_rtc_time(tm) + RTC_OFFSET;
- if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
- nowtime >> 24, nowtime >> 16, nowtime >> 8,
- nowtime) < 0)
- return -ENXIO;
- while (!req.complete)
- cuda_poll();
- if ((req.reply_len != 3) && (req.reply_len != 7))
- printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
- req.reply_len);
- return 0;
-}
-
-#else
-#define cuda_get_time() 0
-#define cuda_get_rtc_time(tm)
-#define cuda_set_rtc_time(tm) 0
-#endif
-
-#ifdef CONFIG_ADB_PMU
-static unsigned long pmu_get_time(void)
-{
- struct adb_request req;
- unsigned int now;
-
- if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
- return 0;
- pmu_wait_complete(&req);
- if (req.reply_len != 4)
- printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
- req.reply_len);
- now = (req.reply[0] << 24) + (req.reply[1] << 16)
- + (req.reply[2] << 8) + req.reply[3];
- return ((unsigned long)now) - RTC_OFFSET;
-}
-
-#define pmu_get_rtc_time(tm) to_rtc_time(pmu_get_time(), (tm))
-
-static int pmu_set_rtc_time(struct rtc_time *tm)
-{
- unsigned int nowtime;
- struct adb_request req;
-
- nowtime = from_rtc_time(tm) + RTC_OFFSET;
- if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
- nowtime >> 16, nowtime >> 8, nowtime) < 0)
- return -ENXIO;
- pmu_wait_complete(&req);
- if (req.reply_len != 0)
- printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
- req.reply_len);
- return 0;
-}
-
-#else
-#define pmu_get_time() 0
-#define pmu_get_rtc_time(tm)
-#define pmu_set_rtc_time(tm) 0
-#endif
-
-#ifdef CONFIG_PMAC_SMU
-static unsigned long smu_get_time(void)
-{
- struct rtc_time tm;
-
- if (smu_get_rtc_time(&tm, 1))
- return 0;
- return from_rtc_time(&tm);
-}
-
-#else
-#define smu_get_time() 0
-#define smu_get_rtc_time(tm, spin)
-#define smu_set_rtc_time(tm, spin) 0
-#endif
-
-/* Can't be __init, it's called when suspending and resuming */
-unsigned long pmac_get_boot_time(void)
-{
- /* Get the time from the RTC, used only at boot time */
- switch (sys_ctrler) {
- case SYS_CTRLER_CUDA:
- return cuda_get_time();
- case SYS_CTRLER_PMU:
- return pmu_get_time();
- case SYS_CTRLER_SMU:
- return smu_get_time();
- default:
- return 0;
- }
-}
-
-void pmac_get_rtc_time(struct rtc_time *tm)
-{
- /* Get the time from the RTC, used only at boot time */
- switch (sys_ctrler) {
- case SYS_CTRLER_CUDA:
- cuda_get_rtc_time(tm);
- break;
- case SYS_CTRLER_PMU:
- pmu_get_rtc_time(tm);
- break;
- case SYS_CTRLER_SMU:
- smu_get_rtc_time(tm, 1);
- break;
- default:
- ;
- }
-}
-
-int pmac_set_rtc_time(struct rtc_time *tm)
-{
- switch (sys_ctrler) {
- case SYS_CTRLER_CUDA:
- return cuda_set_rtc_time(tm);
- case SYS_CTRLER_PMU:
- return pmu_set_rtc_time(tm);
- case SYS_CTRLER_SMU:
- return smu_set_rtc_time(tm, 1);
- default:
- return -ENODEV;
- }
-}
-
-#ifdef CONFIG_PPC32
-/*
- * Calibrate the decrementer register using VIA timer 1.
- * This is used both on powermacs and CHRP machines.
- */
-int __init via_calibrate_decr(void)
-{
- struct device_node *vias;
- volatile unsigned char __iomem *via;
- int count = VIA_TIMER_FREQ_6 / 100;
- unsigned int dstart, dend;
- struct resource rsrc;
-
- vias = of_find_node_by_name(NULL, "via-cuda");
- if (vias == NULL)
- vias = of_find_node_by_name(NULL, "via-pmu");
- if (vias == NULL)
- vias = of_find_node_by_name(NULL, "via");
- if (vias == NULL || of_address_to_resource(vias, 0, &rsrc)) {
- of_node_put(vias);
- return 0;
- }
- of_node_put(vias);
- via = ioremap(rsrc.start, resource_size(&rsrc));
- if (via == NULL) {
- printk(KERN_ERR "Failed to map VIA for timer calibration !\n");
- return 0;
- }
-
- /* set timer 1 for continuous interrupts */
- out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
- /* set the counter to a small value */
- out_8(&via[T1CH], 2);
- /* set the latch to `count' */
- out_8(&via[T1LL], count);
- out_8(&via[T1LH], count >> 8);
- /* wait until it hits 0 */
- while ((in_8(&via[IFR]) & T1_INT) == 0)
- ;
- dstart = get_dec();
- /* clear the interrupt & wait until it hits 0 again */
- in_8(&via[T1CL]);
- while ((in_8(&via[IFR]) & T1_INT) == 0)
- ;
- dend = get_dec();
-
- ppc_tb_freq = (dstart - dend) * 100 / 6;
-
- iounmap(via);
-
- return 1;
-}
-#endif
-
-/*
- * Query the OF and get the decr frequency.
- */
-void __init pmac_calibrate_decr(void)
-{
- generic_calibrate_decr();
-
-#ifdef CONFIG_PPC32
- /* We assume MacRISC2 machines have correct device-tree
- * calibration. That's better since the VIA itself seems
- * to be slightly off. --BenH
- */
- if (!of_machine_is_compatible("MacRISC2") &&
- !of_machine_is_compatible("MacRISC3") &&
- !of_machine_is_compatible("MacRISC4"))
- if (via_calibrate_decr())
- return;
-
- /* Special case: QuickSilver G4s seem to have a badly calibrated
- * timebase-frequency in OF, VIA is much better on these. We should
- * probably implement calibration based on the KL timer on these
- * machines anyway... -BenH
- */
- if (of_machine_is_compatible("PowerMac3,5"))
- if (via_calibrate_decr())
- return;
-#endif
-}
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_adb.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_adb.c
deleted file mode 100644
index 44e0b55a..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_adb.c
+++ /dev/null
@@ -1,219 +0,0 @@
-#include <linux/string.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/bitops.h>
-#include <linux/ptrace.h>
-#include <linux/adb.h>
-#include <linux/pmu.h>
-#include <linux/cuda.h>
-#include <asm/machdep.h>
-#include <asm/io.h>
-#include <asm/page.h>
-#include <asm/xmon.h>
-#include <asm/prom.h>
-#include <asm/bootx.h>
-#include <asm/errno.h>
-#include <asm/pmac_feature.h>
-#include <asm/processor.h>
-#include <asm/delay.h>
-#include <asm/btext.h>
-#include <asm/time.h>
-#include <asm/udbg.h>
-
-/*
- * This implementation is "special", it can "patch" the current
- * udbg implementation and work on top of it. It must thus be
- * initialized last
- */
-
-static void (*udbg_adb_old_putc)(char c);
-static int (*udbg_adb_old_getc)(void);
-static int (*udbg_adb_old_getc_poll)(void);
-
-static enum {
- input_adb_none,
- input_adb_pmu,
- input_adb_cuda,
-} input_type = input_adb_none;
-
-int xmon_wants_key, xmon_adb_keycode;
-
-static inline void udbg_adb_poll(void)
-{
-#ifdef CONFIG_ADB_PMU
- if (input_type == input_adb_pmu)
- pmu_poll_adb();
-#endif /* CONFIG_ADB_PMU */
-#ifdef CONFIG_ADB_CUDA
- if (input_type == input_adb_cuda)
- cuda_poll();
-#endif /* CONFIG_ADB_CUDA */
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-
-static int udbg_adb_use_btext;
-static int xmon_adb_shiftstate;
-
-static unsigned char xmon_keytab[128] =
- "asdfhgzxcv\000bqwer" /* 0x00 - 0x0f */
- "yt123465=97-80]o" /* 0x10 - 0x1f */
- "u[ip\rlj'k;\\,/nm." /* 0x20 - 0x2f */
- "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
- "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
- "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
-
-static unsigned char xmon_shift_keytab[128] =
- "ASDFHGZXCV\000BQWER" /* 0x00 - 0x0f */
- "YT!@#$^%+(&_*)}O" /* 0x10 - 0x1f */
- "U{IP\rLJ\"K:|<?NM>" /* 0x20 - 0x2f */
- "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0" /* 0x30 - 0x3f */
- "\0.\0*\0+\0\0\0\0\0/\r\0-\0" /* 0x40 - 0x4f */
- "\0\0000123456789\0\0\0"; /* 0x50 - 0x5f */
-
-static int udbg_adb_local_getc(void)
-{
- int k, t, on;
-
- xmon_wants_key = 1;
- for (;;) {
- xmon_adb_keycode = -1;
- t = 0;
- on = 0;
- k = -1;
- do {
- if (--t < 0) {
- on = 1 - on;
- btext_drawchar(on? 0xdb: 0x20);
- btext_drawchar('\b');
- t = 200000;
- }
- udbg_adb_poll();
- if (udbg_adb_old_getc_poll)
- k = udbg_adb_old_getc_poll();
- } while (k == -1 && xmon_adb_keycode == -1);
- if (on)
- btext_drawstring(" \b");
- if (k != -1)
- return k;
- k = xmon_adb_keycode;
-
- /* test for shift keys */
- if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
- xmon_adb_shiftstate = (k & 0x80) == 0;
- continue;
- }
- if (k >= 0x80)
- continue; /* ignore up transitions */
- k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
- if (k != 0)
- break;
- }
- xmon_wants_key = 0;
- return k;
-}
-#endif /* CONFIG_BOOTX_TEXT */
-
-static int udbg_adb_getc(void)
-{
-#ifdef CONFIG_BOOTX_TEXT
- if (udbg_adb_use_btext && input_type != input_adb_none)
- return udbg_adb_local_getc();
-#endif
- if (udbg_adb_old_getc)
- return udbg_adb_old_getc();
- return -1;
-}
-
-/* getc_poll() is not really used, unless you have the xmon-over modem
- * hack that doesn't quite concern us here, thus we just poll the low level
- * ADB driver to prevent it from timing out and call back the original poll
- * routine.
- */
-static int udbg_adb_getc_poll(void)
-{
- udbg_adb_poll();
-
- if (udbg_adb_old_getc_poll)
- return udbg_adb_old_getc_poll();
- return -1;
-}
-
-static void udbg_adb_putc(char c)
-{
-#ifdef CONFIG_BOOTX_TEXT
- if (udbg_adb_use_btext)
- btext_drawchar(c);
-#endif
- if (udbg_adb_old_putc)
- return udbg_adb_old_putc(c);
-}
-
-void __init udbg_adb_init_early(void)
-{
-#ifdef CONFIG_BOOTX_TEXT
- if (btext_find_display(1) == 0) {
- udbg_adb_use_btext = 1;
- udbg_putc = udbg_adb_putc;
- }
-#endif
-}
-
-int __init udbg_adb_init(int force_btext)
-{
- struct device_node *np;
-
- /* Capture existing callbacks */
- udbg_adb_old_putc = udbg_putc;
- udbg_adb_old_getc = udbg_getc;
- udbg_adb_old_getc_poll = udbg_getc_poll;
-
- /* Check if our early init was already called */
- if (udbg_adb_old_putc == udbg_adb_putc)
- udbg_adb_old_putc = NULL;
-#ifdef CONFIG_BOOTX_TEXT
- if (udbg_adb_old_putc == btext_drawchar)
- udbg_adb_old_putc = NULL;
-#endif
-
- /* Set ours as output */
- udbg_putc = udbg_adb_putc;
- udbg_getc = udbg_adb_getc;
- udbg_getc_poll = udbg_adb_getc_poll;
-
-#ifdef CONFIG_BOOTX_TEXT
- /* Check if we should use btext output */
- if (btext_find_display(force_btext) == 0)
- udbg_adb_use_btext = 1;
-#endif
-
- /* See if there is a keyboard in the device tree with a parent
- * of type "adb". If not, we return a failure, but we keep the
- * bext output set for now
- */
- for (np = NULL; (np = of_find_node_by_name(np, "keyboard")) != NULL;) {
- struct device_node *parent = of_get_parent(np);
- int found = (parent && strcmp(parent->type, "adb") == 0);
- of_node_put(parent);
- if (found)
- break;
- }
- if (np == NULL)
- return -ENODEV;
- of_node_put(np);
-
-#ifdef CONFIG_ADB_PMU
- if (find_via_pmu())
- input_type = input_adb_pmu;
-#endif
-#ifdef CONFIG_ADB_CUDA
- if (find_via_cuda())
- input_type = input_adb_cuda;
-#endif
-
- /* Same as above: nothing found, keep btext set for output */
- if (input_type == input_adb_none)
- return -ENODEV;
-
- return 0;
-}
diff --git a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_scc.c b/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_scc.c
deleted file mode 100644
index d83135a9..00000000
--- a/ANDROID_3.4.5/arch/powerpc/platforms/powermac/udbg_scc.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * udbg for zilog scc ports as found on Apple PowerMacs
- *
- * Copyright (C) 2001-2005 PPC 64 Team, IBM Corp
- *
- * 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.
- */
-#include <linux/types.h>
-#include <asm/udbg.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/pmac_feature.h>
-
-extern u8 real_readb(volatile u8 __iomem *addr);
-extern void real_writeb(u8 data, volatile u8 __iomem *addr);
-
-#define SCC_TXRDY 4
-#define SCC_RXRDY 1
-
-static volatile u8 __iomem *sccc;
-static volatile u8 __iomem *sccd;
-
-static void udbg_scc_putc(char c)
-{
- if (sccc) {
- while ((in_8(sccc) & SCC_TXRDY) == 0)
- ;
- out_8(sccd, c);
- if (c == '\n')
- udbg_scc_putc('\r');
- }
-}
-
-static int udbg_scc_getc_poll(void)
-{
- if (sccc) {
- if ((in_8(sccc) & SCC_RXRDY) != 0)
- return in_8(sccd);
- else
- return -1;
- }
- return -1;
-}
-
-static int udbg_scc_getc(void)
-{
- if (sccc) {
- while ((in_8(sccc) & SCC_RXRDY) == 0)
- ;
- return in_8(sccd);
- }
- return -1;
-}
-
-static unsigned char scc_inittab[] = {
- 13, 0, /* set baud rate divisor */
- 12, 0,
- 14, 1, /* baud rate gen enable, src=rtxc */
- 11, 0x50, /* clocks = br gen */
- 5, 0xea, /* tx 8 bits, assert DTR & RTS */
- 4, 0x46, /* x16 clock, 1 stop */
- 3, 0xc1, /* rx enable, 8 bits */
-};
-
-void udbg_scc_init(int force_scc)
-{
- const u32 *reg;
- unsigned long addr;
- struct device_node *stdout = NULL, *escc = NULL, *macio = NULL;
- struct device_node *ch, *ch_def = NULL, *ch_a = NULL;
- const char *path;
- int i, x;
-
- escc = of_find_node_by_name(NULL, "escc");
- if (escc == NULL)
- goto bail;
- macio = of_get_parent(escc);
- if (macio == NULL)
- goto bail;
- path = of_get_property(of_chosen, "linux,stdout-path", NULL);
- if (path != NULL)
- stdout = of_find_node_by_path(path);
- for (ch = NULL; (ch = of_get_next_child(escc, ch)) != NULL;) {
- if (ch == stdout)
- ch_def = of_node_get(ch);
- if (strcmp(ch->name, "ch-a") == 0)
- ch_a = of_node_get(ch);
- }
- if (ch_def == NULL && !force_scc)
- goto bail;
-
- ch = ch_def ? ch_def : ch_a;
-
- /* Get address within mac-io ASIC */
- reg = of_get_property(escc, "reg", NULL);
- if (reg == NULL)
- goto bail;
- addr = reg[0];
-
- /* Get address of mac-io PCI itself */
- reg = of_get_property(macio, "assigned-addresses", NULL);
- if (reg == NULL)
- goto bail;
- addr += reg[2];
-
- /* Lock the serial port */
- pmac_call_feature(PMAC_FTR_SCC_ENABLE, ch,
- PMAC_SCC_ASYNC | PMAC_SCC_FLAG_XMON, 1);
-
- if (ch == ch_a)
- addr += 0x20;
- sccc = ioremap(addr & PAGE_MASK, PAGE_SIZE) ;
- sccc += addr & ~PAGE_MASK;
- sccd = sccc + 0x10;
-
- mb();
-
- for (i = 20000; i != 0; --i)
- x = in_8(sccc);
- out_8(sccc, 0x09); /* reset A or B side */
- out_8(sccc, 0xc0);
-
- /* If SCC was the OF output port, read the BRG value, else
- * Setup for 38400 or 57600 8N1 depending on the machine
- */
- if (ch_def != NULL) {
- out_8(sccc, 13);
- scc_inittab[1] = in_8(sccc);
- out_8(sccc, 12);
- scc_inittab[3] = in_8(sccc);
- } else if (of_machine_is_compatible("RackMac1,1")
- || of_machine_is_compatible("RackMac1,2")
- || of_machine_is_compatible("MacRISC4")) {
- /* Xserves and G5s default to 57600 */
- scc_inittab[1] = 0;
- scc_inittab[3] = 0;
- } else {
- /* Others default to 38400 */
- scc_inittab[1] = 0;
- scc_inittab[3] = 1;
- }
-
- for (i = 0; i < sizeof(scc_inittab); ++i)
- out_8(sccc, scc_inittab[i]);
-
-
- udbg_putc = udbg_scc_putc;
- udbg_getc = udbg_scc_getc;
- udbg_getc_poll = udbg_scc_getc_poll;
-
- udbg_puts("Hello World !\n");
-
- bail:
- of_node_put(macio);
- of_node_put(escc);
- of_node_put(stdout);
- of_node_put(ch_def);
- of_node_put(ch_a);
-}
-
-#ifdef CONFIG_PPC64
-static void udbg_real_scc_putc(char c)
-{
- while ((real_readb(sccc) & SCC_TXRDY) == 0)
- ;
- real_writeb(c, sccd);
- if (c == '\n')
- udbg_real_scc_putc('\r');
-}
-
-void __init udbg_init_pmac_realmode(void)
-{
- sccc = (volatile u8 __iomem *)0x80013020ul;
- sccd = (volatile u8 __iomem *)0x80013030ul;
-
- udbg_putc = udbg_real_scc_putc;
- udbg_getc = NULL;
- udbg_getc_poll = NULL;
-}
-#endif /* CONFIG_PPC64 */