diff -uNr linux-2.4.20/CREDITS linux-2.4.20-ben5/CREDITS
--- linux-2.4.20/CREDITS 2002-11-29 00:53:08.000000000 +0100
+++ linux-2.4.20-ben5/CREDITS 2003-01-30 11:52:35.000000000 +0100
@@ -1488,7 +1488,7 @@
S: United Kingdom
N: Ani Joshi
-E: ajoshi@shell.unixbox.com
+E: ajoshi@kernel.crashing.org
D: fbdev hacking
N: Bernhard Kaindl
diff -uNr linux-2.4.20/Documentation/Configure.help linux-2.4.20-ben5/Documentation/Configure.help
--- linux-2.4.20/Documentation/Configure.help 2002-11-29 00:53:08.000000000 +0100
+++ linux-2.4.20-ben5/Documentation/Configure.help 2003-01-30 11:55:42.000000000 +0100
@@ -26242,6 +26242,29 @@
If unsure, say N.
+CONFIG_CPU_FREQ
+ Clock scaling allows you to change the clock speed of CPUs on the
+ fly. This is a nice method to save battery power on notebooks,
+ because the lower the clock speed, the less power the CPU consumes.
+
+ For more information, take a look at linux/Documentation/cpufreq or
+ at
+
+ If in doubt, say N.
+
+CONFIG_CPU_FREQ_24_API
+ This enables the /proc/sys/cpu/ sysctl interface for controlling
+ CPUFreq, as known from the 2.4.-kernel patches for CPUFreq. Note
+ that some drivers do not support this interface or offer less
+ functionality.
+
+ If you say N here, you'll be able to control CPUFreq using the
+ new /proc/cpufreq interface.
+
+ For details, take a look at linux/Documentation/cpufreq.
+
+ If in doubt, say N.
+
#
# A couple of things I keep forgetting:
# capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -uNr linux-2.4.20/Documentation/cpufreq linux-2.4.20-ben5/Documentation/cpufreq
--- linux-2.4.20/Documentation/cpufreq 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/Documentation/cpufreq 2003-01-30 11:54:52.000000000 +0100
@@ -0,0 +1,361 @@
+ CPU frequency and voltage scaling code in the Linux(TM) kernel
+
+
+ L i n u x C P U F r e q
+
+
+
+
+ Dominik Brodowski
+ David Kimdon
+
+
+
+ Clock scaling allows you to change the clock speed of the CPUs on the
+ fly. This is a nice method to save battery power, because the lower
+ the clock speed, the less power the CPU consumes.
+
+
+
+Contents:
+---------
+1. Supported architectures
+2. User interface
+2.1 /proc/cpufreq interface [2.6]
+2.2. /proc/sys/cpu/ interface [2.4]
+3. CPUFreq core and interfaces
+3.1 General information
+3.2 CPUFreq notifiers
+3.3 CPUFreq architecture drivers
+4. Mailing list and Links
+
+
+
+1. Supported architectures
+==========================
+
+ARM:
+ ARM Integrator, SA 1100, SA1110
+--------------------------------
+ This driver will be ported to new CPUFreq core soon, so
+ far it will not work.
+
+
+AMD Elan:
+ SC400, SC410
+--------------------------------
+ You need to specify the highest allowed CPU frequency as
+ a module parameter ("max_freq") or as boot parameter
+ ("elanfreq="). Else the available speed range will be
+ limited to the speed at which the CPU runs while this
+ module is loaded.
+
+
+VIA Cyrix Longhaul:
+ VIA Samuel/CyrixIII, VIA Cyrix Samuel/C3,
+ VIA Cyrix Ezra, VIA Cyrix Ezra-T
+--------------------------------
+ If you do not want to scale the Front Side Bus or voltage,
+ pass the module parameter "dont_scale_fsb 1" or
+ "dont_scale_voltage 1". Additionally, it is advised that
+ you pass the current Front Side Bus speed (in MHz) to
+ this module as module parameter "current_fsb", e.g.
+ "current_fsb 133" for a Front Side Bus speed of 133 MHz.
+
+
+Intel SpeedStep:
+ certain mobile Intel Pentium III (Coppermine), and all mobile
+ Intel Pentium III-M (Tualatin) and mobile Intel Pentium 4 P4-Ms.
+--------------------------------
+ Unfortunately only modern Intel ICH2-M and ICH3-M chipsets are
+ supported.
+
+
+P4 CPU Clock Modulation:
+ Intel Pentium 4 Xeon processors
+---------------------------------
+ Note that you can only switch the speed of two logical CPUs at
+ once - but each phyiscal CPU may have different throttling levels.
+
+
+PowerNow! K6:
+ mobile AMD K6-2+ / mobile K6-3+:
+--------------------------------
+ No known issues.
+
+
+Transmeta Crusoe Longrun:
+ Transmeta Crusoe processors:
+--------------------------------
+ Does not work with the 2.4. /proc/sys/cpu/ interface.
+
+
+
+2. User Interface
+=================
+
+2.1 /proc/cpufreq interface [2.6]
+***********************************
+
+Starting in the patches for kernel 2.5.33, CPUFreq uses a "policy"
+interface /proc/cpufreq.
+
+When you "cat" this file, you'll find something like:
+
+--
+ minimum CPU frequency - maximum CPU frequency - policy
+CPU 0 1200000 ( 75%) - 1600000 (100%) - performance
+--
+
+This means the current policy allows this CPU to be run anywhere
+between 1.2 GHz (the value is in kHz) and 1.6 GHz with an eye towards
+performance.
+
+To change the policy, "echo" the desired new policy into
+/proc/cpufreq. Use one of the following formats:
+
+cpu_nr:min_freq:max_freq:policy
+cpu_nr%min_freq%max_freq%policy
+min_freq:max_freq:policy
+min_freq%max_freq%policy
+
+with cpu_nr being the CPU which shall be affected, min_freq and
+max_freq the lower and upper limit of the CPU core frequency in kHz,
+and policy either "performance" or "powersave".
+A few examples:
+
+root@notebook:#echo -n "0:0:0:powersave" > /proc/cpufreq
+ sets the CPU #0 to the lowest supported frequency.
+
+root@notebook:#echo -n "1%100%100%performance" > /proc/cpufreq
+ sets the CPU #1 to the highest supported frequency.
+
+root@notebook:#echo -n "1000000:2000000:performance" > /proc/cpufreq
+ to set the frequency of all CPUs between 1 GHz and 2 GHz and to
+ the policy "performance".
+
+Please note that the values you "echo" into /proc/cpufreq are
+validated first, and may be limited by hardware or thermal
+considerations. Because of this, a read from /proc/cpufreq might
+differ from what was written into it.
+
+
+When you read /proc/cpufreq for the first time after a CPUFreq driver
+has been initialized, you'll see the "default policy" for this
+driver. If this does not suit your needs, you can pass a boot
+parameter to the cpufreq core. Use the following syntax for this:
+ "cpufreq=min_freq:max_freq:policy", i.e. you may not chose a
+specific CPU and you need to specify the limits in kHz and not in
+per cent.
+
+
+2.2 /proc/cpufreq interface [2.4]
+***********************************
+
+Previsiously (and still available as a config option), CPUFreq used
+a "sysctl" interface which is located in
+ /proc/sys/cpu/0/
+ /proc/sys/cpu/1/ ... (SMP only)
+
+In these directories, you will find three files of importance for
+CPUFreq: speed-max, speed-min and speed:
+
+speed shows the current CPU frequency in kHz,
+speed-min the minimum supported CPU frequency, and
+speed-max the maximum supported CPU frequency.
+
+
+To change the CPU frequency, "echo" the desired CPU frequency (in kHz)
+to speed. For example, to set the CPU speed to the lowest/highest
+allowed frequency do:
+
+root@notebook:# cat /proc/sys/cpu/0/speed-min > /proc/sys/cpu/0/speed
+root@notebook:# cat /proc/sys/cpu/0/speed-max > /proc/sys/cpu/0/speed
+
+
+
+3. CPUFreq core and interfaces
+===============================
+
+3.1 General information
+*************************
+
+The CPUFreq core code is located in linux/kernel/cpufreq.c. This
+cpufreq code offers a standardized interface for the CPUFreq
+architecture drivers (those pieces of code that do actual
+frequency transitions), as well as to "notifiers". These are device
+drivers or other part of the kernel that need to be informed of
+policy changes (like thermal modules like ACPI) or of all
+frequency changes (like timing code) or even need to force certain
+speed limits (like LCD drivers on ARM architecture). Additionally, the
+kernel "constant" loops_per_jiffy is updated on frequency changes
+here.
+
+
+3.2 CPUFreq notifiers
+***********************
+
+CPUFreq notifiers conform to the standard kernel notifier interface.
+See linux/include/linux/notifier.h for details on notifiers.
+
+There are two different CPUFreq notifiers - policy notifiers and
+transition notifiers.
+
+
+3.2.1 CPUFreq policy notifiers
+******************************
+
+These are notified when a new policy is intended to be set. Each
+CPUFreq policy notifier is called three times for a policy transition:
+
+1.) During CPUFREQ_ADJUST all CPUFreq notifiers may change the limit if
+ they see a need for this - may it be thermal considerations or
+ hardware limitations.
+
+2.) During CPUFREQ_INCOMPATIBLE only changes may be done in order to avoid
+ hardware failure.
+
+3.) And during CPUFREQ_NOTIFY all notifiers are informed of the new policy
+ - if two hardware drivers failed to agree on a new policy before this
+ stage, the incompatible hardware shall be shut down, and the user
+ informed of this.
+
+The phase is specified in the second argument to the notifier.
+
+The third argument, a void *pointer, points to a struct cpufreq_policy
+consisting of five values: cpu, min, max, policy and max_cpu_freq. Min
+and max are the lower and upper frequencies (in kHz) of the new
+policy, policy the new policy, cpu the number of the affected CPU or
+CPUFREQ_ALL_CPUS for all CPUs; and max_cpu_freq the maximum supported
+CPU frequency. This value is given for informational purposes only.
+
+
+3.2.2 CPUFreq transition notifiers
+**********************************
+
+These are notified twice when the CPUfreq driver switches the CPU core
+frequency and this change has any external implications.
+
+The second argument specifies the phase - CPUFREQ_PRECHANGE or
+CPUFREQ_POSTCHANGE.
+
+The third argument is a struct cpufreq_freqs with the following
+values:
+cpu - number of the affected CPU or CPUFREQ_ALL_CPUS
+old - old frequency
+new - new frequency
+
+
+3.3 CPUFreq architecture drivers
+**********************************
+
+CPUFreq architecture drivers are the pieces of kernel code that
+actually perform CPU frequency transitions. These need to be
+initialized separately (separate initcalls), and may be
+modularized. They interact with the CPUFreq core in the following way:
+
+cpufreq_register()
+------------------
+cpufreq_register registers an arch driver to the CPUFreq core. Please
+note that only one arch driver may be registered at any time. -EBUSY
+is returned when an arch driver is already registered. The argument to
+cpufreq_register, struct cpufreq_driver *driver, is described later.
+
+cpufreq_unregister()
+--------------------
+cpufreq_unregister unregisters an arch driver, e.g. on module
+unloading. Please note that there is no check done that this is called
+from the driver which actually registered itself to the core, so
+please only call this function when you are sure the arch driver got
+registered correctly before.
+
+cpufreq_notify_transition()
+---------------------------
+On "dumb" hardware where only fixed frequency can be set, the driver
+must call cpufreq_notify_transition() once before, and once after the
+actual transition.
+
+struct cpufreq_driver
+---------------------
+On initialization, the arch driver is supposed to pass a pointer
+to a struct cpufreq_driver *cpufreq_driver consisting of the following
+entries:
+
+cpufreq_verify_t verify: This is a pointer to a function with the
+ following definition:
+ void verify_function (struct cpufreq_policy *policy).
+ This function must verify the new policy is within the limits
+ supported by the CPU, and at least one supported CPU is within
+ this range. It may be useful to use cpufreq.h /
+ cpufreq_verify_within_limits for this.
+
+cpufreq_setpolicy_t setpolicy: This is a pointer to a function with
+ the following definition:
+ void setpolicy_function (struct cpufreq_policy *policy).
+ This function must set the CPU to the new policy. If it is a
+ "dumb" CPU which only allows fixed frequencies to be set, it
+ shall set it to the lowest within the limit for
+ CPUFREQ_POLICY_POWERSAVE, and to the highest for
+ CPUFREQ_POLICY_PERFORMANCE. Once CONFIG_CPU_FREQ_DYNAMIC is
+ implemented, it can use a dynamic method to adjust the speed
+ between the lower and upper limit.
+
+struct cpufreq_policy *policy: This is an array of NR_CPUS struct
+ cpufreq_policies, containing the current policies set for these
+ CPUs. Note that policy[0].max_cpu_freq must contain the
+ absolute maximum CPU frequency supported by _all_ CPUs.
+
+In case the driver is expected to run with the 2.4.-style API
+(/proc/sys/cpu/.../), two more values must be passed
+#ifdef CONFIG_CPU_FREQ_24_API
+ unsigned int cpu_min_freq;
+ unsigned int cpu_cur_freq[NR_CPUS];
+#endif
+ with cpu_min_freq being the minimum CPU frequency supported by
+ the CPUs; and the entries in cpu_cur_freq reflecting the
+ current speed of the appropriate CPU.
+
+Some Requirements to CPUFreq architecture drivers
+-------------------------------------------------
+* Only call cpufreq_register() when the ability to switch CPU
+ frequencies is _verified_ or can't be missing
+* cpufreq_unregister() may only be called if cpufreq_register() has
+ been successfully(!) called before.
+* kfree() the struct cpufreq_driver only after the call to
+ cpufreq_unregister(), unless cpufreq_register() failed.
+* Be aware that there is currently no error management in the
+ setpolicy() code in the CPUFreq core. So only call yourself a
+ cpufreq_driver if you are really a working cpufreq_driver!
+
+
+
+4. Mailing list and Links
+*************************
+
+
+Mailing List
+------------
+There is a CPU frequency changing CVS commit and general list where
+you can report bugs, problems or submit patches. To post a message,
+send an email to cpufreq@www.linux.org.uk, to subscribe go to
+http://www.linux.org.uk/mailman/listinfo/cpufreq. Previous post to the
+mailing list are available to subscribers at
+http://www.linux.org.uk/mailman/private/cpufreq/.
+
+
+Links
+-----
+the FTP archives:
+* ftp://ftp.linux.org.uk/pub/linux/cpufreq/
+
+how to access the CVS repository:
+* http://cvs.arm.linux.org.uk/
+
+the CPUFreq Mailing list:
+* http://www.linux.org.uk/mailman/listinfo/cpufreq
+
+Clock and voltage scaling for the SA-1100:
+* http://www.lart.tudelft.nl/projects/scaling
+
+CPUFreq project homepage
+* http://www.brodo.de/cpufreq/
diff -uNr linux-2.4.20/MAINTAINERS linux-2.4.20-ben5/MAINTAINERS
--- linux-2.4.20/MAINTAINERS 2002-11-29 00:53:08.000000000 +0100
+++ linux-2.4.20-ben5/MAINTAINERS 2003-01-30 11:53:05.000000000 +0100
@@ -1160,8 +1160,8 @@
NVIDIA (RIVA) FRAMEBUFFER DRIVER
P: Ani Joshi
-M: ajoshi@shell.unixbox.com
-L: linux-nvidia@lists.surfsouth.com
+M: ajoshi@kernel.crashing.org
+L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
OLYMPIC NETWORK DRIVER
@@ -1336,13 +1336,13 @@
RADEON FRAMEBUFFER DISPLAY DRIVER
P: Ani Joshi
-M: ajoshi@shell.unixbox.com
+M: ajoshi@kernel.crashing.org
L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
RAGE128 FRAMEBUFFER DISPLAY DRIVER
P: Ani Joshi
-M: ajoshi@shell.unixbox.com
+M: ajoshi@kernel.crashing.org
L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
diff -uNr linux-2.4.20/Makefile linux-2.4.20-ben5/Makefile
--- linux-2.4.20/Makefile 2002-11-29 00:53:16.000000000 +0100
+++ linux-2.4.20-ben5/Makefile 2003-01-30 11:55:46.000000000 +0100
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 20
-EXTRAVERSION =
+EXTRAVERSION = -ben4
KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
diff -uNr linux-2.4.20/arch/alpha/mm/fault.c linux-2.4.20-ben5/arch/alpha/mm/fault.c
--- linux-2.4.20/arch/alpha/mm/fault.c 2002-11-29 00:53:08.000000000 +0100
+++ linux-2.4.20-ben5/arch/alpha/mm/fault.c 2003-01-30 11:52:49.000000000 +0100
@@ -124,7 +124,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/arm/mm/fault-common.c linux-2.4.20-ben5/arch/arm/mm/fault-common.c
--- linux-2.4.20/arch/arm/mm/fault-common.c 2002-11-29 00:53:09.000000000 +0100
+++ linux-2.4.20-ben5/arch/arm/mm/fault-common.c 2003-01-30 11:56:00.000000000 +0100
@@ -229,7 +229,7 @@
goto survive;
check_stack:
- if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr))
+ if (vma->vm_flags & VM_GROWSDOWN && !expand_stack(vma, addr, NULL))
goto good_area;
out:
return fault;
diff -uNr linux-2.4.20/arch/cris/mm/fault.c linux-2.4.20-ben5/arch/cris/mm/fault.c
--- linux-2.4.20/arch/cris/mm/fault.c 2002-11-29 00:53:09.000000000 +0100
+++ linux-2.4.20-ben5/arch/cris/mm/fault.c 2003-01-30 11:53:05.000000000 +0100
@@ -315,7 +315,7 @@
if (address + PAGE_SIZE < rdusp())
goto bad_area;
}
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
diff -uNr linux-2.4.20/arch/i386/mm/fault.c linux-2.4.20-ben5/arch/i386/mm/fault.c
--- linux-2.4.20/arch/i386/mm/fault.c 2002-11-29 00:53:09.000000000 +0100
+++ linux-2.4.20-ben5/arch/i386/mm/fault.c 2003-01-30 11:52:39.000000000 +0100
@@ -32,7 +32,7 @@
*/
int __verify_write(const void * addr, unsigned long size)
{
- struct vm_area_struct * vma;
+ struct vm_area_struct * vma, * prev_vma;
unsigned long start = (unsigned long) addr;
if (!size)
@@ -78,7 +78,8 @@
check_stack:
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, start) == 0)
+ find_vma_prev(current->mm, start, &prev_vma);
+ if (expand_stack(vma, start, prev_vma) == 0)
goto good_area;
bad_area:
@@ -141,7 +142,7 @@
{
struct task_struct *tsk;
struct mm_struct *mm;
- struct vm_area_struct * vma;
+ struct vm_area_struct * vma, * prev_vma;
unsigned long address;
unsigned long page;
unsigned long fixup;
@@ -202,7 +203,8 @@
if (address + 32 < regs->esp)
goto bad_area;
}
- if (expand_stack(vma, address))
+ find_vma_prev(mm, address, &prev_vma);
+ if (expand_stack(vma, address, prev_vma))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/ia64/mm/fault.c linux-2.4.20-ben5/arch/ia64/mm/fault.c
--- linux-2.4.20/arch/ia64/mm/fault.c 2002-11-29 00:53:09.000000000 +0100
+++ linux-2.4.20-ben5/arch/ia64/mm/fault.c 2003-01-30 11:52:49.000000000 +0100
@@ -134,7 +134,7 @@
if (rgn_index(address) != rgn_index(vma->vm_start)
|| rgn_offset(address) >= RGN_MAP_LIMIT)
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
} else {
vma = prev_vma;
diff -uNr linux-2.4.20/arch/m68k/mm/fault.c linux-2.4.20-ben5/arch/m68k/mm/fault.c
--- linux-2.4.20/arch/m68k/mm/fault.c 2002-11-29 00:53:09.000000000 +0100
+++ linux-2.4.20-ben5/arch/m68k/mm/fault.c 2003-01-30 11:55:16.000000000 +0100
@@ -120,7 +120,7 @@
if (address + 256 < rdusp())
goto map_err;
}
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto map_err;
/*
diff -uNr linux-2.4.20/arch/mips/mm/fault.c linux-2.4.20-ben5/arch/mips/mm/fault.c
--- linux-2.4.20/arch/mips/mm/fault.c 2002-11-29 00:53:10.000000000 +0100
+++ linux-2.4.20-ben5/arch/mips/mm/fault.c 2003-01-30 11:52:36.000000000 +0100
@@ -113,7 +113,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/mips64/mm/fault.c linux-2.4.20-ben5/arch/mips64/mm/fault.c
--- linux-2.4.20/arch/mips64/mm/fault.c 2002-11-29 00:53:10.000000000 +0100
+++ linux-2.4.20-ben5/arch/mips64/mm/fault.c 2003-01-30 11:54:31.000000000 +0100
@@ -137,7 +137,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/ppc/8260_io/Makefile linux-2.4.20-ben5/arch/ppc/8260_io/Makefile
--- linux-2.4.20/arch/ppc/8260_io/Makefile 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8260_io/Makefile 2003-01-30 11:54:01.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:19 cort
+# BK Id: SCCS/s.Makefile 1.5 06/05/01 21:22:01 paulus
#
#
# Makefile for the linux MPC8xx ppc-specific parts of comm processor
diff -uNr linux-2.4.20/arch/ppc/8260_io/commproc.c linux-2.4.20-ben5/arch/ppc/8260_io/commproc.c
--- linux-2.4.20/arch/ppc/8260_io/commproc.c 2001-11-03 02:43:54.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/8260_io/commproc.c 2003-01-30 11:55:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.commproc.c 1.10 10/16/01 16:21:52 trini
+ * BK Id: SCCS/s.commproc.c 1.11 11/04/01 22:58:20 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/8260_io/enet.c linux-2.4.20-ben5/arch/ppc/8260_io/enet.c
--- linux-2.4.20/arch/ppc/8260_io/enet.c 2001-10-08 20:40:13.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8260_io/enet.c 2003-01-30 11:52:38.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.enet.c 1.9 09/14/01 18:01:16 trini
+ * BK Id: SCCS/s.enet.c 1.10 10/08/01 16:49:24 trini
*/
/*
* Ethernet driver for Motorola MPC8260.
diff -uNr linux-2.4.20/arch/ppc/8260_io/fcc_enet.c linux-2.4.20-ben5/arch/ppc/8260_io/fcc_enet.c
--- linux-2.4.20/arch/ppc/8260_io/fcc_enet.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8260_io/fcc_enet.c 2003-01-30 11:54:42.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fcc_enet.c 1.7 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.fcc_enet.c 1.11 06/05/01 21:22:01 paulus
*/
/*
* Fast Ethernet Controller (FCC) driver for Motorola MPC8260.
diff -uNr linux-2.4.20/arch/ppc/8260_io/uart.c linux-2.4.20-ben5/arch/ppc/8260_io/uart.c
--- linux-2.4.20/arch/ppc/8260_io/uart.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8260_io/uart.c 2003-01-30 11:54:26.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.uart.c 1.13 12/29/01 14:50:03 trini
+ * BK Id: SCCS/s.uart.c 1.16 11/19/02 08:55:00 trini
*/
/*
* UART driver for MPC8260 CPM SCC or SMC
@@ -910,9 +910,9 @@
* enables, because we want to put them back if they were
* present.
*/
- prev_mode = smcp->smc_smcmr;
- smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART;
- smcp->smc_smcmr |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+ prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN);
+ smcp->smc_smcmr = smcr_mk_clen(bits) | cval | SMCMR_SM_UART
+ | prev_mode;
}
else {
sccp = &immr->im_scc[idx - SCC_IDX_BASE];
diff -uNr linux-2.4.20/arch/ppc/8xx_io/Makefile linux-2.4.20-ben5/arch/ppc/8xx_io/Makefile
--- linux-2.4.20/arch/ppc/8xx_io/Makefile 2001-09-08 21:39:33.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8xx_io/Makefile 2003-01-30 11:53:05.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.6 08/30/01 09:33:48 trini
+# BK Id: SCCS/s.Makefile 1.7 09/09/01 12:20:42 trini
#
#
# Makefile for the linux MPC8xx ppc-specific parts of comm processor
diff -uNr linux-2.4.20/arch/ppc/8xx_io/commproc.c linux-2.4.20-ben5/arch/ppc/8xx_io/commproc.c
--- linux-2.4.20/arch/ppc/8xx_io/commproc.c 2001-11-03 02:43:54.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/8xx_io/commproc.c 2003-01-30 11:53:14.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.commproc.c 1.15 10/16/01 16:21:52 trini
+ * BK Id: SCCS/s.commproc.c 1.16 11/04/01 22:58:20 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/8xx_io/enet.c linux-2.4.20-ben5/arch/ppc/8xx_io/enet.c
--- linux-2.4.20/arch/ppc/8xx_io/enet.c 2001-10-17 23:37:01.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8xx_io/enet.c 2003-01-30 11:53:56.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.enet.c 1.17 10/11/01 11:55:47 trini
+ * BK Id: SCCS/s.enet.c 1.18 10/17/01 18:40:00 trini
*/
/*
* Ethernet driver for Motorola MPC8xx.
diff -uNr linux-2.4.20/arch/ppc/8xx_io/fec.c linux-2.4.20-ben5/arch/ppc/8xx_io/fec.c
--- linux-2.4.20/arch/ppc/8xx_io/fec.c 2002-11-29 00:53:10.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/8xx_io/fec.c 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.fec.c 1.24 09/11/02 14:41:30 paulus
*/
/*
* Fast Ethernet Controller (FEC) driver for Motorola MPC8xx.
diff -uNr linux-2.4.20/arch/ppc/8xx_io/uart.c linux-2.4.20-ben5/arch/ppc/8xx_io/uart.c
--- linux-2.4.20/arch/ppc/8xx_io/uart.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/8xx_io/uart.c 2003-01-30 11:52:50.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.uart.c 1.23 12/29/01 14:50:03 trini
+ * BK Id: SCCS/s.uart.c 1.26 11/19/02 08:55:00 trini
*/
/*
* UART driver for MPC860 CPM SCC or SMC
@@ -1008,9 +1008,9 @@
* enables, because we want to put them back if they were
* present.
*/
- prev_mode = smcp->smc_smcmr;
- new_mode = smcr_mk_clen(bits) | cval | SMCMR_SM_UART;
- new_mode |= (prev_mode & (SMCMR_REN | SMCMR_TEN));
+ prev_mode = smcp->smc_smcmr & (SMCMR_REN | SMCMR_TEN);
+ new_mode = smcr_mk_clen(bits) | cval | SMCMR_SM_UART
+ | prev_mode;
if (!(prev_mode & SMCMR_PEN))
/* If parity is disabled, mask out even/odd */
prev_mode &= ~SMCMR_PM_EVEN;
diff -uNr linux-2.4.20/arch/ppc/Makefile linux-2.4.20-ben5/arch/ppc/Makefile
--- linux-2.4.20/arch/ppc/Makefile 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/Makefile 2003-01-30 11:54:55.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: %F% %I% %G% %U% %#%
+# BK Id: SCCS/s.Makefile 1.31 11/27/02 12:15:43 benh
#
# This file is included by the global makefile so that you can add your own
# architecture-specific flags and dependencies. Remember to do have actions
diff -uNr linux-2.4.20/arch/ppc/amiga/Makefile linux-2.4.20-ben5/arch/ppc/amiga/Makefile
--- linux-2.4.20/arch/ppc/amiga/Makefile 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/Makefile 2003-01-30 11:52:44.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.5 05/21/01 00:48:24 cort
+# BK Id: SCCS/s.Makefile 1.7 06/05/01 21:22:02 paulus
#
#
# Makefile for Linux arch/m68k/amiga source directory
diff -uNr linux-2.4.20/arch/ppc/amiga/amiga_ksyms.c linux-2.4.20-ben5/arch/ppc/amiga/amiga_ksyms.c
--- linux-2.4.20/arch/ppc/amiga/amiga_ksyms.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/amiga_ksyms.c 2003-01-30 11:55:34.000000000 +0100
@@ -1,4 +1,4 @@
/*
- * BK Id: SCCS/s.amiga_ksyms.c 1.5 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.amiga_ksyms.c 1.7 06/05/01 21:22:02 paulus
*/
#include "../../m68k/amiga/amiga_ksyms.c"
diff -uNr linux-2.4.20/arch/ppc/amiga/amiints.c linux-2.4.20-ben5/arch/ppc/amiga/amiints.c
--- linux-2.4.20/arch/ppc/amiga/amiints.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/amiga/amiints.c 2003-01-30 11:55:45.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.amiints.c 1.11 08/29/02 13:07:54 paulus
*/
/*
* linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code
diff -uNr linux-2.4.20/arch/ppc/amiga/amisound.c linux-2.4.20-ben5/arch/ppc/amiga/amisound.c
--- linux-2.4.20/arch/ppc/amiga/amisound.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/amisound.c 2003-01-30 11:54:34.000000000 +0100
@@ -1,4 +1,4 @@
/*
- * BK Id: SCCS/s.amisound.c 1.5 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.amisound.c 1.7 06/05/01 21:22:02 paulus
*/
#include "../../m68k/amiga/amisound.c"
diff -uNr linux-2.4.20/arch/ppc/amiga/bootinfo.c linux-2.4.20-ben5/arch/ppc/amiga/bootinfo.c
--- linux-2.4.20/arch/ppc/amiga/bootinfo.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/bootinfo.c 2003-01-30 11:52:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.bootinfo.c 1.5 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.bootinfo.c 1.7 06/05/01 21:22:02 paulus
*/
/*
* linux/arch/ppc/amiga/bootinfo.c
diff -uNr linux-2.4.20/arch/ppc/amiga/chipram.c linux-2.4.20-ben5/arch/ppc/amiga/chipram.c
--- linux-2.4.20/arch/ppc/amiga/chipram.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/chipram.c 2003-01-30 11:52:58.000000000 +0100
@@ -1,4 +1,4 @@
/*
- * BK Id: SCCS/s.chipram.c 1.7 05/21/01 00:49:49 cort
+ * BK Id: SCCS/s.chipram.c 1.9 06/05/01 21:22:02 paulus
*/
#include "../../m68k/amiga/chipram.c"
diff -uNr linux-2.4.20/arch/ppc/amiga/cia.c linux-2.4.20-ben5/arch/ppc/amiga/cia.c
--- linux-2.4.20/arch/ppc/amiga/cia.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/amiga/cia.c 2003-01-30 11:53:27.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.cia.c 1.10 08/29/02 13:07:54 paulus
*/
/*
* linux/arch/m68k/amiga/cia.c - CIA support
diff -uNr linux-2.4.20/arch/ppc/amiga/config.c linux-2.4.20-ben5/arch/ppc/amiga/config.c
--- linux-2.4.20/arch/ppc/amiga/config.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/amiga/config.c 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.config.c 1.16 08/29/02 13:07:54 paulus
*/
#define m68k_debug_device debug_device
diff -uNr linux-2.4.20/arch/ppc/amiga/ints.c linux-2.4.20-ben5/arch/ppc/amiga/ints.c
--- linux-2.4.20/arch/ppc/amiga/ints.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/ints.c 2003-01-30 11:54:53.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ints.c 1.5 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.ints.c 1.7 06/05/01 21:22:02 paulus
*/
/*
* linux/arch/ppc/amiga/ints.c
diff -uNr linux-2.4.20/arch/ppc/amiga/pcmcia.c linux-2.4.20-ben5/arch/ppc/amiga/pcmcia.c
--- linux-2.4.20/arch/ppc/amiga/pcmcia.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/amiga/pcmcia.c 2003-01-30 11:53:55.000000000 +0100
@@ -1,4 +1,4 @@
/*
- * BK Id: SCCS/s.pcmcia.c 1.5 05/17/01 18:14:20 cort
+ * BK Id: SCCS/s.pcmcia.c 1.7 06/05/01 21:22:02 paulus
*/
#include "../../m68k/amiga/pcmcia.c"
diff -uNr linux-2.4.20/arch/ppc/amiga/time.c linux-2.4.20-ben5/arch/ppc/amiga/time.c
--- linux-2.4.20/arch/ppc/amiga/time.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/amiga/time.c 2003-01-30 11:55:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.time.c 1.9 10/09/02 10:28:17 paulus
*/
#include /* CONFIG_HEARTBEAT */
#include
diff -uNr linux-2.4.20/arch/ppc/boot/chrp/Makefile linux-2.4.20-ben5/arch/ppc/boot/chrp/Makefile
--- linux-2.4.20/arch/ppc/boot/chrp/Makefile 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/chrp/Makefile 2003-01-30 11:54:33.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.15 01/11/02 10:46:06 trini
+# BK Id: SCCS/s.Makefile 1.16 03/07/02 13:42:36 trini
#
# Makefile for making ELF bootable images for booting on CHRP
# using Open Firmware.
diff -uNr linux-2.4.20/arch/ppc/boot/chrp/main.c linux-2.4.20-ben5/arch/ppc/boot/chrp/main.c
--- linux-2.4.20/arch/ppc/boot/chrp/main.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/chrp/main.c 2003-01-30 11:52:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.main.c 1.16 01/12/02 10:36:33 trini
+ * BK Id: SCCS/s.main.c 1.17 03/07/02 13:42:36 trini
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/chrp/misc.S linux-2.4.20-ben5/arch/ppc/boot/chrp/misc.S
--- linux-2.4.20/arch/ppc/boot/chrp/misc.S 2001-05-25 00:02:06.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/chrp/misc.S 2003-01-30 11:54:57.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:16:59 cort
+ * BK Id: SCCS/s.misc.S 1.7 06/05/01 20:20:04 paulus
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/chrp/start.c linux-2.4.20-ben5/arch/ppc/boot/chrp/start.c
--- linux-2.4.20/arch/ppc/boot/chrp/start.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/chrp/start.c 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.start.c 1.8 07/25/01 18:13:07 trini
+ * BK Id: SCCS/s.start.c 1.10 06/25/02 10:29:26 paulus
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/common/crt0.S linux-2.4.20-ben5/arch/ppc/boot/common/crt0.S
--- linux-2.4.20/arch/ppc/boot/common/crt0.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/boot/common/crt0.S 2003-01-30 11:55:34.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.crt0.S 1.14 01/11/02 10:46:07 trini
+ * BK Id: SCCS/s.crt0.S 1.16 08/13/02 20:27:36 paulus
*/
/* Copyright (c) 1997 Paul Mackerras
* Initial Power Macintosh COFF version.
diff -uNr linux-2.4.20/arch/ppc/boot/common/ns16550.c linux-2.4.20-ben5/arch/ppc/boot/common/ns16550.c
--- linux-2.4.20/arch/ppc/boot/common/ns16550.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/common/ns16550.c 2003-01-30 11:52:54.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ns16550.c 1.16 03/13/02 09:17:06 trini
+ * BK Id: SCCS/s.ns16550.c 1.17 04/16/02 20:08:22 paulus
*/
/*
* COM1 NS16550 support
diff -uNr linux-2.4.20/arch/ppc/boot/common/string.S linux-2.4.20-ben5/arch/ppc/boot/common/string.S
--- linux-2.4.20/arch/ppc/boot/common/string.S 2001-05-25 00:02:06.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/common/string.S 2003-01-30 11:54:51.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.string.S 1.8 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.string.S 1.9 06/05/01 20:01:06 paulus
*/
/*
* String handling functions for PowerPC.
diff -uNr linux-2.4.20/arch/ppc/boot/include/nonstdio.h linux-2.4.20-ben5/arch/ppc/boot/include/nonstdio.h
--- linux-2.4.20/arch/ppc/boot/include/nonstdio.h 2001-08-28 15:58:33.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/include/nonstdio.h 2003-01-30 11:52:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.nonstdio.h 1.9 07/25/01 18:13:07 trini
+ * BK Id: SCCS/s.nonstdio.h 1.10 08/29/01 08:49:23 paulus
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/include/rs6000.h linux-2.4.20-ben5/arch/ppc/boot/include/rs6000.h
--- linux-2.4.20/arch/ppc/boot/include/rs6000.h 2001-05-25 00:02:06.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/include/rs6000.h 2003-01-30 11:54:12.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.rs6000.h 1.7 05/18/01 15:17:23 cort
+ * BK Id: SCCS/s.rs6000.h 1.8 06/05/01 20:20:05 paulus
*/
/* IBM RS/6000 "XCOFF" file definitions for BFD.
Copyright (C) 1990, 1991 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/boot/include/zlib.h linux-2.4.20-ben5/arch/ppc/boot/include/zlib.h
--- linux-2.4.20/arch/ppc/boot/include/zlib.h 2001-05-25 00:02:06.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/include/zlib.h 2003-01-30 11:52:44.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort
+ * BK Id: SCCS/s.zlib.h 1.9 06/05/01 20:20:05 paulus
*/
/*
* This file is derived from zlib.h and zconf.h from the zlib-0.95
diff -uNr linux-2.4.20/arch/ppc/boot/lib/zlib.c linux-2.4.20-ben5/arch/ppc/boot/lib/zlib.c
--- linux-2.4.20/arch/ppc/boot/lib/zlib.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/lib/zlib.c 2003-01-30 11:55:25.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.zlib.c 1.9 12/05/01 16:19:42 mporter
+ * BK Id: SCCS/s.zlib.c 1.12 03/21/02 14:10:28 trini
*/
/*
* This file is derived from various .h and .c files from the zlib-0.95
diff -uNr linux-2.4.20/arch/ppc/boot/pmac/Makefile linux-2.4.20-ben5/arch/ppc/boot/pmac/Makefile
--- linux-2.4.20/arch/ppc/boot/pmac/Makefile 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/pmac/Makefile 2003-01-30 11:55:56.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.19 01/16/02 11:08:07 trini
+# BK Id: SCCS/s.Makefile 1.20 03/07/02 13:42:36 trini
#
# Makefile for making XCOFF bootable images for booting on PowerMacs
# using Open Firmware.
diff -uNr linux-2.4.20/arch/ppc/boot/pmac/chrpmain.c linux-2.4.20-ben5/arch/ppc/boot/pmac/chrpmain.c
--- linux-2.4.20/arch/ppc/boot/pmac/chrpmain.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/pmac/chrpmain.c 2003-01-30 11:55:51.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.chrpmain.c 1.18 01/11/02 10:46:07 trini
+ * BK Id: SCCS/s.chrpmain.c 1.19 03/07/02 13:42:37 trini
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/pmac/misc.S linux-2.4.20-ben5/arch/ppc/boot/pmac/misc.S
--- linux-2.4.20/arch/ppc/boot/pmac/misc.S 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/pmac/misc.S 2003-01-30 11:53:04.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:17:15 cort
+ * BK Id: SCCS/s.misc.S 1.7 06/05/01 20:20:05 paulus
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/pmac/start.c linux-2.4.20-ben5/arch/ppc/boot/pmac/start.c
--- linux-2.4.20/arch/ppc/boot/pmac/start.c 2001-08-28 15:58:33.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/pmac/start.c 2003-01-30 11:55:24.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.start.c 1.10 07/25/01 18:13:07 trini
+ * BK Id: SCCS/s.start.c 1.11 08/29/01 08:49:23 paulus
*/
/*
* Copyright (C) Paul Mackerras 1997.
diff -uNr linux-2.4.20/arch/ppc/boot/prep/Makefile linux-2.4.20-ben5/arch/ppc/boot/prep/Makefile
--- linux-2.4.20/arch/ppc/boot/prep/Makefile 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/Makefile 2003-01-30 11:56:05.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.30 01/26/02 12:27:41 trini
+# BK Id: SCCS/s.Makefile 1.32 08/29/02 13:11:12 paulus
#
# arch/ppc/boot/Makefile
#
diff -uNr linux-2.4.20/arch/ppc/boot/prep/head.S linux-2.4.20-ben5/arch/ppc/boot/prep/head.S
--- linux-2.4.20/arch/ppc/boot/prep/head.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/head.S 2003-01-30 11:52:40.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.head.S 1.13 01/11/02 10:46:07 trini
+ * BK Id: SCCS/s.head.S 1.15 08/13/02 21:25:13 paulus
*/
#include
diff -uNr linux-2.4.20/arch/ppc/boot/prep/iso_font.h linux-2.4.20-ben5/arch/ppc/boot/prep/iso_font.h
--- linux-2.4.20/arch/ppc/boot/prep/iso_font.h 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/iso_font.h 2003-01-30 11:54:55.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.iso_font.h 1.6 05/18/01 15:16:42 cort
+ * BK Id: SCCS/s.iso_font.h 1.7 06/05/01 20:20:05 paulus
*/
static const unsigned char font[] = {
/* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
diff -uNr linux-2.4.20/arch/ppc/boot/prep/kbd.c linux-2.4.20-ben5/arch/ppc/boot/prep/kbd.c
--- linux-2.4.20/arch/ppc/boot/prep/kbd.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/kbd.c 2003-01-30 11:54:11.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.kbd.c 1.9 01/11/02 10:46:07 trini
+ * BK Id: SCCS/s.kbd.c 1.10 03/07/02 13:42:37 trini
*/
#include
diff -uNr linux-2.4.20/arch/ppc/boot/prep/misc.c linux-2.4.20-ben5/arch/ppc/boot/prep/misc.c
--- linux-2.4.20/arch/ppc/boot/prep/misc.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/misc.c 2003-01-30 11:52:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.misc.c 1.25 01/26/02 12:27:41 trini
+ * BK Id: SCCS/s.misc.c 1.27 03/07/02 13:42:37 trini
*
* arch/ppc/boot/prep/misc.c
*
diff -uNr linux-2.4.20/arch/ppc/boot/prep/of1275.c linux-2.4.20-ben5/arch/ppc/boot/prep/of1275.c
--- linux-2.4.20/arch/ppc/boot/prep/of1275.c 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/of1275.c 2003-01-30 11:54:02.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.of1275.c 1.6 05/18/01 15:16:42 cort
+ * BK Id: SCCS/s.of1275.c 1.7 06/05/01 20:20:05 paulus
*/
/* Open Firmware Client Interface */
diff -uNr linux-2.4.20/arch/ppc/boot/prep/of1275.h linux-2.4.20-ben5/arch/ppc/boot/prep/of1275.h
--- linux-2.4.20/arch/ppc/boot/prep/of1275.h 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/of1275.h 2003-01-30 11:53:31.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.of1275.h 1.6 05/18/01 15:16:42 cort
+ * BK Id: SCCS/s.of1275.h 1.7 06/05/01 20:20:05 paulus
*/
/* 6.3.2.1 Client interface */
diff -uNr linux-2.4.20/arch/ppc/boot/prep/vreset.c linux-2.4.20-ben5/arch/ppc/boot/prep/vreset.c
--- linux-2.4.20/arch/ppc/boot/prep/vreset.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/prep/vreset.c 2003-01-30 11:54:08.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.vreset.c 1.13 01/11/02 10:46:08 trini
+ * BK Id: SCCS/s.vreset.c 1.14 03/07/02 13:42:37 trini
*/
/*
* vreset.c
diff -uNr linux-2.4.20/arch/ppc/boot/utils/addnote.c linux-2.4.20-ben5/arch/ppc/boot/utils/addnote.c
--- linux-2.4.20/arch/ppc/boot/utils/addnote.c 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/utils/addnote.c 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.addnote.c 1.7 05/18/01 15:17:23 cort
+ * BK Id: SCCS/s.addnote.c 1.8 06/05/01 20:20:06 paulus
*/
/*
* Program to hack in a PT_NOTE program header entry in an ELF file.
diff -uNr linux-2.4.20/arch/ppc/boot/utils/hack-coff.c linux-2.4.20-ben5/arch/ppc/boot/utils/hack-coff.c
--- linux-2.4.20/arch/ppc/boot/utils/hack-coff.c 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/utils/hack-coff.c 2003-01-30 11:55:52.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.hack-coff.c 1.8 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.hack-coff.c 1.9 06/05/01 20:20:06 paulus
*/
/*
* hack-coff.c - hack the header of an xcoff file to fill in
diff -uNr linux-2.4.20/arch/ppc/boot/utils/mknote.c linux-2.4.20-ben5/arch/ppc/boot/utils/mknote.c
--- linux-2.4.20/arch/ppc/boot/utils/mknote.c 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/utils/mknote.c 2003-01-30 11:54:29.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mknote.c 1.7 05/18/01 15:17:23 cort
+ * BK Id: SCCS/s.mknote.c 1.8 06/05/01 20:20:06 paulus
*/
/*
* Copyright (C) Cort Dougan 1999.
diff -uNr linux-2.4.20/arch/ppc/boot/utils/mkprep.c linux-2.4.20-ben5/arch/ppc/boot/utils/mkprep.c
--- linux-2.4.20/arch/ppc/boot/utils/mkprep.c 2001-05-25 00:02:07.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/boot/utils/mkprep.c 2003-01-30 11:52:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mkprep.c 1.7 05/18/01 06:20:29 patch
+ * BK Id: SCCS/s.mkprep.c 1.8 06/05/01 20:20:06 paulus
*/
/*
* Makes a prep bootable image which can be dd'd onto
diff -uNr linux-2.4.20/arch/ppc/config.in linux-2.4.20-ben5/arch/ppc/config.in
--- linux-2.4.20/arch/ppc/config.in 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/config.in 2003-01-30 11:52:46.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: %F% %I% %G% %U% %#%
+# BK Id: SCCS/s.config.in 1.54 05/21/02 16:43:05 benh
#
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/config-language.txt.
@@ -52,6 +52,17 @@
define_bool CONFIG_PPC_STD_MMU n
fi
+bool 'CPU Frequency scaling' CONFIG_CPU_FREQ
+if [ "$CONFIG_CPU_FREQ" = "y" ]; then
+ bool ' /proc/sys/cpu/ interface (2.4.)' CONFIG_CPU_FREQ_24_API
+ if [ "$CONFIG_CPU_FREQ_24_API" = "n" ]; then
+ define_bool CONFIG_CPU_FREQ_26_API y
+ fi
+ if [ "$CONFIG_ADB_PMU" = "y" ]; then
+ bool " Support for Apple PowerBooks" CONFIG_CPU_FREQ_PMAC
+ fi
+fi
+
if [ "$CONFIG_8260" = "y" ]; then
define_bool CONFIG_SERIAL_CONSOLE y
bool 'Support for EST8260' CONFIG_EST8260
diff -uNr linux-2.4.20/arch/ppc/configs/pmac_defconfig linux-2.4.20-ben5/arch/ppc/configs/pmac_defconfig
--- linux-2.4.20/arch/ppc/configs/pmac_defconfig 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/configs/pmac_defconfig 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
#
-# Automatically generated make config: don't edit
+# Automatically generated by make menuconfig: don't edit
#
# CONFIG_UID16 is not set
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
@@ -30,6 +30,10 @@
# CONFIG_8xx is not set
# CONFIG_8260 is not set
CONFIG_PPC_STD_MMU=y
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_24_API is not set
+CONFIG_CPU_FREQ_26_API=y
+CONFIG_CPU_FREQ_PMAC=y
CONFIG_ALL_PPC=y
# CONFIG_APUS is not set
# CONFIG_SPRUCE is not set
@@ -37,9 +41,7 @@
# CONFIG_GEMINI is not set
# CONFIG_SMP is not set
CONFIG_ALTIVEC=y
-CONFIG_TAU=y
-# CONFIG_TAU_INT is not set
-# CONFIG_TAU_AVERAGE is not set
+# CONFIG_TAU is not set
CONFIG_PPC_ISATIMER=y
#
@@ -78,7 +80,7 @@
CONFIG_PPC_RTC=y
CONFIG_PPC601_SYNC_FIX=y
CONFIG_PROC_DEVICETREE=y
-CONFIG_PPC_RTAS=y
+# CONFIG_PPC_RTAS is not set
CONFIG_BOOTX_TEXT=y
# CONFIG_PREP_RESIDUAL is not set
# CONFIG_PROC_PREPRESIDUAL is not set
@@ -98,7 +100,7 @@
#
# Block devices
#
-CONFIG_BLK_DEV_FD=m
+# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -152,7 +154,7 @@
CONFIG_IP_NF_CONNTRACK=m
CONFIG_IP_NF_FTP=m
CONFIG_IP_NF_IRC=m
-# CONFIG_IP_NF_QUEUE is not set
+CONFIG_IP_NF_QUEUE=m
CONFIG_IP_NF_IPTABLES=m
CONFIG_IP_NF_MATCH_LIMIT=m
CONFIG_IP_NF_MATCH_MAC=m
@@ -182,8 +184,12 @@
CONFIG_IP_NF_NAT_SNMP_BASIC=m
CONFIG_IP_NF_NAT_IRC=m
CONFIG_IP_NF_NAT_FTP=m
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_TOS=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_DSCP=m
+CONFIG_IP_NF_TARGET_MARK=m
+CONFIG_IP_NF_TARGET_LOG=m
CONFIG_IP_NF_TARGET_ULOG=m
CONFIG_IP_NF_TARGET_TCPMSS=m
CONFIG_IP_NF_ARPTABLES=m
@@ -193,12 +199,14 @@
# CONFIG_IP_NF_COMPAT_IPFWADM is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
-# CONFIG_ATM is not set
+CONFIG_ATM=y
+CONFIG_ATM_CLIP=y
+CONFIG_ATM_CLIP_NO_ICMP=y
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+# CONFIG_ATM_BR2684_IPFILTER is not set
# CONFIG_VLAN_8021Q is not set
-
-#
-#
-#
# CONFIG_IPX is not set
CONFIG_ATALK=m
@@ -236,10 +244,6 @@
# IDE, ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
-
-#
-# Please see Documentation/ide.txt for help/info on IDE drives
-#
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
@@ -258,12 +262,8 @@
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=y
-CONFIG_BLK_DEV_IDESCSI=y
+CONFIG_BLK_DEV_IDESCSI=m
# CONFIG_IDE_TASK_IOCTL is not set
-
-#
-# IDE chipset support/bugfixes
-#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
@@ -273,7 +273,7 @@
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
-CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_PCI_AUTO is not set
# CONFIG_IDEDMA_ONLYDISK is not set
CONFIG_BLK_DEV_IDEDMA=y
# CONFIG_IDEDMA_PCI_WIP is not set
@@ -286,7 +286,7 @@
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD74XX is not set
# CONFIG_AMD74XX_OVERRIDE is not set
-CONFIG_BLK_DEV_CMD64X=y
+# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_BLK_DEV_CMD680 is not set
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
@@ -295,9 +295,9 @@
# CONFIG_BLK_DEV_HPT366 is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX is not set
-# CONFIG_PDC202XX_BURST is not set
-# CONFIG_PDC202XX_FORCE is not set
+CONFIG_BLK_DEV_PDC202XX=y
+CONFIG_PDC202XX_BURST=y
+CONFIG_PDC202XX_FORCE=y
# CONFIG_BLK_DEV_SVWKS is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_SLC90E66 is not set
@@ -322,10 +322,6 @@
# SCSI support
#
CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
@@ -334,10 +330,6 @@
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=y
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
@@ -353,15 +345,11 @@
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AACRAID is not set
-CONFIG_SCSI_AIC7XXX=m
+CONFIG_SCSI_AIC7XXX=y
CONFIG_AIC7XXX_CMDS_PER_DEVICE=253
CONFIG_AIC7XXX_RESET_DELAY_MS=15000
# CONFIG_AIC7XXX_PROBE_EISA_VL is not set
# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set
-CONFIG_SCSI_AIC7XXX_OLD=m
-# CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT is not set
-CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=8
-CONFIG_AIC7XXX_OLD_PROC_STATS=y
# CONFIG_SCSI_DPT_I2O is not set
CONFIG_SCSI_ADVANSYS=m
# CONFIG_SCSI_IN2000 is not set
@@ -402,7 +390,7 @@
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
-CONFIG_SCSI_MESH_RESET_DELAY_MS=500
+CONFIG_SCSI_MESH_RESET_DELAY_MS=4000
CONFIG_SCSI_MAC53C94=y
#
@@ -414,24 +402,12 @@
# IEEE 1394 (FireWire) support (EXPERIMENTAL)
#
CONFIG_IEEE1394=m
-
-#
-# Device Drivers
-#
-
-#
-# Texas Instruments PCILynx requires I2C bit-banging
-#
CONFIG_IEEE1394_OHCI1394=m
-
-#
-# Protocol Drivers
-#
CONFIG_IEEE1394_VIDEO1394=m
CONFIG_IEEE1394_SBP2=m
# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set
CONFIG_IEEE1394_ETH1394=m
-# CONFIG_IEEE1394_DV1394 is not set
+CONFIG_IEEE1394_DV1394=m
CONFIG_IEEE1394_RAWIO=m
# CONFIG_IEEE1394_CMP is not set
# CONFIG_IEEE1394_VERBOSEDEBUG is not set
@@ -448,7 +424,7 @@
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
-# CONFIG_TUN is not set
+CONFIG_TUN=m
# CONFIG_ETHERTAP is not set
#
@@ -529,6 +505,7 @@
CONFIG_PPP_DEFLATE=y
CONFIG_PPP_BSDCOMP=m
# CONFIG_PPPOE is not set
+# CONFIG_PPPOATM is not set
# CONFIG_SLIP is not set
#
@@ -546,10 +523,6 @@
CONFIG_APPLE_AIRPORT=m
# CONFIG_PLX_HERMES is not set
CONFIG_PCI_HERMES=m
-
-#
-# Wireless Pcmcia cards support
-#
CONFIG_PCMCIA_HERMES=m
# CONFIG_AIRO_CS is not set
CONFIG_NET_WIRELESS=y
@@ -590,6 +563,21 @@
# CONFIG_AIRONET4500_CS is not set
#
+# ATM drivers
+#
+# CONFIG_ATM_TCP is not set
+# CONFIG_ATM_LANAI is not set
+# CONFIG_ATM_ENI is not set
+# CONFIG_ATM_FIRESTREAM is not set
+# CONFIG_ATM_ZATM is not set
+# CONFIG_ATM_NICSTAR is not set
+# CONFIG_ATM_IDT77252 is not set
+# CONFIG_ATM_AMBASSADOR is not set
+# CONFIG_ATM_HORIZON is not set
+# CONFIG_ATM_IA is not set
+# CONFIG_ATM_FORE200E_MAYBE is not set
+
+#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
@@ -598,18 +586,10 @@
# IrDA (infrared) support
#
CONFIG_IRDA=m
-
-#
-# IrDA protocols
-#
CONFIG_IRLAN=m
CONFIG_IRNET=m
CONFIG_IRCOMM=m
-# CONFIG_IRDA_ULTRA is not set
-
-#
-# IrDA options
-#
+CONFIG_IRDA_ULTRA=y
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRDA_FAST_RR=y
# CONFIG_IRDA_DEBUG is not set
@@ -617,21 +597,9 @@
#
# Infrared-port device drivers
#
-
-#
-# SIR device drivers
-#
CONFIG_IRTTY_SIR=m
-# CONFIG_IRPORT_SIR is not set
-
-#
-# Dongle support
-#
+CONFIG_IRPORT_SIR=m
# CONFIG_DONGLE is not set
-
-#
-# FIR device drivers
-#
# CONFIG_USB_IRDA is not set
# CONFIG_NSC_FIR is not set
# CONFIG_WINBOND_FIR is not set
@@ -643,7 +611,65 @@
#
# ISDN subsystem
#
-# CONFIG_ISDN is not set
+CONFIG_ISDN=m
+CONFIG_ISDN_BOOL=y
+CONFIG_ISDN_PPP=y
+CONFIG_ISDN_PPP_VJ=y
+CONFIG_ISDN_MPP=y
+CONFIG_ISDN_PPP_BSDCOMP=m
+# CONFIG_ISDN_AUDIO is not set
+
+#
+# ISDN feature submodules
+#
+# CONFIG_ISDN_DRV_LOOP is not set
+# CONFIG_ISDN_DIVERSION is not set
+
+#
+# Passive ISDN cards
+#
+CONFIG_ISDN_DRV_HISAX=m
+CONFIG_ISDN_HISAX=y
+# CONFIG_HISAX_EURO is not set
+# CONFIG_HISAX_1TR6 is not set
+# CONFIG_HISAX_NI1 is not set
+CONFIG_HISAX_MAX_CARDS=8
+# CONFIG_HISAX_TELESPCI is not set
+# CONFIG_HISAX_S0BOX is not set
+# CONFIG_HISAX_FRITZPCI is not set
+# CONFIG_HISAX_AVM_A1_PCMCIA is not set
+# CONFIG_HISAX_ELSA is not set
+# CONFIG_HISAX_DIEHLDIVA is not set
+# CONFIG_HISAX_SEDLBAUER is not set
+# CONFIG_HISAX_NETJET is not set
+# CONFIG_HISAX_NETJET_U is not set
+# CONFIG_HISAX_NICCY is not set
+# CONFIG_HISAX_BKM_A4T is not set
+# CONFIG_HISAX_SCT_QUADRO is not set
+CONFIG_HISAX_GAZEL=y
+# CONFIG_HISAX_HFC_PCI is not set
+# CONFIG_HISAX_W6692 is not set
+# CONFIG_HISAX_HFC_SX is not set
+# CONFIG_HISAX_ENTERNOW_PCI is not set
+# CONFIG_HISAX_DEBUG is not set
+# CONFIG_HISAX_SEDLBAUER_CS is not set
+# CONFIG_HISAX_ELSA_CS is not set
+# CONFIG_HISAX_AVM_A1_CS is not set
+CONFIG_HISAX_ST5481=m
+# CONFIG_HISAX_FRITZ_PCIPNP is not set
+
+#
+# Active ISDN cards
+#
+# CONFIG_ISDN_DRV_ICN is not set
+# CONFIG_ISDN_DRV_PCBIT is not set
+# CONFIG_ISDN_DRV_SC is not set
+# CONFIG_ISDN_DRV_ACT2000 is not set
+# CONFIG_ISDN_DRV_EICON is not set
+# CONFIG_ISDN_DRV_TPAM is not set
+# CONFIG_ISDN_CAPI is not set
+# CONFIG_HYSDN is not set
+# CONFIG_HYSDN_CAPI is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
@@ -660,7 +686,7 @@
#
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
-# CONFIG_FB_RIVA is not set
+CONFIG_FB_RIVA=y
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
# CONFIG_FB_PM3 is not set
@@ -733,7 +759,7 @@
CONFIG_ADB=y
CONFIG_ADB_MACIO=y
CONFIG_INPUT_ADBHID=y
-CONFIG_MAC_ADBKEYCODES=y
+# CONFIG_MAC_ADBKEYCODES is not set
CONFIG_MAC_EMUMOUSEBTN=y
CONFIG_MAC_HID=y
# CONFIG_ANSLCD is not set
@@ -784,10 +810,6 @@
# CONFIG_INPUT_EMU10K1 is not set
# CONFIG_INPUT_SERIO is not set
# CONFIG_INPUT_SERPORT is not set
-
-#
-# Joysticks
-#
# CONFIG_INPUT_ANALOG is not set
# CONFIG_INPUT_A3D is not set
# CONFIG_INPUT_ADI is not set
@@ -813,6 +835,7 @@
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_AMD_PM768 is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
# CONFIG_DTLK is not set
@@ -823,19 +846,54 @@
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_AGP is not set
+CONFIG_AGP=m
+# CONFIG_AGP_INTEL is not set
+# CONFIG_AGP_I810 is not set
+# CONFIG_AGP_VIA is not set
+# CONFIG_AGP_AMD is not set
+# CONFIG_AGP_AMD_8151 is not set
+# CONFIG_AGP_SIS is not set
+# CONFIG_AGP_ALI is not set
+# CONFIG_AGP_SWORKS is not set
+CONFIG_AGP_UNINORTH=y
# CONFIG_DRM is not set
#
# PCMCIA character devices
#
-# CONFIG_PCMCIA_SERIAL_CS is not set
+CONFIG_PCMCIA_SERIAL_CS=m
# CONFIG_SYNCLINK_CS is not set
#
# Multimedia devices
#
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=m
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_PROC_FS is not set
+# CONFIG_I2C_PARPORT is not set
+# CONFIG_VIDEO_PMS is not set
+CONFIG_VIDEO_PLANB=m
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_ZORAN_BUZ is not set
+# CONFIG_VIDEO_ZORAN_DC10 is not set
+# CONFIG_VIDEO_ZORAN_LML33 is not set
+# CONFIG_VIDEO_ZR36120 is not set
+# CONFIG_VIDEO_MEYE is not set
+
+#
+# Radio Adapters
+#
+# CONFIG_RADIO_GEMTEK_PCI is not set
+# CONFIG_RADIO_MAXIRADIO is not set
+# CONFIG_RADIO_MAESTRO is not set
+# CONFIG_RADIO_MIROPCM20 is not set
#
# File systems
@@ -878,7 +936,7 @@
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
-CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_FS is not set
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
@@ -1017,81 +1075,53 @@
#
CONFIG_USB=y
# CONFIG_USB_DEBUG is not set
-
-#
-# Miscellaneous USB options
-#
CONFIG_USB_DEVICEFS=y
# CONFIG_USB_BANDWIDTH is not set
# CONFIG_USB_LONG_TIMEOUT is not set
-
-#
-# USB Host Controller Drivers
-#
# CONFIG_USB_EHCI_HCD is not set
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
CONFIG_USB_OHCI=y
-
-#
-# USB Device Class drivers
-#
-# CONFIG_USB_AUDIO is not set
+CONFIG_USB_AUDIO=m
# CONFIG_USB_EMI26 is not set
# CONFIG_USB_BLUETOOTH is not set
# CONFIG_USB_MIDI is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_DPCM is not set
-# CONFIG_USB_STORAGE_HP8200e is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
+CONFIG_USB_STORAGE=m
+CONFIG_USB_STORAGE_DEBUG=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_DPCM=y
+CONFIG_USB_STORAGE_HP8200e=y
+CONFIG_USB_STORAGE_SDDR09=y
# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
+CONFIG_USB_STORAGE_JUMPSHOT=y
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
-
-#
-# USB Human Interface Devices (HID)
-#
CONFIG_USB_HID=y
CONFIG_USB_HIDINPUT=y
-# CONFIG_USB_HIDDEV is not set
+CONFIG_USB_HIDDEV=y
# CONFIG_USB_AIPTEK is not set
# CONFIG_USB_WACOM is not set
-
-#
-# USB Imaging devices
-#
# CONFIG_USB_DC2XX is not set
# CONFIG_USB_MDC800 is not set
CONFIG_USB_SCANNER=m
# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_HPUSBSCSI is not set
-
-#
-# USB Multimedia devices
-#
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
-#
-# USB Network adaptors
-#
+# CONFIG_USB_IBMCAM is not set
+CONFIG_USB_OV511=m
+CONFIG_USB_PWC=m
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_DABUSB is not set
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RTL8150 is not set
# CONFIG_USB_KAWETH is not set
# CONFIG_USB_CATC is not set
-# CONFIG_USB_CDCETHER is not set
+CONFIG_USB_CDCETHER=m
# CONFIG_USB_USBNET is not set
-
-#
-# USB port drivers
-#
# CONFIG_USB_USS720 is not set
#
@@ -1110,18 +1140,24 @@
# CONFIG_USB_SERIAL_IR is not set
# CONFIG_USB_SERIAL_EDGEPORT is not set
# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
+CONFIG_USB_SERIAL_KEYSPAN_PDA=m
+CONFIG_USB_SERIAL_KEYSPAN=m
+CONFIG_USB_SERIAL_KEYSPAN_USA28=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
+CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19=y
+CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
+CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
+CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
# CONFIG_USB_SERIAL_MCT_U232 is not set
# CONFIG_USB_SERIAL_KLSI is not set
# CONFIG_USB_SERIAL_PL2303 is not set
# CONFIG_USB_SERIAL_CYBERJACK is not set
# CONFIG_USB_SERIAL_XIRCOM is not set
# CONFIG_USB_SERIAL_OMNINET is not set
-
-#
-# USB Miscellaneous drivers
-#
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_AUERSWALD is not set
# CONFIG_USB_TIGL is not set
diff -uNr linux-2.4.20/arch/ppc/kernel/Makefile linux-2.4.20-ben5/arch/ppc/kernel/Makefile
--- linux-2.4.20/arch/ppc/kernel/Makefile 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/Makefile 2003-01-30 11:55:46.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: %F% %I% %G% %U% %#%
+# BK Id: SCCS/s.Makefile 1.49 10/29/02 20:27:52 benh
#
#
# Makefile for the linux kernel.
diff -uNr linux-2.4.20/arch/ppc/kernel/align.c linux-2.4.20-ben5/arch/ppc/kernel/align.c
--- linux-2.4.20/arch/ppc/kernel/align.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/align.c 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.align.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.align.c 1.7 06/05/01 21:22:02 paulus
*/
/*
* align.c - handle alignment exceptions for the Power PC.
diff -uNr linux-2.4.20/arch/ppc/kernel/bitops.c linux-2.4.20-ben5/arch/ppc/kernel/bitops.c
--- linux-2.4.20/arch/ppc/kernel/bitops.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/bitops.c 2003-01-30 11:52:58.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.bitops.c 1.7 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.bitops.c 1.9 06/05/01 21:22:02 paulus
*/
/*
* Copyright (C) 1996 Paul Mackerras.
diff -uNr linux-2.4.20/arch/ppc/kernel/btext.c linux-2.4.20-ben5/arch/ppc/kernel/btext.c
--- linux-2.4.20/arch/ppc/kernel/btext.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/btext.c 2003-01-30 11:55:36.000000000 +0100
@@ -45,22 +45,14 @@
static unsigned char vga_font[cmapsz];
int boot_text_mapped;
+int force_printk_to_btext;
boot_infos_t disp_bi;
extern char *klimit;
-/*
- * Powermac can use btext_* after boot for xmon,
- * chrp only uses it during early boot.
- */
-#ifdef CONFIG_XMON
-#define BTEXT __pmac
-#define BTDATA __pmacdata
-#else
-#define BTEXT __init
-#define BTDATA __initdata
-#endif /* CONFIG_XMON */
+#define BTEXT
+#define BTDATA
/*
* This is called only when we are booted via BootX.
diff -uNr linux-2.4.20/arch/ppc/kernel/checks.c linux-2.4.20-ben5/arch/ppc/kernel/checks.c
--- linux-2.4.20/arch/ppc/kernel/checks.c 2001-05-22 02:04:46.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/checks.c 2003-01-30 11:54:34.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.checks.c 1.6 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.checks.c 1.8 06/05/01 21:22:02 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/kernel/cputable.c linux-2.4.20-ben5/arch/ppc/kernel/cputable.c
--- linux-2.4.20/arch/ppc/kernel/cputable.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/cputable.c 2003-01-30 11:53:00.000000000 +0100
@@ -144,7 +144,16 @@
32, 32,
__setup_cpu_750cx
},
- { /* 750FX (All revs for now) */
+ { /* 750FX rev 2.0 must disable HID0[DPM] */
+ 0xffffffff, 0x70000200, "750FX",
+ CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
+ CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
+ CPU_FTR_NO_DPM,
+ COMMON_PPC,
+ 32, 32,
+ __setup_cpu_750
+ },
+ { /* 750FX (All revs except 2.0) */
0xffff0000, 0x70000000, "750FX",
CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB |
CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_HPTE_TABLE | CPU_FTR_CAN_NAP |
diff -uNr linux-2.4.20/arch/ppc/kernel/entry.S linux-2.4.20-ben5/arch/ppc/kernel/entry.S
--- linux-2.4.20/arch/ppc/kernel/entry.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/entry.S 2003-01-30 11:54:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.entry.S 1.26 01/25/02 15:15:24 benh
+ * BK Id: SCCS/s.entry.S 1.29 01/20/03 22:26:36 benh
*/
/*
* PowerPC version
@@ -166,7 +166,6 @@
.globl ret_from_syscall_2
ret_from_syscall_2:
stw r3,RESULT(r1) /* Save result */
- stw r3,GPR0(r1) /* temporary gross hack to make strace work */
li r10,-_LAST_ERRNO
cmpl 0,r3,r10
blt 60f
diff -uNr linux-2.4.20/arch/ppc/kernel/find_name.c linux-2.4.20-ben5/arch/ppc/kernel/find_name.c
--- linux-2.4.20/arch/ppc/kernel/find_name.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/find_name.c 2003-01-30 11:54:17.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.find_name.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.find_name.c 1.7 06/05/01 21:22:02 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/kernel/galaxy_pci.c linux-2.4.20-ben5/arch/ppc/kernel/galaxy_pci.c
--- linux-2.4.20/arch/ppc/kernel/galaxy_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/galaxy_pci.c 2003-01-30 11:56:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.galaxy_pci.c 1.10 08/13/02 20:27:37 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/kernel/head.S linux-2.4.20-ben5/arch/ppc/kernel/head.S
--- linux-2.4.20/arch/ppc/kernel/head.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/head.S 2003-01-30 11:54:22.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.head.S 1.58 01/25/03 21:28:49 benh
*/
/*
* PowerPC version
@@ -40,6 +40,8 @@
#include
#endif
+#undef DEBUG_RESET
+
#ifdef CONFIG_PPC64BRIDGE
#define LOAD_BAT(n, reg, RA, RB) \
ld RA,(n*32)+0(reg); \
@@ -310,15 +312,31 @@
.long ret_from_except
/* System reset */
-#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
-#ifdef CONFIG_GEMINI
+/* MVME/MTX and gemini start the secondary here
+ * Changed so that location is dynamically changed to a
+ * branch for CPU startup, then restored, so we still have
+ * the exception vector around for debugging
+ */
+#if defined(CONFIG_SMP) && defined(CONFIG_GEMINI)
. = 0x100
b __secondary_start_gemini
-#else /* CONFIG_GEMINI */
- STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)
-#endif /* CONFIG_GEMINI */
+#else
+#ifdef DEBUG_RESET
+ . = 0x100
+ li r3,0
+ mfspr r0,SRR0
+ stw r0,0(r3)
+ mfspr r0,SRR1
+ stw r0,4(r3)
+ mflr r0
+ stw r0,8(r3)
+ stw r1,12(r3)
+ stw r2,16(r3)
+1: nop
+ b 1b
#else
STD_EXCEPTION(0x100, Reset, UnknownException)
+#endif
#endif
/* Machine check */
@@ -1348,12 +1366,14 @@
blr
_GLOBAL(__setup_cpu_7400)
mflr r4
+ bl setup_7400_workarounds
bl setup_common_caches
bl setup_750_7400_hid0
mtlr r4
blr
_GLOBAL(__setup_cpu_7410)
mflr r4
+ bl setup_7410_workarounds
bl setup_common_caches
bl setup_750_7400_hid0
li r3,0
@@ -1414,6 +1434,51 @@
isync
blr
+/* 7400 <= rev 2.7 and 7410 rev = 1.0 suffer from some
+ * erratas we work around here.
+ * Moto MPC710CE.pdf describes them, those are errata
+ * #3, #4 and #5
+ * Note that we assume the firmware didn't choose to
+ * apply other workarounds (there are other ones documented
+ * in the .pdf). It appear that Apple firmware only works
+ * around #3 and with the same fix we use. We may want to
+ * check if the CPU is using 60x bus mode in which case
+ * the workaround for errata #4 is useless. Also, we may
+ * want to explicitely clear HID0_NOPDST as this is not
+ * needed once we have applied workaround #5 (though it's
+ * not set by Apple's firmware at least).
+ */
+setup_7400_workarounds:
+ mfpvr r3
+ rlwinm r3,r3,0,20,31
+ cmpwi 0,r3,0x0207
+ ble 1f
+ blr
+setup_7410_workarounds:
+ mfpvr r3
+ rlwinm r3,r3,0,20,31
+ cmpwi 0,r3,0x0100
+ bnelr
+ /* Make sure 7410 has L2CR2 cleared */
+ li r11,0
+ mtspr SPRN_L2CR2,r11
+ sync
+1:
+ mfspr r11,SPRN_MSSSR0
+ /* Errata #3: Set L1OPQ_SIZE to 0x10 */
+ rlwinm r11,r11,0,9,6
+ oris r11,r11,0x0100
+ /* Errata #4: Set L2MQ_SIZE to 1 (check for MPX mode first ?) */
+ oris r11,r11,0x0002
+ /* Errata #5: Set DRLT_SIZE to 0x01 */
+ rlwinm r11,r11,0,5,2
+ oris r11,r11,0x0800
+ sync
+ mtspr SPRN_MSSSR0,r11
+ sync
+ isync
+ blr
+
/* 740/750/7400/7410
* Enable Store Gathering (SGE), Address Brodcast (ABE),
* Branch History Table (BHTE), Branch Target ICache (BTIC)
@@ -1423,7 +1488,9 @@
setup_750_7400_hid0:
mfspr r11,HID0
ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+BEGIN_FTR_SECTION
oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
li r3,HID0_SPD
andc r11,r11,r3 /* clear SPD: enable speculative */
li r3,0
@@ -1439,6 +1506,18 @@
* (waiting for confirmation)
*/
setup_750cx:
+ mfspr r10, SPRN_HID1
+ rlwinm r10,r10,4,28,31
+ cmpi cr0,r10,7
+ cmpi cr1,r10,9
+ cmpi cr2,r10,11
+ cror 4*cr0+eq,4*cr0+eq,4*cr1+eq
+ cror 4*cr0+eq,4*cr0+eq,4*cr2+eq
+ bnelr
+ lwz r6,CPU_SPEC_FEATURES(r5)
+ li r7,CPU_FTR_CAN_NAP
+ andc r6,r6,r7
+ stw r6,CPU_SPEC_FEATURES(r5)
blr
/* 750fx specific
@@ -1476,7 +1555,9 @@
/* All of the bits we have to set.....
*/
ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK
+BEGIN_FTR_SECTION
oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
/* All of the bits we have to clear....
*/
diff -uNr linux-2.4.20/arch/ppc/kernel/head_4xx.S linux-2.4.20-ben5/arch/ppc/kernel/head_4xx.S
--- linux-2.4.20/arch/ppc/kernel/head_4xx.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/head_4xx.S 2003-01-30 11:54:59.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.head_4xx.S 1.6 05/21/01 11:50:00 paulus
+ * BK Id: SCCS/s.head_4xx.S 1.9 08/13/02 20:27:37 paulus
*/
/*
* Copyright (c) 1995-1996 Gary Thomas
diff -uNr linux-2.4.20/arch/ppc/kernel/head_8xx.S linux-2.4.20-ben5/arch/ppc/kernel/head_8xx.S
--- linux-2.4.20/arch/ppc/kernel/head_8xx.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/head_8xx.S 2003-01-30 11:52:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.head_8xx.S 1.31 09/11/02 14:41:30 paulus
*/
/*
* arch/ppc/kernel/except_8xx.S
diff -uNr linux-2.4.20/arch/ppc/kernel/i8259.c linux-2.4.20-ben5/arch/ppc/kernel/i8259.c
--- linux-2.4.20/arch/ppc/kernel/i8259.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/i8259.c 2003-01-30 11:55:34.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.i8259.c 1.18 10/12/02 14:14:20 paulus
*/
#include
@@ -21,17 +21,37 @@
int i8259_pic_irq_offset;
-/* Acknowledge the irq using the PCI host bridge's interrupt acknowledge
- * feature. (Polling is somehow broken on some IBM and Motorola PReP boxes.)
+/*
+ * Acknowledge the IRQ using either the PCI host bridge's interrupt
+ * acknowledge feature or poll. How i8259_init() is called determines
+ * which is called. It should be noted that polling is broken on some
+ * IBM and Motorola PReP boxes so we must use the int-ack feature on them.
*/
-int i8259_irq(struct pt_regs *regs)
+int
+i8259_irq(struct pt_regs *regs)
{
int irq;
- spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
+ spin_lock(&i8259_lock);
- irq = *pci_intack;
- if (irq==7) {
+ /* Either int-ack or poll for the IRQ */
+ if (pci_intack)
+ irq = *pci_intack;
+ else {
+ /* Perform an interrupt acknowledge cycle on controller 1. */
+ outb(0x0C, 0x20); /* prepare for poll */
+ irq = inb(0x20) & 7;
+ if (irq == 2 ) {
+ /*
+ * Interrupt is cascaded so perform interrupt
+ * acknowledge on controller 2.
+ */
+ outb(0x0C, 0xA0); /* prepare for poll */
+ irq = (inb(0xA0) & 7) + 8;
+ }
+ }
+
+ if (irq == 7) {
/*
* This may be a spurious interrupt.
*
@@ -39,47 +59,13 @@
* significant bit is not set then there is no valid
* interrupt.
*/
- if(~inb(0x20)&0x80) {
+ if (!pci_intack)
+ outb(0x0B, 0x20); /* ISR register */
+ if(~inb(0x20) & 0x80)
irq = -1;
- }
}
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return irq;
-}
-
-/* Poke the 8259's directly using poll commands. */
-int i8259_poll(struct pt_regs *regs)
-{
- int irq;
- spin_lock/*_irqsave*/(&i8259_lock/*, flags*/);
- /*
- * Perform an interrupt acknowledge cycle on controller 1
- */
- outb(0x0C, 0x20); /* prepare for poll */
- irq = inb(0x20) & 7;
- if (irq == 2) {
- /*
- * Interrupt is cascaded so perform interrupt
- * acknowledge on controller 2
- */
- outb(0x0C, 0xA0); /* prepare for poll */
- irq = (inb(0xA0) & 7) + 8;
- } else if (irq==7) {
- /*
- * This may be a spurious interrupt
- *
- * Read the interrupt status register. If the most
- * significant bit is not set then there is no valid
- * interrupt
- */
- outb(0x0b, 0x20);
- if(~inb(0x20)&0x80) {
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
- return -1;
- }
- }
- spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/);
+ spin_unlock(&i8259_lock);
return irq;
}
diff -uNr linux-2.4.20/arch/ppc/kernel/idle.c linux-2.4.20-ben5/arch/ppc/kernel/idle.c
--- linux-2.4.20/arch/ppc/kernel/idle.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/idle.c 2003-01-30 11:53:09.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.idle.c 1.26 10/29/02 20:27:52 benh
*/
/*
* Idle daemon for PowerPC. Idle daemon will handle any action
diff -uNr linux-2.4.20/arch/ppc/kernel/idle_6xx.S linux-2.4.20-ben5/arch/ppc/kernel/idle_6xx.S
--- linux-2.4.20/arch/ppc/kernel/idle_6xx.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/idle_6xx.S 2003-01-30 11:54:42.000000000 +0100
@@ -107,13 +107,23 @@
andis. r0,r3,HID0_NAP@h
beq 2f
BEGIN_FTR_SECTION
- /* Disable L2 prefetch on some 745x */
+ /* Disable L2 prefetch on some 745x and try to ensure
+ * L2 prefetch engines are idle. As explained by errata
+ * text, we can't be sure they are, we just hope very hard
+ * that well be enough (sic !). At least I noticed Apple
+ * doesn't even bother doing the dcbf's here...
+ */
mfspr r4,SPRN_MSSCR0
rlwinm r4,r4,0,0,29
sync
mtspr SPRN_MSSCR0,r4
sync
isync
+ lis r4,KERNELBASE@h
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
+ dcbf 0,r4
END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR)
#ifdef DEBUG
lis r6,nap_enter_count@ha
@@ -142,7 +152,9 @@
END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
andc r4,r4,r5
or r4,r4,r3
- oris r4,r4,HID0_DPM@h /* that should be done once for all ... */
+BEGIN_FTR_SECTION
+ oris r4,r4,HID0_DPM@h /* that should be done once for all */
+END_FTR_SECTION_IFCLR(CPU_FTR_NO_DPM)
mtspr SPRN_HID0,r4
BEGIN_FTR_SECTION
DSSALL
diff -uNr linux-2.4.20/arch/ppc/kernel/indirect_pci.c linux-2.4.20-ben5/arch/ppc/kernel/indirect_pci.c
--- linux-2.4.20/arch/ppc/kernel/indirect_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/indirect_pci.c 2003-01-30 11:52:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.indirect_pci.c 1.12 08/13/02 20:27:37 paulus
*/
/*
* Support for indirect PCI bridges.
diff -uNr linux-2.4.20/arch/ppc/kernel/irq.c linux-2.4.20-ben5/arch/ppc/kernel/irq.c
--- linux-2.4.20/arch/ppc/kernel/irq.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/irq.c 2003-01-30 11:53:55.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.irq.c 1.39 06/04/02 16:06:19 benh
*/
/*
* arch/ppc/kernel/irq.c
@@ -78,6 +78,10 @@
unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
atomic_t ppc_n_lost_interrupts;
+#ifdef CONFIG_DEBUG_SPINLOCK
+int debug_long_irqlock;
+#endif /* CONFIG_DEBUG_SPINLOCK */
+
/* nasty hack for shared irq's since we need to do kmalloc calls but
* can't very early in the boot when we need to do a request irq.
* this needs to be removed.
@@ -528,27 +532,21 @@
int irq, first = 1;
hardirq_enter( cpu );
- for (;;) {
- /*
- * Every arch is required to implement ppc_md.get_irq.
- * This function will either return an irq number or -1 to
- * indicate there are no more pending. But the first time
- * through the loop this means there wasn't and IRQ pending.
- * The value -2 is for buggy hardware and means that this IRQ
- * has already been handled. -- Tom
- */
- irq = ppc_md.get_irq( regs );
-
- if (irq >= 0)
- ppc_irq_dispatch_handler( regs, irq );
- else {
- if (irq != -2 && first)
- /* That's not SMP safe ... but who cares ? */
- ppc_spurious_interrupts++;
- break;
- }
+ /*
+ * Every platform is required to implement ppc_md.get_irq.
+ * This function will either return an irq number or -1 to
+ * indicate there are no more pending. But the first time
+ * through the loop this means there wasn't an IRQ pending.
+ * The value -2 is for buggy hardware and means that this IRQ
+ * has already been handled. -- Tom
+ */
+ while ((irq = ppc_md.get_irq(regs)) >= 0) {
+ ppc_irq_dispatch_handler(regs, irq);
first = 0;
}
+ if (irq != -2 && first)
+ /* That's not SMP safe ... but who cares ? */
+ ppc_spurious_interrupts++;
hardirq_exit( cpu );
if (softirq_pending(cpu))
@@ -596,6 +594,24 @@
unsigned long *stack;
int cpu = smp_processor_id();
+#ifdef CONFIG_XMON
+ xmon_printf("\n%s, CPU %d:\n", str, cpu);
+ xmon_printf("irq: %d [%d %d]\n",
+ atomic_read(&global_irq_count),
+ local_irq_count(0),
+ local_irq_count(1));
+ xmon_printf("bh: %d [%d %d]\n",
+ atomic_read(&global_bh_count),
+ local_bh_count(0),
+ local_bh_count(1));
+ stack = (unsigned long *) &str;
+ for (i = 40; i ; i--) {
+ unsigned long x = *++stack;
+ if (x > (unsigned long) &init_task_union && x < (unsigned long) &vsprintf) {
+ xmon_printf("<[%08lx]> ", x);
+ }
+ }
+#endif /* CONFIG_XMON */
printk("\n%s, CPU %d:\n", str, cpu);
printk("irq: %d [%d %d]\n",
atomic_read(&global_irq_count),
@@ -712,6 +728,9 @@
do {
do {
if (loops-- == 0) {
+#ifdef CONFIG_XMON
+ xmon_printf("get_irqlock(%d) waiting, global_irq_holder=%d\n", cpu, global_irq_holder);
+#endif
printk("get_irqlock(%d) waiting, global_irq_holder=%d\n", cpu, global_irq_holder);
#ifdef CONFIG_XMON
xmon(0);
diff -uNr linux-2.4.20/arch/ppc/kernel/m8260_setup.c linux-2.4.20-ben5/arch/ppc/kernel/m8260_setup.c
--- linux-2.4.20/arch/ppc/kernel/m8260_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/m8260_setup.c 2003-01-30 11:54:38.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.m8260_setup.c 1.33 09/26/02 22:13:19 paulus
*/
/*
* linux/arch/ppc/kernel/setup.c
diff -uNr linux-2.4.20/arch/ppc/kernel/m8xx_setup.c linux-2.4.20-ben5/arch/ppc/kernel/m8xx_setup.c
--- linux-2.4.20/arch/ppc/kernel/m8xx_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/m8xx_setup.c 2003-01-30 11:55:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.m8xx_setup.c 1.45 10/12/02 14:14:20 paulus
*
* linux/arch/ppc/kernel/setup.c
*
@@ -45,6 +45,7 @@
#include
#include
#include
+#include
#include "ppc8xx_pic.h"
@@ -63,9 +64,9 @@
m8xx_setup_arch(void)
{
int cpm_page;
-
+
cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
-
+
/* Reset the Communication Processor Module.
*/
m8xx_cpm_reset(cpm_page);
@@ -73,10 +74,10 @@
#ifdef notdef
ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
#endif
-
+
#ifdef CONFIG_BLK_DEV_INITRD
#if 0
- ROOT_DEV = to_kdev_t(0x0200); /* floppy */
+ ROOT_DEV = to_kdev_t(0x0200); /* floppy */
rd_prompt = 1;
rd_doload = 1;
rd_image_start = 0;
@@ -218,7 +219,7 @@
__asm__("mtmsr %0" : : "r" (msr) );
dummy = ((immap_t *)IMAP_ADDR)->im_clkrst.res[0];
- printk("Restart failed\n");
+ printk("Restart failed\n");
while(1);
}
@@ -241,7 +242,7 @@
bd_t *bp;
bp = (bd_t *)__res;
-
+
seq_printf(m, "clock\t\t: %ldMHz\n"
"bus clock\t: %ldMHz\n",
bp->bi_intfreq / 1000000,
@@ -264,7 +265,7 @@
for ( i = 0 ; i < NR_SIU_INTS ; i++ )
irq_desc[i].handler = &ppc8xx_pic;
-
+
/* We could probably incorporate the CPM into the multilevel
* interrupt structure.
*/
@@ -275,7 +276,7 @@
for ( i = NR_SIU_INTS ; i < (NR_SIU_INTS + NR_8259_INTS) ; i++ )
irq_desc[i].handler = &i8259_pic;
i8259_pic.irq_offset = NR_SIU_INTS;
- i8259_init();
+ i8259_init(0);
request_8xxirq(ISA_BRIDGE_INT, mbx_i8259_action, 0, "8259 cascade", NULL);
enable_irq(ISA_BRIDGE_INT);
#endif
@@ -297,7 +298,7 @@
{
bd_t *binfo;
extern unsigned char __res[];
-
+
binfo = (bd_t *)__res;
return binfo->bi_memsize;
@@ -348,7 +349,7 @@
if ( r3 )
memcpy( (void *)__res,(void *)(r3+KERNELBASE), sizeof(bd_t) );
-
+
#ifdef CONFIG_PCI
m8xx_setup_pci_ptrs();
#endif
@@ -363,7 +364,7 @@
#endif /* CONFIG_BLK_DEV_INITRD */
/* take care of cmd line */
if ( r6 )
- {
+ {
*(char *)(r7+KERNELBASE) = 0;
strcpy(cmd_line, (char *)(r6+KERNELBASE));
}
@@ -397,5 +398,5 @@
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
m8xx_ide_init();
-#endif
+#endif
}
diff -uNr linux-2.4.20/arch/ppc/kernel/misc.S linux-2.4.20-ben5/arch/ppc/kernel/misc.S
--- linux-2.4.20/arch/ppc/kernel/misc.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/misc.S 2003-01-30 11:54:00.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.misc.S 1.50 10/20/02 20:14:44 benh
*/
/*
* This file contains miscellaneous low-level functions.
diff -uNr linux-2.4.20/arch/ppc/kernel/mk_defs.c linux-2.4.20-ben5/arch/ppc/kernel/mk_defs.c
--- linux-2.4.20/arch/ppc/kernel/mk_defs.c 2001-08-28 15:58:33.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/mk_defs.c 2003-01-30 11:52:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mk_defs.c 1.11 08/19/01 22:43:23 paulus
+ * BK Id: SCCS/s.mk_defs.c 1.12 08/29/01 08:49:24 paulus
*/
/*
* This program is used to generate definitions needed by
diff -uNr linux-2.4.20/arch/ppc/kernel/open_pic.c linux-2.4.20-ben5/arch/ppc/kernel/open_pic.c
--- linux-2.4.20/arch/ppc/kernel/open_pic.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/open_pic.c 2003-01-30 11:55:50.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.open_pic.c 1.40 10/12/02 14:14:20 paulus
*/
/*
* arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling
@@ -38,7 +38,6 @@
static u_int NumSources;
static int open_pic_irq_offset;
static volatile OpenPIC_Source *ISR[NR_IRQS];
-static volatile unsigned char* chrp_int_ack_special;
/* Global Operations */
static void openpic_disable_8259_pass_through(void);
@@ -309,7 +308,6 @@
return;
open_pic_irq_offset = offset;
- chrp_int_ack_special = (volatile unsigned char*)chrp_ack;
/* Initialize timer interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic: timer",0x3ba);
@@ -776,14 +774,8 @@
/* Yep - because openpic !=> i8259, for one thing. -VAL */
if (open_pic_irq_offset && irq == open_pic_irq_offset)
{
- /*
- * This magic address generates a PCI IACK cycle.
- */
- if ( chrp_int_ack_special )
- irq = *chrp_int_ack_special;
#ifndef CONFIG_GEMINI
- else
- irq = i8259_poll(regs);
+ irq = i8259_irq(regs);
#endif
openpic_eoi();
}
diff -uNr linux-2.4.20/arch/ppc/kernel/pci-dma.c linux-2.4.20-ben5/arch/ppc/kernel/pci-dma.c
--- linux-2.4.20/arch/ppc/kernel/pci-dma.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/pci-dma.c 2003-01-30 11:53:14.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pci-dma.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.pci-dma.c 1.7 06/05/01 21:22:03 paulus
*/
/*
* Copyright (C) 2000 Ani Joshi
diff -uNr linux-2.4.20/arch/ppc/kernel/pci.c linux-2.4.20-ben5/arch/ppc/kernel/pci.c
--- linux-2.4.20/arch/ppc/kernel/pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/pci.c 2003-01-30 11:56:00.000000000 +0100
@@ -1,8 +1,8 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pci.c 1.60 01/20/03 21:55:26 benh
*/
/*
- * Common pmac/prep/chrp pci routines. -- Cort
+ * Common PCI code for PPC architecture
*/
#include
@@ -25,7 +25,7 @@
#include
#include
-#undef DEBUG
+#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -113,7 +113,11 @@
int reg;
struct pci_controller* hose = dev->sysdata;
unsigned long io_offset;
-
+
+ if (dev->vendor == PCI_VENDOR_ID_APPLE && dev->device == PCI_DEVICE_ID_APPLE_KEYLARGO) {
+ printk("trying to reloc keylargo !! skipping\n");
+ return;
+ }
new = res->start;
if (hose && res->flags & IORESOURCE_IO) {
io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -335,8 +339,9 @@
{
struct resource *pr, *r = &dev->resource[idx];
- DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n",
- dev->slot_name, idx, r->start, r->end, r->flags);
+ DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx), vd: %04x, dev: %04x\n",
+ dev->slot_name, idx, r->start, r->end, r->flags,
+ dev->vendor, dev->device);
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0) {
printk(KERN_ERR "PCI: Cannot allocate resource region %d"
@@ -795,6 +800,10 @@
}
ranges += np;
}
+ DBG("hose %s, pci_mem_offset: %08lx, start0: %08lx\n",
+ dev->name, hose->pci_mem_offset, hose->mem_resources[0].start);
+ DBG(" io_base_virt: %p, io_base_phys: %08lx, isa_mem_base: %08lx\n",
+ hose->io_base_virt, hose->io_base_phys, isa_mem_base);
}
/* We create the "pci-OF-bus-map" property now so it appears in the
@@ -894,7 +903,8 @@
struct pci_dev *dev = pci_dev_b(ln);
u16 class = dev->class >> 8;
- if (class == PCI_CLASS_DISPLAY_VGA || class == PCI_CLASS_NOT_DEFINED_VGA)
+ if (class == PCI_CLASS_DISPLAY_VGA ||
+ class == PCI_CLASS_NOT_DEFINED_VGA)
*found_vga = 1;
if (class >> 8 == PCI_BASE_CLASS_BRIDGE && dev->subordinate)
rc |= check_for_io_childs(dev->subordinate, res, found_vga);
@@ -905,7 +915,8 @@
struct resource *r;
unsigned long r_size;
- if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI && i >= PCI_BRIDGE_RESOURCES)
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_PCI
+ && i >= PCI_BRIDGE_RESOURCES)
continue;
r = &dev->resource[i];
r_size = r->end - r->start;
@@ -931,30 +942,45 @@
do_fixup_p2p_level(struct pci_bus *bus)
{
struct list_head *ln;
- int i;
+ int i, parent_io;
int has_vga = 0;
+
+ for (parent_io=0; parent_io<4; parent_io++)
+ if (bus->resource[parent_io]->flags & IORESOURCE_IO)
+ break;
+ if (parent_io >= 4)
+ return;
for (ln=bus->children.next; ln != &bus->children; ln=ln->next) {
struct pci_bus *b = pci_bus_b(ln);
struct pci_dev *d = b->self;
struct pci_controller* hose = (struct pci_controller *)d->sysdata;
struct resource *res = b->resource[0];
+ struct resource tmp_res;
unsigned long max;
int found_vga = 0;
- res->end = 0;
- res->start = 0x1000;
+ memset(&tmp_res, 0, sizeof(tmp_res));
+ tmp_res.start = bus->resource[parent_io]->start;
+
+ /* We don't let low addresses go through that closed P2P bridge, well,
+ * that may not be necessary but I feel safer that way
+ */
+ if (tmp_res.start == 0)
+ tmp_res.start = 0x1000;
- if (!list_empty(&b->devices) && res && res->flags == 0 && res != bus->resource[0] &&
+ if (!list_empty(&b->devices) && res && res->flags == 0 &&
+ res != bus->resource[parent_io] &&
(d->class >> 8) == PCI_CLASS_BRIDGE_PCI &&
- check_for_io_childs(b, res, &found_vga)) {
+ check_for_io_childs(b, &tmp_res, &found_vga)) {
u8 io_base_lo;
printk(KERN_INFO "Fixing up IO bus %s\n", b->name);
if (found_vga) {
if (has_vga) {
- printk(KERN_WARNING "Skipping VGA, already active on bus segment\n");
+ printk(KERN_WARNING "Skipping VGA, already active"
+ " on bus segment\n");
found_vga = 0;
} else
has_vga = 1;
@@ -962,10 +988,13 @@
pci_read_config_byte(d, PCI_IO_BASE, &io_base_lo);
if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32)
- max = ((unsigned long) hose->io_base_virt - isa_io_base) + 0xffffffff;
+ max = ((unsigned long) hose->io_base_virt
+ - isa_io_base) + 0xffffffff;
else
- max = ((unsigned long) hose->io_base_virt - isa_io_base) + 0xffff;
-
+ max = ((unsigned long) hose->io_base_virt
+ - isa_io_base) + 0xffff;
+
+ *res = tmp_res;
res->flags = IORESOURCE_IO;
res->name = b->name;
@@ -976,10 +1005,12 @@
continue;
if ((r->flags & IORESOURCE_IO) == 0)
continue;
- DBG("Trying to allocate from %08lx, size %08lx from parent res %d: %08lx -> %08lx\n",
+ DBG("Trying to allocate from %08lx, size %08lx from parent"
+ " res %d: %08lx -> %08lx\n",
res->start, res->end, i, r->start, r->end);
- if (allocate_resource(r, res, res->end + 1, res->start, max, res->end + 1, NULL, NULL) < 0) {
+ if (allocate_resource(r, res, res->end + 1, res->start, max,
+ res->end + 1, NULL, NULL) < 0) {
DBG("Failed !\n");
continue;
}
@@ -1085,6 +1116,9 @@
return PCI_SLOT(dev->devfn);
}
+/* Where does that come from ? Doesn't seem to be correct for us, but we
+ * don't use it anyway so ... -BenH.
+ */
void __init
pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
{
diff -uNr linux-2.4.20/arch/ppc/kernel/pci.h linux-2.4.20-ben5/arch/ppc/kernel/pci.h
--- linux-2.4.20/arch/ppc/kernel/pci.h 2001-08-12 21:43:26.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/pci.h 2003-01-30 11:55:25.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pci.h 1.10 08/08/01 16:35:43 paulus
+ * BK Id: SCCS/s.pci.h 1.11 08/13/01 10:44:12 paulus
*/
#ifndef __PPC_KERNEL_PCI_H__
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc-stub.c linux-2.4.20-ben5/arch/ppc/kernel/ppc-stub.c
--- linux-2.4.20/arch/ppc/kernel/ppc-stub.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc-stub.c 2003-01-30 11:54:41.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc-stub.c 1.6 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.ppc-stub.c 1.8 06/05/01 21:22:03 paulus
*/
/*
* ppc-stub.c: KGDB support for the Linux kernel.
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc4xx_pic.c linux-2.4.20-ben5/arch/ppc/kernel/ppc4xx_pic.c
--- linux-2.4.20/arch/ppc/kernel/ppc4xx_pic.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc4xx_pic.c 2003-01-30 11:54:27.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc4xx_pic.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.ppc4xx_pic.c 1.8 08/13/02 20:27:37 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc8260_pic.c linux-2.4.20-ben5/arch/ppc/kernel/ppc8260_pic.c
--- linux-2.4.20/arch/ppc/kernel/ppc8260_pic.c 2002-02-25 20:37:55.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc8260_pic.c 2003-01-30 11:54:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc8260_pic.c 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.ppc8260_pic.c 1.9 02/14/02 12:33:42 trini
*/
#include
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc8260_pic.h linux-2.4.20-ben5/arch/ppc/kernel/ppc8260_pic.h
--- linux-2.4.20/arch/ppc/kernel/ppc8260_pic.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc8260_pic.h 2003-01-30 11:56:03.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.ppc8260_pic.h 1.10 08/13/02 20:27:37 paulus
*/
#ifndef _PPC_KERNEL_PPC8260_H
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc8xx_pic.c linux-2.4.20-ben5/arch/ppc/kernel/ppc8xx_pic.c
--- linux-2.4.20/arch/ppc/kernel/ppc8xx_pic.c 2002-02-25 20:37:55.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc8xx_pic.c 2003-01-30 11:52:57.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc8xx_pic.c 1.13 12/01/01 17:19:48 trini
+ * BK Id: SCCS/s.ppc8xx_pic.c 1.14 12/27/01 10:08:50 trini
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc8xx_pic.h linux-2.4.20-ben5/arch/ppc/kernel/ppc8xx_pic.h
--- linux-2.4.20/arch/ppc/kernel/ppc8xx_pic.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc8xx_pic.h 2003-01-30 11:54:21.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.ppc8xx_pic.h 1.10 08/13/02 20:27:38 paulus
*/
#ifndef _PPC_KERNEL_PPC8xx_H
#define _PPC_KERNEL_PPC8xx_H
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc_htab.c linux-2.4.20-ben5/arch/ppc/kernel/ppc_htab.c
--- linux-2.4.20/arch/ppc/kernel/ppc_htab.c 2001-11-03 02:43:54.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc_htab.c 2003-01-30 11:56:02.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc_htab.c 1.19 10/16/01 15:58:42 trini
+ * BK Id: SCCS/s.ppc_htab.c 1.20 11/04/01 22:58:20 paulus
*/
/*
* PowerPC hash table management proc entry. Will show information
diff -uNr linux-2.4.20/arch/ppc/kernel/ppc_ksyms.c linux-2.4.20-ben5/arch/ppc/kernel/ppc_ksyms.c
--- linux-2.4.20/arch/ppc/kernel/ppc_ksyms.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ppc_ksyms.c 2003-01-30 11:54:10.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.ppc_ksyms.c 1.74 11/23/02 10:51:37 benh
*/
#include
#include
@@ -17,6 +17,7 @@
#include
#include
#include
+#include
#include
#include
@@ -317,7 +318,7 @@
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers);
#ifdef CONFIG_XMON
-extern void xmon_printf(char *fmt, ...);
+extern void xmon_printf(const char *fmt, ...);
EXPORT_SYMBOL(xmon);
EXPORT_SYMBOL(xmon_printf);
#endif
@@ -348,6 +349,10 @@
EXPORT_SYMBOL(cpm_free_handler);
#endif /* CONFIG_8xx */
+/* Those should really be inline */
+EXPORT_SYMBOL(atomic_clear_mask);
+EXPORT_SYMBOL(atomic_set_mask);
+
EXPORT_SYMBOL(ret_to_user_hook);
EXPORT_SYMBOL(next_mmu_context);
EXPORT_SYMBOL(set_context);
@@ -362,6 +367,10 @@
EXPORT_SYMBOL(ret_from_intercept);
EXPORT_SYMBOL(cur_cpu_spec);
#if defined(CONFIG_ALL_PPC)
+extern int map_page(unsigned long va, unsigned long pa, int flags);
+
+EXPORT_SYMBOL(map_page);
+EXPORT_SYMBOL(get_vm_area);
extern unsigned long agp_special_page;
EXPORT_SYMBOL_NOVERS(agp_special_page);
#endif /* defined(CONFIG_ALL_PPC) */
diff -uNr linux-2.4.20/arch/ppc/kernel/prep_nvram.c linux-2.4.20-ben5/arch/ppc/kernel/prep_nvram.c
--- linux-2.4.20/arch/ppc/kernel/prep_nvram.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/prep_nvram.c 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.prep_nvram.c 1.14 08/13/02 20:27:38 paulus
*/
/*
* arch/ppc/platforms/prep_nvram.c
diff -uNr linux-2.4.20/arch/ppc/kernel/process.c linux-2.4.20-ben5/arch/ppc/kernel/process.c
--- linux-2.4.20/arch/ppc/kernel/process.c 2001-11-26 14:29:17.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/process.c 2003-01-30 11:53:24.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.process.c 1.34 11/23/01 16:38:29 paulus
+ * BK Id: SCCS/s.process.c 1.36 08/20/02 15:26:44 benh
*/
/*
* linux/arch/ppc/kernel/process.c
@@ -453,14 +453,19 @@
unsigned long i;
printk("Call backtrace: ");
+ if (sp == NULL)
+ sp = (unsigned long *)_get_SP();
while (sp) {
- if (__get_user( i, &sp[1] ))
+ if (__get_user(sp, (unsigned long **)sp))
+ break;
+ if (sp == NULL)
+ break;
+ if (__get_user(i, &sp[1]))
break;
if (cnt++ % 7 == 0)
printk("\n");
printk("%08lX ", i);
- if (cnt > 32) break;
- if (__get_user(sp, (unsigned long **)sp))
+ if (cnt > 32)
break;
}
printk("\n");
diff -uNr linux-2.4.20/arch/ppc/kernel/prom.c linux-2.4.20-ben5/arch/ppc/kernel/prom.c
--- linux-2.4.20/arch/ppc/kernel/prom.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/prom.c 2003-01-30 11:54:24.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.prom.c 1.59 10/20/02 20:14:45 benh
*/
/*
* Procedures for interfacing to the Open Firmware PROM on
diff -uNr linux-2.4.20/arch/ppc/kernel/prom_init.c linux-2.4.20-ben5/arch/ppc/kernel/prom_init.c
--- linux-2.4.20/arch/ppc/kernel/prom_init.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/prom_init.c 2003-01-30 11:52:57.000000000 +0100
@@ -266,7 +266,7 @@
{
phandle node;
ihandle ih;
- int i;
+ int i, j;
char type[16], *path;
static unsigned char default_colors[] = {
0x00, 0x00, 0x00,
@@ -325,26 +325,26 @@
break;
}
-try_again:
/*
* Open the first display and set its colormap.
*/
- if (prom_num_displays > 0) {
- path = prom_display_paths[0];
+ for (j=0; j 0)
- prom_disp_node = prom_display_nodes[0];
- else
+ if (--prom_num_displays > 0) {
+ prom_disp_node = prom_display_nodes[j];
+ j--;
+ } else
prom_disp_node = NULL;
- goto try_again;
+ continue;
} else {
prom_print("... ok\n");
/*
diff -uNr linux-2.4.20/arch/ppc/kernel/ptrace.c linux-2.4.20-ben5/arch/ppc/kernel/ptrace.c
--- linux-2.4.20/arch/ppc/kernel/ptrace.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/ptrace.c 2003-01-30 11:54:22.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ptrace.c 1.14 01/17/02 23:05:50 paulus
+ * BK Id: SCCS/s.ptrace.c 1.16 08/13/02 20:27:38 paulus
*/
/*
* linux/arch/ppc/kernel/ptrace.c
diff -uNr linux-2.4.20/arch/ppc/kernel/qspan_pci.c linux-2.4.20-ben5/arch/ppc/kernel/qspan_pci.c
--- linux-2.4.20/arch/ppc/kernel/qspan_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/qspan_pci.c 2003-01-30 11:54:41.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.qspan_pci.c 1.9 08/13/02 20:27:38 paulus
*/
/*
* QSpan pci routines.
diff -uNr linux-2.4.20/arch/ppc/kernel/semaphore.c linux-2.4.20-ben5/arch/ppc/kernel/semaphore.c
--- linux-2.4.20/arch/ppc/kernel/semaphore.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/semaphore.c 2003-01-30 11:55:44.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.semaphore.c 1.12 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.semaphore.c 1.14 06/05/01 21:22:03 paulus
*/
/*
* PowerPC-specific semaphore code.
diff -uNr linux-2.4.20/arch/ppc/kernel/setup.c linux-2.4.20-ben5/arch/ppc/kernel/setup.c
--- linux-2.4.20/arch/ppc/kernel/setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/setup.c 2003-01-30 11:53:04.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.setup.c 1.83 10/29/02 20:27:53 benh
*/
/*
* Common prep/pmac/chrp boot and setup code.
@@ -154,7 +154,7 @@
return 0;
pvr = cpu_data[i].pvr;
lpj = cpu_data[i].loops_per_jiffy;
- seq_printf(m, "processor\t: %lu\n", i);
+ seq_printf(m, "processor\t: %u\n", i);
#else
pvr = mfspr(PVR);
lpj = loops_per_jiffy;
@@ -331,6 +331,7 @@
unsigned long r6, unsigned long r7)
{
#ifdef CONFIG_BOOTX_TEXT
+ extern int force_printk_to_btext;
if (boot_text_mapped) {
btext_clearscreen();
btext_welcome();
@@ -417,6 +418,25 @@
}
cmd_line[sizeof(cmd_line) - 1] = 0;
+ /* Debug stuff, do not merge ! */
+#ifdef CONFIG_ADB_PMU
+ if (strstr(cmd_line, "fake_sleep")) {
+ extern int __fake_sleep;
+ __fake_sleep = 1;
+ }
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB
+ if (strstr(cmd_line, "adb_sync")) {
+ extern int __adb_probe_sync;
+ __adb_probe_sync = 1;
+ }
+#endif /* CONFIG_ADB */
+ if (strstr(cmd_line, "nol3") && cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR)
+ _set_L3CR(0);
+#ifdef CONFIG_BOOTX_TEXT
+ if (strstr(cmd_line, "printkbtext"))
+ force_printk_to_btext = 1;
+#endif
switch (_machine) {
case _MACH_Pmac:
pmac_init(r3, r4, r5, r6, r7);
diff -uNr linux-2.4.20/arch/ppc/kernel/signal.c linux-2.4.20-ben5/arch/ppc/kernel/signal.c
--- linux-2.4.20/arch/ppc/kernel/signal.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/signal.c 2003-01-30 11:53:10.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.signal.c 1.15 11/27/02 09:12:55 paulus
*/
/*
* linux/arch/ppc/kernel/signal.c
diff -uNr linux-2.4.20/arch/ppc/kernel/smp.c linux-2.4.20-ben5/arch/ppc/kernel/smp.c
--- linux-2.4.20/arch/ppc/kernel/smp.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/smp.c 2003-01-30 11:52:50.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.smp.c 1.40 03/28/02 16:54:23 hozer
+ * BK Id: SCCS/s.smp.c 1.42 06/29/02 09:39:41 hozer
*/
/*
* Smp support for ppc.
@@ -230,6 +230,10 @@
timeout = 1000000;
while (atomic_read(&data.started) != cpus) {
if (--timeout == 0) {
+#ifdef CONFIG_XMON
+ xmon_printf("smp_call_function on cpu %d: other cpus not responding (%d)\n",
+ smp_processor_id(), atomic_read(&data.started));
+#endif
printk("smp_call_function on cpu %d: other cpus not responding (%d)\n",
smp_processor_id(), atomic_read(&data.started));
goto out;
@@ -242,6 +246,10 @@
timeout = 1000000;
while (atomic_read(&data.finished) != cpus) {
if (--timeout == 0) {
+#ifdef CONFIG_XMON
+ xmon_printf("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n",
+ smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
+#endif
printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n",
smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
goto out;
diff -uNr linux-2.4.20/arch/ppc/kernel/softemu8xx.c linux-2.4.20-ben5/arch/ppc/kernel/softemu8xx.c
--- linux-2.4.20/arch/ppc/kernel/softemu8xx.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/softemu8xx.c 2003-01-30 11:55:21.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.softemu8xx.c 1.8 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.softemu8xx.c 1.10 06/05/01 21:22:04 paulus
*/
/*
* Software emulation of some PPC instructions for the 8xx core.
diff -uNr linux-2.4.20/arch/ppc/kernel/syscalls.c linux-2.4.20-ben5/arch/ppc/kernel/syscalls.c
--- linux-2.4.20/arch/ppc/kernel/syscalls.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/kernel/syscalls.c 2003-01-30 11:55:21.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.syscalls.c 1.13 03/13/02 09:12:22 trini
+ * BK Id: SCCS/s.syscalls.c 1.14 04/16/02 20:08:22 paulus
*/
/*
* linux/arch/ppc/kernel/sys_ppc.c
diff -uNr linux-2.4.20/arch/ppc/kernel/time.c linux-2.4.20-ben5/arch/ppc/kernel/time.c
--- linux-2.4.20/arch/ppc/kernel/time.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/time.c 2003-01-30 11:52:37.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.time.c 1.36 11/11/02 11:10:25 trini
*/
/*
* Common time routines among all ppc machines.
@@ -295,13 +295,11 @@
write_unlock_irqrestore(&xtime_lock, flags);
}
-
+/* This function is only called on the boot processor */
void __init time_init(void)
{
time_t sec, old_sec;
unsigned old_stamp, stamp, elapsed;
- /* This function is only called on the boot processor */
- unsigned long flags;
if (ppc_md.time_init != NULL)
time_offset = ppc_md.time_init();
@@ -318,32 +316,33 @@
/* Now that the decrementer is calibrated, it can be used in case the
* clock is stuck, but the fact that we have to handle the 601
* makes things more complex. Repeatedly read the RTC until the
- * next second boundary to try to achieve some precision...
+ * next second boundary to try to achieve some precision. If there
+ * is no RTC, we still need to set tb_last_stamp and
+ * last_jiffy_stamp(cpu 0) to the current stamp.
*/
+ stamp = get_native_tbl();
if (ppc_md.get_rtc_time) {
- stamp = get_native_tbl();
sec = ppc_md.get_rtc_time();
elapsed = 0;
do {
old_stamp = stamp;
old_sec = sec;
stamp = get_native_tbl();
- if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000;
+ if (__USE_RTC() && stamp < old_stamp)
+ old_stamp -= 1000000000;
elapsed += stamp - old_stamp;
sec = ppc_md.get_rtc_time();
} while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
- if (sec==old_sec) {
+ if (sec == old_sec)
printk("Warning: real time clock seems stuck!\n");
- }
- write_lock_irqsave(&xtime_lock, flags);
xtime.tv_sec = sec;
- last_jiffy_stamp(0) = tb_last_stamp = stamp;
xtime.tv_usec = 0;
/* No update now, we just read the time from the RTC ! */
last_rtc_update = xtime.tv_sec;
- write_unlock_irqrestore(&xtime_lock, flags);
}
+ last_jiffy_stamp(0) = tb_last_stamp = stamp;
+
/* Not exact, but the timer interrupt takes care of this */
set_dec(tb_ticks_per_jiffy);
diff -uNr linux-2.4.20/arch/ppc/kernel/traps.c linux-2.4.20-ben5/arch/ppc/kernel/traps.c
--- linux-2.4.20/arch/ppc/kernel/traps.c 2001-11-03 02:43:54.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/kernel/traps.c 2003-01-30 11:54:38.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.traps.c 1.22 10/11/01 10:33:09 paulus
+ * BK Id: SCCS/s.traps.c 1.25 11/07/02 18:38:50 benh
*/
/*
* linux/arch/ppc/kernel/traps.c
@@ -38,6 +38,9 @@
#include
#include
#include
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include
+#endif
extern int fix_alignment(struct pt_regs *);
extern void bad_page_fault(struct pt_regs *, unsigned long, int sig);
@@ -78,10 +81,25 @@
void die(const char * str, struct pt_regs * fp, long err)
{
+#ifdef CONFIG_BOOTX_TEXT
+ extern int force_printk_to_btext;
+#endif
console_verbose();
spin_lock_irq(&oops_lock);
+#ifdef CONFIG_BOOTX_TEXT
+ force_printk_to_btext = 1;
+#endif
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (_machine == _MACH_Pmac) {
+ set_backlight_enable(1);
+ set_backlight_level(BACKLIGHT_MAX);
+ }
+#endif
printk("Oops: %s, sig: %ld\n", str, err);
show_regs(fp);
+#ifdef CONFIG_BOOTX_TEXT
+ force_printk_to_btext = 0;
+#endif
spin_unlock_irq(&oops_lock);
/* do_exit() should take care of panic'ing from an interrupt
* context so we don't handle it here
@@ -345,6 +363,7 @@
{
printk(KERN_CRIT "Kernel stack overflow in process %p, r1=%lx\n",
current, regs->gpr[1]);
+ print_backtrace((unsigned long *)regs->gpr[1]);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
debugger(regs);
#endif
diff -uNr linux-2.4.20/arch/ppc/lib/Makefile linux-2.4.20-ben5/arch/ppc/lib/Makefile
--- linux-2.4.20/arch/ppc/lib/Makefile 2001-11-16 19:10:08.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/lib/Makefile 2003-01-30 11:53:29.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.10 11/08/01 07:57:40 paulus
+# BK Id: SCCS/s.Makefile 1.11 11/18/01 16:35:08 paulus
#
#
# Makefile for ppc-specific library files..
diff -uNr linux-2.4.20/arch/ppc/lib/checksum.S linux-2.4.20-ben5/arch/ppc/lib/checksum.S
--- linux-2.4.20/arch/ppc/lib/checksum.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/lib/checksum.S 2003-01-30 11:54:21.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.checksum.S 1.10 08/13/02 20:27:38 paulus
*/
/*
* This file contains assembly-language implementations
diff -uNr linux-2.4.20/arch/ppc/lib/locks.c linux-2.4.20-ben5/arch/ppc/lib/locks.c
--- linux-2.4.20/arch/ppc/lib/locks.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/lib/locks.c 2003-01-30 11:52:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.locks.c 1.15 05/04/02 16:12:57 benh
*/
/*
* Locks for smp ppc
@@ -18,8 +18,16 @@
#if SPINLOCK_DEBUG
+/* Route debug output to xmon when possible, there are more chances
+ * for it to work than the console
+ */
+#ifdef CONFIG_XMON
+extern void xmon_printf(const char* fmt,...);
+#define printk xmon_printf
+#endif
+
#undef INIT_STUCK
-#define INIT_STUCK 200000000 /*0xffffffff*/
+#define INIT_STUCK 0xffffffff
/*
* Try to acquire a spinlock.
@@ -59,6 +67,9 @@
lock, cpu, __builtin_return_address(0),
lock->owner_cpu,lock->owner_pc);
stuck = INIT_STUCK;
+#ifdef CONFIG_XMON
+// xmon(NULL);
+#endif /* CONFIG_XMON */
/* steal the lock */
/*xchg_u32((void *)&lock->lock,0);*/
}
@@ -88,7 +99,7 @@
lp, smp_processor_id(), (int)lp->owner_cpu,
lp->owner_pc,lp->lock);
lp->owner_pc = lp->owner_cpu = 0;
- wmb();
+ mb();
lp->lock = 0;
}
@@ -122,7 +133,7 @@
/* try to get the read lock again */
goto again;
}
- wmb();
+ __asm__ __volatile__ ("isync" : : : "memory");
}
void _read_unlock(rwlock_t *rw)
@@ -131,7 +142,7 @@
printk("_read_unlock(): %s/%d (nip %08lX) lock %lx\n",
current->comm,current->pid,current->thread.regs->nip,
rw->lock);
- wmb();
+ mb();
atomic_dec((atomic_t *) &(rw)->lock);
}
@@ -172,7 +183,7 @@
}
goto again;
}
- wmb();
+ __asm__ __volatile__ ("isync" : : : "memory");
}
void _write_unlock(rwlock_t *rw)
@@ -181,7 +192,7 @@
printk("_write_lock(): %s/%d (nip %08lX) lock %lx\n",
current->comm,current->pid,current->thread.regs->nip,
rw->lock);
- wmb();
+ mb();
clear_bit(31,&(rw)->lock);
}
diff -uNr linux-2.4.20/arch/ppc/lib/strcase.c linux-2.4.20-ben5/arch/ppc/lib/strcase.c
--- linux-2.4.20/arch/ppc/lib/strcase.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/lib/strcase.c 2003-01-30 11:54:20.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.strcase.c 1.5 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.strcase.c 1.7 06/05/01 21:22:04 paulus
*/
#include
diff -uNr linux-2.4.20/arch/ppc/lib/string.S linux-2.4.20-ben5/arch/ppc/lib/string.S
--- linux-2.4.20/arch/ppc/lib/string.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/lib/string.S 2003-01-30 11:54:18.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.string.S 1.13 08/13/02 20:27:38 paulus
*/
/*
* String handling functions for PowerPC.
diff -uNr linux-2.4.20/arch/ppc/math-emu/Makefile linux-2.4.20-ben5/arch/ppc/math-emu/Makefile
--- linux-2.4.20/arch/ppc/math-emu/Makefile 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/Makefile 2003-01-30 11:52:54.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:22 cort
+# BK Id: SCCS/s.Makefile 1.5 06/05/01 21:22:04 paulus
#
#
#
diff -uNr linux-2.4.20/arch/ppc/math-emu/double.h linux-2.4.20-ben5/arch/ppc/math-emu/double.h
--- linux-2.4.20/arch/ppc/math-emu/double.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/double.h 2003-01-30 11:54:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.double.h 1.5 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.double.h 1.7 06/05/01 21:22:04 paulus
*/
/*
* Definitions for IEEE Double Precision
diff -uNr linux-2.4.20/arch/ppc/math-emu/fabs.c linux-2.4.20-ben5/arch/ppc/math-emu/fabs.c
--- linux-2.4.20/arch/ppc/math-emu/fabs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fabs.c 2003-01-30 11:55:15.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fabs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fabs.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fadd.c linux-2.4.20-ben5/arch/ppc/math-emu/fadd.c
--- linux-2.4.20/arch/ppc/math-emu/fadd.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fadd.c 2003-01-30 11:55:17.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fadd.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fadd.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fadds.c linux-2.4.20-ben5/arch/ppc/math-emu/fadds.c
--- linux-2.4.20/arch/ppc/math-emu/fadds.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fadds.c 2003-01-30 11:55:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fadds.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fadds.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fcmpo.c linux-2.4.20-ben5/arch/ppc/math-emu/fcmpo.c
--- linux-2.4.20/arch/ppc/math-emu/fcmpo.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fcmpo.c 2003-01-30 11:52:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fcmpo.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fcmpo.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fcmpu.c linux-2.4.20-ben5/arch/ppc/math-emu/fcmpu.c
--- linux-2.4.20/arch/ppc/math-emu/fcmpu.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fcmpu.c 2003-01-30 11:53:05.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fcmpu.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fcmpu.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fctiw.c linux-2.4.20-ben5/arch/ppc/math-emu/fctiw.c
--- linux-2.4.20/arch/ppc/math-emu/fctiw.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fctiw.c 2003-01-30 11:54:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fctiw.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fctiw.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fctiwz.c linux-2.4.20-ben5/arch/ppc/math-emu/fctiwz.c
--- linux-2.4.20/arch/ppc/math-emu/fctiwz.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fctiwz.c 2003-01-30 11:55:17.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fctiwz.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fctiwz.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fdiv.c linux-2.4.20-ben5/arch/ppc/math-emu/fdiv.c
--- linux-2.4.20/arch/ppc/math-emu/fdiv.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fdiv.c 2003-01-30 11:54:03.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fdiv.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fdiv.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fdivs.c linux-2.4.20-ben5/arch/ppc/math-emu/fdivs.c
--- linux-2.4.20/arch/ppc/math-emu/fdivs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fdivs.c 2003-01-30 11:54:07.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fdivs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fdivs.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmadd.c linux-2.4.20-ben5/arch/ppc/math-emu/fmadd.c
--- linux-2.4.20/arch/ppc/math-emu/fmadd.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmadd.c 2003-01-30 11:54:07.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmadd.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmadd.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmadds.c linux-2.4.20-ben5/arch/ppc/math-emu/fmadds.c
--- linux-2.4.20/arch/ppc/math-emu/fmadds.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmadds.c 2003-01-30 11:55:52.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmadds.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmadds.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmr.c linux-2.4.20-ben5/arch/ppc/math-emu/fmr.c
--- linux-2.4.20/arch/ppc/math-emu/fmr.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmr.c 2003-01-30 11:54:32.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmr.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmr.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmsub.c linux-2.4.20-ben5/arch/ppc/math-emu/fmsub.c
--- linux-2.4.20/arch/ppc/math-emu/fmsub.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmsub.c 2003-01-30 11:52:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmsub.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmsub.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmsubs.c linux-2.4.20-ben5/arch/ppc/math-emu/fmsubs.c
--- linux-2.4.20/arch/ppc/math-emu/fmsubs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmsubs.c 2003-01-30 11:55:51.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmsubs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmsubs.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmul.c linux-2.4.20-ben5/arch/ppc/math-emu/fmul.c
--- linux-2.4.20/arch/ppc/math-emu/fmul.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmul.c 2003-01-30 11:53:19.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmul.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmul.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fmuls.c linux-2.4.20-ben5/arch/ppc/math-emu/fmuls.c
--- linux-2.4.20/arch/ppc/math-emu/fmuls.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fmuls.c 2003-01-30 11:53:14.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fmuls.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fmuls.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fnabs.c linux-2.4.20-ben5/arch/ppc/math-emu/fnabs.c
--- linux-2.4.20/arch/ppc/math-emu/fnabs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fnabs.c 2003-01-30 11:54:26.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fnabs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fnabs.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fneg.c linux-2.4.20-ben5/arch/ppc/math-emu/fneg.c
--- linux-2.4.20/arch/ppc/math-emu/fneg.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fneg.c 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fneg.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fneg.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fnmadd.c linux-2.4.20-ben5/arch/ppc/math-emu/fnmadd.c
--- linux-2.4.20/arch/ppc/math-emu/fnmadd.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fnmadd.c 2003-01-30 11:55:30.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fnmadd.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fnmadd.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fnmadds.c linux-2.4.20-ben5/arch/ppc/math-emu/fnmadds.c
--- linux-2.4.20/arch/ppc/math-emu/fnmadds.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fnmadds.c 2003-01-30 11:54:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fnmadds.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fnmadds.c 1.8 06/05/01 21:22:04 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fnmsub.c linux-2.4.20-ben5/arch/ppc/math-emu/fnmsub.c
--- linux-2.4.20/arch/ppc/math-emu/fnmsub.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fnmsub.c 2003-01-30 11:55:26.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fnmsub.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fnmsub.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fnmsubs.c linux-2.4.20-ben5/arch/ppc/math-emu/fnmsubs.c
--- linux-2.4.20/arch/ppc/math-emu/fnmsubs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fnmsubs.c 2003-01-30 11:54:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fnmsubs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fnmsubs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fres.c linux-2.4.20-ben5/arch/ppc/math-emu/fres.c
--- linux-2.4.20/arch/ppc/math-emu/fres.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fres.c 2003-01-30 11:55:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fres.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fres.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/frsp.c linux-2.4.20-ben5/arch/ppc/math-emu/frsp.c
--- linux-2.4.20/arch/ppc/math-emu/frsp.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/frsp.c 2003-01-30 11:53:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.frsp.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.frsp.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/frsqrte.c linux-2.4.20-ben5/arch/ppc/math-emu/frsqrte.c
--- linux-2.4.20/arch/ppc/math-emu/frsqrte.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/frsqrte.c 2003-01-30 11:54:42.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.frsqrte.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.frsqrte.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fsel.c linux-2.4.20-ben5/arch/ppc/math-emu/fsel.c
--- linux-2.4.20/arch/ppc/math-emu/fsel.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fsel.c 2003-01-30 11:54:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fsel.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fsel.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fsqrt.c linux-2.4.20-ben5/arch/ppc/math-emu/fsqrt.c
--- linux-2.4.20/arch/ppc/math-emu/fsqrt.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fsqrt.c 2003-01-30 11:52:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fsqrt.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fsqrt.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fsqrts.c linux-2.4.20-ben5/arch/ppc/math-emu/fsqrts.c
--- linux-2.4.20/arch/ppc/math-emu/fsqrts.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fsqrts.c 2003-01-30 11:54:22.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fsqrts.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fsqrts.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fsub.c linux-2.4.20-ben5/arch/ppc/math-emu/fsub.c
--- linux-2.4.20/arch/ppc/math-emu/fsub.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fsub.c 2003-01-30 11:54:29.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fsub.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fsub.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/fsubs.c linux-2.4.20-ben5/arch/ppc/math-emu/fsubs.c
--- linux-2.4.20/arch/ppc/math-emu/fsubs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/fsubs.c 2003-01-30 11:53:05.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fsubs.c 1.6 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.fsubs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/lfd.c linux-2.4.20-ben5/arch/ppc/math-emu/lfd.c
--- linux-2.4.20/arch/ppc/math-emu/lfd.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/lfd.c 2003-01-30 11:53:19.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.lfd.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.lfd.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/lfs.c linux-2.4.20-ben5/arch/ppc/math-emu/lfs.c
--- linux-2.4.20/arch/ppc/math-emu/lfs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/lfs.c 2003-01-30 11:56:00.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.lfs.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.lfs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/math.c linux-2.4.20-ben5/arch/ppc/math-emu/math.c
--- linux-2.4.20/arch/ppc/math-emu/math.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/math.c 2003-01-30 11:54:02.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.math.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.math.c 1.8 06/05/01 21:22:05 paulus
*/
/*
* arch/ppc/math-emu/math.c
diff -uNr linux-2.4.20/arch/ppc/math-emu/mcrfs.c linux-2.4.20-ben5/arch/ppc/math-emu/mcrfs.c
--- linux-2.4.20/arch/ppc/math-emu/mcrfs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mcrfs.c 2003-01-30 11:52:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mcrfs.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mcrfs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/mffs.c linux-2.4.20-ben5/arch/ppc/math-emu/mffs.c
--- linux-2.4.20/arch/ppc/math-emu/mffs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mffs.c 2003-01-30 11:54:00.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mffs.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mffs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/mtfsb0.c linux-2.4.20-ben5/arch/ppc/math-emu/mtfsb0.c
--- linux-2.4.20/arch/ppc/math-emu/mtfsb0.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mtfsb0.c 2003-01-30 11:54:17.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mtfsb0.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mtfsb0.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/mtfsb1.c linux-2.4.20-ben5/arch/ppc/math-emu/mtfsb1.c
--- linux-2.4.20/arch/ppc/math-emu/mtfsb1.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mtfsb1.c 2003-01-30 11:52:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mtfsb1.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mtfsb1.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/mtfsf.c linux-2.4.20-ben5/arch/ppc/math-emu/mtfsf.c
--- linux-2.4.20/arch/ppc/math-emu/mtfsf.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mtfsf.c 2003-01-30 11:55:24.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mtfsf.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mtfsf.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/mtfsfi.c linux-2.4.20-ben5/arch/ppc/math-emu/mtfsfi.c
--- linux-2.4.20/arch/ppc/math-emu/mtfsfi.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/mtfsfi.c 2003-01-30 11:55:42.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mtfsfi.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mtfsfi.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/op-1.h linux-2.4.20-ben5/arch/ppc/math-emu/op-1.h
--- linux-2.4.20/arch/ppc/math-emu/op-1.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/op-1.h 2003-01-30 11:54:06.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.op-1.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.op-1.h 1.7 06/05/01 21:22:05 paulus
*/
/*
* Basic one-word fraction declaration and manipulation.
diff -uNr linux-2.4.20/arch/ppc/math-emu/op-2.h linux-2.4.20-ben5/arch/ppc/math-emu/op-2.h
--- linux-2.4.20/arch/ppc/math-emu/op-2.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/op-2.h 2003-01-30 11:56:02.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.op-2.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.op-2.h 1.7 06/05/01 21:22:05 paulus
*/
/*
* Basic two-word fraction declaration and manipulation.
diff -uNr linux-2.4.20/arch/ppc/math-emu/op-4.h linux-2.4.20-ben5/arch/ppc/math-emu/op-4.h
--- linux-2.4.20/arch/ppc/math-emu/op-4.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/op-4.h 2003-01-30 11:54:58.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.op-4.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.op-4.h 1.7 06/05/01 21:22:05 paulus
*/
/*
* Basic four-word fraction declaration and manipulation.
diff -uNr linux-2.4.20/arch/ppc/math-emu/op-common.h linux-2.4.20-ben5/arch/ppc/math-emu/op-common.h
--- linux-2.4.20/arch/ppc/math-emu/op-common.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/op-common.h 2003-01-30 11:53:26.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.op-common.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.op-common.h 1.7 06/05/01 21:22:05 paulus
*/
#define _FP_DECL(wc, X) \
diff -uNr linux-2.4.20/arch/ppc/math-emu/sfp-machine.h linux-2.4.20-ben5/arch/ppc/math-emu/sfp-machine.h
--- linux-2.4.20/arch/ppc/math-emu/sfp-machine.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/sfp-machine.h 2003-01-30 11:55:52.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.sfp-machine.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.sfp-machine.h 1.7 06/05/01 21:22:05 paulus
*/
/* Machine-dependent software floating-point definitions. PPC version.
Copyright (C) 1997 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/math-emu/single.h linux-2.4.20-ben5/arch/ppc/math-emu/single.h
--- linux-2.4.20/arch/ppc/math-emu/single.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/single.h 2003-01-30 11:54:31.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.single.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.single.h 1.7 06/05/01 21:22:05 paulus
*/
/*
* Definitions for IEEE Single Precision
diff -uNr linux-2.4.20/arch/ppc/math-emu/soft-fp.h linux-2.4.20-ben5/arch/ppc/math-emu/soft-fp.h
--- linux-2.4.20/arch/ppc/math-emu/soft-fp.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/soft-fp.h 2003-01-30 11:54:15.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.soft-fp.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.soft-fp.h 1.7 06/05/01 21:22:05 paulus
*/
#ifndef SOFT_FP_H
#define SOFT_FP_H
diff -uNr linux-2.4.20/arch/ppc/math-emu/stfd.c linux-2.4.20-ben5/arch/ppc/math-emu/stfd.c
--- linux-2.4.20/arch/ppc/math-emu/stfd.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/stfd.c 2003-01-30 11:56:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.stfd.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.stfd.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/stfiwx.c linux-2.4.20-ben5/arch/ppc/math-emu/stfiwx.c
--- linux-2.4.20/arch/ppc/math-emu/stfiwx.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/stfiwx.c 2003-01-30 11:52:55.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.stfiwx.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.stfiwx.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/stfs.c linux-2.4.20-ben5/arch/ppc/math-emu/stfs.c
--- linux-2.4.20/arch/ppc/math-emu/stfs.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/stfs.c 2003-01-30 11:55:56.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.stfs.c 1.6 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.stfs.c 1.8 06/05/01 21:22:05 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/math-emu/types.c linux-2.4.20-ben5/arch/ppc/math-emu/types.c
--- linux-2.4.20/arch/ppc/math-emu/types.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/types.c 2003-01-30 11:55:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.types.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.types.c 1.7 06/05/01 21:22:05 paulus
*/
#include "soft-fp.h"
diff -uNr linux-2.4.20/arch/ppc/math-emu/udivmodti4.c linux-2.4.20-ben5/arch/ppc/math-emu/udivmodti4.c
--- linux-2.4.20/arch/ppc/math-emu/udivmodti4.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/math-emu/udivmodti4.c 2003-01-30 11:55:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.udivmodti4.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.udivmodti4.c 1.7 06/05/01 21:22:05 paulus
*/
/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */
diff -uNr linux-2.4.20/arch/ppc/mm/4xx_tlb.c linux-2.4.20-ben5/arch/ppc/mm/4xx_tlb.c
--- linux-2.4.20/arch/ppc/mm/4xx_tlb.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/4xx_tlb.c 2003-01-30 11:54:55.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.4xx_tlb.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.4xx_tlb.c 1.7 06/05/01 21:22:05 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/mm/4xx_tlb.h linux-2.4.20-ben5/arch/ppc/mm/4xx_tlb.h
--- linux-2.4.20/arch/ppc/mm/4xx_tlb.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/4xx_tlb.h 2003-01-30 11:55:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.4xx_tlb.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.4xx_tlb.h 1.7 06/05/01 21:22:05 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/mm/Makefile linux-2.4.20-ben5/arch/ppc/mm/Makefile
--- linux-2.4.20/arch/ppc/mm/Makefile 2001-08-28 15:58:33.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/Makefile 2003-01-30 11:55:17.000000000 +0100
@@ -1,4 +1,4 @@
-# BK Id: SCCS/s.Makefile 1.8 08/16/01 17:25:47 paulus
+# BK Id: SCCS/s.Makefile 1.9 08/29/01 08:49:24 paulus
#
#
# Makefile for the linux ppc-specific parts of the memory manager.
diff -uNr linux-2.4.20/arch/ppc/mm/extable.c linux-2.4.20-ben5/arch/ppc/mm/extable.c
--- linux-2.4.20/arch/ppc/mm/extable.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/extable.c 2003-01-30 11:55:00.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.extable.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.extable.c 1.7 06/05/01 21:22:06 paulus
*/
/*
* linux/arch/ppc/mm/extable.c
diff -uNr linux-2.4.20/arch/ppc/mm/fault.c linux-2.4.20-ben5/arch/ppc/mm/fault.c
--- linux-2.4.20/arch/ppc/mm/fault.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/mm/fault.c 2003-01-30 11:55:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fault.c 1.15 09/24/01 16:35:10 paulus
+ * BK Id: SCCS/s.fault.c 1.20 01/23/03 17:54:25 benh
*/
/*
* arch/ppc/mm/fault.c
@@ -64,7 +64,7 @@
void do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
- struct vm_area_struct * vma;
+ struct vm_area_struct * vma, * prev_vma;
struct mm_struct *mm = current->mm;
siginfo_t info;
int code = SEGV_MAPERR;
@@ -111,7 +111,16 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ /* Only allow stack grow on writes */
+ if (!is_write) {
+ printk(KERN_DEBUG "Process %s tried to read below stack\n",
+ current->comm);
+ printk(KERN_DEBUG " addr: %08lx, gpr1: %08lx, pc: %08lx, lr: %08lx\n",
+ address, regs->gpr[1], regs->nip, regs->link);
+ goto bad_area;
+ }
+ vma = find_vma_prev(mm, address, &prev_vma);
+ if (expand_stack(vma, address, prev_vma))
goto bad_area;
good_area:
diff -uNr linux-2.4.20/arch/ppc/mm/hashtable.S linux-2.4.20-ben5/arch/ppc/mm/hashtable.S
--- linux-2.4.20/arch/ppc/mm/hashtable.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/mm/hashtable.S 2003-01-30 11:54:24.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.hashtable.S 1.20 08/13/02 20:27:38 paulus
*/
/*
* arch/ppc/kernel/hashtable.S
diff -uNr linux-2.4.20/arch/ppc/mm/init.c linux-2.4.20-ben5/arch/ppc/mm/init.c
--- linux-2.4.20/arch/ppc/mm/init.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/init.c 2003-01-30 11:52:41.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.init.c 1.43 03/12/02 12:13:51 paulus
+ * BK Id: SCCS/s.init.c 1.47 06/25/02 17:31:35 benh
*/
/*
* PowerPC version
@@ -329,7 +329,7 @@
#ifdef CONFIG_HIGHMEM
ioremap_base = PKMAP_BASE;
#else
- ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 */
+ ioremap_base = 0xfe000000UL; /* for now, could be 0xfffff000 (or 0 ?)*/
#endif /* CONFIG_HIGHMEM */
ioremap_bot = ioremap_base;
@@ -458,6 +458,17 @@
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
+ /* Sanity check: did ioremap_bot stomp over vmalloc space ? We keep
+ * a minimal 16Mb guard though if you only have 16Mb left, you'll
+ * probably run into trouble, so we also printk something if you
+ * have less than 64Mb. This is meant to help diagnosing such problems
+ * as debugging it can be really painful. --BenH.
+ */
+ if (VMALLOC_END < (VMALLOC_START + 0x01000000UL))
+ panic("Argh ! Virtual space exhausted !");
+ if (VMALLOC_END < (VMALLOC_START + 0x04000000UL))
+ printk(KERN_WARNING "Warning ! Virtual space small !");
+
totalram_pages += free_all_bootmem();
#ifdef CONFIG_BLK_DEV_INITRD
@@ -619,6 +630,10 @@
void clear_user_page(void *page, unsigned long vaddr)
{
clear_page(page);
+ /* That should not be necessary, but a glibc "feature" makes
+ * in important as glibc fails to invalidate blank pages
+ * properly
+ */
__flush_dcache_icache(page);
}
diff -uNr linux-2.4.20/arch/ppc/mm/mem_pieces.c linux-2.4.20-ben5/arch/ppc/mm/mem_pieces.c
--- linux-2.4.20/arch/ppc/mm/mem_pieces.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/mem_pieces.c 2003-01-30 11:52:39.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mem_pieces.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mem_pieces.c 1.7 06/05/01 21:22:06 paulus
*/
/*
* Copyright (c) 1996 Paul Mackerras
diff -uNr linux-2.4.20/arch/ppc/mm/mem_pieces.h linux-2.4.20-ben5/arch/ppc/mm/mem_pieces.h
--- linux-2.4.20/arch/ppc/mm/mem_pieces.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/mem_pieces.h 2003-01-30 11:54:51.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mem_pieces.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.mem_pieces.h 1.7 06/05/01 21:22:06 paulus
*/
/*
* Copyright (c) 1996 Paul Mackerras
diff -uNr linux-2.4.20/arch/ppc/mm/pgtable.c linux-2.4.20-ben5/arch/ppc/mm/pgtable.c
--- linux-2.4.20/arch/ppc/mm/pgtable.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/mm/pgtable.c 2003-01-30 11:54:59.000000000 +0100
@@ -248,7 +248,7 @@
total_lowmem = max_low_mem;
#ifndef CONFIG_HIGHMEM
printk(KERN_INFO "Warning, memory limited to %ld Mb, use CONFIG_HIGHMEM"
- " to reach %ld Mb\n", max_low_mem >> 20, total_lowmem >> 20);
+ " to reach %ld Mb\n", max_low_mem >> 20, (total_lowmem+ram) >> 20);
total_memory = total_lowmem;
#endif /* CONFIG_HIGHMEM */
}
@@ -305,7 +305,7 @@
{
int i;
- if (virt > KERNELBASE && virt < ioremap_bot)
+ if (virt > KERNELBASE && (virt < ioremap_bot || !ioremap_bot))
ioremap_bot = ioremap_base = virt;
#ifdef HAVE_BATS
diff -uNr linux-2.4.20/arch/ppc/platforms/Makefile linux-2.4.20-ben5/arch/ppc/platforms/Makefile
--- linux-2.4.20/arch/ppc/platforms/Makefile 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/Makefile 2003-01-30 11:54:33.000000000 +0100
@@ -43,6 +43,9 @@
prep_time.o prep_setup.o pmac_sleep.o \
pmac_nvram.o
obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o
+ifeq ($(CONFIG_ALL_PPC),y)
+obj-$(CONFIG_CPU_FREQ_PMAC) += pmac_cpufreq.o
+endif
obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o
obj-$(CONFIG_PREP_RESIDUAL) += residual.o
obj-$(CONFIG_GEMINI) += gemini_pci.o gemini_setup.o gemini_prom.o
diff -uNr linux-2.4.20/arch/ppc/platforms/apus_pci.c linux-2.4.20-ben5/arch/ppc/platforms/apus_pci.c
--- linux-2.4.20/arch/ppc/platforms/apus_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/apus_pci.c 2003-01-30 11:55:35.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.apus_pci.c 1.7 08/31/02 12:27:55 paulus
*/
/*
* Copyright (C) Michel Dänzer
diff -uNr linux-2.4.20/arch/ppc/platforms/apus_pci.h linux-2.4.20-ben5/arch/ppc/platforms/apus_pci.h
--- linux-2.4.20/arch/ppc/platforms/apus_pci.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/apus_pci.h 2003-01-30 11:55:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.apus_pci.h 1.6 08/13/02 21:40:09 paulus
*/
/*
* Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer
diff -uNr linux-2.4.20/arch/ppc/platforms/apus_setup.c linux-2.4.20-ben5/arch/ppc/platforms/apus_setup.c
--- linux-2.4.20/arch/ppc/platforms/apus_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/apus_setup.c 2003-01-30 11:52:57.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.apus_setup.c 1.34 10/09/02 10:28:18 paulus
*/
/*
* arch/ppc/platforms/apus_setup.c
diff -uNr linux-2.4.20/arch/ppc/platforms/bseip.h linux-2.4.20-ben5/arch/ppc/platforms/bseip.h
--- linux-2.4.20/arch/ppc/platforms/bseip.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/bseip.h 2003-01-30 11:54:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.bseip.h 1.10 08/17/01 15:23:17 paulus
+ * BK Id: SCCS/s.bseip.h 1.13 08/13/02 20:27:38 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/platforms/chrp_pci.c linux-2.4.20-ben5/arch/ppc/platforms/chrp_pci.c
--- linux-2.4.20/arch/ppc/platforms/chrp_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/chrp_pci.c 2003-01-30 11:55:25.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.chrp_pci.c 1.29 09/11/02 14:41:31 paulus
*/
/*
* CHRP pci routines.
diff -uNr linux-2.4.20/arch/ppc/platforms/chrp_setup.c linux-2.4.20-ben5/arch/ppc/platforms/chrp_setup.c
--- linux-2.4.20/arch/ppc/platforms/chrp_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/chrp_setup.c 2003-01-30 11:54:00.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.chrp_setup.c 1.59 01/20/03 21:59:06 benh
*/
/*
* arch/ppc/platforms/setup.c
@@ -56,6 +56,11 @@
#include
#include
+#ifdef CONFIG_SERIAL
+#include
+#include
+#endif
+
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
void chrp_calibrate_decr(void);
@@ -411,7 +416,6 @@
chrp_init_irq_openpic(unsigned long intack)
{
int i;
- unsigned char* chrp_int_ack_special = 0;
int nmi_irq = -1;
unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
@@ -421,12 +425,10 @@
OpenPIC_InitSenses = init_senses;
OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
- if (intack)
- chrp_int_ack_special = (unsigned char *) ioremap(intack, 1);
- openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
+ openpic_init(1, NUM_8259_INTERRUPTS, 0, nmi_irq);
for (i = 0; i < NUM_8259_INTERRUPTS; i++)
irq_desc[i].handler = &i8259_pic;
- i8259_init(0);
+ i8259_init(intack);
}
static void __init
@@ -572,6 +574,18 @@
}
#endif
+#ifdef CONFIG_VT
+static void __chrp
+dummy_pckbd_leds(unsigned char leds)
+{
+}
+
+static void __init
+dummy_pckbd_init_hw(void)
+{
+}
+#endif /* CONFIG_VT */
+
void __init
chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
@@ -596,6 +610,14 @@
/* Check if it's a briq */
machine = get_property(root, "model", NULL);
is_briq = machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0;
+#ifdef CONFIG_SERIAL
+ if (is_briq) {
+ /* briQ has a different serial clock */
+ extern struct serial_state rs_table[];
+ rs_table[0].baud_base = (7372800 / 16);
+ rs_table[1].baud_base = (7372800 / 16);
+ }
+#endif /* CONFIG_SERIAL */
ppc_md.setup_arch = chrp_setup_arch;
ppc_md.show_percpuinfo = of_show_percpuinfo;
@@ -623,8 +645,8 @@
ppc_md.kbd_getkeycode = pckbd_getkeycode;
ppc_md.kbd_translate = pckbd_translate;
ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
- ppc_md.kbd_leds = pckbd_leds;
- ppc_md.kbd_init_hw = pckbd_init_hw;
+ ppc_md.kbd_leds = is_briq ? dummy_pckbd_leds : pckbd_leds;
+ ppc_md.kbd_init_hw = is_briq ? dummy_pckbd_init_hw : pckbd_init_hw;
#ifdef CONFIG_MAGIC_SYSRQ
ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
SYSRQ_KEY = 0x54;
diff -uNr linux-2.4.20/arch/ppc/platforms/chrp_time.c linux-2.4.20-ben5/arch/ppc/platforms/chrp_time.c
--- linux-2.4.20/arch/ppc/platforms/chrp_time.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/chrp_time.c 2003-01-30 11:52:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.chrp_time.c 1.13 08/13/02 20:27:38 paulus
*/
/*
* arch/ppc/platforms/chrp_time.c
diff -uNr linux-2.4.20/arch/ppc/platforms/error_log.c linux-2.4.20-ben5/arch/ppc/platforms/error_log.c
--- linux-2.4.20/arch/ppc/platforms/error_log.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/error_log.c 2003-01-30 11:55:56.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.error_log.c 1.6 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.error_log.c 1.7 08/13/02 21:31:33 paulus
*/
/*
* arch/ppc/kernel/error_log.c
diff -uNr linux-2.4.20/arch/ppc/platforms/error_log.h linux-2.4.20-ben5/arch/ppc/platforms/error_log.h
--- linux-2.4.20/arch/ppc/platforms/error_log.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/error_log.h 2003-01-30 11:54:08.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.error_log.h 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.error_log.h 1.6 08/13/02 21:31:33 paulus
*/
#ifndef __ERROR_LOG_H__
#define __ERROR_LOG_H__
diff -uNr linux-2.4.20/arch/ppc/platforms/est8260.h linux-2.4.20-ben5/arch/ppc/platforms/est8260.h
--- linux-2.4.20/arch/ppc/platforms/est8260.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/est8260.h 2003-01-30 11:52:37.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.est8260.h 1.5 05/17/01 18:14:24 cort
+ * BK Id: SCCS/s.est8260.h 1.9 08/13/02 20:27:38 paulus
*/
/* Board information for the EST8260, which should be generic for
diff -uNr linux-2.4.20/arch/ppc/platforms/fads.h linux-2.4.20-ben5/arch/ppc/platforms/fads.h
--- linux-2.4.20/arch/ppc/platforms/fads.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/fads.h 2003-01-30 11:53:54.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.fads.h 1.14 10/26/01 10:14:09 trini
+ * BK Id: SCCS/s.fads.h 1.17 08/13/02 20:27:38 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/platforms/gemini.h linux-2.4.20-ben5/arch/ppc/platforms/gemini.h
--- linux-2.4.20/arch/ppc/platforms/gemini.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/gemini.h 2003-01-30 11:54:07.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.gemini.h 1.7 08/31/02 12:27:55 paulus
*/
/*
* arch/ppc/platforms/gemini.h
diff -uNr linux-2.4.20/arch/ppc/platforms/gemini_pci.c linux-2.4.20-ben5/arch/ppc/platforms/gemini_pci.c
--- linux-2.4.20/arch/ppc/platforms/gemini_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/gemini_pci.c 2003-01-30 11:54:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.gemini_pci.c 1.8 08/13/02 21:40:09 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/platforms/gemini_prom.S linux-2.4.20-ben5/arch/ppc/platforms/gemini_prom.S
--- linux-2.4.20/arch/ppc/platforms/gemini_prom.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/gemini_prom.S 2003-01-30 11:53:05.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.gemini_prom.S 1.7 08/13/02 21:40:09 paulus
*/
/*
* arch/ppc/kernel/gemini_prom.S
diff -uNr linux-2.4.20/arch/ppc/platforms/gemini_serial.h linux-2.4.20-ben5/arch/ppc/platforms/gemini_serial.h
--- linux-2.4.20/arch/ppc/platforms/gemini_serial.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/gemini_serial.h 2003-01-30 11:54:02.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.gemini_serial.h 1.7 08/13/02 21:40:09 paulus
*/
#ifdef __KERNEL__
#ifndef __ASMPPC_GEMINI_SERIAL_H
diff -uNr linux-2.4.20/arch/ppc/platforms/gemini_setup.c linux-2.4.20-ben5/arch/ppc/platforms/gemini_setup.c
--- linux-2.4.20/arch/ppc/platforms/gemini_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/gemini_setup.c 2003-01-30 11:54:59.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.gemini_setup.c 1.22 09/30/02 15:08:18 paulus
*/
/*
* arch/ppc/platforms/setup.c
diff -uNr linux-2.4.20/arch/ppc/platforms/ivms8.h linux-2.4.20-ben5/arch/ppc/platforms/ivms8.h
--- linux-2.4.20/arch/ppc/platforms/ivms8.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/ivms8.h 2003-01-30 11:54:34.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ivms8.h 1.8 10/26/01 10:14:09 trini
+ * BK Id: SCCS/s.ivms8.h 1.9 08/13/02 21:33:06 paulus
*/
/*
* Speech Design Integrated Voicemail board specific definitions
diff -uNr linux-2.4.20/arch/ppc/platforms/mbx.h linux-2.4.20-ben5/arch/ppc/platforms/mbx.h
--- linux-2.4.20/arch/ppc/platforms/mbx.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/mbx.h 2003-01-30 11:52:47.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.mbx.h 1.11 08/17/01 15:23:17 paulus
+ * BK Id: SCCS/s.mbx.h 1.14 08/13/02 20:27:38 paulus
*/
/*
* A collection of structures, addresses, and values associated with
diff -uNr linux-2.4.20/arch/ppc/platforms/oak.h linux-2.4.20-ben5/arch/ppc/platforms/oak.h
--- linux-2.4.20/arch/ppc/platforms/oak.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/oak.h 2003-01-30 11:55:20.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.oak.h 1.12 10/11/01 13:05:07 trini
+ * BK Id: SCCS/s.oak.h 1.15 08/13/02 20:27:39 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/platforms/oak_setup.c linux-2.4.20-ben5/arch/ppc/platforms/oak_setup.c
--- linux-2.4.20/arch/ppc/platforms/oak_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/oak_setup.c 2003-01-30 11:55:29.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.oak_setup.c 1.16 08/29/02 13:07:58 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/platforms/oak_setup.h linux-2.4.20-ben5/arch/ppc/platforms/oak_setup.h
--- linux-2.4.20/arch/ppc/platforms/oak_setup.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/oak_setup.h 2003-01-30 11:53:06.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.oak_setup.h 1.5 05/17/01 18:14:21 cort
+ * BK Id: SCCS/s.oak_setup.h 1.9 08/13/02 20:27:39 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_backlight.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_backlight.c
--- linux-2.4.20/arch/ppc/platforms/pmac_backlight.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_backlight.c 2003-01-30 11:53:04.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pmac_backlight.c 1.10 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.pmac_backlight.c 1.13 08/13/02 20:27:39 paulus
*/
/*
* Miscellaneous procedures for dealing with the PowerMac hardware.
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_cpufreq.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_cpufreq.c
--- linux-2.4.20/arch/ppc/platforms/pmac_cpufreq.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_cpufreq.c 2003-01-30 11:55:40.000000000 +0100
@@ -0,0 +1,344 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#undef DEBUG_FREQ
+
+extern void low_choose_750fx_pll(int pll);
+extern void low_sleep_handler(void);
+extern void openpic_sleep_save_intrs(void);
+extern void openpic_sleep_restore_intrs(void);
+extern void enable_kernel_altivec(void);
+extern void enable_kernel_fp(void);
+
+static unsigned int low_freq;
+static unsigned int hi_freq;
+static unsigned int cur_freq;
+static int cpufreq_uses_pmu;
+
+#define PMAC_CPU_LOW_SPEED 1
+#define PMAC_CPU_HIGH_SPEED 0
+
+static inline void
+wakeup_decrementer(void)
+{
+ set_dec(tb_ticks_per_jiffy);
+ /* No currently-supported powerbook has a 601,
+ * so use get_tbl, not native
+ */
+ last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
+}
+
+#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.
+ */
+ extern void calibrate_delay(void);
+
+ unsigned long save_lpj = loops_per_jiffy;
+ calibrate_delay();
+ loops_per_jiffy = save_lpj;
+}
+#endif
+
+/* Switch CPU speed under 750FX CPU control
+ */
+static int __pmac
+cpu_750fx_cpu_speed(int low_speed)
+{
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+#endif
+ low_choose_750fx_pll(low_speed);
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+ debug_calc_bogomips();
+#endif
+
+ return 0;
+}
+
+/* Switch CPU speed under PMU control
+ */
+static int __pmac
+pmu_set_cpu_speed(unsigned int low_speed)
+{
+ struct adb_request req;
+ unsigned long save_l2cr;
+ unsigned long save_l3cr;
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
+#endif
+ /* Disable all interrupt sources on openpic */
+ openpic_sleep_save_intrs();
+
+ /* Make sure the PMU is idle */
+ pmu_suspend();
+
+ /* Make sure the decrementer won't interrupt us */
+ asm volatile("mtdec %0" : : "r" (0x7fffffff));
+ /* Make sure any pending DEC interrupt occuring 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_disable();
+
+ /* Giveup the FPU & vec */
+ enable_kernel_fp();
+
+#ifdef CONFIG_ALTIVEC
+ if (cur_cpu_spec[0]->cpu_features & 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) */
+ if (save_l3cr != 0xffffffff && (save_l3cr & L3CR_L3E) != 0)
+ _set_L3CR(save_l3cr & 0x7fffffff);
+ if (save_l2cr != 0xffffffff && (save_l2cr & L2CR_L2E) != 0)
+ _set_L2CR(save_l2cr & 0x7fffffff);
+
+ /* 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();
+
+ pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,1,1);
+
+ low_sleep_handler();
+
+ 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 */
+ set_context(current->active_mm->context, current->active_mm->pgd);
+
+#ifdef DEBUG_FREQ
+ printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1));
+#endif
+
+ /* Restore decrementer */
+ wakeup_decrementer();
+
+ /* Restore interrupts */
+ openpic_sleep_restore_intrs();
+
+ pmu_resume();
+
+ /* Let interrupts flow again ... */
+ local_irq_enable();
+
+#ifdef DEBUG_FREQ
+ debug_calc_bogomips();
+#endif
+
+ return 0;
+}
+
+static int __pmac
+do_set_cpu_speed(int speed_mode)
+{
+ struct cpufreq_freqs freqs;
+ int rc;
+
+ freqs.old = cur_freq;
+ freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+ freqs.cpu = CPUFREQ_ALL_CPUS;
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+ if (cpufreq_uses_pmu)
+ rc = pmu_set_cpu_speed(speed_mode);
+ else
+ rc = cpu_750fx_cpu_speed(speed_mode);
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+ cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+
+ return rc;
+}
+
+static int __pmac
+pmac_cpufreq_verify(struct cpufreq_policy *policy)
+{
+ if (!policy)
+ return -EINVAL;
+
+ policy->cpu = 0; /* UP only */
+
+ cpufreq_verify_within_limits(policy, low_freq, hi_freq);
+
+ if ((policy->min > low_freq) &&
+ (policy->max < hi_freq))
+ policy->max = hi_freq;
+
+ return 0;
+}
+
+static int __pmac
+pmac_cpufreq_setpolicy(struct cpufreq_policy *policy)
+{
+ int rc;
+
+ if (!policy)
+ return -EINVAL;
+ if (policy->min > low_freq)
+ rc = do_set_cpu_speed(PMAC_CPU_HIGH_SPEED);
+ else if (policy->max < hi_freq)
+ rc = do_set_cpu_speed(PMAC_CPU_LOW_SPEED);
+ else if (policy->policy == CPUFREQ_POLICY_POWERSAVE)
+ rc = do_set_cpu_speed(PMAC_CPU_LOW_SPEED);
+ else
+ rc = do_set_cpu_speed(PMAC_CPU_HIGH_SPEED);
+
+ return rc;
+}
+
+unsigned int __pmac
+pmac_get_cur_cpufreq(void)
+{
+ return cur_freq;
+}
+
+
+/* Currently, we support the following machines:
+ *
+ * - Titanium PowerBook 800 (PMU based, 667Mhz & 800Mhz)
+ * - Titanium PowerBook 500 (PMU based, 300Mhz & 500Mhz)
+ * - iBook2 500 (PMU based, 400Mhz & 500Mhz)
+ * - iBook2 700 (CPU based, 400Mhz & 700Mhz, support low voltage)
+ */
+static int __init
+pmac_cpufreq_setup(void)
+{
+ struct device_node *cpunode;
+ struct cpufreq_driver *driver;
+ u32 *value;
+ int has_freq_ctl = 0;
+ int rc;
+
+ memset(&driver, 0, sizeof(driver));
+
+ /* Assume only one CPU */
+ cpunode = find_type_devices("cpu");
+ if (!cpunode)
+ goto out;
+
+ /* Get current cpu clock freq */
+ value = (u32 *)get_property(cpunode, "clock-frequency", NULL);
+ if (!value)
+ goto out;
+ cur_freq = (*value) / 1000;
+
+ /* Check for tibook 800Mhz or 1Ghz */
+ if (machine_is_compatible("PowerBook3,4") || machine_is_compatible("PowerBook3,5")) {
+ value = (u32 *)get_property(cpunode, "min-clock-frequency", NULL);
+ if (!value)
+ goto out;
+ low_freq = (*value) / 1000;
+
+ value = (u32 *)get_property(cpunode, "max-clock-frequency", NULL);
+ if (!value)
+ goto out;
+ hi_freq = (*value) / 1000;
+ has_freq_ctl = 1;
+ cpufreq_uses_pmu = 1;
+ }
+ /* Else check for iBook2 500 */
+ else if (machine_is_compatible("PowerBook4,1")) {
+ /* We only know about 500Mhz model */
+ if (cur_freq < 450000 || cur_freq > 550000)
+ goto out;
+ hi_freq = cur_freq;
+ low_freq = 400000;
+ has_freq_ctl = 1;
+ cpufreq_uses_pmu = 1;
+ }
+ /* Else check for TiPb 500 */
+ else if (machine_is_compatible("PowerBook3,2")) {
+ /* We only know about 500Mhz model */
+ if (cur_freq < 450000 || cur_freq > 550000)
+ goto out;
+ hi_freq = cur_freq;
+ low_freq = 300000;
+ has_freq_ctl = 1;
+ cpufreq_uses_pmu = 1;
+ }
+ /* Else check for 750FX */
+ else if (PVR_VER(mfspr(PVR)) == 0x7000) {
+ if (get_property(cpunode, "dynamic-power-step", NULL) == NULL)
+ goto out;
+ hi_freq = cur_freq;
+ value = (u32 *)get_property(cpunode, "reduced-clock-frequency", NULL);
+ if (!value)
+ goto out;
+ low_freq = (*value) / 1000;
+ cpufreq_uses_pmu = 0;
+ has_freq_ctl = 1;
+ }
+out:
+ if (!has_freq_ctl)
+ return -ENODEV;
+
+ /* initialization of main "cpufreq" code*/
+ driver = kmalloc(sizeof(struct cpufreq_driver) +
+ NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);
+ if (!driver)
+ return -ENOMEM;
+
+ driver->policy = (struct cpufreq_policy *) (driver + 1);
+
+#ifdef CONFIG_CPU_FREQ_24_API
+ driver->cpu_min_freq[0] = low_freq;
+ driver->cpu_cur_freq[0] = cur_freq;
+#endif
+
+ driver->verify = &pmac_cpufreq_verify;
+ driver->setpolicy = &pmac_cpufreq_setpolicy;
+
+ driver->policy[0].cpu = 0;
+ driver->policy[0].min = low_freq;
+ driver->policy[0].max = cur_freq;
+ driver->policy[0].max_cpu_freq = hi_freq;
+ driver->policy[0].policy = (cur_freq == low_freq) ?
+ CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;
+
+ rc = cpufreq_register(driver);
+ if (rc)
+ kfree(driver);
+ return rc;
+}
+
+__initcall(pmac_cpufreq_setup);
+
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_feature.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_feature.c
--- linux-2.4.20/arch/ppc/platforms/pmac_feature.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_feature.c 2003-01-30 11:55:42.000000000 +0100
@@ -17,6 +17,8 @@
* - 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
@@ -79,7 +81,8 @@
macio_gatwick,
macio_paddington,
macio_keylargo,
- macio_pangea
+ macio_pangea,
+ macio_intrepid,
};
static const char* macio_names[] __pmacdata =
@@ -92,7 +95,8 @@
"Gatwick",
"Paddington",
"Keylargo",
- "Pangea"
+ "Pangea",
+ "Intrepid"
};
static struct macio_chip
@@ -538,7 +542,7 @@
return 0;
}
-static u32 save_fcr[5] __pmacdata;
+static u32 save_fcr[6] __pmacdata;
static u32 save_mbcr __pmacdata;
static u32 save_gpio_levels[2] __pmacdata;
static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT] __pmacdata;
@@ -814,8 +818,96 @@
}
static int __pmac
+pangea_modem_enable(struct device_node* node, int param, int 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 int __pmac
+core99_ata100_enable(struct device_node* node, int value)
+{
+ unsigned long flags;
+ struct pci_dev *pdev = NULL;
+ u8 pbus, pid;
+
+ 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_find_slot(pbus, pid);
+ if (pdev == NULL)
+ return 0;
+ pci_enable_device(pdev);
+ pci_set_master(pdev);
+ }
+ return 0;
+}
+
+static int __pmac
core99_ide_enable(struct device_node* node, int param, int 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,
@@ -826,6 +918,8 @@
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;
}
@@ -873,7 +967,8 @@
struct macio_chip* macio;
macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
return -ENODEV;
LOCK(flags);
@@ -1010,40 +1105,14 @@
static int __pmac
core99_reset_cpu(struct device_node* node, int param, int value)
{
- const int reset_lines[] = { KL_GPIO_RESET_CPU0,
- KL_GPIO_RESET_CPU1,
- KL_GPIO_RESET_CPU2,
- KL_GPIO_RESET_CPU3 };
- int reset_io;
- unsigned long flags;
- struct macio_chip* macio;
-
- macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
- return -ENODEV;
- if (param > 3 || param < 0)
- return -ENODEV;
-
- reset_io = reset_lines[param];
-
- LOCK(flags);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE);
- (void)MACIO_IN8(reset_io);
- udelay(1);
- MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTPUT_ENABLE | KEYLARGO_GPIO_OUTOUT_DATA);
- (void)MACIO_IN8(reset_io);
- UNLOCK(flags);
-
- return 0;
-}
-
-static int __pmac
-rackmac_reset_cpu(struct device_node* node, int param, int value)
-{
- int reset_io;
+ unsigned int reset_io = 0;
unsigned long flags;
struct macio_chip* macio;
struct device_node* np;
+ 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)
@@ -1062,14 +1131,14 @@
break;
}
}
- if (np == NULL)
- return -ENODEV;
+ 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);
+ MACIO_OUT8(reset_io, KEYLARGO_GPIO_OUTOUT_DATA | KEYLARGO_GPIO_OUTPUT_ENABLE);
(void)MACIO_IN8(reset_io);
UNLOCK(flags);
@@ -1087,15 +1156,19 @@
u32 reg;
macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
return -ENODEV;
-
+
+ /* XXX Fix handling of 3rd USB controller in Intrepid, move the
+ * port connect stuff (KL4_*) to the sleep code eventually
+ */
prop = (char *)get_property(node, "AAPL,clock-id", NULL);
if (!prop)
return -ENODEV;
- if (strncmp(prop, "usb0u048", strlen("usb0u048")) == 0)
+ if (strncmp(prop, "usb0u048", 8) == 0)
number = 0;
- else if (strncmp(prop, "usb1u148", strlen("usb1u148")) == 0)
+ else if (strncmp(prop, "usb1u148", 8) == 0)
number = 2;
else
return -ENODEV;
@@ -1166,7 +1239,8 @@
struct macio_chip* macio;
macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
return -ENODEV;
if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
return -ENODEV;
@@ -1195,7 +1269,8 @@
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)
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
return -ENODEV;
if (!(macio->flags & MACIO_FLAG_FW_SUPPORTED))
return -ENODEV;
@@ -1234,23 +1309,24 @@
}
static void __pmac
-keylargo_shutdown(struct macio_chip* macio, int restart)
+keylargo_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
- mdelay(1);
- MACIO_BIS(KEYLARGO_FCR0, KL0_USB_REF_SUSPEND);
- (void)MACIO_IN32(KEYLARGO_FCR0);
- mdelay(100);
+ 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);
-
- (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
+
MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
+ MACIO_BIS(KEYLARGO_MBCR, KL_MBCR_MB0_IDE_ENABLE);
MACIO_BIC(KEYLARGO_FCR1,
KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
@@ -1261,27 +1337,33 @@
KL1_EIDE0_ENABLE | KL1_EIDE0_RESET_N |
KL1_EIDE1_ENABLE | KL1_EIDE1_RESET_N |
KL1_UIDE_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- udelay(10);
MACIO_BIC(KEYLARGO_FCR2, KL2_IOBUS_ENABLE);
- udelay(10);
+
temp = MACIO_IN32(KEYLARGO_FCR3);
- if (macio->rev >= 2)
- temp |= (KL3_SHUTDOWN_PLL2X | KL3_SHUTDOWN_PLL_TOTAL);
-
+ 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 | KL3_SHUTDOWN_PLLKW12;
+ KL3_SHUTDOWN_PLLKW35;
+ if (sleep_mode)
+ temp |= KL3_SHUTDOWN_PLLKW12;
temp &= ~(KL3_CLK66_ENABLE | KL3_CLK49_ENABLE | KL3_CLK45_ENABLE
- | KL3_CLK31_ENABLE | KL3_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE
- | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_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);
- (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
}
static void __pmac
-pangea_shutdown(struct macio_chip* macio, int restart)
+pangea_shutdown(struct macio_chip* macio, int sleep_mode)
{
u32 temp;
@@ -1289,10 +1371,6 @@
KL0_SCC_CELL_ENABLE |
KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR0); udelay(10);
- MACIO_BIC(KEYLARGO_MBCR, KL_MBCR_MB0_DEV_MASK);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
-
MACIO_BIC(KEYLARGO_FCR1,
KL1_AUDIO_SEL_22MCLK | KL1_AUDIO_CLK_ENABLE_BIT |
KL1_AUDIO_CLK_OUT_ENABLE | KL1_AUDIO_CELL_ENABLE |
@@ -1300,18 +1378,54 @@
KL1_I2S0_ENABLE | KL1_I2S1_CELL_ENABLE |
KL1_I2S1_CLK_ENABLE_BIT | KL1_I2S1_ENABLE |
KL1_UIDE_ENABLE);
- (void)MACIO_IN32(KEYLARGO_FCR1); udelay(10);
+ if (pmac_mb.board_flags & PMAC_MB_MOBILE)
+ MACIO_BIC(KEYLARGO_FCR1, KL1_UIDE_RESET_N);
MACIO_BIS(KEYLARGO_FCR2, KL2_ALT_DATA_OUT);
- udelay(10);
+
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_TIMER_CLK18_ENABLE | KL3_I2S1_CLK18_ENABLE
- | KL3_I2S0_CLK18_ENABLE | KL3_VIA_CLK16_ENABLE);
+ 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);
- (void)MACIO_IN32(KEYLARGO_FCR3); udelay(10);
+
+ /* Flush posted writes & wait a bit */
+ (void)MACIO_IN32(KEYLARGO_FCR0); mdelay(1);
+}
+
+static void __pmac
+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 |
+ KL0_USB0_CELL_ENABLE | KL0_USB1_CELL_ENABLE);
+
+ MACIO_BIC(KEYLARGO_FCR1,
+ KL1_USB2_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);
+ 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_IT_SHUTDOWN_PLL1 | KL3_IT_SHUTDOWN_PLL2 |
+ KL3_IT_SHUTDOWN_PLL3;
+ 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(1);
}
static int __pmac
@@ -1321,7 +1435,8 @@
int i;
macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
+ 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
@@ -1337,7 +1452,11 @@
}
/* We make sure int. modem is off (in case driver lost it) */
- core99_modem_enable(macio->of_node, 0, 0);
+ 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);
@@ -1354,12 +1473,15 @@
save_gpio_normal[i] = MACIO_IN8(KEYLARGO_GPIO_0+i);
/* Save the FCRs */
- save_mbcr = MACIO_IN32(KEYLARGO_MBCR);
+ 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);
@@ -1368,9 +1490,11 @@
* Turn off as much as we can
*/
if (macio->type == macio_pangea)
- pangea_shutdown(macio, 0);
+ pangea_shutdown(macio, 1);
+ else if (macio->type == macio_intrepid)
+ intrepid_shutdown(macio, 1);
else if (macio->type == macio_keylargo)
- keylargo_shutdown(macio, 0);
+ keylargo_shutdown(macio, 1);
/*
* Put the host bridge to sleep
@@ -1400,7 +1524,8 @@
int i;
macio = &macio_chips[0];
- if (macio->type != macio_keylargo && macio->type != macio_pangea)
+ if (macio->type != macio_keylargo && macio->type != macio_pangea &&
+ macio->type != macio_intrepid)
return -ENODEV;
/*
@@ -1414,9 +1539,11 @@
/*
* Restore KeyLargo
*/
-
- MACIO_OUT32(KEYLARGO_MBCR, save_mbcr);
- (void)MACIO_IN32(KEYLARGO_MBCR); udelay(10);
+
+ 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]);
@@ -1427,6 +1554,10 @@
(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);
@@ -1477,61 +1608,6 @@
}
static int __pmac
-pangea_modem_enable(struct device_node* node, int param, int 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)
- 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 int __pmac
generic_get_mb_info(struct device_node* node, int param, int value)
{
switch(param) {
@@ -1547,7 +1623,6 @@
return 0;
}
-
/*
* Table definitions
*/
@@ -1657,7 +1732,7 @@
{ PMAC_FTR_1394_CABLE_POWER, core99_firewire_cable_power },
{ PMAC_FTR_SLEEP_STATE, core99_sleep_state },
#ifdef CONFIG_SMP
- { PMAC_FTR_RESET_CPU, rackmac_reset_cpu },
+ { PMAC_FTR_RESET_CPU, core99_reset_cpu },
#endif /* CONFIG_SMP */
{ PMAC_FTR_READ_GPIO, core99_read_gpio },
{ PMAC_FTR_WRITE_GPIO, core99_write_gpio },
@@ -1683,6 +1758,26 @@
{ PMAC_FTR_WRITE_GPIO, core99_write_gpio },
{ 0, NULL }
};
+
+/* Intrepid features
+ */
+static struct feature_table_entry intrepid_features[] __pmacdata = {
+ { 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 }
+};
static struct pmac_mb_def pmac_mb_defs[] __pmacdata = {
/* Warning: ordering is important as some models may claim
@@ -1714,11 +1809,11 @@
},
{ "AAPL,3400/2400", "PowerBook 3400",
PMAC_TYPE_HOOPER, ohare_features,
- PMAC_MB_CAN_SLEEP
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
},
{ "AAPL,3500", "PowerBook 3500",
PMAC_TYPE_KANGA, ohare_features,
- PMAC_MB_CAN_SLEEP
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
},
{ "AAPL,Gossamer", "PowerMac G3 (Gossamer)",
PMAC_TYPE_GOSSAMER, heathrow_desktop_features,
@@ -1730,11 +1825,11 @@
},
{ "AAPL,PowerBook1998", "PowerBook Wallstreet",
PMAC_TYPE_WALLSTREET, heathrow_laptop_features,
- PMAC_MB_CAN_SLEEP
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
},
{ "PowerBook1,1", "PowerBook 101 (Lombard)",
PMAC_TYPE_101_PBOOK, paddington_features,
- PMAC_MB_CAN_SLEEP
+ PMAC_MB_CAN_SLEEP | PMAC_MB_MOBILE
},
{ "iMac,1", "iMac (first generation)",
PMAC_TYPE_ORIG_IMAC, paddington_features,
@@ -1746,15 +1841,15 @@
},
{ "PowerBook4,3", "iBook 2 rev. 2",
PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "PowerBook4,2", "iBook 2",
PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "PowerBook4,1", "iBook 2",
PMAC_TYPE_IBOOK2, pangea_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "PowerMac4,4", "eMac",
PMAC_TYPE_EMAC, core99_features,
@@ -1774,7 +1869,7 @@
},
{ "PowerBook2,1", "iBook (first generation)",
PMAC_TYPE_ORIG_IBOOK, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99
+ PMAC_MB_CAN_SLEEP | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
},
{ "PowerMac3,1", "PowerMac G4 AGP Graphics",
PMAC_TYPE_SAWTOOTH, core99_features,
@@ -1798,7 +1893,7 @@
},
{ "PowerBook2,2", "iBook FireWire",
PMAC_TYPE_FW_IBOOK, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
},
{ "PowerMac5,1", "PowerMac G4 Cube",
PMAC_TYPE_CUBE, core99_features,
@@ -1814,19 +1909,23 @@
},
{ "PowerBook3,1", "PowerBook Pismo",
PMAC_TYPE_PISMO, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_OLD_CORE99 | PMAC_MB_MOBILE
},
{ "PowerBook3,2", "PowerBook Titanium",
PMAC_TYPE_TITANIUM, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "PowerBook3,3", "PowerBook Titanium II",
PMAC_TYPE_TITANIUM2, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "PowerBook3,4", "PowerBook Titanium III",
PMAC_TYPE_TITANIUM3, core99_features,
- PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
+ },
+ { "PowerBook3,5", "PowerBook Titanium IV",
+ PMAC_TYPE_TITANIUM4, core99_features,
+ PMAC_MB_CAN_SLEEP | PMAC_MB_HAS_FW_POWER | PMAC_MB_MOBILE
},
{ "RackMac1,1", "XServe",
PMAC_TYPE_RACKMAC, rackmac_features,
@@ -1931,6 +2030,11 @@
pmac_mb.model_name = "Unknown Pangea-based";
pmac_mb.features = pangea_features;
break;
+ case macio_intrepid:
+ pmac_mb.model_id = PMAC_TYPE_UNKNOWN_PANGEA;
+ pmac_mb.model_name = "Unknown Pangea-based";
+ pmac_mb.features = intrepid_features;
+ break;
default:
return -ENODEV;
}
@@ -1977,6 +2081,12 @@
* NAP mode
*/
powersave_lowspeed = 1;
+
+ /* 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);
return 0;
@@ -2060,6 +2170,8 @@
u32* did = (u32 *)get_property(node, "device-id", NULL);
if (*did == 0x00000025)
type = macio_pangea;
+ if (*did == 0x0000003e)
+ type = macio_intrepid;
}
macio_chips[i].of_node = node;
macio_chips[i].type = type;
@@ -2154,7 +2266,8 @@
}
if (macio_chips[0].type == macio_keylargo ||
- macio_chips[0].type == macio_pangea) {
+ 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
*/
@@ -2185,6 +2298,17 @@
np = np->next;
}
+ /* Enable ATA-100 before PCI probe. */
+ np = find_devices("ata-6");
+ while(np) {
+ if (np->parent
+ && device_is_compatible(np->parent, "uni-north")
+ && device_is_compatible(np, "kauai-ata")) {
+ core99_ata100_enable(np, 1);
+ }
+ np = np->next;
+ }
+
/* Switch airport off */
np = find_devices("radio");
while(np) {
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_nvram.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_nvram.c
--- linux-2.4.20/arch/ppc/platforms/pmac_nvram.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_nvram.c 2003-01-30 11:54:48.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pmac_nvram.c 1.17 12/01/01 20:09:06 benh
+ * BK Id: SCCS/s.pmac_nvram.c 1.20 08/13/02 20:27:39 paulus
*/
/*
* Miscellaneous procedures for dealing with the PowerMac hardware.
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_pci.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_pci.c
--- linux-2.4.20/arch/ppc/platforms/pmac_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_pci.c 2003-01-30 11:55:16.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pmac_pci.c 1.38 08/13/02 20:27:39 paulus
*/
/*
* Support for PCI bridges found on Power Macintoshes.
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_pic.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_pic.c
--- linux-2.4.20/arch/ppc/platforms/pmac_pic.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_pic.c 2003-01-30 11:52:50.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.pmac_pic.c 1.24 12/19/01 10:53:01 paulus
+ * BK Id: SCCS/s.pmac_pic.c 1.27 08/13/02 20:27:39 paulus
*/
#include
#include
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_pic.h linux-2.4.20-ben5/arch/ppc/platforms/pmac_pic.h
--- linux-2.4.20/arch/ppc/platforms/pmac_pic.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_pic.h 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pmac_pic.h 1.12 08/13/02 20:27:39 paulus
*/
#ifndef __PPC_PLATFORMS_PMAC_PIC_H
#define __PPC_PLATFORMS_PMAC_PIC_H
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_setup.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_setup.c
--- linux-2.4.20/arch/ppc/platforms/pmac_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_setup.c 2003-01-30 11:52:49.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pmac_setup.c 1.66 10/04/02 15:02:22 benh
*/
/*
* arch/ppc/platforms/setup.c
@@ -53,6 +53,7 @@
#include
#include
#include
+#include
#include
#include
@@ -155,6 +156,14 @@
struct device_node *cpu_node;
int *fp, s;
+#ifdef CONFIG_CPU_FREQ_PMAC
+ extern unsigned int pmac_get_cur_cpufreq(void);
+ unsigned int freq = pmac_get_cur_cpufreq();
+ if (freq != 0) {
+ seq_printf(m, "clock\t\t: %dMHz\n", freq/1000);
+ return 0;
+ }
+#endif /* CONFIG_CPU_FREQ_PMAC */
cpu_node = find_type_devices("cpu");
if (!cpu_node)
return 0;
@@ -207,6 +216,18 @@
/* print parsed model */
seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
seq_printf(m, "pmac flags\t: %08x\n", mbflags);
+#if 0
+{
+ extern long nap_return_count;
+ extern long nap_enter_count;
+ extern long nap_save_msscr0;
+ extern long dbg_nap_ret;
+ seq_printf(m, "nap_return_count: %d\n", nap_return_count);
+ seq_printf(m, "nap_enter_count\t: %d\n", nap_enter_count);
+ seq_printf(m, "nap_save_msscr0\t: %x\n", nap_save_msscr0);
+ seq_printf(m, "dbg_nap_ret\t: %x\n", dbg_nap_ret);
+}
+#endif
/* find l2 cache info */
np = find_devices("l2-cache");
@@ -313,6 +334,14 @@
sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);
ohare_init();
+ /* Check & display some CPU config registers for diagnostic */
+ if (pvr == 0x8000 || pvr == 0x8001) { /* 745x */
+ printk(KERN_INFO "CPU MSCCR0 : 0x%08x\n", mfspr(SPRN_MSSCR0));
+ printk(KERN_INFO "CPU HID1 : 0x%08x\n", mfspr(SPRN_HID1));
+ }
+ if (pvr == 0x0008 || pvr == 0x7000) /* 750's */
+ printk(KERN_INFO "CPU HID1 : 0x%08x\n", mfspr(SPRN_HID1));
+
/* Lookup PCI hosts */
pmac_find_bridges();
@@ -333,6 +362,9 @@
}
}
+#if 0
+ printk("MSSCR0: %x\n", mfspr(SPRN_MSSCR0));
+#endif
if (ppc_override_l2cr)
printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_sleep.S linux-2.4.20-ben5/arch/ppc/platforms/pmac_sleep.S
--- linux-2.4.20/arch/ppc/platforms/pmac_sleep.S 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_sleep.S 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pmac_sleep.S 1.33 10/20/02 20:14:45 benh
*/
/*
* This file contains sleep low-level functions for PowerBook G3.
@@ -55,7 +55,7 @@
.text
.align 5
-#if defined(CONFIG_PMAC_PBOOK)
+#if defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ_PMAC)
/* 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
@@ -477,7 +477,60 @@
isync
rfi
-#endif /* defined(CONFIG_PMAC_PBOOK) */
+#endif /* defined(CONFIG_PMAC_PBOOK) || defined(CONFIG_CPU_FREQ) */
+
+#ifdef CONFIG_CPU_FREQ_PMAC
+
+/* This gets called by via-pmu.c to switch the PLL selection
+ * on 750fx CPU. This function should really be moved to some
+ * other place (as most of the cpufreq code in via-pmu
+ */
+_GLOBAL(low_choose_750fx_pll)
+ /* Clear MSR:EE */
+ mfmsr r7
+ rlwinm r0,r7,0,17,15
+ mtmsr r0
+
+ /* If switching to PLL1, disable HID0:BTIC */
+ cmpli cr0,r3,0
+ beq 1f
+ mfspr r5,HID0
+ rlwinm r5,r5,0,27,25
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+
+1:
+ /* Calc new HID1 value */
+ mfspr r4,SPRN_HID1 /* Build a HID1:PS bit from parameter */
+ rlwinm r5,r3,16,15,15 /* Clear out HID1:PS from value read */
+ rlwinm r4,r4,0,16,14 /* Could have I used rlwimi here ? */
+ or r4,r4,r5
+ mtspr SPRN_HID1,r4
+
+ /* Store new HID1 image */
+ lwz r6,PROCESSOR(r2)
+ slwi r6,r6,2
+ addis r6,r6,nap_save_hid1@ha
+ stw r4,nap_save_hid1@l(r6)
+
+ /* If switching to PLL0, enable HID0:BTIC */
+ cmpli cr0,r3,0
+ bne 1f
+ mfspr r5,HID0
+ ori r5,r5,HID0_BTIC
+ sync
+ mtspr HID0,r5
+ isync
+ sync
+
+1:
+ /* Return */
+ mtmsr r7
+ blr
+
+#endif /* CONFIG_CPU_FREQ_PMAC */
.data
.globl sleep_storage
diff -uNr linux-2.4.20/arch/ppc/platforms/pmac_time.c linux-2.4.20-ben5/arch/ppc/platforms/pmac_time.c
--- linux-2.4.20/arch/ppc/platforms/pmac_time.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/pmac_time.c 2003-01-30 11:55:52.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.pmac_time.c 1.27 10/20/02 20:14:45 benh
*/
/*
* Support for periodic interrupts (100 per second) and for getting
@@ -206,7 +206,7 @@
printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
tb_ticks_per_jiffy, dstart - dend);
- iounmap(via);
+ iounmap((void*)via);
return 1;
}
diff -uNr linux-2.4.20/arch/ppc/platforms/prep_pci.c linux-2.4.20-ben5/arch/ppc/platforms/prep_pci.c
--- linux-2.4.20/arch/ppc/platforms/prep_pci.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/prep_pci.c 2003-01-30 11:55:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.prep_pci.c 1.33 12/20/01 15:36:12 trini
+ * BK Id: SCCS/s.prep_pci.c 1.36 08/13/02 20:27:39 paulus
*/
/*
* PReP pci functions.
diff -uNr linux-2.4.20/arch/ppc/platforms/prep_setup.c linux-2.4.20-ben5/arch/ppc/platforms/prep_setup.c
--- linux-2.4.20/arch/ppc/platforms/prep_setup.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/prep_setup.c 2003-01-30 11:54:01.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.prep_setup.c 1.59 11/07/02 11:46:58 trini
*/
/*
* linux/arch/ppc/kernel/setup.c
@@ -59,6 +59,7 @@
#include
#include
#include
+#include
#if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
#include <../drivers/sound/sound_config.h>
@@ -621,12 +622,24 @@
prep_init_IRQ(void)
{
int i;
+ unsigned int pci_viddid, pci_did;
if (OpenPIC_Addr != NULL)
openpic_init(1, NUM_8259_INTERRUPTS, 0, -1);
for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ )
irq_desc[i].handler = &i8259_pic;
- i8259_init(0xbffffff0); /* PCI interrupt ack address for MPC105 and 106 */
+ /* If we are on an MPC10x, we want to use the int-ack,
+ * otherwise we poll. */
+ early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &pci_viddid);
+ pci_did = (pci_viddid & 0xffff0000) >> 16;
+ if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA)
+ && ((pci_did == PCI_DEVICE_ID_MOTOROLA_MPC105)
+ || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC106)
+ || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC107)))
+ /* PCI interrupt ack address for MPC105 and 106 */
+ i8259_init(0xbffffff0);
+ else
+ i8259_init(0);
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -uNr linux-2.4.20/arch/ppc/platforms/prep_time.c linux-2.4.20-ben5/arch/ppc/platforms/prep_time.c
--- linux-2.4.20/arch/ppc/platforms/prep_time.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/prep_time.c 2003-01-30 11:55:46.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.prep_time.c 1.13 08/13/02 20:27:40 paulus
*/
/*
* arch/ppc/platforms/prep_time.c
diff -uNr linux-2.4.20/arch/ppc/platforms/proc_rtas.c linux-2.4.20-ben5/arch/ppc/platforms/proc_rtas.c
--- linux-2.4.20/arch/ppc/platforms/proc_rtas.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/proc_rtas.c 2003-01-30 11:54:45.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.proc_rtas.c 1.5 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.proc_rtas.c 1.6 08/13/02 21:32:03 paulus
*/
/*
* arch/ppc/kernel/proc_rtas.c
diff -uNr linux-2.4.20/arch/ppc/platforms/residual.c linux-2.4.20-ben5/arch/ppc/platforms/residual.c
--- linux-2.4.20/arch/ppc/platforms/residual.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/residual.c 2003-01-30 11:55:56.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.residual.c 1.15 02/05/02 18:08:35 trini
+ * BK Id: SCCS/s.residual.c 1.18 08/13/02 20:27:40 paulus
*/
/*
* Code to deal with the PReP residual data.
diff -uNr linux-2.4.20/arch/ppc/platforms/rpxclassic.h linux-2.4.20-ben5/arch/ppc/platforms/rpxclassic.h
--- linux-2.4.20/arch/ppc/platforms/rpxclassic.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/rpxclassic.h 2003-01-30 11:55:23.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.rpxclassic.h 1.14 08/13/02 20:27:40 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/platforms/rpxhiox.h linux-2.4.20-ben5/arch/ppc/platforms/rpxhiox.h
--- linux-2.4.20/arch/ppc/platforms/rpxhiox.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/rpxhiox.h 2003-01-30 11:54:57.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.rpxhiox.h 1.3 05/17/01 18:14:25 cort
+ * BK Id: SCCS/s.rpxhiox.h 1.4 08/13/02 21:33:06 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/platforms/rpxlite.h linux-2.4.20-ben5/arch/ppc/platforms/rpxlite.h
--- linux-2.4.20/arch/ppc/platforms/rpxlite.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/rpxlite.h 2003-01-30 11:55:15.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: %F% %I% %G% %U% %#%
+ * BK Id: SCCS/s.rpxlite.h 1.14 08/13/02 20:27:41 paulus
*/
/*
diff -uNr linux-2.4.20/arch/ppc/platforms/spd8xx.h linux-2.4.20-ben5/arch/ppc/platforms/spd8xx.h
--- linux-2.4.20/arch/ppc/platforms/spd8xx.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/spd8xx.h 2003-01-30 11:53:04.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.spd8xx.h 1.8 10/27/01 13:39:41 trini
+ * BK Id: SCCS/s.spd8xx.h 1.9 08/13/02 21:33:06 paulus
*/
/*
* Speech Design SPD8xxTS board specific definitions
diff -uNr linux-2.4.20/arch/ppc/platforms/tqm8xx.h linux-2.4.20-ben5/arch/ppc/platforms/tqm8xx.h
--- linux-2.4.20/arch/ppc/platforms/tqm8xx.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/tqm8xx.h 2003-01-30 11:54:52.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.tqm8xx.h 1.8 08/30/01 09:01:04 trini
+ * BK Id: SCCS/s.tqm8xx.h 1.9 08/13/02 21:33:06 paulus
*/
/*
* TQM8xx(L) board specific definitions
diff -uNr linux-2.4.20/arch/ppc/platforms/walnut.c linux-2.4.20-ben5/arch/ppc/platforms/walnut.c
--- linux-2.4.20/arch/ppc/platforms/walnut.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/walnut.c 2003-01-30 11:53:09.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.walnut_setup.c 1.10 11/13/01 21:26:07 paulus
+ * BK Id: SCCS/s.walnut.c 1.13 08/13/02 20:27:41 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/platforms/walnut.h linux-2.4.20-ben5/arch/ppc/platforms/walnut.h
--- linux-2.4.20/arch/ppc/platforms/walnut.h 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/platforms/walnut.h 2003-01-30 11:55:18.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.walnut_setup.h 1.5 05/17/01 18:14:22 cort
+ * BK Id: SCCS/s.walnut.h 1.9 08/13/02 20:27:41 paulus
*/
/*
*
diff -uNr linux-2.4.20/arch/ppc/xmon/Makefile linux-2.4.20-ben5/arch/ppc/xmon/Makefile
--- linux-2.4.20/arch/ppc/xmon/Makefile 2001-07-02 23:34:57.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/Makefile 2003-01-30 11:54:43.000000000 +0100
@@ -1,9 +1,11 @@
-# BK Id: SCCS/s.Makefile 1.6 06/27/01 14:49:58 trini
+# BK Id: SCCS/s.Makefile 1.8 06/25/02 16:33:15 trini
#
# Makefile for xmon
O_TARGET := x.o
+CFLAGS_xmon.o += -I$(TOPDIR)/arch/$(ARCH)/mm
+
ifdef CONFIG_8xx
obj-y := start_8xx.o
else
diff -uNr linux-2.4.20/arch/ppc/xmon/adb.c linux-2.4.20-ben5/arch/ppc/xmon/adb.c
--- linux-2.4.20/arch/ppc/xmon/adb.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/adb.c 2003-01-30 11:56:06.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.adb.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.adb.c 1.7 06/05/01 21:22:06 paulus
*/
/*
* Copyright (C) 1996 Paul Mackerras.
diff -uNr linux-2.4.20/arch/ppc/xmon/ansidecl.h linux-2.4.20-ben5/arch/ppc/xmon/ansidecl.h
--- linux-2.4.20/arch/ppc/xmon/ansidecl.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/ansidecl.h 2003-01-30 11:54:06.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ansidecl.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.ansidecl.h 1.7 06/05/01 21:22:06 paulus
*/
/* ANSI and traditional C compatability macros
Copyright 1991, 1992 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/xmon/nonstdio.h linux-2.4.20-ben5/arch/ppc/xmon/nonstdio.h
--- linux-2.4.20/arch/ppc/xmon/nonstdio.h 2002-02-25 20:37:55.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/xmon/nonstdio.h 2003-01-30 11:52:37.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.nonstdio.h 1.8 12/01/01 20:09:07 benh
+ * BK Id: SCCS/s.nonstdio.h 1.9 12/27/01 10:08:51 trini
*/
typedef int FILE;
extern FILE *xmon_stdin, *xmon_stdout;
diff -uNr linux-2.4.20/arch/ppc/xmon/ppc-dis.c linux-2.4.20-ben5/arch/ppc/xmon/ppc-dis.c
--- linux-2.4.20/arch/ppc/xmon/ppc-dis.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/ppc-dis.c 2003-01-30 11:55:32.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc-dis.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.ppc-dis.c 1.7 06/05/01 21:22:06 paulus
*/
/* ppc-dis.c -- Disassemble PowerPC instructions
Copyright 1994 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/xmon/ppc-opc.c linux-2.4.20-ben5/arch/ppc/xmon/ppc-opc.c
--- linux-2.4.20/arch/ppc/xmon/ppc-opc.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/ppc-opc.c 2003-01-30 11:53:19.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc-opc.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.ppc-opc.c 1.7 06/05/01 21:22:06 paulus
*/
/* ppc-opc.c -- PowerPC opcode list
Copyright 1994 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/xmon/ppc.h linux-2.4.20-ben5/arch/ppc/xmon/ppc.h
--- linux-2.4.20/arch/ppc/xmon/ppc.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/ppc.h 2003-01-30 11:54:48.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.ppc.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.ppc.h 1.7 06/05/01 21:22:06 paulus
*/
/* ppc.h -- Header file for PowerPC opcode table
Copyright 1994 Free Software Foundation, Inc.
diff -uNr linux-2.4.20/arch/ppc/xmon/privinst.h linux-2.4.20-ben5/arch/ppc/xmon/privinst.h
--- linux-2.4.20/arch/ppc/xmon/privinst.h 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/privinst.h 2003-01-30 11:54:53.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.privinst.h 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.privinst.h 1.7 06/05/01 21:22:06 paulus
*/
/*
* Copyright (C) 1996 Paul Mackerras.
diff -uNr linux-2.4.20/arch/ppc/xmon/setjmp.c linux-2.4.20-ben5/arch/ppc/xmon/setjmp.c
--- linux-2.4.20/arch/ppc/xmon/setjmp.c 2001-05-22 02:04:47.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/setjmp.c 2003-01-30 11:54:12.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.setjmp.c 1.5 05/17/01 18:14:23 cort
+ * BK Id: SCCS/s.setjmp.c 1.7 06/05/01 21:22:06 paulus
*/
/*
* Copyright (C) 1996 Paul Mackerras.
diff -uNr linux-2.4.20/arch/ppc/xmon/start.c linux-2.4.20-ben5/arch/ppc/xmon/start.c
--- linux-2.4.20/arch/ppc/xmon/start.c 2002-08-03 02:39:43.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/start.c 2003-01-30 11:52:54.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.start.c 1.20 04/09/02 21:01:58 paulus
+ * BK Id: SCCS/s.start.c 1.24 05/21/02 16:23:20 benh
*/
/*
* Copyright (C) 1996 Paul Mackerras.
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -25,10 +26,13 @@
#include
#endif
+#define CONFIG_XMON_FW
+
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
extern void xmon_printf(const char *fmt, ...);
static int xmon_expect(const char *str, unsigned int timeout);
+extern char cmd_line[512];
static int console;
static int use_screen;
@@ -36,6 +40,21 @@
static int xmon_use_sccb;
static struct device_node *channel_node;
+/* There are used when hooked via firewire */
+#ifdef CONFIG_XMON_FW
+volatile unsigned int xmon_fw_outbuf_size;
+volatile unsigned char xmon_fw_outbuf[1024];
+volatile unsigned int xmon_fw_oflags;
+volatile unsigned int xmon_fw_iflags;
+volatile unsigned int xmon_fw_idata;
+#define XMON_FW_FLAGS_OUT_ENTERED 0x00000001
+#define XMON_FW_FLAGS_OUT_DATA 0x00000002
+#define XMON_FW_FLAGS_OUT_ACK 0x00000004
+#define XMON_FW_FLAGS_IN_ATTACHED 0x00000001
+#define XMON_FW_FLAGS_IN_DATA 0x00000002
+#define XMON_FW_FLAGS_IN_ACK 0x00000004
+#endif
+
#define TB_SPEED 25000000
static inline unsigned int readtb(void)
@@ -61,7 +80,9 @@
volatile unsigned char *base;
use_screen = 0;
-
+ /* Typically used for firewire debugging */
+ if (strstr(cmd_line, "xmon_noio"))
+ return;
if (_machine == _MACH_Pmac) {
struct device_node *np;
unsigned long addr;
@@ -173,6 +194,114 @@
#endif /* CONFIG_ADB_CUDA */
}
+#if 0
+static void
+bx_printf(const char* fmt, ...)
+{
+ static char dbgbuf[2048];
+ va_list ap;
+ int n;
+
+ va_start(ap, fmt);
+ n = vsprintf(dbgbuf, fmt, ap);
+ va_end(ap);
+ btext_drawstring(dbgbuf);
+}
+#endif
+
+#ifdef CONFIG_XMON_FW
+static int
+xmon_fw_write(void* ptr, int nb)
+{
+ char* p = (char *)ptr;
+ int c, i;
+
+ while (nb && (xmon_fw_iflags & XMON_FW_FLAGS_IN_ATTACHED)) {
+ c = (nb > 1024) ? 1024 : nb;
+ memcpy((void *)xmon_fw_outbuf, p, c);
+ xmon_fw_outbuf_size = c;
+ wmb();
+ xmon_fw_oflags |= XMON_FW_FLAGS_OUT_DATA;
+ wmb();
+ for (i=0; i<1000; i++) {
+ rmb();
+ if (xmon_fw_iflags & XMON_FW_FLAGS_IN_ACK)
+ break;
+ mdelay(1);
+ }
+ xmon_fw_oflags &= ~XMON_FW_FLAGS_OUT_DATA;
+ wmb();
+ if ((xmon_fw_iflags & XMON_FW_FLAGS_IN_ACK) == 0) {
+ xmon_fw_iflags = 0;
+ break;
+ }
+ for (i=0; i<1000; i++) {
+ rmb();
+ if ((xmon_fw_iflags & XMON_FW_FLAGS_IN_ACK) == 0)
+ break;
+ mdelay(1);
+ }
+ if ((xmon_fw_iflags & XMON_FW_FLAGS_IN_ACK) != 0) {
+ xmon_fw_iflags = 0;
+ break;
+ }
+ nb -= c;
+ p += c;
+ }
+ return (xmon_fw_iflags & XMON_FW_FLAGS_IN_ATTACHED) != 0;
+}
+
+static int
+xmon_fw_read(void* ptr, int nb)
+{
+ int t, on, i;
+ unsigned int k;
+ char c[3];
+ char* p = (char *)ptr;
+
+ while (nb) {
+ t = 0;
+ on = 0;
+ while(xmon_fw_iflags & XMON_FW_FLAGS_IN_ATTACHED) {
+ if (xmon_fw_iflags & XMON_FW_FLAGS_IN_DATA)
+ break;
+ if (--t < 0) {
+ on = 1 - on;
+ c[0] = on? 0xdb: 0x20;
+ c[1] = '\b';
+ if (!xmon_fw_write(c, 2))
+ break;
+ t = 2000000;
+ }
+ rmb();
+ }
+ k = xmon_fw_idata & 0xff;
+ xmon_fw_oflags |= XMON_FW_FLAGS_OUT_ACK;
+ wmb();
+ for (i=0; i<1000; i++) {
+ rmb();
+ if ((xmon_fw_iflags & XMON_FW_FLAGS_IN_DATA) == 0)
+ break;
+ mdelay(1);
+ }
+ if (xmon_fw_iflags & XMON_FW_FLAGS_IN_DATA) {
+ xmon_fw_iflags = 0;
+ break;
+ }
+ xmon_fw_oflags &= ~XMON_FW_FLAGS_OUT_ACK;
+ wmb();
+ if (on) {
+ c[0] = 0x20; c[1] = '\b';
+ xmon_fw_write(c, 2);
+ }
+ *(p++) = k;
+ nb--;
+ }
+ return (xmon_fw_iflags & XMON_FW_FLAGS_IN_ATTACHED) != 0;
+}
+
+#endif /* CONFIG_XMON_FW */
+
int
xmon_write(void *handle, void *ptr, int nb)
{
@@ -188,9 +317,17 @@
if (--lock_wait == 0)
break;
#endif
-
+#ifdef CONFIG_XMON_FW
+ if (xmon_fw_write(ptr, nb))
+ goto out;
+#endif /* CONFIG_XMON_FW */
#ifdef CONFIG_BOOTX_TEXT
- if (use_screen) {
+#ifdef CONFIG_MORE_DEBUG
+ if (1)
+#else
+ if (use_screen)
+#endif
+ {
/* write it on the screen */
for (i = 0; i < nb; ++i)
btext_drawchar(*p++);
@@ -199,6 +336,9 @@
#endif
if (!scc_initialized)
xmon_init_scc();
+ if (!sccd)
+ goto out;
+
ct = 0;
for (i = 0; i < nb; ++i) {
while ((*sccc & TXRDY) == 0)
@@ -293,6 +433,10 @@
char *p = ptr;
int i;
+#ifdef CONFIG_XMON_FW
+ if (xmon_fw_read(ptr, nb))
+ return nb;
+#endif /* CONFIG_XMON_FW */
#ifdef CONFIG_BOOTX_TEXT
if (use_screen) {
for (i = 0; i < nb; ++i)
@@ -302,6 +446,8 @@
#endif
if (!scc_initialized)
xmon_init_scc();
+ if (sccd == NULL)
+ return 0;
for (i = 0; i < nb; ++i) {
while ((*sccc & RXRDY) == 0)
do_poll_adb();
@@ -324,7 +470,8 @@
static unsigned char scc_inittab[] = {
13, 0, /* set baud rate divisor */
- 12, 1,
+// 12, 1,
+ 12, 0,
14, 1, /* baud rate gen enable, src=rtxc */
11, 0x50, /* clocks = br gen */
5, 0xea, /* tx 8 bits, assert DTR & RTS */
@@ -335,6 +482,8 @@
void
xmon_init_scc()
{
+ if (sccd == NULL && channel_node == NULL)
+ return;
if ( _machine == _MACH_chrp )
{
sccd[3] = 0x83; eieio(); /* LCR = 8N1 + DLAB */
@@ -573,11 +722,19 @@
pmu_suspend();
}
#endif
+#ifdef CONFIG_XMON_FW
+ xmon_fw_oflags |= XMON_FW_FLAGS_OUT_ENTERED;
+ wmb();
+#endif /* CONFIG_XMON_FW */
}
void
xmon_leave(void)
{
+#ifdef CONFIG_XMON_FW
+ xmon_fw_oflags &= ~XMON_FW_FLAGS_OUT_ENTERED;
+ wmb();
+#endif /* CONFIG_XMON_FW */
#ifdef CONFIG_ADB_PMU
if (_machine == _MACH_Pmac) {
pmu_resume();
diff -uNr linux-2.4.20/arch/ppc/xmon/start_8xx.c linux-2.4.20-ben5/arch/ppc/xmon/start_8xx.c
--- linux-2.4.20/arch/ppc/xmon/start_8xx.c 2001-10-08 20:40:13.000000000 +0200
+++ linux-2.4.20-ben5/arch/ppc/xmon/start_8xx.c 2003-01-30 11:55:44.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.start_8xx.c 1.10 09/14/01 18:01:17 trini
+ * BK Id: SCCS/s.start_8xx.c 1.11 10/08/01 16:49:27 trini
*/
/*
* Copyright (C) 1996 Paul Mackerras.
diff -uNr linux-2.4.20/arch/ppc/xmon/subr_prf.c linux-2.4.20-ben5/arch/ppc/xmon/subr_prf.c
--- linux-2.4.20/arch/ppc/xmon/subr_prf.c 2002-02-25 20:37:55.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/xmon/subr_prf.c 2003-01-30 11:52:36.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.subr_prf.c 1.8 12/01/01 20:09:07 benh
+ * BK Id: SCCS/s.subr_prf.c 1.9 12/27/01 10:08:51 trini
*/
/*
* Written by Cort Dougan to replace the version originally used
diff -uNr linux-2.4.20/arch/ppc/xmon/xmon.c linux-2.4.20-ben5/arch/ppc/xmon/xmon.c
--- linux-2.4.20/arch/ppc/xmon/xmon.c 2002-02-25 20:37:55.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc/xmon/xmon.c 2003-01-30 11:52:37.000000000 +0100
@@ -1,5 +1,5 @@
/*
- * BK Id: SCCS/s.xmon.c 1.18 12/01/01 20:09:07 benh
+ * BK Id: SCCS/s.xmon.c 1.24 11/07/02 18:38:50 benh
*/
/*
* Routines providing a simple monitor for use on the PowerMac.
@@ -14,6 +14,10 @@
#include
#include
#include
+#ifdef CONFIG_PMAC_BACKLIGHT
+#include
+#endif
+#include "mmu_decl.h"
#include "nonstdio.h"
#include "privinst.h"
@@ -203,6 +207,18 @@
*/
#endif /* CONFIG_SMP */
remove_bpts();
+#ifdef CONFIG_PMAC_BACKLIGHT
+ if (_machine == _MACH_Pmac) {
+ if( setjmp(bus_error_jmp) == 0 ) {
+ debugger_fault_handler = handle_fault;
+ sync();
+ set_backlight_enable(1);
+ set_backlight_level(BACKLIGHT_MAX);
+ sync();
+ }
+ debugger_fault_handler = 0;
+ }
+#endif /* CONFIG_PMAC_BACKLIGHT */
cmd = cmds(excp);
if (cmd == 's') {
xmon_trace[smp_processor_id()] = SSTEP;
@@ -925,7 +941,6 @@
static void
dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
{
- extern void *Hash;
extern unsigned long Hash_size;
unsigned *htab = Hash;
unsigned hsize = Hash_size;
@@ -984,7 +999,6 @@
static void
dump_hash_table_seg(unsigned seg, unsigned start, unsigned end)
{
- extern void *Hash;
extern unsigned long Hash_size;
unsigned *htab = Hash;
unsigned hsize = Hash_size;
@@ -1050,6 +1064,8 @@
int seg;
unsigned seg_start, seg_end;
+ if (Hash == NULL)
+ return;
hash_ctx = 0;
hash_start = 0;
hash_end = 0xfffff000;
diff -uNr linux-2.4.20/arch/ppc64/config.in linux-2.4.20-ben5/arch/ppc64/config.in
--- linux-2.4.20/arch/ppc64/config.in 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/ppc64/config.in 2003-01-30 11:52:57.000000000 +0100
@@ -8,6 +8,7 @@
define_bool CONFIG_GENERIC_BUST_SPINLOCK n
define_bool CONFIG_GENERIC_ISA_DMA y
define_bool CONFIG_HAVE_DEC_LOCK y
+define_bool CONFIG_PPC_ISATIMER y
mainmenu_name "64 bit PowerPC Linux Kernel Configuration"
diff -uNr linux-2.4.20/arch/s390/mm/fault.c linux-2.4.20-ben5/arch/s390/mm/fault.c
--- linux-2.4.20/arch/s390/mm/fault.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/s390/mm/fault.c 2003-01-30 11:53:00.000000000 +0100
@@ -210,7 +210,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/s390x/mm/fault.c linux-2.4.20-ben5/arch/s390x/mm/fault.c
--- linux-2.4.20/arch/s390x/mm/fault.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/s390x/mm/fault.c 2003-01-30 11:52:39.000000000 +0100
@@ -210,7 +210,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/sh/mm/fault.c linux-2.4.20-ben5/arch/sh/mm/fault.c
--- linux-2.4.20/arch/sh/mm/fault.c 2002-11-29 00:53:11.000000000 +0100
+++ linux-2.4.20-ben5/arch/sh/mm/fault.c 2003-01-30 11:55:35.000000000 +0100
@@ -74,7 +74,7 @@
check_stack:
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, start) == 0)
+ if (expand_stack(vma, start, NULL) == 0)
goto good_area;
bad_area:
@@ -114,7 +114,7 @@
goto good_area;
if (!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/arch/sparc/mm/fault.c linux-2.4.20-ben5/arch/sparc/mm/fault.c
--- linux-2.4.20/arch/sparc/mm/fault.c 2001-12-21 18:41:53.000000000 +0100
+++ linux-2.4.20-ben5/arch/sparc/mm/fault.c 2003-01-30 11:54:21.000000000 +0100
@@ -251,7 +251,7 @@
goto good_area;
if(!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if(expand_stack(vma, address))
+ if(expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
@@ -498,7 +498,7 @@
goto good_area;
if(!(vma->vm_flags & VM_GROWSDOWN))
goto bad_area;
- if(expand_stack(vma, address))
+ if(expand_stack(vma, address, NULL))
goto bad_area;
good_area:
info.si_code = SEGV_ACCERR;
diff -uNr linux-2.4.20/arch/sparc64/mm/fault.c linux-2.4.20-ben5/arch/sparc64/mm/fault.c
--- linux-2.4.20/arch/sparc64/mm/fault.c 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/arch/sparc64/mm/fault.c 2003-01-30 11:54:59.000000000 +0100
@@ -389,7 +389,7 @@
goto bad_area;
}
}
- if (expand_stack(vma, address))
+ if (expand_stack(vma, address, NULL))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
diff -uNr linux-2.4.20/drivers/char/Config.in linux-2.4.20-ben5/drivers/char/Config.in
--- linux-2.4.20/drivers/char/Config.in 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/Config.in 2003-01-30 11:52:36.000000000 +0100
@@ -152,6 +152,9 @@
if [ "$CONFIG_PPC64" ] ; then
bool 'pSeries Hypervisor Virtual Console support' CONFIG_HVC_CONSOLE
fi
+if [ "$CONFIG_ALL_PPC" = "y" ]; then
+ tristate 'Total Impact briQ front panel driver' CONFIG_BRIQ_PANEL
+fi
source drivers/i2c/Config.in
@@ -291,6 +294,7 @@
if [ "$CONFIG_IA64" = "y" ]; then
bool ' HP ZX1 AGP support' CONFIG_AGP_HP_ZX1
fi
+ dep_bool ' Apple UniNorth support' CONFIG_AGP_UNINORTH $CONFIG_ALL_PPC
fi
bool 'Direct Rendering Manager (XFree86 DRI support)' CONFIG_DRM
diff -uNr linux-2.4.20/drivers/char/Makefile linux-2.4.20-ben5/drivers/char/Makefile
--- linux-2.4.20/drivers/char/Makefile 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/Makefile 2003-01-30 11:55:20.000000000 +0100
@@ -232,6 +232,7 @@
obj-$(CONFIG_INTEL_RNG) += i810_rng.o
obj-$(CONFIG_AMD_RNG) += amd768_rng.o
obj-$(CONFIG_AMD_PM768) += amd76x_pm.o
+obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
obj-$(CONFIG_ITE_GPIO) += ite_gpio.o
obj-$(CONFIG_AU1000_GPIO) += au1000_gpio.o
diff -uNr linux-2.4.20/drivers/char/agp/agpgart_be.c linux-2.4.20-ben5/drivers/char/agp/agpgart_be.c
--- linux-2.4.20/drivers/char/agp/agpgart_be.c 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/agp/agpgart_be.c 2003-01-30 11:53:23.000000000 +0100
@@ -44,6 +44,10 @@
#include
#include
+#ifdef CONFIG_AGP_UNINORTH
+#include
+#endif
+
#include
#include "agp.h"
@@ -71,7 +75,7 @@
{
#if defined(__i386__) || defined(__x86_64__)
asm volatile ("wbinvd":::"memory");
-#elif defined(__alpha__) || defined(__ia64__) || defined(__sparc__)
+#elif defined(__alpha__) || defined(__ia64__) || defined(__sparc__) || defined(__powerpc__)
/* ??? I wonder if we'll really need to flush caches, or if the
core logic can manage to keep the system coherent. The ARM
speaks only of using `cflush' to get things in memory in
@@ -4391,6 +4395,437 @@
#endif /* CONFIG_AGP_HP_ZX1 */
+#ifdef CONFIG_AGP_UNINORTH
+
+static int uninorth_fetch_size(void)
+{
+ int i;
+ u32 temp;
+ aper_size_info_32 *values;
+
+ pci_read_config_dword(agp_bridge.dev, UNI_N_CFG_GART_BASE, &temp);
+ temp &= ~(0xfffff000);
+ values = A_SIZE_32(agp_bridge.aperture_sizes);
+
+ for (i = 0; i < agp_bridge.num_aperture_sizes; i++) {
+ if (temp == values[i].size_value) {
+ agp_bridge.previous_size =
+ agp_bridge.current_size = (void *) (values + i);
+ agp_bridge.aperture_size_idx = i;
+ return values[i].size;
+ }
+ }
+
+ agp_bridge.previous_size =
+ agp_bridge.current_size = (void *) (values + 1);
+ agp_bridge.aperture_size_idx = 1;
+ return values[1].size;
+
+ return 0;
+}
+
+static void uninorth_tlbflush(agp_memory * mem)
+{
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_ENABLE);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_2xRESET);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_ENABLE);
+}
+
+static void uninorth_cleanup(void)
+{
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ 0);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ UNI_N_CFG_GART_2xRESET);
+ pci_write_config_dword(agp_bridge.dev, UNI_N_CFG_GART_CTRL,
+ 0);
+}
+
+static int uninorth_configure(void)
+{
+ aper_size_info_32 *current_size;
+
+ current_size = A_SIZE_32(agp_bridge.current_size);
+
+ printk("agp: configuring for size idx: %d\n", current_size->size_value);
+
+ /* aperture size and gatt addr */
+ pci_write_config_dword(agp_bridge.dev,
+ UNI_N_CFG_GART_BASE,
+ (agp_bridge.gatt_bus_addr & 0xfffff000)
+ | current_size->size_value);
+
+ /* HACK ALERT
+ * UniNorth seem to be buggy enough not to handle properly when
+ * the AGP aperture isn't mapped at bus physical address 0
+ */
+ agp_bridge.gart_bus_addr = 0;
+ pci_write_config_dword(agp_bridge.dev,
+ UNI_N_CFG_AGP_BASE, agp_bridge.gart_bus_addr);
+
+ return 0;
+}
+
+static unsigned long uninorth_mask_memory(unsigned long addr, int type)
+{
+ return addr;/* | agp_bridge.masks[0].mask;*/
+}
+
+static int uninorth_insert_memory(agp_memory * mem,
+ off_t pg_start, int type)
+{
+ int i, j, num_entries;
+ void *temp;
+
+ temp = agp_bridge.current_size;
+ num_entries = A_SIZE_32(temp)->num_entries;
+
+ if (type != 0 || mem->type != 0) {
+ /* The generic routines know nothing of memory types */
+ return -EINVAL;
+ }
+ if ((pg_start + mem->page_count) > num_entries) {
+ return -EINVAL;
+ }
+ j = pg_start;
+
+ while (j < (pg_start + mem->page_count)) {
+ if (!PGE_EMPTY(agp_bridge.gatt_table[j])) {
+ return -EBUSY;
+ }
+ j++;
+ }
+
+ if (mem->is_flushed == FALSE) {
+ CACHE_FLUSH();
+ mem->is_flushed = TRUE;
+ }
+ for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
+ agp_bridge.gatt_table[j] = cpu_to_le32((mem->memory[i] & 0xfffff000) | 0x00000001UL);
+ flush_dcache_range(__va(mem->memory[i]), __va(mem->memory[i])+0x1000);
+ }
+ (void)in_le32((volatile u32*)&agp_bridge.gatt_table[pg_start]);
+ mb();
+ flush_dcache_range((unsigned long)&agp_bridge.gatt_table[pg_start],
+ (unsigned long)&agp_bridge.gatt_table[pg_start + mem->page_count]);
+
+ agp_bridge.tlb_flush(mem);
+ return 0;
+}
+
+static void uninorth_agp_enable(u32 mode)
+{
+ struct pci_dev *device = NULL;
+ u32 command, scratch, cap_id;
+ u8 cap_ptr;
+
+ pci_read_config_dword(agp_bridge.dev,
+ agp_bridge.capndx + 4,
+ &command);
+
+ /*
+ * PASS1: go throu all devices that claim to be
+ * AGP devices and collect their data.
+ */
+
+ while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
+ device)) != NULL) {
+ pci_read_config_dword(device, 0x04, &scratch);
+
+ if (!(scratch & 0x00100000))
+ continue;
+
+ pci_read_config_byte(device, 0x34, &cap_ptr);
+
+ if (cap_ptr != 0x00) {
+ do {
+ pci_read_config_dword(device,
+ cap_ptr, &cap_id);
+
+ if ((cap_id & 0xff) != 0x02)
+ cap_ptr = (cap_id >> 8) & 0xff;
+ }
+ while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+ }
+ if (cap_ptr != 0x00) {
+ /*
+ * Ok, here we have a AGP device. Disable impossible
+ * settings, and adjust the readqueue to the minimum.
+ */
+
+ pci_read_config_dword(device, cap_ptr + 4, &scratch);
+
+ /* adjust RQ depth */
+ command =
+ ((command & ~0xff000000) |
+ min_t(u32, (mode & 0xff000000),
+ min_t(u32, (command & 0xff000000),
+ (scratch & 0xff000000))));
+
+ /* disable SBA if it's not supported */
+ if (!((command & 0x00000200) &&
+ (scratch & 0x00000200) &&
+ (mode & 0x00000200)))
+ command &= ~0x00000200;
+
+ /* disable FW if it's not supported */
+ if (!((command & 0x00000010) &&
+ (scratch & 0x00000010) &&
+ (mode & 0x00000010)))
+ command &= ~0x00000010;
+
+ if (!((command & 4) &&
+ (scratch & 4) &&
+ (mode & 4)))
+ command &= ~0x00000004;
+
+ if (!((command & 2) &&
+ (scratch & 2) &&
+ (mode & 2)))
+ command &= ~0x00000002;
+
+ if (!((command & 1) &&
+ (scratch & 1) &&
+ (mode & 1)))
+ command &= ~0x00000001;
+ }
+ }
+ /*
+ * PASS2: Figure out the 4X/2X/1X setting and enable the
+ * target (our motherboard chipset).
+ */
+
+ if (command & 4) {
+ command &= ~3; /* 4X */
+ }
+ if (command & 2) {
+ command &= ~5; /* 2X */
+ }
+ if (command & 1) {
+ command &= ~6; /* 1X */
+ }
+ command |= 0x00000100;
+
+ uninorth_tlbflush(NULL);
+
+ do {
+ pci_write_config_dword(agp_bridge.dev,
+ agp_bridge.capndx + 8,
+ command);
+ pci_read_config_dword(agp_bridge.dev,
+ agp_bridge.capndx + 8,
+ &scratch);
+ } while((scratch & 0x100) == 0);
+
+ /*
+ * PASS3: Go throu all AGP devices and update the
+ * command registers.
+ */
+
+ while ((device = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8,
+ device)) != NULL) {
+ pci_read_config_dword(device, 0x04, &scratch);
+
+ if (!(scratch & 0x00100000))
+ continue;
+
+ pci_read_config_byte(device, 0x34, &cap_ptr);
+
+ if (cap_ptr != 0x00) {
+ do {
+ pci_read_config_dword(device,
+ cap_ptr, &cap_id);
+
+ if ((cap_id & 0xff) != 0x02)
+ cap_ptr = (cap_id >> 8) & 0xff;
+ }
+ while (((cap_id & 0xff) != 0x02) && (cap_ptr != 0x00));
+ }
+ if (cap_ptr != 0x00)
+ pci_write_config_dword(device, cap_ptr + 8, command);
+ }
+
+ uninorth_tlbflush(NULL);
+}
+
+static int uninorth_create_gatt_table(void)
+{
+ char *table;
+ char *table_end;
+ int size;
+ int page_order;
+ int num_entries;
+ int i;
+ void *temp;
+ struct page *page;
+
+ /* The generic routines can't handle 2 level gatt's */
+ if (agp_bridge.size_type == LVL2_APER_SIZE) {
+ return -EINVAL;
+ }
+
+ table = NULL;
+ i = agp_bridge.aperture_size_idx;
+ temp = agp_bridge.current_size;
+ size = page_order = num_entries = 0;
+
+ do {
+ size = A_SIZE_32(temp)->size;
+ page_order = A_SIZE_32(temp)->page_order;
+ num_entries = A_SIZE_32(temp)->num_entries;
+
+ table = (char *) __get_free_pages(GFP_KERNEL, page_order);
+
+ if (table == NULL) {
+ i++;
+ agp_bridge.current_size = A_IDX32();
+ } else {
+ agp_bridge.aperture_size_idx = i;
+ }
+ } while ((table == NULL) &&
+ (i < agp_bridge.num_aperture_sizes));
+
+ if (table == NULL) {
+ return -ENOMEM;
+ }
+ table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+ SetPageReserved(page);
+
+ agp_bridge.gatt_table_real = (unsigned long *) table;
+ agp_bridge.gatt_table = (unsigned long *)table;
+ agp_bridge.gatt_bus_addr = virt_to_phys(table);
+
+ for (i = 0; i < num_entries; i++) {
+ agp_bridge.gatt_table[i] =
+ (unsigned long) agp_bridge.scratch_page;
+ }
+
+ flush_dcache_range((unsigned long)table, (unsigned long)table_end);
+
+ return 0;
+}
+
+static int uninorth_free_gatt_table(void)
+{
+ int page_order;
+ char *table, *table_end;
+ void *temp;
+ struct page *page;
+
+ temp = agp_bridge.current_size;
+ page_order = A_SIZE_32(temp)->page_order;
+
+ /* Do not worry about freeing memory, because if this is
+ * called, then all agp memory is deallocated and removed
+ * from the table.
+ */
+
+ table = (char *) agp_bridge.gatt_table_real;
+ table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
+
+ for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
+ ClearPageReserved(page);
+
+ free_pages((unsigned long) agp_bridge.gatt_table_real, page_order);
+
+ return 0;
+}
+
+static unsigned long uninorth_agp_alloc_page(void)
+{
+ struct page * page;
+
+ page = alloc_page(GFP_KERNEL);
+ if (page == NULL) {
+ return 0;
+ }
+ get_page(page);
+ LockPage(page);
+ SetPageReserved(page);
+ atomic_inc(&agp_bridge.current_memory_agp);
+ return (unsigned long)page_address(page);
+}
+
+static void uninorth_agp_destroy_page(unsigned long addr)
+{
+ void *pt = (void *) addr;
+ struct page *page;
+
+ if (pt == NULL) {
+ return;
+ }
+
+ page = virt_to_page(pt);
+ ClearPageReserved(page);
+ put_page(page);
+ UnlockPage(page);
+ free_page((unsigned long) pt);
+ atomic_dec(&agp_bridge.current_memory_agp);
+}
+
+/* Setup function */
+static gatt_mask uninorth_masks[] =
+{
+ {0x00000000, 0}
+};
+
+static aper_size_info_32 uninorth_sizes[7] =
+{
+#if 0 /* Not sure uninorth supports that high aperture sizes */
+ {256, 65536, 6, 64},
+ {128, 32768, 5, 32},
+ {64, 16384, 4, 16},
+#endif
+ {32, 8192, 3, 8},
+ {16, 4096, 2, 4},
+ {8, 2048, 1, 2},
+ {4, 1024, 0, 1}
+};
+
+static int __init uninorth_setup (struct pci_dev *pdev)
+{
+ agp_bridge.masks = uninorth_masks;
+ agp_bridge.num_of_masks = 1;
+ agp_bridge.aperture_sizes = (void *)uninorth_sizes;
+ agp_bridge.size_type = U32_APER_SIZE;
+ agp_bridge.num_aperture_sizes = 4; //7;
+ agp_bridge.dev_private_data = NULL;
+ agp_bridge.needs_scratch_page = FALSE;
+ agp_bridge.configure = uninorth_configure;
+ agp_bridge.fetch_size = uninorth_fetch_size;
+ agp_bridge.cleanup = uninorth_cleanup;
+ agp_bridge.tlb_flush = uninorth_tlbflush;
+ agp_bridge.mask_memory = uninorth_mask_memory;
+ agp_bridge.agp_enable = uninorth_agp_enable;
+ agp_bridge.cache_flush = global_cache_flush;
+ agp_bridge.create_gatt_table = uninorth_create_gatt_table;
+ agp_bridge.free_gatt_table = uninorth_free_gatt_table;
+ agp_bridge.insert_memory = uninorth_insert_memory;
+ agp_bridge.remove_memory = agp_generic_remove_memory;
+ agp_bridge.alloc_by_type = agp_generic_alloc_by_type;
+ agp_bridge.free_by_type = agp_generic_free_by_type;
+ agp_bridge.agp_alloc_page = uninorth_agp_alloc_page;
+ agp_bridge.agp_destroy_page = uninorth_agp_destroy_page;
+ agp_bridge.suspend = agp_generic_suspend;
+ agp_bridge.resume = agp_generic_resume;
+ agp_bridge.cant_use_aperture = 1;
+
+ return 0;
+
+ (void) pdev; /* unused */
+}
+
+#endif /* CONFIG_AGP_UNINORTH */
+
/* per-chipset initialization data.
* note -- all chipsets for a single vendor MUST be grouped together
*/
@@ -4731,6 +5166,33 @@
hp_zx1_setup },
#endif
+#ifdef CONFIG_AGP_UNINORTH
+ { PCI_DEVICE_ID_APPLE_UNI_N_AGP,
+ PCI_VENDOR_ID_APPLE,
+ APPLE_UNINORTH,
+ "Apple",
+ "UniNorth",
+ uninorth_setup },
+ { PCI_DEVICE_ID_APPLE_UNI_N_AGP_P,
+ PCI_VENDOR_ID_APPLE,
+ APPLE_UNINORTH,
+ "Apple",
+ "UniNorth/Pangea",
+ uninorth_setup },
+ { PCI_DEVICE_ID_APPLE_UNI_N_AGP15,
+ PCI_VENDOR_ID_APPLE,
+ APPLE_UNINORTH,
+ "Apple",
+ "UniNorth 1.5",
+ uninorth_setup },
+ { PCI_DEVICE_ID_APPLE_UNI_N_AGP2,
+ PCI_VENDOR_ID_APPLE,
+ APPLE_UNINORTH,
+ "Apple",
+ "UniNorth 2",
+ uninorth_setup },
+#endif /* CONFIG_AGP_UNINORTH */
+
{ 0, }, /* dummy final entry, always present */
};
diff -uNr linux-2.4.20/drivers/char/briq_panel.c linux-2.4.20-ben5/drivers/char/briq_panel.c
--- linux-2.4.20/drivers/char/briq_panel.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/briq_panel.c 2003-01-30 11:54:17.000000000 +0100
@@ -0,0 +1,251 @@
+/*
+ * Drivers for the Total Impact PPC based computer "BRIQ"
+ * by Dr. Karsten Jeppesen
+ *
+ *
+ * 010407 Coding started
+ *
+ * 04/20/2002 1.1 Adapted to 2.4, small cleanups
+ */
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#define TOTALIMPACT_VFD_MINOR 156
+#define VFD_IOPORT 0x0390
+#define LED_IOPORT 0x0398
+#define TI_VER "1.1 (04/20/2002)"
+#define TI_MSG0 "Loading Linux"
+
+static int vfd_is_open;
+static unsigned char vfd[40];
+static int vfd_cursor;
+static unsigned char ledpb, led;
+
+
+static void UpdateVFD( void )
+{
+ int i;
+ outb(0x02, VFD_IOPORT); /* cursor home */
+ for (i=0; i<20; i++) outb(vfd[i], VFD_IOPORT + 1);
+ outb(0xc0, VFD_IOPORT); /* cursor to next line */
+ for (i=20; i<40; i++) outb(vfd[i], VFD_IOPORT + 1);
+
+}
+
+static void SetLED( char state)
+{
+ if ( state == 'R' ) led = 0x01;
+ else if ( state == 'G' ) led = 0x02;
+ else if ( state == 'Y' ) led = 0x03;
+ else if ( state == 'X' ) led = 0x00;
+ outb(led, LED_IOPORT);
+}
+
+static int do_open(struct inode *ino, struct file *filep)
+{
+ if (vfd_is_open) return -EBUSY;
+ MOD_INC_USE_COUNT;
+ vfd_is_open = 1;
+ return(0);
+}
+
+static int do_release(struct inode *ino, struct file *filep)
+{
+ if (!vfd_is_open) return -ENODEV;
+ MOD_DEC_USE_COUNT;
+ vfd_is_open = 0;
+ return(0);
+}
+
+
+static ssize_t do_read(struct file *file, char *buf, size_t count,
+ loff_t *ppos)
+{
+ unsigned short c;
+ unsigned char cp;
+
+ /* Can't seek (pread) on this device */
+ if (ppos != &file->f_pos) return -ESPIPE;
+ if (!vfd_is_open) return -ENODEV;
+ c = (inb( LED_IOPORT ) & 0x000c) | (ledpb & 0x0003);
+ SetLED(' ');
+ if ((!(ledpb & 0x0004)) && (c & 0x0004))
+ { /* upper button released */
+ cp = ' ';
+ ledpb = c;
+ if (copy_to_user(buf, &cp, 1)) return -EFAULT;
+ return(1);
+ }
+ else if ((!(ledpb & 0x0008)) && (c & 0x0008))
+ { /* lower button released */
+ cp = '\r';
+ ledpb = c;
+ if (copy_to_user(buf, &cp, 1)) return -EFAULT;
+ return(1);
+ } else
+ {
+ ledpb = c;
+ return(0);
+ }
+}
+
+
+static void ScrollVFD( void )
+{
+ int i;
+ for (i=0; i<20; i++)
+ {
+ vfd[i] = vfd[i+20];
+ vfd[i+20] = ' ';
+ }
+ vfd_cursor = 20;
+}
+
+
+static ssize_t do_write(struct file *file, const char *buf, size_t len,
+ loff_t *ppos)
+{
+ size_t indx = len;
+ int i, esc=0;
+ /* Can't seek (pwrite) on this device */
+ if (ppos != &file->f_pos) return -ESPIPE;
+ if (!vfd_is_open) return -EBUSY;
+ for (;;)
+ {
+ if (!indx) break;
+ if (esc)
+ {
+ SetLED(*buf);
+ esc = 0;
+ }
+ else if (*buf == 27)
+ {
+ esc = 1;
+ }
+ else if (*buf == 12)
+ { /* do a form feed */
+ for (i=0; i<40; i++) vfd[i] = ' ';
+ vfd_cursor = 0;
+ }
+ else if (*buf == 10)
+ {
+ if (vfd_cursor < 20) vfd_cursor = 20;
+ else if (vfd_cursor < 40) vfd_cursor = 40;
+ else if (vfd_cursor < 60) vfd_cursor = 60;
+ if (vfd_cursor > 59) ScrollVFD();
+ }
+ else
+ {
+ /* just a character */
+ if (vfd_cursor > 39) ScrollVFD();
+ vfd[vfd_cursor++] = *buf;
+ }
+ indx--;
+ buf++;
+ }
+ UpdateVFD();
+ return len;
+}
+
+
+static struct file_operations vfd_fops = {
+ read: do_read, /* Read */
+ write: do_write, /* Write */
+ open: do_open, /* Open */
+ release: do_release, /* Release */
+};
+
+
+static struct miscdevice ti_vfd_miscdev = {
+ TOTALIMPACT_VFD_MINOR,
+ "vfd",
+ &vfd_fops
+};
+
+
+static int __init briq_panel_init(void)
+{
+ struct device_node *root = find_path_device("/");
+ char *machine;
+ int i;
+
+ machine = get_property(root, "model", NULL);
+ if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0)
+ return -ENODEV;
+
+ printk(KERN_INFO "ti_briq: v%s Dr. Karsten Jeppesen (kj@totalimpact.com)\n", TI_VER);
+
+ if (!request_region( VFD_IOPORT, 4, "BRIQ Front Panel"))
+ return -EBUSY;
+ if (!request_region( LED_IOPORT, 2, "BRIQ Front Panel")) {
+ release_region(VFD_IOPORT, 4);
+ return -EBUSY;
+ }
+ ledpb = inb( LED_IOPORT ) & 0x000c;
+
+ if (misc_register(&ti_vfd_miscdev) < 0) {
+ release_region(VFD_IOPORT, 4);
+ release_region(LED_IOPORT, 2);
+ return -EBUSY;
+ }
+
+ outb(0x38, VFD_IOPORT); /* Function set */
+ outb(0x01, VFD_IOPORT); /* Clear display */
+ outb(0x0c, VFD_IOPORT); /* Display on */
+ outb(0x06, VFD_IOPORT); /* Entry normal */
+ for (i=0; i<40; i++) vfd[i]=' ';
+#ifndef MODULE
+ vfd[0] = 'L';
+ vfd[1] = 'o';
+ vfd[2] = 'a';
+ vfd[3] = 'd';
+ vfd[4] = 'i';
+ vfd[5] = 'n';
+ vfd[6] = 'g';
+ vfd[7] = ' ';
+ vfd[8] = '.';
+ vfd[9] = '.';
+ vfd[10] = '.';
+#endif /* !MODULE */
+ UpdateVFD();
+
+ return 0;
+}
+
+
+static void __exit briq_panel_exit(void)
+{
+ misc_deregister(&ti_vfd_miscdev);
+ release_region(VFD_IOPORT, 4);
+ release_region(LED_IOPORT, 2);
+}
+
+
+module_init(briq_panel_init);
+module_exit(briq_panel_exit);
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Karsten Jeppesen ");
+MODULE_DESCRIPTION("Driver for the Total Impact briQ front panel");
+EXPORT_NO_SYMBOLS;
diff -uNr linux-2.4.20/drivers/char/defkeymap.c linux-2.4.20-ben5/drivers/char/defkeymap.c
--- linux-2.4.20/drivers/char/defkeymap.c 1999-10-07 19:17:09.000000000 +0200
+++ linux-2.4.20-ben5/drivers/char/defkeymap.c 2003-01-30 11:54:25.000000000 +0100
@@ -1,3 +1,4 @@
+
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
@@ -37,7 +38,7 @@
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
@@ -56,7 +57,7 @@
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
@@ -94,7 +95,7 @@
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
@@ -132,7 +133,7 @@
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
- 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
+ 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
@@ -147,6 +148,7 @@
unsigned int keymap_count = 7;
+
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
@@ -184,6 +186,7 @@
'\033', '[', 'P', 0,
};
+
char *funcbufptr = func_buf;
int funcbufsize = sizeof(func_buf);
int funcbufleft = 0; /* space left */
diff -uNr linux-2.4.20/drivers/char/drm/drmP.h linux-2.4.20-ben5/drivers/char/drm/drmP.h
--- linux-2.4.20/drivers/char/drm/drmP.h 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/drmP.h 2003-01-30 11:53:25.000000000 +0100
@@ -324,6 +324,15 @@
DRM(ioremapfree)( (map)->handle, (map)->size ); \
} while (0)
+#define DRM_IOREMAPAGP(map, dev) \
+ (map)->handle = DRM(ioremap_agp)( (map)->offset, (map)->size, (dev) )
+
+#define DRM_IOREMAPAGPFREE(map) \
+ do { \
+ if ( (map)->handle && (map)->size ) \
+ DRM(ioremap_agp_free)( (map)->handle, (map)->size ); \
+ } while (0)
+
#define DRM_FIND_MAP(_map, _o) \
do { \
struct list_head *_list; \
@@ -758,6 +767,9 @@
extern void *DRM(ioremap)(unsigned long offset, unsigned long size);
extern void DRM(ioremapfree)(void *pt, unsigned long size);
+extern void *DRM(ioremap_agp)(unsigned long offset, unsigned long size, drm_device_t *dev);
+extern void DRM(ioremap_agp_free)(void *pt, unsigned long size);
+
#if __REALLY_HAVE_AGP
extern agp_memory *DRM(alloc_agp)(int pages, u32 type);
extern int DRM(free_agp)(agp_memory *handle, int pages);
diff -uNr linux-2.4.20/drivers/char/drm/drm_memory.h linux-2.4.20-ben5/drivers/char/drm/drm_memory.h
--- linux-2.4.20/drivers/char/drm/drm_memory.h 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/drm_memory.h 2003-01-30 11:54:08.000000000 +0100
@@ -313,6 +313,107 @@
return pt;
}
+/* PPC specific routine used by ioremap_agp, to be replaced by some
+ * more generic implementation
+ */
+extern int map_page(unsigned long va, unsigned long pa, int flags);
+
+void *DRM(ioremap_agp)(unsigned long offset, unsigned long size, drm_device_t *dev)
+{
+ void *pt;
+ struct vm_struct *area;
+ struct drm_agp_mem *agpmem;
+ unsigned int flags = _PAGE_NO_CACHE|_PAGE_KERNEL|_PAGE_PRESENT|_PAGE_RW|_PAGE_DIRTY;
+ int err, i;
+
+ printk("drm: ioremap_agp, offset: 0x%08lx, size: 0x%08lx\n", offset, size);
+
+#if __REALLY_HAVE_AGP
+ if (!size) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Mapping 0 bytes at 0x%08lx\n", offset);
+ return NULL;
+ }
+
+ if (!dev->agp || !dev->agp->cant_use_aperture)
+ return DRM(ioremap)(offset, size);
+
+ /* XXX This has to be changed into something more generic
+ * this implementation is really only valid on PPC
+ */
+ area = get_vm_area(size, VM_IOREMAP);
+ if (area == 0) {
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ printk("->NULL\n");
+ return NULL;
+ }
+ pt = (void *)VMALLOC_VMADDR(area->addr);
+ err = 0;
+ for (i = 0; i < size && err == 0; i += PAGE_SIZE) {
+ unsigned long baddr = offset + i;
+ unsigned long index;
+
+ /*
+ * It's AGP memory - find the real physical page to map
+ */
+ for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
+ if (agpmem->bound <= baddr &&
+ agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
+ break;
+ }
+ if (!agpmem) {
+ printk("drm: not matching AGP page in ioremap_agp\n");
+ err = 1;
+ break;
+ }
+ index = (baddr - agpmem->bound) >> PAGE_SHIFT;
+ err = map_page(((unsigned long)pt)+i, agpmem->memory->memory[index], flags);
+ }
+ if (err) {
+ vfree((void *)pt);
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
+ spin_unlock(&DRM(mem_lock));
+ printk("->NULL\n");
+ return NULL;
+ }
+
+ spin_lock(&DRM(mem_lock));
+ ++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
+ spin_unlock(&DRM(mem_lock));
+ printk("->pt=0x%p\n", pt);
+ return pt;
+#else
+ return NULL;
+#endif
+}
+
+void DRM(ioremap_agp_free)(void *pt, unsigned long size)
+{
+ int alloc_count;
+ int free_count;
+
+ if (!pt)
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Attempt to free NULL pointer\n");
+ else
+ vfree(pt);
+
+ spin_lock(&DRM(mem_lock));
+ DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
+ free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
+ alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
+ spin_unlock(&DRM(mem_lock));
+ if (free_count > alloc_count) {
+ DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
+ "Excess frees: %d frees, %d allocs\n",
+ free_count, alloc_count);
+ }
+}
+
void DRM(ioremapfree)(void *pt, unsigned long size)
{
int alloc_count;
diff -uNr linux-2.4.20/drivers/char/drm/drm_vm.h linux-2.4.20-ben5/drivers/char/drm/drm_vm.h
--- linux-2.4.20/drivers/char/drm/drm_vm.h 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/drm_vm.h 2003-01-30 11:56:02.000000000 +0100
@@ -379,7 +379,13 @@
if ( !priv->authenticated ) return -EACCES;
- if (!VM_OFFSET(vma)) return DRM(mmap_dma)(filp, vma);
+ /* We check for "dma". On Apple's UniNorth, it's valid to have
+ * the AGP mapped at physical address 0
+ * --BenH.
+ */
+ if (!VM_OFFSET(vma) && (!dev->agp ||
+ dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE))
+ return DRM(mmap_dma)(filp, vma);
/* A sequential search of a linked list is
fine here because: 1) there will only be
@@ -419,16 +425,22 @@
switch (map->type) {
case _DRM_AGP:
-#if defined(__alpha__)
- /*
- * On Alpha we can't talk to bus dma address from the
- * CPU, so for memory of type DRM_AGP, we'll deal with
- * sorting out the real physical pages and mappings
- * in nopage()
- */
- vma->vm_ops = &DRM(vm_ops);
- break;
+ if (!dev->agp)
+ return -ENODEV;
+ if (dev->agp->cant_use_aperture) {
+ /*
+ * On Alpha we can't talk to bus dma address from the
+ * CPU, so for memory of type DRM_AGP, we'll deal with
+ * sorting out the real physical pages and mappings
+ * in nopage()
+ */
+#if defined(__powerpc__)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
#endif
+ vma->vm_flags |= VM_IO;
+ vma->vm_ops = &DRM(vm_ops);
+ break;
+ }
/* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
diff -uNr linux-2.4.20/drivers/char/drm/r128_cce.c linux-2.4.20-ben5/drivers/char/drm/r128_cce.c
--- linux-2.4.20/drivers/char/drm/r128_cce.c 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/r128_cce.c 2003-01-30 11:52:46.000000000 +0100
@@ -37,6 +37,10 @@
#define R128_FIFO_DEBUG 0
+#if __REALLY_HAVE_AGP && defined(CONFIG_ALL_PPC)
+extern unsigned long agp_special_page;
+#endif
+
/* CCE microcode (from ATI) */
static u32 r128_cce_microcode[] = {
@@ -340,6 +344,14 @@
SET_RING_HEAD( &dev_priv->ring, 0 );
if ( !dev_priv->is_pci ) {
+#if __REALLY_HAVE_AGP && defined(CONFIG_ALL_PPC)
+ if (_machine == _MACH_Pmac) {
+ dev_priv->ring.head = (__volatile__ u32 *) agp_special_page;
+ SET_RING_HEAD( &dev_priv->ring, 0 );
+ R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
+ __pa( dev_priv->ring.head ) );
+ } else
+#endif
R128_WRITE( R128_PM4_BUFFER_DL_RPTR_ADDR,
dev_priv->ring_rptr->offset );
} else {
@@ -549,9 +561,9 @@
init->sarea_priv_offset);
if ( !dev_priv->is_pci ) {
- DRM_IOREMAP( dev_priv->cce_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAPAGP( dev_priv->cce_ring, dev );
+ DRM_IOREMAPAGP( dev_priv->ring_rptr, dev );
+ DRM_IOREMAPAGP( dev_priv->buffers, dev );
if(!dev_priv->cce_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev_priv->buffers->handle) {
@@ -623,10 +635,11 @@
drm_r128_private_t *dev_priv = dev->dev_private;
if ( !dev_priv->is_pci ) {
- DRM_IOREMAPFREE( dev_priv->cce_ring );
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
- DRM_IOREMAPFREE( dev_priv->buffers );
- } else {
+ DRM_IOREMAPAGPFREE( dev_priv->cce_ring );
+ DRM_IOREMAPAGPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPAGPFREE( dev_priv->buffers );
+ }
+ else {
if (!DRM(ati_pcigart_cleanup)( dev,
dev_priv->phys_pci_gart,
dev_priv->bus_pci_gart ))
diff -uNr linux-2.4.20/drivers/char/drm/r128_drv.h linux-2.4.20-ben5/drivers/char/drm/r128_drv.h
--- linux-2.4.20/drivers/char/drm/r128_drv.h 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/r128_drv.h 2003-01-30 11:55:41.000000000 +0100
@@ -34,8 +34,13 @@
#ifndef __R128_DRV_H__
#define __R128_DRV_H__
+#ifdef __powerpc__
+#define GET_RING_HEAD( ring ) in_le32((volatile u32 *)(ring)->head)
+#define SET_RING_HEAD( ring, val ) out_le32((volatile u32 *)(ring)->head, (val) )
+#else
#define GET_RING_HEAD( ring ) le32_to_cpu( *(ring)->head )
#define SET_RING_HEAD( ring, val ) *(ring)->head = cpu_to_le32( val )
+#endif
typedef struct drm_r128_freelist {
unsigned int age;
@@ -397,6 +402,9 @@
wmb(); \
R128_DEREF(reg) = val; \
} while (0)
+#elif defined (__powerpc__)
+#define R128_READ(reg) in_le32( (volatile u32 *)R128_ADDR( reg ) )
+#define R128_WRITE(reg,val) out_le32( (volatile u32 *)R128_ADDR( reg ), (val) )
#else
#define R128_READ(reg) le32_to_cpu( R128_DEREF( reg ) )
#define R128_WRITE(reg,val) \
@@ -418,6 +426,9 @@
wmb(); \
R128_DEREF8(reg) = val; \
} while (0)
+#elif defined (__powerpc__)
+#define R128_READ8(reg) in_8( (volatile u8 *)R128_ADDR(reg) )
+#define R128_WRITE8(reg,val) out_8( (volatile u8 *)R128_ADDR(reg), val )
#else
#define R128_READ8(reg) R128_DEREF8( reg )
#define R128_WRITE8(reg,val) do { R128_DEREF8( reg ) = val; } while (0)
@@ -493,8 +504,11 @@
* Ring control
*/
+#ifdef __powerpc__
+#define r128_flush_write_combine() (void)in_le32(ring)
+#else
#define r128_flush_write_combine() mb()
-
+#endif
#define R128_VERBOSE 0
diff -uNr linux-2.4.20/drivers/char/drm/radeon_cp.c linux-2.4.20-ben5/drivers/char/drm/radeon_cp.c
--- linux-2.4.20/drivers/char/drm/radeon_cp.c 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/radeon_cp.c 2003-01-30 11:55:29.000000000 +0100
@@ -37,12 +37,15 @@
#define RADEON_FIFO_DEBUG 0
-#if defined(__alpha__)
+#if defined(__alpha__) || defined(__powerpc__)
# define PCIGART_ENABLED
#else
# undef PCIGART_ENABLED
#endif
+#if __REALLY_HAVE_AGP && defined(CONFIG_ALL_PPC)
+extern unsigned long agp_special_page;
+#endif
/* CP microcode (from ATI) */
static u32 radeon_cp_microcode[][2] = {
@@ -313,7 +316,7 @@
return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
}
-#if RADEON_FIFO_DEBUG
+#if 1 /* RADEON_FIFO_DEBUG */
static void radeon_status( drm_radeon_private_t *dev_priv )
{
printk( "%s:\n", __FUNCTION__ );
@@ -400,7 +403,8 @@
udelay( 1 );
}
-#if RADEON_FIFO_DEBUG
+#if 1 /* RADEON_FIFO_DEBUG */
+ printk("wait_for_idle timeout\n");
DRM_ERROR( "failed!\n" );
radeon_status( dev_priv );
#endif
@@ -611,6 +615,14 @@
dev_priv->ring.tail = cur_read_ptr;
if ( !dev_priv->is_pci ) {
+#if __REALLY_HAVE_AGP && defined(CONFIG_ALL_PPC)
+ if (_machine == _MACH_Pmac) {
+ dev_priv->ring.head = (__volatile__ u32 *) agp_special_page;
+ *dev_priv->ring.head = cur_read_ptr;
+ RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
+ __pa( dev_priv->ring.head ) );
+ } else
+#endif
RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR,
dev_priv->ring_rptr->offset );
} else {
@@ -835,9 +847,9 @@
init->sarea_priv_offset);
if ( !dev_priv->is_pci ) {
- DRM_IOREMAP( dev_priv->cp_ring );
- DRM_IOREMAP( dev_priv->ring_rptr );
- DRM_IOREMAP( dev_priv->buffers );
+ DRM_IOREMAPAGP( dev_priv->cp_ring, dev );
+ DRM_IOREMAPAGP( dev_priv->ring_rptr, dev );
+ DRM_IOREMAPAGP( dev_priv->buffers, dev );
if(!dev_priv->cp_ring->handle ||
!dev_priv->ring_rptr->handle ||
!dev_priv->buffers->handle) {
@@ -982,9 +994,9 @@
drm_radeon_private_t *dev_priv = dev->dev_private;
if ( !dev_priv->is_pci ) {
- DRM_IOREMAPFREE( dev_priv->cp_ring );
- DRM_IOREMAPFREE( dev_priv->ring_rptr );
- DRM_IOREMAPFREE( dev_priv->buffers );
+ DRM_IOREMAPAGPFREE( dev_priv->cp_ring );
+ DRM_IOREMAPAGPFREE( dev_priv->ring_rptr );
+ DRM_IOREMAPAGPFREE( dev_priv->buffers );
} else {
if (!DRM(ati_pcigart_cleanup)( dev,
dev_priv->phys_pci_gart,
@@ -1351,14 +1363,15 @@
int i;
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
- radeon_update_ring_snapshot( ring );
+ radeon_update_ring_snapshot( dev_priv, ring );
if ( ring->space > n )
return 0;
udelay( 1 );
}
/* FIXME: This return value is ignored in the BEGIN_RING macro! */
-#if RADEON_FIFO_DEBUG
+#if 1 /* RADEON_FIFO_DEBUG */
+ printk("wait ring timeout\n");
radeon_status( dev_priv );
DRM_ERROR( "failed!\n" );
#endif
diff -uNr linux-2.4.20/drivers/char/drm/radeon_drv.h linux-2.4.20-ben5/drivers/char/drm/radeon_drv.h
--- linux-2.4.20/drivers/char/drm/radeon_drv.h 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/radeon_drv.h 2003-01-30 11:53:03.000000000 +0100
@@ -31,6 +31,14 @@
#ifndef __RADEON_DRV_H__
#define __RADEON_DRV_H__
+#if defined(__powerpc__)
+#define GET_RING_HEAD(ring) in_le32((volatile u32 *)(ring)->head)
+#define SET_RING_HEAD(ring,val) out_le32((volatile u32 *)(ring)->head, (val))
+#else
+#define GET_RING_HEAD(ring) le32_to_cpu(*(ring)->head)
+#define SET_RING_HEAD(ring,val) *(ring)->head = cpu_to_le32(val)
+#endif
+
typedef struct drm_radeon_freelist {
unsigned int age;
drm_buf_t *buf;
@@ -150,12 +158,7 @@
extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n );
static inline void
-radeon_update_ring_snapshot( drm_radeon_ring_buffer_t *ring )
-{
- ring->space = (*(volatile int *)ring->head - ring->tail) * sizeof(u32);
- if ( ring->space <= 0 )
- ring->space += ring->size;
-}
+radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv, drm_radeon_ring_buffer_t *ring );
extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv );
extern int radeon_do_cleanup_cp( drm_device_t *dev );
@@ -539,6 +542,9 @@
wmb(); \
RADEON_DEREF(reg) = val; \
} while (0)
+#elif defined(__powerpc__)
+#define RADEON_READ(reg) in_le32((volatile u32 *)RADEON_ADDR(reg))
+#define RADEON_WRITE(reg,val) out_le32((volatile u32 *)RADEON_ADDR(reg), (val))
#else
#define RADEON_READ(reg) RADEON_DEREF( reg )
#define RADEON_WRITE(reg, val) do { RADEON_DEREF( reg ) = val; } while (0)
@@ -557,6 +563,9 @@
wmb(); \
RADEON_DEREF8( reg ) = val; \
} while (0)
+#elif defined(__powerpc__)
+#define RADEON_READ8(reg) in_8((volatile u8 *)RADEON_ADDR(reg))
+#define RADEON_WRITE8(reg,val) out_8((volatile u8 *)RADEON_ADDR(reg), (val))
#else
#define RADEON_READ8(reg) RADEON_DEREF8( reg )
#define RADEON_WRITE8(reg, val) do { RADEON_DEREF8( reg ) = val; } while (0)
@@ -652,7 +661,7 @@
drm_radeon_ring_buffer_t *ring = &dev_priv->ring; int i; \
if ( ring->space < ring->high_mark ) { \
for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \
- radeon_update_ring_snapshot( ring ); \
+ radeon_update_ring_snapshot( dev_priv, ring ); \
if ( ring->space >= ring->high_mark ) \
goto __ring_space_done; \
udelay( 1 ); \
@@ -694,12 +703,28 @@
* Ring control
*/
+#if defined(__powerpc__)
+#define radeon_flush_write_combine() do { mb(); (void)in_le32(ring); mb(); } while(0)
+#else
#define radeon_flush_write_combine() mb()
-
+#endif
#define RADEON_VERBOSE 0
+#define RADEON_DEBUG
+#ifdef RADEON_DEBUG
+#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; int dbg;
+#define DEBUG_INIT(n) dbg = n
+#define DEBUG_INC() do { if (dbg <= 0) printk("Argh 1 ! (%s:%d)\n", __FILE__, __LINE__); \
+ dbg--; } while(0)
+#define DEBUG_END() do { if (dbg != 0) printk("Argh 2/%d ! (%s:%d)\n", dbg, __FILE__, __LINE__); \
+ dbg--; } while(0)
+#else
#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring;
+#define DEBUG_INIT()
+#define DEBUG_INC()
+#define DEBUG_END()
+#endif
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
@@ -713,6 +738,7 @@
ring = dev_priv->ring.start; \
write = dev_priv->ring.tail; \
mask = dev_priv->ring.tail_mask; \
+ DEBUG_INIT(n); \
} while (0)
#define ADVANCE_RING() do { \
@@ -720,6 +746,7 @@
DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
write, dev_priv->ring.tail ); \
} \
+ DEBUG_END(); \
radeon_flush_write_combine(); \
dev_priv->ring.tail = write; \
RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \
@@ -730,10 +757,20 @@
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), write ); \
} \
- ring[write++] = (x); \
+ DEBUG_INC(); \
+ ring[write++] = cpu_to_le32(x); \
write &= mask; \
} while (0)
#define RADEON_PERFORMANCE_BOXES 0
+static inline void
+radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv, drm_radeon_ring_buffer_t *ring )
+{
+// ring->space = (GET_RING_HEAD(ring) - ring->tail) * sizeof(u32);
+ ring->space = (RADEON_READ(0x710) - ring->tail) * sizeof(u32);
+ if ( ring->space <= 0 )
+ ring->space += ring->size;
+}
+
#endif /* __RADEON_DRV_H__ */
diff -uNr linux-2.4.20/drivers/char/drm/radeon_state.c linux-2.4.20-ben5/drivers/char/drm/radeon_state.c
--- linux-2.4.20/drivers/char/drm/radeon_state.c 2002-11-29 00:53:12.000000000 +0100
+++ linux-2.4.20-ben5/drivers/char/drm/radeon_state.c 2003-01-30 11:55:27.000000000 +0100
@@ -849,7 +849,7 @@
u32 *data = (u32 *)
((char *)dev_priv->buffers->handle
+ buf->offset + start);
- data[dwords++] = RADEON_CP_PACKET2;
+ data[dwords++] = cpu_to_le32(RADEON_CP_PACKET2);
}
buf_priv->dispatched = 1;
@@ -913,18 +913,22 @@
data = (u32 *)((char *)dev_priv->buffers->handle
+ buf->offset + start);
- data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 );
+ data[0] = cpu_to_le32(CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ));
- data[1] = offset;
- data[2] = RADEON_MAX_VB_VERTS;
- data[3] = format;
- data[4] = (prim | RADEON_PRIM_WALK_IND |
+ data[1] = cpu_to_le32(offset);
+ data[2] = cpu_to_le32(RADEON_MAX_VB_VERTS);
+ data[3] = cpu_to_le32(format);
+ data[4] = cpu_to_le32((prim | RADEON_PRIM_WALK_IND |
RADEON_COLOR_ORDER_RGBA |
RADEON_VTX_FMT_RADEON_MODE |
- (count << RADEON_NUM_VERTICES_SHIFT) );
+ (count << RADEON_NUM_VERTICES_SHIFT) ));
if ( count & 0x1 ) {
+#ifdef __LITTLE_ENDIAN
data[dwords-1] &= 0x0000ffff;
+#else
+ data[dwords-1] &= 0xffff0000;
+#endif
}
do {
@@ -1067,22 +1071,22 @@
*/
buffer = (u32 *)((char *)dev_priv->buffers->handle + buf->offset);
- buffer[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 );
- buffer[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL |
+ buffer[0] = cpu_to_le32(CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ));
+ buffer[1] = cpu_to_le32((RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_BRUSH_NONE |
(format << 8) |
RADEON_GMC_SRC_DATATYPE_COLOR |
RADEON_ROP3_S |
RADEON_DP_SRC_SOURCE_HOST_DATA |
RADEON_GMC_CLR_CMP_CNTL_DIS |
- RADEON_GMC_WR_MSK_DIS);
+ RADEON_GMC_WR_MSK_DIS));
- buffer[2] = (tex->pitch << 22) | (tex->offset >> 10);
- buffer[3] = 0xffffffff;
- buffer[4] = 0xffffffff;
- buffer[5] = (y << 16) | image->x;
- buffer[6] = (height << 16) | image->width;
- buffer[7] = dwords;
+ buffer[2] = cpu_to_le32((tex->pitch << 22) | (tex->offset >> 10));
+ buffer[3] = cpu_to_le32(0xffffffff);
+ buffer[4] = cpu_to_le32(0xffffffff);
+ buffer[5] = cpu_to_le32((y << 16) | image->x);
+ buffer[6] = cpu_to_le32((height << 16) | image->width);
+ buffer[7] = cpu_to_le32(dwords);
buffer += 8;
diff -uNr linux-2.4.20/drivers/i2c/i2c-keywest.c linux-2.4.20-ben5/drivers/i2c/i2c-keywest.c
--- linux-2.4.20/drivers/i2c/i2c-keywest.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/i2c/i2c-keywest.c 2003-01-30 11:53:00.000000000 +0100
@@ -256,6 +256,7 @@
len = 1;
buffer = &data->byte;
iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+ //iface->cur_mode |= KW_I2C_MODE_COMBINED;
break;
case I2C_SMBUS_WORD_DATA:
len = 2;
@@ -267,6 +268,7 @@
len = data->block[0];
buffer = &data->block[1];
iface->cur_mode |= KW_I2C_MODE_STANDARDSUB;
+ //iface->cur_mode |= KW_I2C_MODE_COMBINED;
break;
default:
return -1;
diff -uNr linux-2.4.20/drivers/ide/aec62xx.c linux-2.4.20-ben5/drivers/ide/aec62xx.c
--- linux-2.4.20/drivers/ide/aec62xx.c 2000-06-20 16:52:36.000000000 +0200
+++ linux-2.4.20-ben5/drivers/ide/aec62xx.c 2003-01-30 11:54:50.000000000 +0100
@@ -51,6 +51,21 @@
extern char *ide_media_verbose(ide_drive_t *);
static struct pci_dev *bmide_dev;
+static const char *aec6280_get_speed(u8 speed)
+{
+ switch(speed) {
+ case 7: return "6";
+ case 6: return "5";
+ case 5: return "4";
+ case 4: return "3";
+ case 3: return "2";
+ case 2: return "1";
+ case 1: return "0";
+ case 0: return "?";
+ }
+ return "?";
+}
+
static int aec62xx_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
@@ -69,6 +84,12 @@
case PCI_DEVICE_ID_ARTOP_ATP860R:
p += sprintf(p, "\n AEC6260 Chipset.\n");
break;
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ p += sprintf(p, "\n AEC6280 Chipset without ROM.\n");
+ break;
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
+ p += sprintf(p, "\n AEC6280 Chipset with ROM.\n");
+ break;
default:
p += sprintf(p, "\n AEC62?? Chipset.\n");
break;
@@ -153,6 +174,41 @@
(void) pci_read_config_byte(bmide_dev, 0x4a, &uart);
p += sprintf(p, "reg4ah = 0x%02x\n", uart);
break;
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
+ (void) pci_read_config_byte(bmide_dev, 0x44, &art);
+ p += sprintf(p, "DMA Mode: %s(%s) %s(%s)",
+ (c0&0x20)?((art&0x0f)?"UDMA":" DMA"):" PIO",
+ aec6280_get_speed(art&0x0f),
+ (c0&0x40)?((art&0xf0)?"UDMA":" DMA"):" PIO",
+ aec6280_get_speed(art>>4));
+ (void) pci_read_config_byte(bmide_dev, 0x45, &art);
+ p += sprintf(p, " %s(%s) %s(%s)\n",
+ (c0&0x20)?((art&0x0f)?"UDMA":" DMA"):" PIO",
+ aec6280_get_speed(art&0x0f),
+ (c0&0x40)?((art&0xf0)?"UDMA":" DMA"):" PIO",
+ aec6280_get_speed(art>>4));
+ (void) pci_read_config_byte(bmide_dev, 0x40, &art);
+ p += sprintf(p, "Active: 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x41, &art);
+ p += sprintf(p, " 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x42, &art);
+ p += sprintf(p, " 0x%02x", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x43, &art);
+ p += sprintf(p, " 0x%02x\n", HIGH_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x40, &art);
+ p += sprintf(p, "Recovery: 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x41, &art);
+ p += sprintf(p, " 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x42, &art);
+ p += sprintf(p, " 0x%02x", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x43, &art);
+ p += sprintf(p, " 0x%02x\n", LOW_4(art));
+ (void) pci_read_config_byte(bmide_dev, 0x49, &uart);
+ p += sprintf(p, "reg49h = 0x%02x ", uart);
+ (void) pci_read_config_byte(bmide_dev, 0x4a, &uart);
+ p += sprintf(p, "reg4ah = 0x%02x\n", uart);
+ break;
default:
break;
}
@@ -177,6 +233,8 @@
struct chipset_bus_clock_list_entry aec62xx_base [] = {
#ifdef CONFIG_BLK_DEV_IDEDMA
+ { XFER_UDMA_6, 0x41, 0x06, 0x31, 0x07 },
+ { XFER_UDMA_5, 0x41, 0x05, 0x31, 0x06 },
{ XFER_UDMA_4, 0x41, 0x04, 0x31, 0x05 },
{ XFER_UDMA_3, 0x41, 0x03, 0x31, 0x04 },
{ XFER_UDMA_2, 0x41, 0x02, 0x31, 0x03 },
@@ -399,6 +457,58 @@
ide_dma_off_quietly);
}
+static int config_aec6280_chipset_for_dma (ide_drive_t *drive, byte ultra)
+{
+ struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+ byte unit = (drive->select.b.unit & 0x01);
+ unsigned long dma_base = hwif->dma_base;
+ byte speed = -1;
+ byte ultra66 = eighty_ninty_three(drive);
+
+ if (drive->media != ide_disk)
+ return ((int) ide_dma_off_quietly);
+
+ if ((id->dma_ultra & 0x0040) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_6;
+ } else if ((id->dma_ultra & 0x0020) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_5;
+ } else if ((id->dma_ultra & 0x0010) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_4;
+ } else if ((id->dma_ultra & 0x0008) && (ultra) && (ultra66)) {
+ speed = XFER_UDMA_3;
+ } else if ((id->dma_ultra & 0x0004) && (ultra)) {
+ speed = XFER_UDMA_2;
+ } else if ((id->dma_ultra & 0x0002) && (ultra)) {
+ speed = XFER_UDMA_1;
+ } else if ((id->dma_ultra & 0x0001) && (ultra)) {
+ speed = XFER_UDMA_0;
+ } else if (id->dma_mword & 0x0004) {
+ speed = XFER_MW_DMA_2;
+ } else if (id->dma_mword & 0x0002) {
+ speed = XFER_MW_DMA_1;
+ } else if (id->dma_mword & 0x0001) {
+ speed = XFER_MW_DMA_0;
+ } else if (id->dma_1word & 0x0004) {
+ speed = XFER_SW_DMA_2;
+ } else if (id->dma_1word & 0x0002) {
+ speed = XFER_SW_DMA_1;
+ } else if (id->dma_1word & 0x0001) {
+ speed = XFER_SW_DMA_0;
+ } else {
+ return ((int) ide_dma_off_quietly);
+ }
+
+ outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
+ (void) aec6260_tune_chipset(drive, speed);
+
+ return ((int) ((id->dma_ultra >> 11) & 3) ? ide_dma_on :
+ ((id->dma_ultra >> 8) & 7) ? ide_dma_on :
+ ((id->dma_mword >> 8) & 7) ? ide_dma_on :
+ ((id->dma_1word >> 8) & 7) ? ide_dma_on :
+ ide_dma_off_quietly);
+}
+
static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
{
switch(HWIF(drive)->pci_dev->device) {
@@ -407,6 +517,9 @@
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
return config_aec6260_chipset_for_dma(drive, ultra);
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
+ return config_aec6260_chipset_for_dma(drive, ultra);
default:
return ((int) ide_dma_off_quietly);
}
@@ -433,6 +546,8 @@
(void) aec6210_tune_chipset(drive, speed);
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
(void) aec6260_tune_chipset(drive, speed);
default:
break;
@@ -551,6 +666,31 @@
void __init ide_init_aec62xx (ide_hwif_t *hwif)
{
+ byte reg49h = 0;
+ byte reg4ah = 0;
+
+ switch(hwif->pci_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
+ /* Clear reset and test bits. */
+ pci_read_config_byte(hwif->pci_dev, 0x49, ®49h);
+ pci_write_config_byte(hwif->pci_dev, 0x49, reg49h & ~0x30);
+ /* Enable chip interrupt output. */
+ pci_read_config_byte(hwif->pci_dev, 0x4a, ®4ah);
+ pci_write_config_byte(hwif->pci_dev, 0x4a, reg4ah & ~0x01);
+#define CONFIG_AEC6280_BURST
+#ifdef CONFIG_AEC6280_BURST
+ /* Must be greater than 0x80 for burst mode. */
+ pci_write_config_byte(hwif->pci_dev, PCI_LATENCY_TIMER, 0x90);
+ /* Enable burst mode. */
+ pci_read_config_byte(hwif->pci_dev, 0x4a, ®4ah);
+ pci_write_config_byte(hwif->pci_dev, 0x4a, reg4ah | 0x80);
+#endif
+ break;
+ default:
+ break;
+ }
+
#ifdef CONFIG_AEC62XX_TUNING
hwif->tuneproc = &aec62xx_tune_drive;
hwif->speedproc = &aec62xx_tune_chipset;
@@ -570,13 +710,20 @@
unsigned long flags;
byte reg54h = 0;
- __save_flags(flags); /* local CPU only */
- __cli(); /* local CPU only */
+ switch(hwif->pci_dev->device) {
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
+ break;
+ default:
+ __save_flags(flags); /* local CPU only */
+ __cli(); /* local CPU only */
- pci_read_config_byte(hwif->pci_dev, 0x54, ®54h);
- pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F));
+ pci_read_config_byte(hwif->pci_dev, 0x54, ®54h);
+ pci_write_config_byte(hwif->pci_dev, 0x54, reg54h & ~(hwif->channel ? 0xF0 : 0x0F));
- __restore_flags(flags); /* local CPU only */
+ __restore_flags(flags); /* local CPU only */
+ break;
+ }
#endif /* CONFIG_AEC62XX_TUNING */
ide_setup_dma(hwif, dmabase, 8);
}
diff -uNr linux-2.4.20/drivers/ide/ide-cs.c linux-2.4.20-ben5/drivers/ide/ide-cs.c
--- linux-2.4.20/drivers/ide/ide-cs.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-cs.c 2003-01-30 11:54:02.000000000 +0100
@@ -92,10 +92,12 @@
int ndev;
dev_node_t node;
int hd;
+ struct tq_struct rel_task;
} ide_info_t;
static void ide_config(dev_link_t *link);
-static void ide_release(u_long arg);
+static void ide_release(void *arg);
+static void ide_release_tm(ulong arg);
static int ide_event(event_t event, int priority,
event_callback_args_t *args);
@@ -136,8 +138,8 @@
if (!info) return NULL;
memset(info, 0, sizeof(*info));
link = &info->link; link->priv = info;
-
- link->release.function = &ide_release;
+ INIT_TQUEUE(&info->rel_task, ide_release, link);
+ link->release.function = &ide_release_tm;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
@@ -198,6 +200,7 @@
return;
del_timer(&link->release);
+ flush_scheduled_tasks();
if (link->state & DEV_CONFIG)
ide_release((u_long)link);
@@ -381,7 +384,7 @@
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
- ide_release((u_long)link);
+ ide_release(link);
} /* ide_config */
@@ -393,12 +396,24 @@
======================================================================*/
-void ide_release(u_long arg)
+static void ide_release_tm(ulong arg)
{
- dev_link_t *link = (dev_link_t *)arg;
+ dev_link_t *link = arg;
+ ide_info_t *info = link->priv;
+
+ if (link->state & DEV_CONFIG)
+ schedule_task(&info->rel_task);
+}
+
+static void ide_release(void *arg)
+{
+ dev_link_t *link = arg;
ide_info_t *info = link->priv;
- DEBUG(0, "ide_release(0x%p)\n", link);
+ if (!(link->state & DEV_CONFIG))
+ return;
+
+ DEBUG(0, "ide_do_release(0x%p)\n", link);
if (info->ndev) {
ide_unregister(info->hd);
diff -uNr linux-2.4.20/drivers/ide/ide-disk.c linux-2.4.20-ben5/drivers/ide/ide-disk.c
--- linux-2.4.20/drivers/ide/ide-disk.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-disk.c 2003-01-30 11:53:05.000000000 +0100
@@ -1286,6 +1286,9 @@
{
drive->addressing = 0;
+ if (HWIF(drive)->addressing)
+ return 0;
+
if (!(drive->id->cfs_enable_2 & 0x0400))
return -EIO;
diff -uNr linux-2.4.20/drivers/ide/ide-dma.c linux-2.4.20-ben5/drivers/ide/ide-dma.c
--- linux-2.4.20/drivers/ide/ide-dma.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-dma.c 2003-01-30 11:54:01.000000000 +0100
@@ -266,11 +266,21 @@
bh = rq->bh;
do {
struct scatterlist *sge;
+ int contig = 0;
+
+ if (bh->b_page) {
+ if (bh_phys(bh) == lastdataend)
+ contig = 1;
+ } else {
+ if ((unsigned long) bh->b_data == lastdataend)
+ contig = 1;
+ }
+
/*
* continue segment from before?
*/
- if (bh_phys(bh) == lastdataend) {
+ if (contig) {
sg[nents - 1].length += bh->b_size;
lastdataend += bh->b_size;
continue;
@@ -288,15 +298,16 @@
if (bh->b_page) {
sge->page = bh->b_page;
sge->offset = bh_offset(bh);
+ lastdataend = bh_phys(bh) + bh->b_size;
} else {
- if (((unsigned long) bh->b_data) < PAGE_SIZE)
+ if ((unsigned long) bh->b_data < PAGE_SIZE)
BUG();
sge->address = bh->b_data;
+ lastdataend = (unsigned long) bh->b_data + bh->b_size;
}
sge->length = bh->b_size;
- lastdataend = bh_phys(bh) + bh->b_size;
nents++;
} while ((bh = bh->b_reqnext) != NULL);
diff -uNr linux-2.4.20/drivers/ide/ide-features.c linux-2.4.20-ben5/drivers/ide/ide-features.c
--- linux-2.4.20/drivers/ide/ide-features.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/ide/ide-features.c 2003-01-30 11:52:36.000000000 +0100
@@ -278,7 +278,11 @@
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
byte unit = (drive->select.b.unit & 0x01);
- outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
+ /* Some interfaces would like to use this routine, but don"t have this
+ * kind of DMA engine. --BenH.
+ */
+ if (hwif->dma_base)
+ outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
/*
@@ -347,10 +351,15 @@
drive->id->dma_1word &= ~0x0F00;
#if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI)
- if (speed > XFER_PIO_4) {
- outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
- } else {
- outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
+ /* Some interfaces would like to use this routine, but don"t have this
+ * kind of DMA engine. --BenH.
+ */
+ if (hwif->dma_base) {
+ if (speed > XFER_PIO_4) {
+ outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);
+ } else {
+ outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2);
+ }
}
#endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */
diff -uNr linux-2.4.20/drivers/ide/ide-pci.c linux-2.4.20-ben5/drivers/ide/ide-pci.c
--- linux-2.4.20/drivers/ide/ide-pci.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-pci.c 2003-01-30 11:53:09.000000000 +0100
@@ -73,6 +73,8 @@
#define DEVID_AEC6210 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF})
#define DEVID_AEC6260 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860})
#define DEVID_AEC6260R ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R})
+#define DEVID_AEC6280 ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865})
+#define DEVID_AEC6280R ((ide_pci_devid_t){PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R})
#define DEVID_W82C105 ((ide_pci_devid_t){PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105})
#define DEVID_UM8673F ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8673F})
#define DEVID_UM8886A ((ide_pci_devid_t){PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8886A})
@@ -444,6 +446,8 @@
{DEVID_AEC6210, "AEC6210", PCI_AEC62XX, NULL, INIT_AEC62XX, DMA_AEC62XX, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 },
{DEVID_AEC6260, "AEC6260", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, NEVER_BOARD, 0 },
{DEVID_AEC6260R,"AEC6260R", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, OFF_BOARD, 0 },
+ {DEVID_AEC6280, "AEC6280", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 },
+ {DEVID_AEC6280R,"AEC6280R", PCI_AEC62XX, ATA66_AEC62XX, INIT_AEC62XX, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, OFF_BOARD, 0 },
{DEVID_W82C105, "W82C105", PCI_W82C105, NULL, INIT_W82C105, DMA_W82C105, {{0x40,0x01,0x01}, {0x40,0x10,0x10}}, ON_BOARD, 0 },
{DEVID_UM8673F, "UM8673F", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
{DEVID_UM8886A, "UM8886A", NULL, NULL, NULL, NULL, {{0x00,0x00,0x00}, {0x00,0x00,0x00}}, ON_BOARD, 0 },
@@ -486,6 +490,8 @@
case PCI_DEVICE_ID_ARTOP_ATP850UF:
case PCI_DEVICE_ID_ARTOP_ATP860:
case PCI_DEVICE_ID_ARTOP_ATP860R:
+ case PCI_DEVICE_ID_ARTOP_ATP865:
+ case PCI_DEVICE_ID_ARTOP_ATP865R:
return dev->irq;
default:
break;
@@ -822,6 +828,8 @@
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6210) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6260R) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6280) ||
+ IDE_PCI_DEVID_EQ(d->devid, DEVID_AEC6280R) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT34X) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_HPT366) ||
IDE_PCI_DEVID_EQ(d->devid, DEVID_CS5530) ||
diff -uNr linux-2.4.20/drivers/ide/ide-pmac.c linux-2.4.20-ben5/drivers/ide/ide-pmac.c
--- linux-2.4.20/drivers/ide/ide-pmac.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-pmac.c 2003-01-30 11:52:39.000000000 +0100
@@ -43,21 +43,23 @@
#include
#endif
#include "ide_modes.h"
+#include "ide-timing.h"
extern char *ide_dmafunc_verbose(ide_dma_action_t dmafunc);
extern void ide_do_request(ide_hwgroup_t *hwgroup, int masked_irq);
-#define IDE_PMAC_DEBUG
-
+#undef IDE_PMAC_DEBUG
#define DMA_WAIT_TIMEOUT 500
-struct pmac_ide_hwif {
+typedef struct pmac_ide_hwif {
ide_ioreg_t regbase;
+ unsigned long mapbase;
int irq;
int kind;
int aapl_bus_id;
+ int cable_80;
struct device_node* node;
- u32 timings[2];
+ u32 timings[4];
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
/* Those fields are duplicating what is in hwif. We currently
* can't use the hwif ones because of some assumptions that are
@@ -72,8 +74,9 @@
int sg_dma_direction;
#endif
-} pmac_ide[MAX_HWIFS] __pmacdata;
+} pmac_ide_hwif_t;
+static pmac_ide_hwif_t pmac_ide[MAX_HWIFS] __pmacdata;
static int pmac_ide_count;
enum {
@@ -81,7 +84,15 @@
controller_heathrow, /* Heathrow/Paddington */
controller_kl_ata3, /* KeyLargo ATA-3 */
controller_kl_ata4, /* KeyLargo ATA-4 */
- controller_kl_ata4_80 /* KeyLargo ATA-4 with 80 conductor cable */
+ controller_un_ata6 /* UniNorth2 ATA-6 */
+};
+
+static const char* model_name[] = {
+ "OHare ATA", /* OHare based */
+ "Heathrow ATA", /* Heathrow/Paddington */
+ "KeyLargo ATA-3", /* KeyLargo ATA-3 */
+ "KeyLargo ATA-4", /* KeyLargo ATA-4 */
+ "UniNorth ATA-6" /* UniNorth2 ATA-6 */
};
/*
@@ -90,6 +101,11 @@
#define IDE_TIMING_CONFIG 0x200
#define IDE_INTERRUPT 0x300
+/* Kauai (U2) ATA has different register setup */
+#define IDE_KAUAI_PIO_CONFIG 0x200
+#define IDE_KAUAI_ULTRA_CONFIG 0x210
+#define IDE_KAUAI_POLL_CONFIG 0x220
+
/*
* Timing configuration register definitions
*/
@@ -100,6 +116,28 @@
#define IDE_SYSCLK_NS 30 /* 33Mhz cell */
#define IDE_SYSCLK_66_NS 15 /* 66Mhz cell */
+/* 100Mhz cell, found in Uninorth 2. I don't have much infos about
+ * this one yet, it appears as a pci device (106b/0033) on uninorth
+ * internal PCI bus and it's clock is controlled like gem or fw. It
+ * appears to be an evolution of keylargo ATA4 with a timing register
+ * extended to 2 32bits registers and a similar DBDMA channel. Other
+ * registers seem to exist but I can't tell much about them.
+ *
+ * So far, I'm using pre-calculated tables for this extracted from
+ * the values used by the MacOS X driver.
+ *
+ * The "PIO" register controls PIO and MDMA timings, the "ULTRA"
+ * register controls the UDMA timings. At least, it seems bit 0
+ * of this one enables UDMA vs. MDMA, and bits 4..7 are the
+ * cycle time in units of 10ns. Bits 8..15 are used by I don't
+ * know their meaning yet
+ */
+#define TR_100_PIOREG_PIO_MASK 0xff000fff
+#define TR_100_PIOREG_MDMA_MASK 0x00fff000
+#define TR_100_UDMAREG_UDMA_MASK 0x0000ffff
+#define TR_100_UDMAREG_UDMA_EN 0x00000001
+
+
/* 66Mhz cell, found in KeyLargo. Can do ultra mode 0 to 2 on
* 40 connector cable and to 4 on 80 connector one.
* Clock unit is 15ns (66Mhz)
@@ -218,12 +256,12 @@
{ 0, 0, 0 }
};
-/* Ultra DMA timings (rounded) */
+/* KeyLargo ATA-4 Ultra DMA timings (rounded) */
struct {
int addrSetup; /* ??? */
int rdy2pause;
int wrDataSetup;
-} udma_timings[] __pmacdata =
+} kl66_udma_timings[] __pmacdata =
{
{ 0, 180, 120 }, /* Mode 0 */
{ 0, 150, 90 }, /* 1 */
@@ -232,6 +270,63 @@
{ 0, 90, 30 } /* 4 */
};
+/* UniNorth 2 ATA/100 timings */
+struct kauai_timing {
+ int cycle_time;
+ u32 timing_reg;
+};
+
+static struct kauai_timing kauai_pio_timings[] __pmacdata =
+{
+ { 930 , 0x08000fff },
+ { 600 , 0x08000a92 },
+ { 383 , 0x0800060f },
+ { 360 , 0x08000492 },
+ { 330 , 0x0800048f },
+ { 300 , 0x080003cf },
+ { 270 , 0x080003cc },
+ { 240 , 0x0800038b },
+ { 239 , 0x0800030c },
+ { 180 , 0x05000249 },
+ { 120 , 0x04000148 }
+};
+
+static struct kauai_timing kauai_mdma_timings[] __pmacdata =
+{
+ { 1260 , 0x00fff000 },
+ { 480 , 0x00618000 },
+ { 360 , 0x00492000 },
+ { 270 , 0x0038e000 },
+ { 240 , 0x0030c000 },
+ { 210 , 0x002cb000 },
+ { 180 , 0x00249000 },
+ { 150 , 0x00209000 },
+ { 120 , 0x00148000 },
+ { 0 , 0 },
+};
+
+static struct kauai_timing kauai_udma_timings[] __pmacdata =
+{
+ { 120 , 0x000070c0 },
+ { 90 , 0x00005d80 },
+ { 60 , 0x00004a60 },
+ { 45 , 0x00003a50 },
+ { 30 , 0x00002a30 },
+ { 20 , 0x00002921 },
+ { 0 , 0 },
+};
+
+static inline u32
+kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
+{
+ int i;
+
+ for (i=0; table[i].cycle_time; i++)
+ if (cycle_time > table[i+1].cycle_time)
+ return table[i].timing_reg;
+ return 0;
+}
+
/* allow up to 256 DBDMA commands per xfer */
#define MAX_DCMDS 256
@@ -240,15 +335,19 @@
* NOTE: There is at least one case I know of a disk that needs about 10sec
* before anwering on the bus. I beleive we could add a kernel command
* line arg to override this delay for such cases.
+ *
+ * NOTE2: This has to be fixed with a BSY wait loop. I'm working on adding
+ * that to the generic probe code.
*/
#define IDE_WAKEUP_DELAY_MS 2000
static void pmac_ide_setup_dma(struct device_node *np, int ix);
static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr);
+static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr);
static int pmac_ide_tune_chipset(ide_drive_t *drive, byte speed);
static void pmac_ide_tuneproc(ide_drive_t *drive, byte pio);
static void pmac_ide_selectproc(ide_drive_t *drive);
+static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
@@ -266,21 +365,6 @@
0
};
-static int __pmac
-pmac_ide_find(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = HWIF(drive);
- ide_ioreg_t base;
- int i;
-
- for (i=0; iio_ports[0])
- return i;
- }
- return -1;
-}
-
/*
* N.B. this can't be an initfunc, because the media-bay task can
* call ide_[un]register at any time.
@@ -315,7 +399,10 @@
*irq = pmac_ide[ix].irq;
ide_hwifs[ix].tuneproc = pmac_ide_tuneproc;
- ide_hwifs[ix].selectproc = pmac_ide_selectproc;
+ if (pmac_ide[ix].kind == controller_un_ata6)
+ ide_hwifs[ix].selectproc = pmac_ide_kauai_selectproc;
+ else
+ ide_hwifs[ix].selectproc = pmac_ide_selectproc;
ide_hwifs[ix].speedproc = &pmac_ide_tune_chipset;
if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table_cpu) {
ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
@@ -347,19 +434,55 @@
static void __pmac
pmac_ide_selectproc(ide_drive_t *drive)
{
- int i = pmac_ide_find(drive);
- if (i < 0)
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+
+ if (pmif == NULL)
return;
if (drive->select.b.unit & 0x01)
out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
- pmac_ide[i].timings[1]);
+ pmif->timings[1]);
else
out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
- pmac_ide[i].timings[0]);
+ pmif->timings[0]);
(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
}
+static void __pmac
+pmac_ide_kauai_selectproc(ide_drive_t *drive)
+{
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+
+ if (pmif == NULL)
+ return;
+
+ if (drive->select.b.unit & 0x01) {
+ out_le32((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG + _IO_BASE),
+ pmif->timings[1]);
+ out_le32((unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG + _IO_BASE),
+ pmif->timings[3]);
+ } else {
+ out_le32((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG + _IO_BASE),
+ pmif->timings[0]);
+ out_le32((unsigned *)(IDE_DATA_REG + IDE_KAUAI_ULTRA_CONFIG + _IO_BASE),
+ pmif->timings[2]);
+ }
+ (void)in_le32((unsigned *)(IDE_DATA_REG + IDE_KAUAI_PIO_CONFIG + _IO_BASE));
+}
+
+static void __pmac
+pmac_ide_do_update_timings(ide_drive_t *drive)
+{
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+
+ if (pmif == NULL)
+ return;
+
+ if (pmif->kind == controller_un_ata6)
+ pmac_ide_kauai_selectproc(drive);
+ else
+ pmac_ide_selectproc(drive);
+}
/* Note: We don't use the generic routine here because for some
* yet unexplained reasons, it cause some media-bay CD-ROMs to
@@ -397,10 +520,10 @@
}
static int __pmac
-pmac_ide_do_setfeature(ide_drive_t *drive, byte command)
+pmac_ide_do_setfeature(ide_drive_t *drive, u8 command)
{
- int result = 1;
ide_hwif_t *hwif = HWIF(drive);
+ int result = 1;
disable_irq(hwif->irq); /* disable_irq_nosync ?? */
udelay(1);
@@ -454,31 +577,36 @@
static void __pmac
pmac_ide_tuneproc(ide_drive_t *drive, byte pio)
{
- ide_pio_data_t d;
- int i;
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
u32 *timings;
unsigned accessTicks, recTicks;
unsigned accessTime, recTime;
+ ide_pio_data_t d;
- i = pmac_ide_find(drive);
- if (i < 0)
+ if (pmif == NULL)
return;
+ /* which drive is it ? */
+ timings = &pmif->timings[drive->select.b.unit & 0x01];
+
pio = ide_get_best_pio_mode(drive, pio, 4, &d);
- accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
- if (drive->select.b.unit & 0x01)
- timings = &pmac_ide[i].timings[1];
- else
- timings = &pmac_ide[i].timings[0];
- recTime = d.cycle_time - ide_pio_timings[pio].active_time
- - ide_pio_timings[pio].setup_time;
- recTime = max(recTime, 150U);
- accessTime = ide_pio_timings[pio].active_time;
- accessTime = max(accessTime, 150U);
- if (pmac_ide[i].kind == controller_kl_ata4 ||
- pmac_ide[i].kind == controller_kl_ata4_80) {
+ switch (pmif->kind) {
+ case controller_un_ata6: {
+ /* 100Mhz cell */
+ u32 tr = kauai_lookup_timing(kauai_pio_timings, d.cycle_time);
+ if (tr == 0)
+ return;
+ *timings = ((*timings) & ~TR_100_PIOREG_PIO_MASK) | tr;
+ break;
+ }
+ case controller_kl_ata4:
/* 66Mhz cell */
+ recTime = d.cycle_time - ide_pio_timings[pio].active_time
+ - ide_pio_timings[pio].setup_time;
+ recTime = max(recTime, 150U);
+ accessTime = ide_pio_timings[pio].active_time;
+ accessTime = max(accessTime, 150U);
accessTicks = SYSCLK_TICKS_66(accessTime);
accessTicks = min(accessTicks, 0x1fU);
recTicks = SYSCLK_TICKS_66(recTime);
@@ -486,9 +614,15 @@
*timings = ((*timings) & ~TR_66_PIO_MASK) |
(accessTicks << TR_66_PIO_ACCESS_SHIFT) |
(recTicks << TR_66_PIO_RECOVERY_SHIFT);
- } else {
+ break;
+ default: {
/* 33Mhz cell */
int ebit = 0;
+ recTime = d.cycle_time - ide_pio_timings[pio].active_time
+ - ide_pio_timings[pio].setup_time;
+ recTime = max(recTime, 150U);
+ accessTime = ide_pio_timings[pio].active_time;
+ accessTime = max(accessTime, 150U);
accessTicks = SYSCLK_TICKS(accessTime);
accessTicks = min(accessTicks, 0x1fU);
accessTicks = max(accessTicks, 4U);
@@ -504,6 +638,8 @@
(recTicks << TR_33_PIO_RECOVERY_SHIFT);
if (ebit)
*timings |= TR_33_PIO_E;
+ break;
+ }
}
#ifdef IDE_PMAC_DEBUG
@@ -512,18 +648,21 @@
#endif
if (drive->select.all == IN_BYTE(IDE_SELECT_REG))
- pmac_ide_selectproc(drive);
+ pmac_ide_do_update_timings(drive);
}
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
static int __pmac
-set_timings_udma(u32 *timings, byte speed)
+set_timings_udma_ata4(u32 *timings, byte speed)
{
unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;
- rdyToPauseTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].rdy2pause);
- wrDataSetupTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].wrDataSetup);
- addrTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].addrSetup);
+ if (speed > XFER_UDMA_4)
+ return 1;
+
+ rdyToPauseTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].rdy2pause);
+ wrDataSetupTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].wrDataSetup);
+ addrTicks = SYSCLK_TICKS_66(kl66_udma_timings[speed & 0xf].addrSetup);
*timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) |
(wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) |
@@ -539,11 +678,28 @@
}
static int __pmac
-set_timings_mdma(int intf_type, u32 *timings, byte speed, int drive_cycle_time)
+set_timings_udma_ata6(u32 *pio_timings, u32 *ultra_timings, byte speed)
+{
+ struct ide_timing *t = ide_timing_find_mode(speed);
+ u32 tr;
+
+ if (speed > XFER_UDMA_5 || t == NULL)
+ return 1;
+ tr = kauai_lookup_timing(kauai_udma_timings, (int)t->udma);
+ if (tr == 0)
+ return 1;
+ *ultra_timings = ((*ultra_timings) & ~TR_100_UDMAREG_UDMA_MASK) | tr;
+ *ultra_timings = (*ultra_timings) | TR_100_UDMAREG_UDMA_EN;
+
+ return 0;
+}
+
+static int __pmac
+set_timings_mdma(int intf_type, u32 *timings, u32 *timings2, byte speed, int drive_cycle_time)
{
int cycleTime, accessTime, recTime;
unsigned accessTicks, recTicks;
- struct mdma_timings_t* tm;
+ struct mdma_timings_t* tm = NULL;
int i;
/* Get default cycle time for mode */
@@ -552,7 +708,7 @@
case 1: cycleTime = 150; break;
case 2: cycleTime = 120; break;
default:
- return -1;
+ return 1;
}
/* Adjust for drive */
if (drive_cycle_time && drive_cycle_time > cycleTime)
@@ -562,8 +718,9 @@
cycleTime = 150;
/* Get the proper timing array for this controller */
switch(intf_type) {
+ case controller_un_ata6:
+ break;
case controller_kl_ata4:
- case controller_kl_ata4_80:
tm = mdma_timings_66;
break;
case controller_kl_ata3:
@@ -573,24 +730,36 @@
tm = mdma_timings_33;
break;
}
- /* Lookup matching access & recovery times */
- i = -1;
- for (;;) {
- if (tm[i+1].cycleTime < cycleTime)
- break;
- i++;
- }
- if (i < 0)
- return -1;
- cycleTime = tm[i].cycleTime;
- accessTime = tm[i].accessTime;
- recTime = tm[i].recoveryTime;
+ if (tm != NULL) {
+ /* Lookup matching access & recovery times */
+ i = -1;
+ for (;;) {
+ if (tm[i+1].cycleTime < cycleTime)
+ break;
+ i++;
+ }
+ if (i < 0)
+ return 1;
+ cycleTime = tm[i].cycleTime;
+ accessTime = tm[i].accessTime;
+ recTime = tm[i].recoveryTime;
#ifdef IDE_PMAC_DEBUG
- printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n",
- cycleTime, accessTime, recTime);
-#endif
- if (intf_type == controller_kl_ata4 || intf_type == controller_kl_ata4_80) {
+ printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n",
+ cycleTime, accessTime, recTime);
+#endif
+ }
+ switch(intf_type) {
+ case controller_un_ata6: {
+ /* 100Mhz cell */
+ u32 tr = kauai_lookup_timing(kauai_mdma_timings, cycleTime);
+ if (tr == 0)
+ return 1;
+ *timings = ((*timings) & ~TR_100_PIOREG_MDMA_MASK) | tr;
+ *timings2 = (*timings2) & ~TR_100_UDMAREG_UDMA_EN;
+ }
+ break;
+ case controller_kl_ata4:
/* 66Mhz cell */
accessTicks = SYSCLK_TICKS_66(accessTime);
accessTicks = min(accessTicks, 0x1fU);
@@ -602,7 +771,8 @@
*timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) |
(accessTicks << TR_66_MDMA_ACCESS_SHIFT) |
(recTicks << TR_66_MDMA_RECOVERY_SHIFT);
- } else if (intf_type == controller_kl_ata3) {
+ break;
+ case controller_kl_ata3:
/* 33Mhz cell on KeyLargo */
accessTicks = SYSCLK_TICKS(accessTime);
accessTicks = max(accessTicks, 1U);
@@ -614,7 +784,8 @@
*timings = ((*timings) & ~TR_33_MDMA_MASK) |
(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |
(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
- } else {
+ break;
+ default: {
/* 33Mhz cell on others */
int halfTick = 0;
int origAccessTime = accessTime;
@@ -639,6 +810,7 @@
(recTicks << TR_33_MDMA_RECOVERY_SHIFT);
if (halfTick)
*timings |= TR_33_MDMA_HALFTICK;
+ }
}
#ifdef IDE_PMAC_DEBUG
printk(KERN_ERR "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",
@@ -654,34 +826,40 @@
static int __pmac
pmac_ide_tune_chipset (ide_drive_t *drive, byte speed)
{
- int intf = pmac_ide_find(drive);
- int unit = (drive->select.b.unit & 0x01);
- int ret = 0;
- u32 *timings;
+ int unit = (drive->select.b.unit & 0x01);
+ int ret = 0;
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+ u32 *timings, *timings2;
- if (intf < 0)
+ if (pmif == NULL)
return 1;
- timings = &pmac_ide[intf].timings[unit];
+ timings = &pmif->timings[unit];
+ timings2 = &pmif->timings[unit+2];
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+ case XFER_UDMA_5:
+ if (pmif->kind != controller_un_ata6)
+ return 1;
case XFER_UDMA_4:
case XFER_UDMA_3:
- if (pmac_ide[intf].kind != controller_kl_ata4_80)
+ if (HWIF(drive)->udma_four == 0)
return 1;
case XFER_UDMA_2:
case XFER_UDMA_1:
case XFER_UDMA_0:
- if (pmac_ide[intf].kind != controller_kl_ata4 &&
- pmac_ide[intf].kind != controller_kl_ata4_80)
- return 1;
- ret = set_timings_udma(timings, speed);
+ if (pmif->kind == controller_kl_ata4)
+ ret = set_timings_udma_ata4(timings, speed);
+ else if (pmif->kind == controller_un_ata6)
+ ret = set_timings_udma_ata6(timings, timings2, speed);
+ else
+ ret = 1;
break;
case XFER_MW_DMA_2:
case XFER_MW_DMA_1:
case XFER_MW_DMA_0:
- ret = set_timings_mdma(pmac_ide[intf].kind, timings, speed, 0);
+ ret = set_timings_mdma(pmif->kind, timings, timings2, speed, 0);
break;
case XFER_SW_DMA_2:
case XFER_SW_DMA_1:
@@ -705,20 +883,23 @@
if (ret)
return ret;
- pmac_ide_selectproc(drive);
+ pmac_ide_do_update_timings(drive);
drive->current_speed = speed;
return 0;
}
static void __pmac
-sanitize_timings(int i)
+sanitize_timings(pmac_ide_hwif_t *pmif)
{
- unsigned value;
+ unsigned int value, value2 = 0;
- switch(pmac_ide[i].kind) {
+ switch(pmif->kind) {
+ case controller_un_ata6:
+ value = 0x08618a92;
+ value2 = 0x00002921;
+ break;
case controller_kl_ata4:
- case controller_kl_ata4_80:
value = 0x0008438c;
break;
case controller_kl_ata3:
@@ -730,7 +911,8 @@
value = 0x00074526;
break;
}
- pmac_ide[i].timings[0] = pmac_ide[i].timings[1] = value;
+ pmif->timings[0] = pmif->timings[1] = value;
+ pmif->timings[2] = pmif->timings[3] = value2;
}
ide_ioreg_t __pmac
@@ -750,6 +932,17 @@
return -1;
}
+struct device_node*
+pmac_ide_get_of_node(int index)
+{
+ /* Don't access the pmac_ide array on non-pmac */
+ if (pmac_ide_count == 0)
+ return NULL;
+ if (pmac_ide[index].regbase == 0)
+ return NULL;
+ return pmac_ide[index].node;
+}
+
int __pmac
pmac_ide_get_irq(ide_ioreg_t base)
{
@@ -792,7 +985,7 @@
int i;
struct device_node *atas;
struct device_node *p, **pp, *removables, **rp;
- unsigned long base;
+ unsigned long base, regbase;
int irq, big_delay;
ide_hwif_t *hwif;
@@ -825,7 +1018,7 @@
for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
struct device_node *tp;
- struct pmac_ide_hwif* pmhw;
+ struct pmac_ide_hwif* pmif;
int *bidp;
int in_bay = 0;
u8 pbus, pid;
@@ -833,29 +1026,88 @@
/*
* If this node is not under a mac-io or dbdma node,
- * leave it to the generic PCI driver.
+ * leave it to the generic PCI driver. Except for U2's
+ * Kauai ATA
*/
- for (tp = np->parent; tp != 0; tp = tp->parent)
- if (tp->type && (strcmp(tp->type, "mac-io") == 0
- || strcmp(tp->type, "dbdma") == 0))
- break;
- if (tp == 0)
- continue;
+ if (!device_is_compatible(np, "kauai-ata")) {
+ for (tp = np->parent; tp != 0; tp = tp->parent)
+ if (tp->type && (strcmp(tp->type, "mac-io") == 0
+ || strcmp(tp->type, "dbdma") == 0))
+ break;
+ if (tp == 0)
+ continue;
- if (np->n_addrs == 0) {
- printk(KERN_WARNING "ide: no address for device %s\n",
- np->full_name);
- continue;
- }
+ if (np->n_addrs == 0) {
+ printk(KERN_WARNING "ide-pmac: no address for device %s\n",
+ np->full_name);
+ continue;
+ }
+ /* We need to find the pci_dev of the mac-io holding the
+ * IDE interface
+ */
+ if (pci_device_from_OF_node(tp, &pbus, &pid) == 0)
+ pdev = pci_find_slot(pbus, pid);
+ if (pdev == NULL)
+ printk(KERN_WARNING "ide-pmac: no PCI host for device %s, DMA disabled\n",
+ np->full_name);
+ /*
+ * Some older OFs have bogus sizes, causing request_OF_resource
+ * to fail. We fix them up here
+ */
+ if (np->addrs[0].size > 0x1000)
+ np->addrs[0].size = 0x1000;
+ if (np->n_addrs > 1 && np->addrs[1].size > 0x100)
+ np->addrs[1].size = 0x100;
- /* We need to find the pci_dev of the mac-io holding the
- * IDE interface
- */
- if (pci_device_from_OF_node(tp, &pbus, &pid) == 0)
- pdev = pci_find_slot(pbus, pid);
- if (pdev == NULL)
- printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n",
- np->full_name);
+ if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) {
+ printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name);
+ continue;
+ }
+
+ base = (unsigned long) ioremap(np->addrs[0].address, 0x400);
+ regbase = base - _IO_BASE;
+
+ /* XXX This is bogus. Should be fixed in the registry by checking
+ the kind of host interrupt controller, a bit like gatwick
+ fixes in irq.c
+ */
+ if (np->n_intrs == 0) {
+ printk(KERN_WARNING "ide-pmac: no intrs for device %s, using 13\n",
+ np->full_name);
+ irq = 13;
+ } else {
+ irq = np->intrs[0].line;
+ }
+ } else {
+ unsigned long rbase, rlen;
+
+ if (pci_device_from_OF_node(np, &pbus, &pid) == 0)
+ pdev = pci_find_slot(pbus, pid);
+ if (pdev == NULL) {
+ printk(KERN_WARNING "ide-pmac: no PCI host for device %s, skipping\n",
+ np->full_name);
+ continue;
+ }
+ if (pci_enable_device(pdev)) {
+ printk(KERN_WARNING "ide-pmac: Can't enable PCI device for %s, skipping\n",
+ np->full_name);
+ continue;
+ }
+ pci_set_master(pdev);
+
+ if (pci_request_regions(pdev, "U2 IDE")) {
+ printk(KERN_ERR "ide-pmac: Cannot obtain PCI resources\n");
+ continue;
+ }
+
+ rbase = pci_resource_start(pdev, 0);
+ rlen = pci_resource_len(pdev, 0);
+
+ base = (unsigned long) ioremap(rbase, rlen);
+ regbase = base + 0x2000 - _IO_BASE;
+
+ irq = pdev->irq;
+ }
/*
* If this slot is taken (e.g. by ide-pci.c) try the next one.
@@ -865,69 +1117,48 @@
++i;
if (i >= MAX_HWIFS)
break;
- pmhw = &pmac_ide[i];
-
- /*
- * Some older OFs have bogus sizes, causing request_OF_resource
- * to fail. We fix them up here
- */
- if (np->addrs[0].size > 0x1000)
- np->addrs[0].size = 0x1000;
- if (np->n_addrs > 1 && np->addrs[1].size > 0x100)
- np->addrs[1].size = 0x100;
-
- if (request_OF_resource(np, 0, " (mac-io IDE IO)") == NULL) {
- printk(KERN_ERR "ide-pmac(%s): can't request IO resource !\n", np->name);
- continue;
- }
+ pmif = &pmac_ide[i];
- base = (unsigned long) ioremap(np->addrs[0].address, 0x400) - _IO_BASE;
-
- /* XXX This is bogus. Should be fixed in the registry by checking
- the kind of host interrupt controller, a bit like gatwick
- fixes in irq.c
- */
- if (np->n_intrs == 0) {
- printk(KERN_WARNING "ide: no intrs for device %s, using 13\n",
- np->full_name);
- irq = 13;
- } else {
- irq = np->intrs[0].line;
- }
- pmhw->regbase = base;
- pmhw->irq = irq;
- pmhw->node = np;
- if (device_is_compatible(np, "keylargo-ata")) {
+ pmif->mapbase = base;
+ pmif->regbase = regbase;
+ pmif->irq = irq;
+ pmif->node = np;
+ pmif->cable_80 = 0;
+ if (device_is_compatible(np, "kauai-ata")) {
+ pmif->kind = controller_un_ata6;
+ pci_set_drvdata(pdev, pmif);
+ } else if (device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0)
- pmhw->kind = controller_kl_ata4;
+ pmif->kind = controller_kl_ata4;
else
- pmhw->kind = controller_kl_ata3;
+ pmif->kind = controller_kl_ata3;
} else if (device_is_compatible(np, "heathrow-ata"))
- pmhw->kind = controller_heathrow;
+ pmif->kind = controller_heathrow;
else
- pmhw->kind = controller_ohare;
+ pmif->kind = controller_ohare;
bidp = (int *)get_property(np, "AAPL,bus-id", NULL);
- pmhw->aapl_bus_id = bidp ? *bidp : 0;
+ pmif->aapl_bus_id = bidp ? *bidp : 0;
- if (pmhw->kind == controller_kl_ata4) {
+ /* Get cable type from device-tree */
+ if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) {
char* cable = get_property(np, "cable-type", NULL);
if (cable && !strncmp(cable, "80-", 3))
- pmhw->kind = controller_kl_ata4_80;
+ pmif->cable_80 = 1;
}
/* Make sure we have sane timings */
- sanitize_timings(i);
+ sanitize_timings(pmif);
if (np->parent && np->parent->name
&& strcasecmp(np->parent->name, "media-bay") == 0) {
#ifdef CONFIG_PMAC_PBOOK
- media_bay_set_ide_infos(np->parent,base,irq,i);
+ media_bay_set_ide_infos(np->parent,regbase,irq,i);
#endif /* CONFIG_PMAC_PBOOK */
in_bay = 1;
if (!bidp)
- pmhw->aapl_bus_id = 1;
- } else if (pmhw->kind == controller_ohare) {
+ pmif->aapl_bus_id = 1;
+ } else if (pmif->kind == controller_ohare) {
/* The code below is having trouble on some ohare machines
* (timing related ?). Until I can put my hand on one of these
* units, I keep the old way
@@ -935,31 +1166,35 @@
ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);
} else {
/* This is necessary to enable IDE when net-booting */
- printk(KERN_INFO "pmac_ide: enabling IDE bus ID %d\n",
- pmhw->aapl_bus_id);
- ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmhw->aapl_bus_id, 1);
- ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmhw->aapl_bus_id, 1);
+ ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);
+ ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);
mdelay(10);
- ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmhw->aapl_bus_id, 0);
+ ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0);
big_delay = 1;
}
hwif = &ide_hwifs[i];
- pmac_ide_init_hwif_ports(&hwif->hw, base, 0, &hwif->irq);
+ hwif->hwif_data = pmif;
+ pmac_ide_init_hwif_ports(&hwif->hw, regbase, 0, &hwif->irq);
memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
hwif->chipset = ide_pmac;
hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || in_bay;
- hwif->udma_four = (pmhw->kind == controller_kl_ata4_80);
+ hwif->udma_four = pmif->cable_80;
hwif->pci_dev = pdev;
hwif->drives[0].unmask = 1;
hwif->drives[1].unmask = 1;
+
+ printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s\n",
+ i, model_name[pmif->kind], pmif->aapl_bus_id,
+ in_bay ? " (mediabay)" : "");
+
#ifdef CONFIG_PMAC_PBOOK
- if (in_bay && check_media_bay_by_base(base, MB_CD) == 0)
+ if (in_bay && check_media_bay_by_base(regbase, MB_CD) == 0)
hwif->noprobe = 0;
#endif /* CONFIG_PMAC_PBOOK */
#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
- if (np->n_addrs >= 2) {
+ if (np->n_addrs >= 2 || pmif->kind == controller_un_ata6) {
/* has a DBDMA controller channel */
pmac_ide_setup_dma(np, i);
}
@@ -968,6 +1203,9 @@
++i;
}
pmac_ide_count = i;
+ if (pmac_ide_count == 0)
+ return;
+
if (big_delay)
mdelay(IDE_WAKEUP_DELAY_MS);
@@ -984,14 +1222,18 @@
{
struct pmac_ide_hwif *pmif = &pmac_ide[ix];
- if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) {
- printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name);
- return;
- }
-
- pmif->dma_regs =
- (volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200);
+ if (pmif->kind == controller_un_ata6) {
+ pmif->dma_regs = (volatile struct dbdma_regs*)(pmif->mapbase + 0x1000);
+ } else {
+ if (request_OF_resource(np, 1, " (mac-io IDE DMA)") == NULL) {
+ printk(KERN_ERR "ide-pmac(%s): can't request DMA resource !\n", np->name);
+ return;
+ }
+ pmif->dma_regs =
+ (volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200);
+ }
+
/*
* Allocate space for the DBDMA commands.
* The +2 is +1 for the stop command and +1 to allow for
@@ -1023,10 +1265,9 @@
}
static int
-pmac_ide_build_sglist (int ix, struct request *rq)
+pmac_ide_build_sglist(ide_hwif_t *hwif, struct request *rq)
{
- ide_hwif_t *hwif = &ide_hwifs[ix];
- struct pmac_ide_hwif *pmif = &pmac_ide[ix];
+ pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
struct buffer_head *bh;
struct scatterlist *sg = pmif->sg_table;
unsigned long lastdataend = ~0UL;
@@ -1043,16 +1284,29 @@
bh = rq->bh;
do {
struct scatterlist *sge;
- unsigned int size = bh->b_size;
+ int contig = 0;
- /* continue segment from before? */
- if (bh_phys(bh) == lastdataend) {
- sg[nents-1].length += size;
- lastdataend += size;
+ if (bh->b_page) {
+ if (bh_phys(bh) == lastdataend)
+ contig = 1;
+ } else {
+ if ((unsigned long) bh->b_data == lastdataend)
+ contig = 1;
+ }
+
+
+ /*
+ * continue segment from before?
+ */
+ if (contig) {
+ sg[nents - 1].length += bh->b_size;
+ lastdataend += bh->b_size;
continue;
}
- /* start new segment */
+ /*
+ * start new segment
+ */
if (nents >= MAX_DCMDS)
return 0;
@@ -1062,13 +1316,16 @@
if (bh->b_page) {
sge->page = bh->b_page;
sge->offset = bh_offset(bh);
+ lastdataend = bh_phys(bh) + bh->b_size;
} else {
- if ((unsigned long)bh->b_data < PAGE_SIZE)
+ if ((unsigned long) bh->b_data < PAGE_SIZE)
BUG();
+
sge->address = bh->b_data;
+ lastdataend = (unsigned long) bh->b_data + bh->b_size;
}
- sge->length = size;
- lastdataend = bh_phys(bh) + size;
+
+ sge->length = bh->b_size;
nents++;
} while ((bh = bh->b_reqnext) != NULL);
@@ -1076,10 +1333,9 @@
}
static int
-pmac_ide_raw_build_sglist (int ix, struct request *rq)
+pmac_ide_raw_build_sglist (ide_hwif_t *hwif, struct request *rq)
{
- ide_hwif_t *hwif = &ide_hwifs[ix];
- struct pmac_ide_hwif *pmif = &pmac_ide[ix];
+ pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
struct scatterlist *sg = hwif->sg_table;
int nents = 0;
ide_task_t *args = rq->special;
@@ -1114,16 +1370,18 @@
* for a transfer and sets the DBDMA channel to point to it.
*/
static int
-pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr)
+pmac_ide_build_dmatable(ide_drive_t *drive, int wr)
{
struct dbdma_cmd *table;
int i, count = 0;
struct request *rq = HWGROUP(drive)->rq;
- volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs;
+ ide_hwif_t *hwif = HWIF(drive);
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
+ volatile struct dbdma_regs *dma = pmif->dma_regs;
struct scatterlist *sg;
/* DMA table is already aligned */
- table = (struct dbdma_cmd *) pmac_ide[ix].dma_table_cpu;
+ table = (struct dbdma_cmd *) pmif->dma_table_cpu;
/* Make sure DMA controller is stopped (necessary ?) */
out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
@@ -1132,14 +1390,14 @@
/* Build sglist */
if (HWGROUP(drive)->rq->cmd == IDE_DRIVE_TASKFILE)
- pmac_ide[ix].sg_nents = i = pmac_ide_raw_build_sglist(ix, rq);
+ pmif->sg_nents = i = pmac_ide_raw_build_sglist(hwif, rq);
else
- pmac_ide[ix].sg_nents = i = pmac_ide_build_sglist(ix, rq);
+ pmif->sg_nents = i = pmac_ide_build_sglist(hwif, rq);
if (!i)
return 0;
/* Build DBDMA commands list */
- sg = pmac_ide[ix].sg_table;
+ sg = pmif->sg_table;
while (i) {
u32 cur_addr;
u32 cur_len;
@@ -1179,81 +1437,40 @@
memset(table, 0, sizeof(struct dbdma_cmd));
out_le16(&table->command, DBDMA_STOP);
- out_le32(&dma->cmdptr, pmac_ide[ix].dma_table_dma);
+ out_le32(&dma->cmdptr, pmif->dma_table_dma);
return 1;
}
/* Teardown mappings after DMA has completed. */
static void
-pmac_ide_destroy_dmatable (ide_drive_t *drive, int ix)
+pmac_ide_destroy_dmatable (ide_drive_t *drive)
{
struct pci_dev *dev = HWIF(drive)->pci_dev;
- struct scatterlist *sg = pmac_ide[ix].sg_table;
- int nents = pmac_ide[ix].sg_nents;
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)HWIF(drive)->hwif_data;
+ struct scatterlist *sg = pmif->sg_table;
+ int nents = pmif->sg_nents;
if (nents) {
- pci_unmap_sg(dev, sg, nents, pmac_ide[ix].sg_dma_direction);
- pmac_ide[ix].sg_nents = 0;
+ pci_unmap_sg(dev, sg, nents, pmif->sg_dma_direction);
+ pmif->sg_nents = 0;
}
}
-static __inline__ unsigned char
-dma_bits_to_command(unsigned char bits)
-{
- if(bits & 0x04)
- return XFER_MW_DMA_2;
- if(bits & 0x02)
- return XFER_MW_DMA_1;
- if(bits & 0x01)
- return XFER_MW_DMA_0;
- return 0;
-}
-
-static __inline__ unsigned char
-udma_bits_to_command(unsigned char bits, int high_speed)
-{
- if (high_speed) {
- if(bits & 0x10)
- return XFER_UDMA_4;
- if(bits & 0x08)
- return XFER_UDMA_3;
- }
- if(bits & 0x04)
- return XFER_UDMA_2;
- if(bits & 0x02)
- return XFER_UDMA_1;
- if(bits & 0x01)
- return XFER_UDMA_0;
- return 0;
-}
-
/* Calculate MultiWord DMA timings */
static int __pmac
-pmac_ide_mdma_enable(ide_drive_t *drive, int idx)
+pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode)
{
- byte bits = drive->id->dma_mword & 0x07;
- byte feature = dma_bits_to_command(bits);
- u32 *timings;
+ ide_hwif_t *hwif = HWIF(drive);
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
int drive_cycle_time;
struct hd_driveid *id = drive->id;
+ u32 *timings, *timings2;
+ u32 timing_local[2];
int ret;
- /* Set feature on drive */
- printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf);
- ret = pmac_ide_do_setfeature(drive, feature);
- if (ret) {
- printk(KERN_WARNING "%s: Failed !\n", drive->name);
- return 0;
- }
-
- if (!drive->init_speed)
- drive->init_speed = feature;
-
/* which drive is it ? */
- if (drive->select.b.unit & 0x01)
- timings = &pmac_ide[idx].timings[1];
- else
- timings = &pmac_ide[idx].timings[0];
+ timings = &pmif->timings[drive->select.b.unit & 0x01];
+ timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2];
/* Check if drive provide explicit cycle time */
if ((id->field_valid & 2) && (id->eide_dma_time))
@@ -1261,58 +1478,97 @@
else
drive_cycle_time = 0;
+ /* Copy timings to local image */
+ timing_local[0] = *timings;
+ timing_local[1] = *timings2;
+
/* Calculate controller timings */
- set_timings_mdma(pmac_ide[idx].kind, timings, feature, drive_cycle_time);
+ ret = set_timings_mdma( pmif->kind,
+ &timing_local[0],
+ &timing_local[1],
+ mode,
+ drive_cycle_time);
+ if (ret)
+ return 0;
+
+ /* Set feature on drive */
+ printk(KERN_INFO "%s: Enabling MultiWord DMA %d\n", drive->name, mode & 0xf);
+ ret = pmac_ide_do_setfeature(drive, mode);
+ if (ret) {
+ printk(KERN_WARNING "%s: Failed !\n", drive->name);
+ return 0;
+ }
+
+ /* Apply timings to controller */
+ *timings = timing_local[0];
+ *timings2 = timing_local[1];
+
+ /* Set speed info in drive */
+ drive->current_speed = mode;
+ if (!drive->init_speed)
+ drive->init_speed = mode;
- drive->current_speed = feature;
return 1;
}
/* Calculate Ultra DMA timings */
static int __pmac
-pmac_ide_udma_enable(ide_drive_t *drive, int idx, int high_speed)
+pmac_ide_udma_enable(ide_drive_t *drive, u16 mode)
{
- byte bits = drive->id->dma_ultra & 0x1f;
- byte feature = udma_bits_to_command(bits, high_speed);
- u32 *timings;
+ ide_hwif_t *hwif = HWIF(drive);
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
+ u32 *timings, *timings2;
+ u32 timing_local[2];
int ret;
+
+ /* which drive is it ? */
+ timings = &pmif->timings[drive->select.b.unit & 0x01];
+ timings2 = &pmif->timings[(drive->select.b.unit & 0x01) + 2];
+ /* Copy timings to local image */
+ timing_local[0] = *timings;
+ timing_local[1] = *timings2;
+
+ /* Calculate timings for interface */
+ if (pmif->kind == controller_un_ata6)
+ ret = set_timings_udma_ata6( &timing_local[0],
+ &timing_local[1],
+ mode);
+ else
+ ret = set_timings_udma_ata4(&timing_local[0], mode);
+ if (ret)
+ return 0;
+
/* Set feature on drive */
- printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf);
- ret = pmac_ide_do_setfeature(drive, feature);
+ printk(KERN_INFO "%s: Enabling Ultra DMA %d\n", drive->name, mode & 0x0f);
+ ret = pmac_ide_do_setfeature(drive, mode);
if (ret) {
printk(KERN_WARNING "%s: Failed !\n", drive->name);
return 0;
}
- if (!drive->init_speed)
- drive->init_speed = feature;
+ /* Apply timings to controller */
+ *timings = timing_local[0];
+ *timings2 = timing_local[1];
- /* which drive is it ? */
- if (drive->select.b.unit & 0x01)
- timings = &pmac_ide[idx].timings[1];
- else
- timings = &pmac_ide[idx].timings[0];
-
- set_timings_udma(timings, feature);
+ /* Set speed info in drive */
+ drive->current_speed = mode;
+ if (!drive->init_speed)
+ drive->init_speed = mode;
- drive->current_speed = feature;
return 1;
}
static int __pmac
pmac_ide_check_dma(ide_drive_t *drive)
{
- int ata4, udma, idx;
struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
int enable = 1;
-
+ int map;
drive->using_dma = 0;
- idx = pmac_ide_find(drive);
- if (idx < 0)
- return 0;
-
if (drive->media == ide_floppy)
enable = 0;
if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE))
@@ -1320,24 +1576,26 @@
if (check_drive_lists(drive, BAD_DMA_DRIVE))
enable = 0;
- udma = 0;
- ata4 = (pmac_ide[idx].kind == controller_kl_ata4 ||
- pmac_ide[idx].kind == controller_kl_ata4_80);
-
- if(enable) {
- if (ata4 && (drive->media == ide_disk) &&
- (id->field_valid & 0x0004) && (id->dma_ultra & 0x1f)) {
- /* UltraDMA modes. */
- drive->using_dma = pmac_ide_udma_enable(drive, idx,
- pmac_ide[idx].kind == controller_kl_ata4_80);
- }
- if (!drive->using_dma && (id->dma_mword & 0x0007)) {
- /* Normal MultiWord DMA modes. */
- drive->using_dma = pmac_ide_mdma_enable(drive, idx);
+ if (enable) {
+ short mode;
+
+ map = XFER_MWDMA;
+ if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6) {
+ map |= XFER_UDMA;
+ if (pmif->cable_80) {
+ map |= XFER_UDMA_66;
+ if (pmif->kind == controller_un_ata6)
+ map |= XFER_UDMA_100;
+ }
}
+ mode = ide_find_best_mode(drive, map);
+ if (mode & XFER_UDMA)
+ drive->using_dma = pmac_ide_udma_enable(drive, mode);
+ else if (mode & XFER_MWDMA)
+ drive->using_dma = pmac_ide_mdma_enable(drive, mode);
OUT_BYTE(0, IDE_CONTROL_REG);
/* Apply settings to controller */
- pmac_ide_selectproc(drive);
+ pmac_ide_do_update_timings(drive);
}
return 0;
}
@@ -1362,22 +1620,16 @@
static int __pmac
pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
- int ix, dstat;
+ int dstat;
volatile struct dbdma_regs *dma;
+ ide_hwif_t *hwif = HWIF(drive);
+ pmac_ide_hwif_t* pmif = (pmac_ide_hwif_t *)hwif->hwif_data;
byte unit = (drive->select.b.unit & 0x01);
byte ata4;
int reading = 0;
- /* Can we stuff a pointer to our intf structure in config_data
- * or select_data in hwif ?
- */
- ix = pmac_ide_find(drive);
- if (ix < 0)
- return 0;
- dma = pmac_ide[ix].dma_regs;
- ata4 = (pmac_ide[ix].kind == controller_kl_ata4 ||
- pmac_ide[ix].kind == controller_kl_ata4_80);
-
+ dma = pmif->dma_regs;
+ ata4 = (pmif->kind == controller_kl_ata4);
switch (func) {
case ide_dma_off:
printk(KERN_INFO "%s: DMA disabled\n", drive->name);
@@ -1394,13 +1646,13 @@
case ide_dma_read:
reading = 1;
case ide_dma_write:
- SELECT_READ_WRITE(HWIF(drive),drive,func);
- if (!pmac_ide_build_dmatable(drive, ix, !reading))
+ SELECT_READ_WRITE(hwif,drive,func);
+ if (!pmac_ide_build_dmatable(drive, !reading))
return 1;
/* Apple adds 60ns to wrDataSetup on reads */
- if (ata4 && (pmac_ide[ix].timings[unit] & TR_66_UDMA_EN)) {
+ if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
out_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE),
- pmac_ide[ix].timings[unit] +
+ pmif->timings[unit] +
(reading ? 0x00800000UL : 0));
(void)in_le32((unsigned *)(IDE_DATA_REG + IDE_TIMING_CONFIG + _IO_BASE));
}
@@ -1426,7 +1678,7 @@
drive->waiting_for_dma = 0;
dstat = in_le32(&dma->status);
out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
- pmac_ide_destroy_dmatable(drive, ix);
+ pmac_ide_destroy_dmatable(drive);
/* verify good dma status */
return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
case ide_dma_test_irq: /* returns 1 if dma irq issued, 0 otherwise */
@@ -1458,14 +1710,14 @@
return 1;
if (!drive->waiting_for_dma)
printk(KERN_WARNING "ide%d, ide_dma_test_irq \
- called while not waiting\n", ix);
+ called while not waiting\n", hwif->index);
/* If dbdma didn't execute the STOP command yet, the
* active bit is still set */
drive->waiting_for_dma++;
if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) {
printk(KERN_WARNING "ide%d, timeout waiting \
- for dbdma command stop\n", ix);
+ for dbdma command stop\n", hwif->index);
return 1;
}
udelay(1);
@@ -1508,8 +1760,8 @@
outb(0x0, base+0x20);
outb(0x0, base+0x40);
outb(0x0, base+0x50);
+ outb(drive->ctl | 2, base+0x160);
outb(0xe0, base+0x70);
- outb(0x2, base+0x160);
for (j = 0; j < 10; j++) {
int status;
mdelay(100);
@@ -1619,7 +1871,7 @@
int j;
/* Reset timings */
- pmac_ide_selectproc(drive);
+ pmac_ide_do_update_timings(drive);
mdelay(10);
/* Wait up to 20 seconds for the drive to be ready */
@@ -1698,7 +1950,7 @@
continue;
/* Make sure we have sane timings */
- sanitize_timings(i);
+ sanitize_timings(&pmac_ide[i]);
/* Check if this is a media bay with an IDE device or not
* a media bay
diff -uNr linux-2.4.20/drivers/ide/ide-probe.c linux-2.4.20-ben5/drivers/ide/ide-probe.c
--- linux-2.4.20/drivers/ide/ide-probe.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide-probe.c 2003-01-30 11:52:37.000000000 +0100
@@ -260,12 +260,22 @@
int retval;
int autoprobe = 0;
unsigned long cookie = 0;
+ ide_hwif_t *hwif = HWIF(drive);
+ int irqdefense = 0;
- if (IDE_CONTROL_REG && !HWIF(drive)->irq) {
+ if (IDE_CONTROL_REG && !hwif->irq) {
autoprobe = 1;
cookie = probe_irq_on();
OUT_BYTE(drive->ctl,IDE_CONTROL_REG); /* enable device irq */
}
+#ifdef CONFIG_IDEPCI_SHARE_IRQ
+ if (hwif->irq && IDE_CHIPSET_IS_PCI(hwif->chipset)) {
+ OUT_BYTE(drive->ctl|2, IDE_CONTROL_REG); /* mask device irq */
+ printk(KERN_WARNING "disabling irq %d defensively\n", hwif->irq);
+ disable_irq(hwif->irq);
+ irqdefense = 1;
+ }
+#endif CONFIG_IDEPCI_SHARE_IRQ
retval = actual_try_to_identify(drive, cmd);
@@ -291,6 +301,12 @@
}
}
}
+
+#ifdef CONFIG_IDEPCI_SHARE_IRQ
+ if (irqdefense)
+ enable_irq(hwif->irq);
+#endif CONFIG_IDEPCI_SHARE_IRQ
+
return retval;
}
@@ -493,6 +509,68 @@
}
/*
+ * This function waits for the hwif to report a non-busy status
+ * see comments in probe_hwif()
+ */
+static int wait_not_busy(ide_hwif_t *hwif, unsigned long timeout)
+{
+ u8 stat = 0;
+
+ while(timeout--) {
+ /* Turn this into a schedule() sleep once I'm sure
+ * about locking issues (2.5 work ?)
+ */
+ mdelay(1);
+ stat = IN_BYTE(hwif->io_ports[IDE_STATUS_OFFSET]);
+ if ((stat & BUSY_STAT) == 0)
+ break;
+ /* Assume a value of 0xff means nothing is connected to
+ * the interface and it doesn't implement the pull-down
+ * resistor on D7
+ */
+ if (stat == 0xff)
+ break;
+ }
+ return ((stat & BUSY_STAT) == 0) ? 0 : -EBUSY;
+}
+
+static int wait_hwif_ready(ide_hwif_t *hwif)
+{
+ int rc;
+
+ printk("Probing IDE interface %s...\n", hwif->name);
+
+ /* Let HW settle down a bit from whatever init state we
+ * come from */
+ mdelay(2);
+
+ /* Wait for BSY bit to go away, spec timeout is 30 seconds,
+ * I know of at least one disk who takes 31 seconds, I use 35
+ * here to be safe
+ */
+ rc = wait_not_busy(hwif, 35000);
+ if (rc)
+ return rc;
+
+ /* Now make sure both master & slave are ready */
+ SELECT_DRIVE(hwif, &hwif->drives[0]);
+ OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ mdelay(2);
+ rc = wait_not_busy(hwif, 10000);
+ if (rc)
+ return rc;
+ SELECT_DRIVE(hwif, &hwif->drives[1]);
+ OUT_BYTE(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
+ mdelay(2);
+ rc = wait_not_busy(hwif, 10000);
+
+ /* Exit function with master reselected (let's be sane) */
+ SELECT_DRIVE(hwif, &hwif->drives[0]);
+
+ return rc;
+}
+
+/*
* This routine only knows how to look for drive units 0 and 1
* on an interface, so any setting of MAX_DRIVES > 2 won't work here.
*/
@@ -532,6 +610,29 @@
__save_flags(flags); /* local CPU only */
__sti(); /* local CPU only; needed for jiffies and irq probing */
+
+ /* This is needed on some PPCs and a bunch of BIOS-less embedded
+ * platforms. Typical cases are:
+ *
+ * - The firmware hard reset the disk before booting the kernel,
+ * the drive is still doing it's poweron-reset sequence, that
+ * can take up to 30 seconds
+ * - The firmware does nothing (or no firmware), the device is
+ * still in POST state (same as above actually).
+ * - Some CD/DVD/Writer combo drives tend to drive the bus during
+ * their reset sequence even when they are non-selected slave
+ * devices, thus preventing discovery of the main HD
+ *
+ * Doing this wait-for-busy should not harm any existing configuration
+ * (at least things won't be worse than what current code does, that
+ * is blindly go & talk to the drive) and fix some issues like the
+ * above.
+ *
+ * BenH.
+ */
+ if (wait_hwif_ready(hwif))
+ printk(KERN_WARNING "%s: Wait for ready failed before probe !\n", hwif->name);
+
/*
* Second drive should only exist if first drive was found,
* but a lot of cdrom drives are configured as single slaves.
diff -uNr linux-2.4.20/drivers/ide/ide-proc.c linux-2.4.20-ben5/drivers/ide/ide-proc.c
--- linux-2.4.20/drivers/ide/ide-proc.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/ide/ide-proc.c 2003-01-30 11:55:22.000000000 +0100
@@ -70,6 +70,11 @@
#include
+#ifdef CONFIG_ALL_PPC
+#include
+#include
+#endif
+
#ifndef MIN
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#endif
@@ -414,13 +419,35 @@
case ide_cmd646: name = "cmd646"; break;
case ide_cy82c693: name = "cy82c693"; break;
case ide_4drives: name = "4drives"; break;
- case ide_pmac: name = "mac-io"; break;
+ case ide_pmac: name = "pmac"; break;
default: name = "(unknown)"; break;
}
len = sprintf(page, "%s\n", name);
PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
}
+#ifdef CONFIG_ALL_PPC
+static int proc_ide_read_devspec
+ (char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ ide_hwif_t *hwif = (ide_hwif_t *) data;
+ int len;
+ struct device_node *ofnode = NULL;
+
+#ifdef CONFIG_BLK_DEV_IDE_PMAC
+ extern struct device_node* pmac_ide_get_of_node(int index);
+ if (hwif->chipset == ide_pmac)
+ ofnode = pmac_ide_get_of_node(hwif->index);
+#endif /* CONFIG_BLK_DEV_IDE_PMAC */
+#ifdef CONFIG_PCI
+ if (ofnode == NULL && hwif->pci_dev)
+ ofnode = pci_device_to_OF_node(hwif->pci_dev);
+#endif /* CONFIG_PCI */
+ len = sprintf(page, "%s\n", ofnode ? ofnode->full_name : "");
+ PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
+}
+#endif /* CONFIG_ALL_PPC */
+
static int proc_ide_read_mate
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
@@ -801,6 +828,9 @@
{ "config", S_IFREG|S_IRUGO|S_IWUSR,proc_ide_read_config, proc_ide_write_config },
{ "mate", S_IFREG|S_IRUGO, proc_ide_read_mate, NULL },
{ "model", S_IFREG|S_IRUGO, proc_ide_read_imodel, NULL },
+#ifdef CONFIG_ALL_PPC
+ { "devspec", S_IFREG|S_IRUGO, proc_ide_read_devspec, NULL },
+#endif
{ NULL, 0, NULL, NULL }
};
diff -uNr linux-2.4.20/drivers/ide/ide.c linux-2.4.20-ben5/drivers/ide/ide.c
--- linux-2.4.20/drivers/ide/ide.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/ide/ide.c 2003-01-30 11:52:37.000000000 +0100
@@ -1049,6 +1049,9 @@
struct request *rq;
byte err;
+#ifdef CONFIG_BLK_DEV_PDC202XX
+ extern int pdc202xx_marvell_idle (ide_drive_t *);/* needed below -- Promise */
+#endif
err = ide_dump_status(drive, msg, stat);
if (drive == NULL || (rq = HWGROUP(drive)->rq) == NULL)
return ide_stopped;
@@ -1083,9 +1086,15 @@
if ((stat & DRQ_STAT) && rq->cmd != WRITE)
try_to_flush_leftover_data(drive);
}
- if (GET_STAT() & (BUSY_STAT|DRQ_STAT))
- OUT_BYTE(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); /* force an abort */
-
+ if (GET_STAT() & (BUSY_STAT|DRQ_STAT)) {
+#ifdef CONFIG_BLK_DEV_PDC202XX
+ /* Give a breath for Idle Immediate by Promise */
+ if (HWIF(drive)->pci_devid.vid == PCI_VENDOR_ID_PROMISE)
+ pdc202xx_marvell_idle(drive);
+ else
+#endif
+ OUT_BYTE(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); /* force an abort */
+ }
if (rq->errors >= ERROR_MAX) {
if (drive->driver != NULL)
DRIVER(drive)->end_request(0, HWGROUP(drive));
@@ -2420,6 +2429,7 @@
hw->irq = irq;
hw->dma = NO_DMA;
hw->ack_intr = ack_intr;
+ hw->chipset = ide_generic;
}
/*
@@ -2481,6 +2491,7 @@
hw_regs_t hw;
ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
hw.irq = irq;
+ hw.chipset = ide_unknown;
return ide_register_hw(&hw, NULL);
}
diff -uNr linux-2.4.20/drivers/ide/pdc202xx.c linux-2.4.20-ben5/drivers/ide/pdc202xx.c
--- linux-2.4.20/drivers/ide/pdc202xx.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/ide/pdc202xx.c 2003-01-30 11:53:02.000000000 +0100
@@ -68,13 +68,20 @@
#include
#include
+#ifdef CONFIG_ALL_PPC
+#include
+#include
+#include
+#include
+#endif
+
#include
#include
#include "ide_modes.h"
-#define PDC202XX_DEBUG_DRIVE_INFO 0
-#define PDC202XX_DECODE_REGISTER_INFO 0
+#define PDC202XX_DEBUG_DRIVE_INFO 1
+#define PDC202XX_DECODE_REGISTER_INFO 1
#define DISPLAY_PDC202XX_TIMINGS
@@ -82,6 +89,9 @@
#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
#endif
+#define OUT_LONG(l,p) outl((l),(p))
+#define IN_LONG(p) inl(p)
+
#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
#include
#include
@@ -89,9 +99,46 @@
static int pdc202xx_get_info(char *, char **, off_t, int);
extern int (*pdc202xx_display_info)(char *, char **, off_t, int); /* ide-proc.c */
extern char *ide_media_verbose(ide_drive_t *);
-static struct pci_dev *bmide_dev;
-static struct hd_driveid *id[4];
-static int speed_rate[4];
+
+#define PDC202_MAX_DEVS 5
+
+static struct pci_dev *pdc202_devs[PDC202_MAX_DEVS];
+static int n_pdc202_devs;
+
+char *pdc202xx_pio_verbose (u32 drive_pci)
+{
+ if ((drive_pci & 0x000ff000) == 0x000ff000) return("NOTSET");
+ if ((drive_pci & 0x00000401) == 0x00000401) return("PIO 4");
+ if ((drive_pci & 0x00000602) == 0x00000602) return("PIO 3");
+ if ((drive_pci & 0x00000803) == 0x00000803) return("PIO 2");
+ if ((drive_pci & 0x00000C05) == 0x00000C05) return("PIO 1");
+ if ((drive_pci & 0x00001309) == 0x00001309) return("PIO 0");
+ return("PIO ?");
+}
+
+char *pdc202xx_dma_verbose (u32 drive_pci)
+{
+ if ((drive_pci & 0x00036000) == 0x00036000) return("MWDMA 2");
+ if ((drive_pci & 0x00046000) == 0x00046000) return("MWDMA 1");
+ if ((drive_pci & 0x00056000) == 0x00056000) return("MWDMA 0");
+ if ((drive_pci & 0x00056000) == 0x00056000) return("SWDMA 2");
+ if ((drive_pci & 0x00068000) == 0x00068000) return("SWDMA 1");
+ if ((drive_pci & 0x000BC000) == 0x000BC000) return("SWDMA 0");
+ return("PIO---");
+}
+
+char *pdc202xx_ultra_verbose (u32 drive_pci, u16 slow_cable)
+{
+ if ((drive_pci & 0x000ff000) == 0x000ff000)
+ return("NOTSET");
+ if ((drive_pci & 0x00012000) == 0x00012000)
+ return((slow_cable) ? "UDMA 2" : "UDMA 4");
+ if ((drive_pci & 0x00024000) == 0x00024000)
+ return((slow_cable) ? "UDMA 1" : "UDMA 3");
+ if ((drive_pci & 0x00036000) == 0x00036000)
+ return("UDMA 0");
+ return(pdc202xx_dma_verbose(drive_pci));
+}
static char * pdc202xx_info (char *buf, struct pci_dev *dev)
{
@@ -99,10 +146,8 @@
u32 bibma = pci_resource_start(dev, 4);
u32 reg60h = 0, reg64h = 0, reg68h = 0, reg6ch = 0;
- u16 reg50h = 0;
- u16 word88 = 0;
- int udmasel[4] = {0,0,0,0}, piosel[4] = {0,0,0,0};
- int i = 0, hd = 0;
+ u16 reg50h = 0, pmask = (1<<10), smask = (1<<11);
+ u8 hi = 0, lo = 0;
/*
* at that point bibma+0x2 et bibma+0xa are byte registers
@@ -114,10 +159,10 @@
u8 sc11 = inb_p((unsigned short)bibma + 0x11);
u8 sc1a = inb_p((unsigned short)bibma + 0x1a);
u8 sc1b = inb_p((unsigned short)bibma + 0x1b);
- /* u8 sc1c = inb_p((unsigned short)bibma + 0x1c);
+ u8 sc1c = inb_p((unsigned short)bibma + 0x1c);
u8 sc1d = inb_p((unsigned short)bibma + 0x1d);
u8 sc1e = inb_p((unsigned short)bibma + 0x1e);
- u8 sc1f = inb_p((unsigned short)bibma + 0x1f); */
+ u8 sc1f = inb_p((unsigned short)bibma + 0x1f);
pci_read_config_word(dev, 0x50, ®50h);
pci_read_config_dword(dev, 0x60, ®60h);
@@ -125,75 +170,141 @@
pci_read_config_dword(dev, 0x68, ®68h);
pci_read_config_dword(dev, 0x6c, ®6ch);
- p+=sprintf(p, "\nPROMISE Ultra series driver Ver %s %s Adapter: ", VERSION, VERDATE);
+ p += sprintf(p, "\n ");
switch(dev->device) {
- case PCI_DEVICE_ID_PROMISE_20275:
- p += sprintf(p, "MBUltra133\n");
- break;
- case PCI_DEVICE_ID_PROMISE_20269:
- p += sprintf(p, "Ultra133 TX2\n");
- break;
- case PCI_DEVICE_ID_PROMISE_20268:
- p += sprintf(p, "Ultra100 TX2\n");
- break;
case PCI_DEVICE_ID_PROMISE_20267:
- p += sprintf(p, "Ultra100\n");
- break;
+ p += sprintf(p, "Ultra100"); break;
case PCI_DEVICE_ID_PROMISE_20265:
- p += sprintf(p, "Ultra100 on M/B\n");
- break;
+ p += sprintf(p, "Ultra100 on M/B"); break;
+ case PCI_DEVICE_ID_PROMISE_20263:
+ p += sprintf(p, "FastTrak 66"); break;
case PCI_DEVICE_ID_PROMISE_20262:
- p += sprintf(p, "Ultra66\n");
- break;
+ p += sprintf(p, "Ultra66"); break;
case PCI_DEVICE_ID_PROMISE_20246:
- p += sprintf(p, "Ultra33\n");
+ p += sprintf(p, "Ultra33");
reg50h |= 0x0c00;
break;
default:
- p += sprintf(p, "Ultra Series\n");
- break;
+ p += sprintf(p, "Ultra Series"); break;
}
+ p += sprintf(p, " Chipset.\n");
- p += sprintf(p, "--------------- Primary Channel ---------------- Secondary Channel -------------\n");
+ p += sprintf(p, "------------------------------- General Status "
+ "---------------------------------\n");
+ p += sprintf(p, "Burst Mode : %sabled\n",
+ (sc1f & 0x01) ? "en" : "dis");
+ p += sprintf(p, "Host Mode : %s\n",
+ (sc1f & 0x08) ? "Tri-Stated" : "Normal");
+ p += sprintf(p, "Bus Clocking : %s\n",
+ ((sc1f & 0xC0) == 0xC0) ? "100 External" :
+ ((sc1f & 0x80) == 0x80) ? "66 External" :
+ ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal");
+ p += sprintf(p, "IO pad select : %s mA\n",
+ ((sc1c & 0x03) == 0x03) ? "10" :
+ ((sc1c & 0x02) == 0x02) ? "8" :
+ ((sc1c & 0x01) == 0x01) ? "6" :
+ ((sc1c & 0x00) == 0x00) ? "4" : "??");
+ SPLIT_BYTE(sc1e, hi, lo);
+ p += sprintf(p, "Status Polling Period : %d\n", hi);
+ p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo);
+ p += sprintf(p, "--------------- Primary Channel "
+ "---------------- Secondary Channel "
+ "-------------\n");
p += sprintf(p, " %s %s\n",
(c0&0x80)?"disabled":"enabled ",
(c1&0x80)?"disabled":"enabled ");
p += sprintf(p, "66 Clocking %s %s\n",
(sc11&0x02)?"enabled ":"disabled",
(sc11&0x08)?"enabled ":"disabled");
- p += sprintf(p, "Mode %s %s\n",
+ p += sprintf(p, " Mode %s Mode %s\n",
(sc1a & 0x01) ? "MASTER" : "PCI ",
(sc1b & 0x01) ? "MASTER" : "PCI ");
- p += sprintf(p, "--------------- drive0 --------- drive1 -------- drive0 ---------- drive1 ------\n");
- p += sprintf(p, "DMA enabled: %s %s %s %s\n",
- (id[0]!=NULL && (c0&0x20))?"yes":"no ",(id[1]!=NULL && (c0&0x40))?"yes":"no ",
- (id[2]!=NULL && (c1&0x20))?"yes":"no ",(id[3]!=NULL && (c1&0x40))?"yes":"no ");
- for( hd = 0; hd < 4 ; hd++) {
- if (id[hd] == NULL)
- continue;
- word88 = id[hd]->dma_ultra;
- for ( i = 7 ; i >= 0 ; i--)
- if (word88 >> (i+8)) {
- udmasel[hd] = i; /* get select UDMA mode */
- break;
- }
- piosel[hd] = (id[hd]->eide_pio_modes >= 0x02) ? 4 : 3;
- }
- p += sprintf(p, "UDMA Mode: %d %d %d %d\n",
- udmasel[0], udmasel[1], udmasel[2], udmasel[3]);
- p += sprintf(p, "PIO Mode: %d %d %d %d\n",
- piosel[0], piosel[1], piosel[2], piosel[3]);
+ p += sprintf(p, " %s %s\n",
+ (sc1d & 0x08) ? "Error " :
+ ((sc1d & 0x05) == 0x05) ? "Not My INTR " :
+ (sc1d & 0x04) ? "Interrupting" :
+ (sc1d & 0x02) ? "FIFO Full " :
+ (sc1d & 0x01) ? "FIFO Empty " : "????????????",
+ (sc1d & 0x80) ? "Error " :
+ ((sc1d & 0x50) == 0x50) ? "Not My INTR " :
+ (sc1d & 0x40) ? "Interrupting" :
+ (sc1d & 0x20) ? "FIFO Full " :
+ (sc1d & 0x10) ? "FIFO Empty " : "????????????");
+ p += sprintf(p, "--------------- drive0 --------- drive1 "
+ "-------- drive0 ---------- drive1 ------\n");
+ p += sprintf(p, "DMA enabled: %s %s "
+ " %s %s\n",
+ (c0&0x20)?"yes":"no ", (c0&0x40)?"yes":"no ",
+ (c1&0x20)?"yes":"no ", (c1&0x40)?"yes":"no ");
+ p += sprintf(p, "DMA Mode: %s %s "
+ " %s %s\n",
+ pdc202xx_ultra_verbose(reg60h, (reg50h & pmask)),
+ pdc202xx_ultra_verbose(reg64h, (reg50h & pmask)),
+ pdc202xx_ultra_verbose(reg68h, (reg50h & smask)),
+ pdc202xx_ultra_verbose(reg6ch, (reg50h & smask)));
+ p += sprintf(p, "PIO Mode: %s %s "
+ " %s %s\n",
+ pdc202xx_pio_verbose(reg60h),
+ pdc202xx_pio_verbose(reg64h),
+ pdc202xx_pio_verbose(reg68h),
+ pdc202xx_pio_verbose(reg6ch));
#if 0
p += sprintf(p, "--------------- Can ATAPI DMA ---------------\n");
#endif
return (char *)p;
}
+static char * pdc202xx_info_new (char *buf, struct pci_dev *dev)
+{
+ char *p = buf;
+
+ p += sprintf(p, "\n ");
+ switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
+ p += sprintf(p, "SBFastTrak 133 Lite"); break;
+ case PCI_DEVICE_ID_PROMISE_20276:
+ p += sprintf(p, "MBFastTrak 133 Lite"); break;
+ case PCI_DEVICE_ID_PROMISE_20275:
+ p += sprintf(p, "MBUltra133"); break;
+ case PCI_DEVICE_ID_PROMISE_20271:
+ p += sprintf(p, "FastTrak TX2000"); break;
+ case PCI_DEVICE_ID_PROMISE_20270:
+ p += sprintf(p, "FastTrak LP/TX2/TX4"); break;
+ case PCI_DEVICE_ID_PROMISE_20269:
+ p += sprintf(p, "Ultra133 TX2"); break;
+ case PCI_DEVICE_ID_PROMISE_20268:
+ p += sprintf(p, "Ultra100 TX2"); break;
+ default:
+ p += sprintf(p, "Ultra series"); break;
+ break;
+ }
+ p += sprintf(p, " Chipset.\n");
+ return (char *)p;
+}
+
static int pdc202xx_get_info (char *buffer, char **addr, off_t offset, int count)
{
char *p = buffer;
-
- p = pdc202xx_info(buffer, bmide_dev);
+ int i;
+
+ for (i = 0; i < n_pdc202_devs; i++) {
+ struct pci_dev *dev = pdc202_devs[i];
+
+ switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ case PCI_DEVICE_ID_PROMISE_20270:
+ p = pdc202xx_info_new(buffer, dev);
+ break;
+ default:
+ p = pdc202xx_info(buffer, dev);
+ break;
+ }
+ }
return p-buffer; /* => must be less than 4k! */
}
#endif /* defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS) */
@@ -324,6 +435,66 @@
#endif /* PDC202XX_DECODE_REGISTER_INFO */
+static byte pdc202xx_ratemask (ide_drive_t *drive)
+{
+ struct pci_dev *dev = HWIF(drive)->pci_dev;
+ u8 mode = 0;
+
+ switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ mode |= 0x04;
+ break;
+ case PCI_DEVICE_ID_PROMISE_20270:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ mode |= 0x03;
+ break;
+ case PCI_DEVICE_ID_PROMISE_20267:
+ case PCI_DEVICE_ID_PROMISE_20265:
+ mode |= 0x03;
+ break;
+ case PCI_DEVICE_ID_PROMISE_20263:
+ case PCI_DEVICE_ID_PROMISE_20262:
+ mode |= 0x02;
+ break;
+ case PCI_DEVICE_ID_PROMISE_20246:
+ mode |= 0x01;
+ break;
+ default:
+ return (mode &= ~0xF8);
+ }
+
+ if (!eighty_ninty_three(drive) &&(mode)) {
+ mode &= ~0xFE;
+ mode |= 0x01;
+ }
+ return (mode &= ~0xF8);
+}
+
+static byte pdc202xx_ratefilter (ide_drive_t *drive, byte speed)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ u8 mode = pdc202xx_ratemask(drive);
+
+ switch(mode) {
+ case 0x04: while (speed > XFER_UDMA_6) speed--; break;
+ case 0x03: while (speed > XFER_UDMA_5) speed--; break;
+ case 0x02: while (speed > XFER_UDMA_4) speed--; break;
+ case 0x01: while (speed > XFER_UDMA_2) speed--; break;
+ case 0x00:
+ default: while (speed > XFER_MW_DMA_2) speed--; break;
+ break;
+ }
+#else
+ while (speed > XFER_PIO_4) speed--;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
+// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed);
+ return speed;
+}
+
static int check_in_drive_lists (ide_drive_t *drive, const char **list)
{
struct hd_driveid *id = drive->id;
@@ -344,25 +515,19 @@
return 0;
}
-static int pdc202xx_tune_chipset (ide_drive_t *drive, byte speed)
+static int pdc202xx_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
+ u8 drive_pci = 0x60 + (drive->dn << 2);
+ u8 speed = pdc202xx_ratefilter(drive, xferspeed);
unsigned int drive_conf;
- int err = 0, i = 0, j = hwif->channel ? 2 : 0 ;
- byte drive_pci, AP, BP, CP, DP;
+ byte AP, BP, CP, DP;
byte TA = 0, TB = 0, TC = 0;
- switch (drive->dn) {
- case 0: drive_pci = 0x60; break;
- case 1: drive_pci = 0x64; break;
- case 2: drive_pci = 0x68; break;
- case 3: drive_pci = 0x6c; break;
- default: return -1;
- }
-
- if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0)) return -1;
+ if ((drive->media != ide_disk) && (speed < XFER_SW_DMA_0))
+ return -1;
pci_read_config_dword(dev, drive_pci, &drive_conf);
pci_read_config_byte(dev, (drive_pci), &AP);
@@ -370,59 +535,53 @@
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
pci_read_config_byte(dev, (drive_pci)|0x03, &DP);
-#ifdef CONFIG_BLK_DEV_IDEDMA
- if (speed >= XFER_SW_DMA_0) {
- if ((BP & 0xF0) && (CP & 0x0F)) {
- /* clear DMA modes of upper 842 bits of B Register */
- /* clear PIO forced mode upper 1 bit of B Register */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0xF0);
- pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
-
- /* clear DMA modes of lower 8421 bits of C Register */
- pci_write_config_byte(dev, (drive_pci)|0x02, CP & ~0x0F);
- pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
- }
- } else {
-#else
- {
-#endif /* CONFIG_BLK_DEV_IDEDMA */
+ if (speed < XFER_SW_DMA_0) {
if ((AP & 0x0F) || (BP & 0x07)) {
/* clear PIO modes of lower 8421 bits of A Register */
- pci_write_config_byte(dev, (drive_pci), AP & ~0x0F);
+ pci_write_config_byte(dev, (drive_pci), AP &~0x0F);
pci_read_config_byte(dev, (drive_pci), &AP);
/* clear PIO modes of lower 421 bits of B Register */
- pci_write_config_byte(dev, (drive_pci)|0x01, BP & ~0x07);
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0x07);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
pci_read_config_byte(dev, (drive_pci), &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
}
+#ifdef CONFIG_BLK_DEV_IDEDMA
+ } else {
+ if ((BP & 0xF0) && (CP & 0x0F)) {
+ /* clear DMA modes of upper 842 bits of B Register */
+ /* clear PIO forced mode upper 1 bit of B Register */
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP &~0xF0);
+ pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
+
+ /* clear DMA modes of lower 8421 bits of C Register */
+ pci_write_config_byte(dev, (drive_pci)|0x02, CP &~0x0F);
+ pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
+ }
+#endif /* CONFIG_BLK_DEV_IDEDMA */
}
pci_read_config_byte(dev, (drive_pci), &AP);
pci_read_config_byte(dev, (drive_pci)|0x01, &BP);
pci_read_config_byte(dev, (drive_pci)|0x02, &CP);
- for ( i = 0; i < 2; i++)
- if (hwif->drives[i].present)
- id[i+j] = hwif->drives[i].id; /* get identify structs */
-
switch(speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
/* case XFER_UDMA_6: */
case XFER_UDMA_5:
- case XFER_UDMA_4: TB = 0x20; TC = 0x01; break; /* speed 8 == UDMA mode 4 */
- case XFER_UDMA_3: TB = 0x40; TC = 0x02; break; /* speed 7 == UDMA mode 3 */
- case XFER_UDMA_2: TB = 0x20; TC = 0x01; break; /* speed 6 == UDMA mode 2 */
- case XFER_UDMA_1: TB = 0x40; TC = 0x02; break; /* speed 5 == UDMA mode 1 */
- case XFER_UDMA_0: TB = 0x60; TC = 0x03; break; /* speed 4 == UDMA mode 0 */
- case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break; /* speed 4 == MDMA mode 2 */
- case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break; /* speed 3 == MDMA mode 1 */
- case XFER_MW_DMA_0: TB = 0x60; TC = 0x05; break; /* speed 2 == MDMA mode 0 */
- case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break; /* speed 0 == SDMA mode 2 */
- case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break; /* speed 1 == SDMA mode 1 */
- case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break; /* speed 0 == SDMA mode 0 */
+ case XFER_UDMA_4: TB = 0x20; TC = 0x01; break;
+ case XFER_UDMA_3: TB = 0x40; TC = 0x02; break;
+ case XFER_UDMA_2: TB = 0x20; TC = 0x01; break;
+ case XFER_UDMA_1: TB = 0x40; TC = 0x02; break;
+ case XFER_UDMA_0: TB = 0x60; TC = 0x03; break;
+ case XFER_MW_DMA_2: TB = 0x60; TC = 0x03; break;
+ case XFER_MW_DMA_1: TB = 0x60; TC = 0x04; break;
+ case XFER_MW_DMA_0: TB = 0x60; TC = 0x05; break;
+ case XFER_SW_DMA_2: TB = 0x60; TC = 0x05; break;
+ case XFER_SW_DMA_1: TB = 0x80; TC = 0x06; break;
+ case XFER_SW_DMA_0: TB = 0xC0; TC = 0x0B; break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
case XFER_PIO_4: TA = 0x01; TB = 0x04; break;
case XFER_PIO_3: TA = 0x02; TB = 0x06; break;
@@ -432,16 +591,14 @@
default: TA = 0x09; TB = 0x13; break;
}
+ if (speed < XFER_SW_DMA_0) {
+ pci_write_config_byte(dev, (drive_pci), AP|TA);
+ pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
#ifdef CONFIG_BLK_DEV_IDEDMA
- if (speed >= XFER_SW_DMA_0) {
+ } else {
pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);
- } else {
-#else
- {
#endif /* CONFIG_BLK_DEV_IDEDMA */
- pci_write_config_byte(dev, (drive_pci), AP|TA);
- pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);
}
#if PDC202XX_DECODE_REGISTER_INFO
@@ -455,12 +612,6 @@
decode_registers(REG_C, CP);
decode_registers(REG_D, DP);
#endif /* PDC202XX_DECODE_REGISTER_INFO */
-
- if (!drive->init_speed)
- drive->init_speed = speed;
- err = ide_config_drive_speed(drive, speed);
- drive->current_speed = speed;
-
#if PDC202XX_DEBUG_DRIVE_INFO
printk("%s: %s drive%d 0x%08x ",
drive->name, ide_xfer_verbose(speed),
@@ -468,175 +619,87 @@
pci_read_config_dword(dev, drive_pci, &drive_conf);
printk("0x%08x\n", drive_conf);
#endif /* PDC202XX_DEBUG_DRIVE_INFO */
- return err;
+
+ return (ide_config_drive_speed(drive, speed));
}
-static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte speed)
+#define set_2regs(a, b) \
+ do { \
+ OUT_BYTE((a + adj), indexreg); \
+ OUT_BYTE(b, datareg); \
+ } while(0)
+
+#define set_ultra(a, b, c) \
+ do { \
+ set_2regs(0x10,(a)); \
+ set_2regs(0x11,(b)); \
+ set_2regs(0x12,(c)); \
+ } while(0)
+
+#define set_ata2(a, b) \
+ do { \
+ set_2regs(0x0e,(a)); \
+ set_2regs(0x0f,(b)); \
+ } while(0)
+
+#define set_pio(a, b, c) \
+ do { \
+ set_2regs(0x0c,(a)); \
+ set_2regs(0x0d,(b)); \
+ set_2regs(0x13,(c)); \
+ } while(0)
+
+
+static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte xferspeed)
{
ide_hwif_t *hwif = HWIF(drive);
+ unsigned long dma_base = hwif->dma_base;
#ifdef CONFIG_BLK_DEV_IDEDMA
- unsigned long indexreg = (hwif->dma_base + 1);
- unsigned long datareg = (hwif->dma_base + 3);
+ u32 indexreg = dma_base+1;
+ u32 datareg = dma_base+3;
#else
struct pci_dev *dev = hwif->pci_dev;
- unsigned long high_16 = pci_resource_start(dev, 4);
- unsigned long indexreg = high_16 + (hwif->channel ? 0x09 : 0x01);
- unsigned long datareg = (indexreg + 2);
+ u32 high_16 = pci_resource_start(dev, 4);
+ u32 indexreg = high_16 + (hwif->channel ? 0x09 : 0x01);
+ u32 datareg = (indexreg + 2);
#endif /* CONFIG_BLK_DEV_IDEDMA */
- byte thold = 0x10;
- byte adj = (drive->dn%2) ? 0x08 : 0x00;
- int set_speed = 0, i=0, j=hwif->channel ? 2:0;
- int err;
+ u8 thold = 0x10;
+ u8 adj = (drive->dn%2) ? 0x08 : 0x00;
+ u8 speed = pdc202xx_ratefilter(drive, xferspeed);
- /* Setting tHOLD bit to 0 if using UDMA mode 2 */
+#ifdef CONFIG_BLK_DEV_IDEDMA
if (speed == XFER_UDMA_2) {
+ u8 data = 0;
OUT_BYTE((thold + adj), indexreg);
- OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg);
+ data = IN_BYTE(datareg);
+ OUT_BYTE((data & 0x7f), datareg);
}
-
- /* We need to set ATA133 timing if ATA133 drives exist */
- if (speed>=XFER_UDMA_6)
- set_speed=1;
+#endif /* CONFIG_BLK_DEV_IDEDMA */
- if (!drive->init_speed)
- drive->init_speed = speed;
-#if PDC202XX_DEBUG_DRIVE_INFO
- printk("%s: Before set_feature = %s, word88 = %#x\n",
- drive->name, ide_xfer_verbose(speed), drive->id->dma_ultra );
-#endif /* PDC202XX_DEBUG_DRIVE_INFO */
- err = ide_config_drive_speed(drive, speed);
- drive->current_speed = speed;
- for ( i = 0 ; i < 2 ; i++)
- if (hwif->drives[i].present) {
- id[i+j] = hwif->drives[i].id; /* get identify structs */
- speed_rate[i+j] = speed; /* get current speed */
- }
- if (set_speed) {
- for (i=0; i<4; i++) {
- if (id[i]==NULL)
- continue;
- switch(speed_rate[i]) {
+ switch (speed) {
#ifdef CONFIG_BLK_DEV_IDEDMA
- case XFER_UDMA_6:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x1a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x01, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xcb, datareg);
- break;
- case XFER_UDMA_5:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x1a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x02, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xcb, datareg);
- break;
- case XFER_UDMA_4:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x1a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x03, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xcd, datareg);
- break;
- case XFER_UDMA_3:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x1a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x05, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xcd, datareg);
- break;
- case XFER_UDMA_2:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x2a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x07, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xcd, datareg);
- break;
- case XFER_UDMA_1:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x3a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x0a, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xd0, datareg);
- break;
- case XFER_UDMA_0:
- OUT_BYTE((0x10 + adj), indexreg);
- OUT_BYTE(0x4a, datareg);
- OUT_BYTE((0x11 + adj), indexreg);
- OUT_BYTE(0x0f, datareg);
- OUT_BYTE((0x12 + adj), indexreg);
- OUT_BYTE(0xd5, datareg);
- break;
- case XFER_MW_DMA_2:
- OUT_BYTE((0x0e + adj), indexreg);
- OUT_BYTE(0x69, datareg);
- OUT_BYTE((0x0f + adj), indexreg);
- OUT_BYTE(0x25, datareg);
- break;
- case XFER_MW_DMA_1:
- OUT_BYTE((0x0e + adj), indexreg);
- OUT_BYTE(0x6b, datareg);
- OUT_BYTE((0x0f+ adj), indexreg);
- OUT_BYTE(0x27, datareg);
- break;
- case XFER_MW_DMA_0:
- OUT_BYTE((0x0e + adj), indexreg);
- OUT_BYTE(0xdf, datareg);
- OUT_BYTE((0x0f + adj), indexreg);
- OUT_BYTE(0x5f, datareg);
- break;
+ case XFER_UDMA_7:
+ speed = XFER_UDMA_6;
+ case XFER_UDMA_6: set_ultra(0x1a, 0x01, 0xcb); break;
+ case XFER_UDMA_5: set_ultra(0x1a, 0x02, 0xcb); break;
+ case XFER_UDMA_4: set_ultra(0x1a, 0x03, 0xcd); break;
+ case XFER_UDMA_3: set_ultra(0x1a, 0x05, 0xcd); break;
+ case XFER_UDMA_2: set_ultra(0x2a, 0x07, 0xcd); break;
+ case XFER_UDMA_1: set_ultra(0x3a, 0x0a, 0xd0); break;
+ case XFER_UDMA_0: set_ultra(0x4a, 0x0f, 0xd5); break;
+ case XFER_MW_DMA_2: set_ata2(0x69, 0x25); break;
+ case XFER_MW_DMA_1: set_ata2(0x6b, 0x27); break;
+ case XFER_MW_DMA_0: set_ata2(0xdf, 0x5f); break;
#endif /* CONFIG_BLK_DEV_IDEDMA */
- case XFER_PIO_4:
- OUT_BYTE((0x0c + adj), indexreg);
- OUT_BYTE(0x23, datareg);
- OUT_BYTE((0x0d + adj), indexreg);
- OUT_BYTE(0x09, datareg);
- OUT_BYTE((0x13 + adj), indexreg);
- OUT_BYTE(0x25, datareg);
- break;
- case XFER_PIO_3:
- OUT_BYTE((0x0c + adj), indexreg);
- OUT_BYTE(0x27, datareg);
- OUT_BYTE((0x0d + adj), indexreg);
- OUT_BYTE(0x0d, datareg);
- OUT_BYTE((0x13 + adj), indexreg);
- OUT_BYTE(0x35, datareg);
- break;
- case XFER_PIO_2:
- OUT_BYTE((0x0c + adj), indexreg);
- OUT_BYTE(0x23, datareg);
- OUT_BYTE((0x0d + adj), indexreg);
- OUT_BYTE(0x26, datareg);
- OUT_BYTE((0x13 + adj), indexreg);
- OUT_BYTE(0x64, datareg);
- break;
- case XFER_PIO_1:
- OUT_BYTE((0x0c + adj), indexreg);
- OUT_BYTE(0x46, datareg);
- OUT_BYTE((0x0d + adj), indexreg);
- OUT_BYTE(0x29, datareg);
- OUT_BYTE((0x13 + adj), indexreg);
- OUT_BYTE(0xa4, datareg);
- break;
- case XFER_PIO_0:
- OUT_BYTE((0x0c + adj), indexreg);
- OUT_BYTE(0xfb, datareg);
- OUT_BYTE((0x0d + adj), indexreg);
- OUT_BYTE(0x2b, datareg);
- OUT_BYTE((0x13 + adj), indexreg);
- OUT_BYTE(0xac, datareg);
- break;
- default:
- }
- }
+ case XFER_PIO_4: set_pio(0x23, 0x09, 0x25); break;
+ case XFER_PIO_3: set_pio(0x27, 0x0d, 0x35); break;
+ case XFER_PIO_2: set_pio(0x23, 0x26, 0x64); break;
+ case XFER_PIO_1: set_pio(0x46, 0x29, 0xa4); break;
+ case XFER_PIO_0: set_pio(0xfb, 0x2b, 0xac); break;
+ default:
}
- return err;
+
+ return (ide_config_drive_speed(drive, speed));
}
/* 0 1 2 3 4 5 6 7 8
@@ -648,7 +711,7 @@
*/
static int config_chipset_for_pio (ide_drive_t *drive, byte pio)
{
- byte speed = 0x00;
+ u8 speed = 0;
pio = (pio == 5) ? 4 : pio;
speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
@@ -662,77 +725,89 @@
}
#ifdef CONFIG_BLK_DEV_IDEDMA
-static int config_chipset_for_dma (ide_drive_t *drive, byte ultra)
+
+static u8 pdc202xx_new_cable_detect (ide_hwif_t *hwif)
+{
+ u8 ata66 = 0;
+ unsigned long dma_base = hwif->dma_base;
+
+ /* Fake detection on RackMac on-board controller */
+#ifdef __CONFIG_ALL_PPC_DISABLED
+ if (machine_is_compatible("RackMac1,1")) {
+ struct device_node *np;
+ np = pci_device_to_OF_node(hwif->pci_dev);
+ if (np && !strcmp(np->name, "AppleKiwi"))
+ return 0;
+ }
+#endif /* CONFIG_ALL_PPC */
+ if (dma_base == 0)
+ dma_base = pci_resource_start(hwif->pci_dev, 4);
+ OUT_BYTE(0x0b, dma_base + 1);
+ ata66 = IN_BYTE(dma_base + 3);
+ return (ata66 & 0x04);
+}
+
+static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
+{
+ u16 CIS = 0, mask = (hwif->channel) ? (1<<11) : (1<<10);
+ pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
+ return ((u8)(CIS & mask));
+}
+
+static int config_chipset_for_dma (ide_drive_t *drive)
{
struct hd_driveid *id = drive->id;
+ u8 mode = pdc202xx_ratemask(drive);
ide_hwif_t *hwif = HWIF(drive);
struct pci_dev *dev = hwif->pci_dev;
- unsigned long high_16 = pci_resource_start(dev, 4);
- unsigned long dma_base = hwif->dma_base;
- unsigned long indexreg = dma_base + 1;
- unsigned long datareg = dma_base + 3;
+ u32 high_16 = pci_resource_start(dev, 4);
+ u32 indexreg = hwif->dma_base+1;
+ u32 datareg = hwif->dma_base+3;
byte iordy = 0x13;
byte adj = (drive->dn%2) ? 0x08 : 0x00;
byte cable = 0;
- byte new_chip = 0;
- byte unit = (drive->select.b.unit & 0x01);
+ byte jumpbit = 0;
unsigned int drive_conf;
byte drive_pci = 0;
byte test1, test2, speed = -1;
byte AP;
- unsigned short EP;
byte CLKSPD = 0;
- byte clockreg = high_16 + 0x11;
- byte udma_33 = ultra;
- byte udma_66 = ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;
+ byte udma_66 = (eighty_ninty_three(drive)) ? 1 : 0;
byte udma_100 = 0;
byte udma_133 = 0;
- byte mask = hwif->channel ? 0x08 : 0x02;
- unsigned short c_mask = hwif->channel ? (1<<11) : (1<<10);
+ byte mask = hwif->channel ? 0x08 : 0x02;
byte ultra_66 = ((id->dma_ultra & 0x0010) ||
(id->dma_ultra & 0x0008)) ? 1 : 0;
- byte ultra_100 = ((id->dma_ultra & 0x0020) ||
- (ultra_66)) ? 1 : 0;
- byte ultra_133 = ((id->dma_ultra & 0x0040) ||
- (ultra_100)) ? 1 : 0;
switch(dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
case PCI_DEVICE_ID_PROMISE_20269:
udma_133 = (udma_66) ? 1 : 0;
udma_100 = (udma_66) ? 1 : 0;
- OUT_BYTE(0x0b, (hwif->dma_base + 1));
- cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));
- new_chip = 1;
- break;
- case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20270:
- udma_100 = (udma_66) ? 1 : 0;
- OUT_BYTE(0x0b, (hwif->dma_base + 1));
- cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));
- new_chip = 1;
+ case PCI_DEVICE_ID_PROMISE_20268:
+ cable = pdc202xx_new_cable_detect(hwif);
+ jumpbit = 1;
break;
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265:
udma_100 = (udma_66) ? 1 : 0;
- pci_read_config_word(dev, 0x50, &EP);
- cable = (EP & c_mask);
- new_chip = 0;
- CLKSPD = IN_BYTE(clockreg);
- break;
+ case PCI_DEVICE_ID_PROMISE_20263:
case PCI_DEVICE_ID_PROMISE_20262:
- pci_read_config_word(dev, 0x50, &EP);
- cable = (EP & c_mask);
- new_chip = 0;
- CLKSPD = IN_BYTE(clockreg);
+ cable = pdc202xx_old_cable_detect(hwif);
+ jumpbit = 0;
break;
default:
- udma_100 = 0; udma_133 = 0; cable = 0; new_chip = 1;
+ cable = 1; jumpbit = 0;
break;
}
+ if (!jumpbit)
+ CLKSPD = IN_BYTE(high_16 + 0x11);
/*
* Set the control register to use the 66Mhz system
* clock for UDMA 3/4 mode operation. If one drive on
@@ -746,122 +821,130 @@
* parameters.
*/
- if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {
-#ifdef DEBUG
- printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");
+ if ((ultra_66) && (cable)) {
+#if 1
+ printk("ULTRA 66/100/133: %s channel of Ultra 66/100/133 "
+ "requires an 80-pin cable for Ultra66 operation.\n",
+ hwif->channel ? "Secondary" : "Primary");
printk(" Switching to Ultra33 mode.\n");
#endif /* DEBUG */
/* Primary : zero out second bit */
/* Secondary : zero out fourth bit */
- //if (!new_chip)
- OUT_BYTE(CLKSPD & ~mask, clockreg);
+ if (!jumpbit)
+ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");
printk("%s reduced to Ultra33 mode.\n", drive->name);
- udma_66 = 0; udma_100 = 0; udma_133 = 0;
+ udma_66 = 0;
} else {
- if ((ultra_66) || (ultra_100) || (ultra_133)) {
+ if (ultra_66) {
/*
* check to make sure drive on same channel
* is u66 capable
*/
if (hwif->drives[!(drive->dn%2)].id) {
- if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0040) ||
- (hwif->drives[!(drive->dn%2)].id->dma_ultra
-& 0x0020) ||
- (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||
- (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {
- OUT_BYTE(CLKSPD | mask, clockreg);
+ if (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0078) {
+ if (!jumpbit)
+ OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
} else {
- OUT_BYTE(CLKSPD & ~mask, clockreg);
+ if (!jumpbit)
+ OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));
}
} else { /* udma4 drive by itself */
- OUT_BYTE(CLKSPD | mask, clockreg);
+ if (!jumpbit)
+ OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));
}
}
}
- if (new_chip) goto chipset_is_set;
+ if (jumpbit) {
+ if (drive->media != ide_disk)
+ return ide_dma_off_quietly;
+ if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */
+ u8 data = 0;
+ OUT_BYTE((iordy + adj), indexreg);
+ data = IN_BYTE(datareg);
+ OUT_BYTE((data|0x03), datareg);
+ }
+ goto jumpbit_is_set;
+ }
- switch(drive->dn) {
- case 0: drive_pci = 0x60;
- pci_read_config_dword(dev, drive_pci, &drive_conf);
- if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
- goto chipset_is_set;
- pci_read_config_byte(dev, (drive_pci), &test1);
- if (!(test1 & SYNC_ERRDY_EN))
- pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);
- break;
- case 1: drive_pci = 0x64;
- pci_read_config_dword(dev, drive_pci, &drive_conf);
- if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
- goto chipset_is_set;
- pci_read_config_byte(dev, 0x60, &test1);
- pci_read_config_byte(dev, (drive_pci), &test2);
- if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))
- pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN);
- break;
- case 2: drive_pci = 0x68;
- pci_read_config_dword(dev, drive_pci, &drive_conf);
- if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
- goto chipset_is_set;
- pci_read_config_byte(dev, (drive_pci), &test1);
- if (!(test1 & SYNC_ERRDY_EN))
- pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);
- break;
- case 3: drive_pci = 0x6c;
- pci_read_config_dword(dev, drive_pci, &drive_conf);
- if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
- goto chipset_is_set;
- pci_read_config_byte(dev, 0x68, &test1);
- pci_read_config_byte(dev, (drive_pci), &test2);
- if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))
- pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN);
- break;
- default:
- return ide_dma_off;
+ drive_pci = 0x60 + (drive->dn << 2);
+ pci_read_config_dword(dev, drive_pci, &drive_conf);
+ if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))
+ goto chipset_is_set;
+
+ pci_read_config_byte(dev, drive_pci, &test1);
+ if (!(test1 & SYNC_ERRDY_EN)) {
+ if (drive->select.b.unit & 0x01) {
+ pci_read_config_byte(dev, drive_pci - 4, &test2);
+ if ((test2 & SYNC_ERRDY_EN) &&
+ !(test1 & SYNC_ERRDY_EN)) {
+ pci_write_config_byte(dev, drive_pci,
+ test1|SYNC_ERRDY_EN);
+ }
+ } else {
+ pci_write_config_byte(dev, drive_pci,
+ test1|SYNC_ERRDY_EN);
+ }
}
chipset_is_set:
- if (drive->media != ide_disk)
+ if (drive->media != ide_disk) {
+ hwif->tuneproc(drive, 5);
return ide_dma_off_quietly;
-
- if (new_chip) {
- if (id->capability & 4) { /* IORDY_EN & PREFETCH_EN */
- OUT_BYTE((iordy + adj), indexreg);
- OUT_BYTE((IN_BYTE(datareg)|0x03), datareg);
- }
}
- else {
- pci_read_config_byte(dev, (drive_pci), &AP);
- if (id->capability & 4) /* IORDY_EN */
- pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
- pci_read_config_byte(dev, (drive_pci), &AP);
- if (drive->media == ide_disk) /* PREFETCH_EN */
- pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
- }
-
- if ((id->dma_ultra & 0x0040)&&(udma_133)) speed = XFER_UDMA_6;
- else if ((id->dma_ultra & 0x0020)&&(udma_100)) speed = XFER_UDMA_5;
- else if ((id->dma_ultra & 0x0010)&&(udma_66)) speed = XFER_UDMA_4;
- else if ((id->dma_ultra & 0x0008)&&(udma_66)) speed = XFER_UDMA_3;
- else if ((id->dma_ultra & 0x0004)&&(udma_33)) speed = XFER_UDMA_2;
- else if ((id->dma_ultra & 0x0002)&&(udma_33)) speed = XFER_UDMA_1;
- else if ((id->dma_ultra & 0x0001)&&(udma_33)) speed = XFER_UDMA_0;
- else if (id->dma_mword & 0x0004) speed = XFER_MW_DMA_2;
- else if (id->dma_mword & 0x0002) speed = XFER_MW_DMA_1;
- else if (id->dma_mword & 0x0001) speed = XFER_MW_DMA_0;
- else if ((id->dma_1word & 0x0004)&&(!new_chip)) speed = XFER_SW_DMA_2;
- else if ((id->dma_1word & 0x0002)&&(!new_chip)) speed = XFER_SW_DMA_1;
- else if ((id->dma_1word & 0x0001)&&(!new_chip)) speed = XFER_SW_DMA_0;
- else {
- /* restore original pci-config space */
- if (!new_chip)
- pci_write_config_dword(dev, drive_pci, drive_conf);
- return ide_dma_off_quietly;
+
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ if (id->capability & 4) /* IORDY_EN */
+ pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);
+ pci_read_config_byte(dev, (drive_pci), &AP);
+ if (drive->media == ide_disk) /* PREFETCH_EN */
+ pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);
+
+jumpbit_is_set:
+
+ switch(mode) {
+ case 0x04:
+ if (id->dma_ultra & 0x0040)
+ { speed = XFER_UDMA_6; break; }
+ case 0x03:
+ if (id->dma_ultra & 0x0020)
+ { speed = XFER_UDMA_5; break; }
+ case 0x02:
+ if (id->dma_ultra & 0x0010)
+ { speed = XFER_UDMA_4; break; }
+ if (id->dma_ultra & 0x0008)
+ { speed = XFER_UDMA_3; break; }
+ case 0x01:
+ if (id->dma_ultra & 0x0004)
+ { speed = XFER_UDMA_2; break; }
+ if (id->dma_ultra & 0x0002)
+ { speed = XFER_UDMA_1; break; }
+ if (id->dma_ultra & 0x0001)
+ { speed = XFER_UDMA_0; break; }
+ case 0x00:
+ if (id->dma_mword & 0x0004)
+ { speed = XFER_MW_DMA_2; break; }
+ if (id->dma_mword & 0x0002)
+ { speed = XFER_MW_DMA_1; break; }
+ if (id->dma_mword & 0x0001)
+ { speed = XFER_MW_DMA_0; break; }
+ if ((id->dma_1word & 0x0004) && (!jumpbit))
+ { speed = XFER_SW_DMA_2; break; }
+ if ((id->dma_1word & 0x0002) && (!jumpbit))
+ { speed = XFER_SW_DMA_1; break; }
+ if ((id->dma_1word & 0x0001) && (!jumpbit))
+ { speed = XFER_SW_DMA_0; break; }
+ default:
+
+ /* restore original pci-config space */
+ if (!jumpbit)
+ pci_write_config_dword(dev, drive_pci, drive_conf);
+ hwif->tuneproc(drive, 5);
+ return ide_dma_off_quietly;
}
- outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);
(void) hwif->speedproc(drive, speed);
return ((int) ((id->dma_ultra >> 14) & 3) ? ide_dma_on :
@@ -872,23 +955,24 @@
ide_dma_off_quietly);
}
-static int config_drive_xfer_rate (ide_drive_t *drive)
+int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
{
- struct hd_driveid *id = drive->id;
- ide_hwif_t *hwif = HWIF(drive);
- ide_dma_action_t dma_func = ide_dma_off_quietly;
+ struct hd_driveid *id = drive->id;
+ ide_hwif_t *hwif = HWIF(drive);
+ ide_dma_action_t dma_func = ide_dma_off_quietly;
- if (id && (id->capability & 1) && hwif->autodma) {
+ drive->init_speed = 0;
+
+ if (id && (id->capability & 1) && HWIF(drive)->autodma) {
/* Consult the list of known "bad" drives */
if (ide_dmaproc(ide_dma_bad_drive, drive)) {
dma_func = ide_dma_off;
goto fast_ata_pio;
}
- dma_func = ide_dma_off_quietly;
if (id->field_valid & 4) {
if (id->dma_ultra & 0x007F) {
/* Force if Capable UltraDMA */
- dma_func = config_chipset_for_dma(drive, 1);
+ dma_func = config_chipset_for_dma(drive);
if ((id->field_valid & 2) &&
(dma_func != ide_dma_on))
goto try_dma_modes;
@@ -898,16 +982,15 @@
if ((id->dma_mword & 0x0007) ||
(id->dma_1word & 0x0007)) {
/* Force if Capable regular DMA modes */
- dma_func = config_chipset_for_dma(drive, 0);
+ dma_func = config_chipset_for_dma(drive);
if (dma_func != ide_dma_on)
goto no_dma_set;
}
} else if (ide_dmaproc(ide_dma_good_drive, drive)) {
- if (id->eide_dma_time > 150) {
+ if (id->eide_dma_time > 150)
goto no_dma_set;
- }
/* Consult the list of known "good" drives */
- dma_func = config_chipset_for_dma(drive, 0);
+ dma_func = config_chipset_for_dma(drive);
if (dma_func != ide_dma_on)
goto no_dma_set;
} else {
@@ -917,10 +1000,9 @@
fast_ata_pio:
dma_func = ide_dma_off_quietly;
no_dma_set:
- (void) config_chipset_for_pio(drive, 5);
+ hwif->tuneproc(drive, 5);
}
-
- return HWIF(drive)->dmaproc(dma_func, drive);
+ return hwif->dmaproc(dma_func, drive);
}
int pdc202xx_quirkproc (ide_drive_t *drive)
@@ -928,9 +1010,110 @@
return ((int) check_in_drive_lists(drive, pdc_quirk_drives));
}
+void pdc202xx_old_ide_dma_begin(ide_drive_t *drive)
+{
+ if (drive->addressing == 1) {
+ struct request *rq = HWGROUP(drive)->rq;
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ u32 high_16 = pci_resource_start(dev, 4);
+ u32 atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
+ u32 word_count = 0;
+ u8 clock = 0;
+
+ clock = IN_BYTE(high_16 + 0x11);
+ OUT_BYTE(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11);
+ word_count = (rq->nr_sectors << 8);
+ word_count = (rq->cmd == READ) ? word_count | 0x05000000 :
+ word_count | 0x06000000;
+ OUT_LONG(word_count, atapi_reg);
+ }
+}
+
+void pdc202xx_old_ide_dma_end(ide_drive_t *drive)
+{
+ if (drive->addressing == 1) {
+ ide_hwif_t *hwif = HWIF(drive);
+ u32 high_16 = pci_resource_start(hwif->pci_dev, 4);
+ u32 atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
+ u8 clock = 0;
+
+ OUT_LONG(0, atapi_reg); /* zero out extra */
+ clock = IN_BYTE(high_16 + 0x11);
+ OUT_BYTE(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11);
+ }
+}
+
+int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = HWIF(drive);
+ struct pci_dev *dev = hwif->pci_dev;
+ unsigned long high_16 = pci_resource_start(dev, 4);
+ u8 dma_stat = 0, sc1d = 0;
+
+ dma_stat = IN_BYTE(hwif->dma_base+2);
+ sc1d = IN_BYTE(high_16 + 0x001d);
+
+ if (hwif->channel) {
+ if ((sc1d & 0x50) == 0x50)
+ goto somebody_else;
+ else if ((sc1d & 0x40) == 0x40)
+ return (dma_stat & 4) == 4;
+ } else {
+ if ((sc1d & 0x05) == 0x05)
+ goto somebody_else;
+ else if ((sc1d & 0x04) == 0x04)
+ return (dma_stat & 4) == 4;
+ }
+somebody_else:
+ return (dma_stat & 4) == 4; /* return 1 if INTR asserted */
+}
+
/*
* pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive.
*/
+int pdc202xx_dmaproc_old (ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch (func) {
+ case ide_dma_check:
+ return pdc202xx_config_drive_xfer_rate(drive);
+ break;
+ case ide_dma_begin:
+ pdc202xx_old_ide_dma_begin(drive);
+ break;
+ case ide_dma_end:
+ pdc202xx_old_ide_dma_end(drive);
+ break;
+ case ide_dma_test_irq:
+ return pdc202xx_old_ide_dma_test_irq(drive);
+ case ide_dma_lostirq:
+ case ide_dma_timeout:
+ if (HWIF(drive)->resetproc != NULL)
+ HWIF(drive)->resetproc(drive);
+ break;
+ default:
+ break;
+ }
+ return ide_dmaproc(func, drive); /* use standard DMA stuff */
+}
+
+int pdc202xx_dmaproc_new (ide_dma_action_t func, ide_drive_t *drive)
+{
+ switch (func) {
+ case ide_dma_check:
+ return pdc202xx_config_drive_xfer_rate(drive);
+ case ide_dma_lostirq:
+ case ide_dma_timeout:
+ if (HWIF(drive)->resetproc != NULL)
+ HWIF(drive)->resetproc(drive);
+ break;
+ default:
+ break;
+ }
+ return ide_dmaproc(func, drive); /* use standard DMA stuff */
+}
+
+#if 0
int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
{
byte dma_stat = 0;
@@ -1020,16 +1203,31 @@
}
return ide_dmaproc(func, drive); /* use standard DMA stuff */
}
+#endif
#endif /* CONFIG_BLK_DEV_IDEDMA */
-void pdc202xx_reset (ide_drive_t *drive)
+void pdc202xx_reset_pci (struct pci_dev *dev)
{
- OUT_BYTE(0x04,IDE_CONTROL_REG);
- mdelay(1000);
- OUT_BYTE(0x00,IDE_CONTROL_REG);
- mdelay(1000);
+ unsigned long high_16 = pci_resource_start(dev, 4);
+ u8 udma_speed_flag = IN_BYTE(high_16 + 0x001f);
+
+ OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
+ mdelay(100);
+ OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
+ mdelay(2000); /* 2 seconds ?! */
+}
+
+void pdc202xx_reset_host (ide_hwif_t *hwif)
+{
+ pdc202xx_reset_pci(hwif->pci_dev);
printk("PDC202XX: %s channel reset.\n",
- HWIF(drive)->channel ? "Secondary" : "Primary");
+ hwif->channel ? "Secondary" : "Primary");
+}
+
+void pdc202xx_reset (ide_drive_t *drive)
+{
+ pdc202xx_reset_host(HWIF(drive));
+ HWIF(drive)->tuneproc(drive, 5);
}
/*
@@ -1058,128 +1256,175 @@
return 0;
}
-unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
+void pdc202xx_marvell_idle (ide_drive_t *drive)
{
- unsigned long high_16 = pci_resource_start(dev, 4);
- byte udma_speed_flag = IN_BYTE(high_16 + 0x001f);
- byte primary_mode = IN_BYTE(high_16 + 0x001a);
- byte secondary_mode = IN_BYTE(high_16 + 0x001b);
+ /* Give a breath for Marvell's Idle Immediate command */
+ OUT_BYTE(0, IDE_NSECTOR_REG); /* timeout disable */
+ OUT_BYTE(WIN_SETIDLE1, IDE_COMMAND_REG);
+}
- OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);
- mdelay(100);
- OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);
- mdelay(2000); /* 2 seconds ?! */
+unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name)
+{
+ u8 udma_speed_flag = 0, primary_mode = 0, secondary_mode = 0;
+ u32 dmabase = pci_resource_start(dev, 4);
if (dev->resource[PCI_ROM_RESOURCE].start) {
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
- printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS,
+ dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);
+ printk("%s: ROM enabled at 0x%08lx\n",
+ name, dev->resource[PCI_ROM_RESOURCE].start);
}
+
+ pdc202_devs[n_pdc202_devs++] = dev;
- printk("%s: (U)DMA Burst Bit %sABLED " \
- "Primary %s Mode " \
- "Secondary %s Mode.\n",
- name,
- (udma_speed_flag & 1) ? "EN" : "DIS",
- (primary_mode & 1) ? "MASTER" : "PCI",
- (secondary_mode & 1) ? "MASTER" : "PCI" );
+#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
+ if (!pdc202xx_proc) {
+ pdc202xx_proc = 1;
+ pdc202xx_display_info = &pdc202xx_get_info;
+ }
+#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
+
+ switch (dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ case PCI_DEVICE_ID_PROMISE_20270:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ break;
+ case PCI_DEVICE_ID_PROMISE_20267:
+ case PCI_DEVICE_ID_PROMISE_20265:
+ case PCI_DEVICE_ID_PROMISE_20263:
+ case PCI_DEVICE_ID_PROMISE_20262:
+ /*
+ * software reset - this is required because the bios
+ * will set UDMA timing on if the hdd supports it. The
+ * user may want to turn udma off. A bug in the pdc20262
+ * is that it cannot handle a downgrade in timing from
+ * UDMA to DMA. Disk accesses after issuing a set
+ * feature command will result in errors. A software
+ * reset leaves the timing registers intact,
+ * but resets the drives.
+ */
+ pdc202xx_reset_pci(dev);
+ default:
+ if (!dmabase)
+ break;
+ udma_speed_flag = IN_BYTE(dmabase + 0x001f);
+ primary_mode = IN_BYTE(dmabase + 0x001a);
+ secondary_mode = IN_BYTE(dmabase + 0x001b);
+ printk("%s: (U)DMA Burst Bit %sABLED " \
+ "Primary %s Mode " \
+ "Secondary %s Mode.\n", name,
+ (udma_speed_flag & 1) ? "EN" : "DIS",
+ (primary_mode & 1) ? "MASTER" : "PCI",
+ (secondary_mode & 1) ? "MASTER" : "PCI" );
#ifdef CONFIG_PDC202XX_BURST
- if (!(udma_speed_flag & 1)) {
- printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1));
- OUT_BYTE(udma_speed_flag|1, high_16 + 0x001f);
- printk("%sCTIVE\n", (IN_BYTE(high_16 + 0x001f) & 1) ? "A" : "INA");
- }
+ if (!(udma_speed_flag & 1)) {
+ u8 burst = 0;
+ printk("%s: FORCING BURST BIT 0x%02x->0x%02x ",
+ name, udma_speed_flag,
+ (udma_speed_flag|1));
+ OUT_BYTE(udma_speed_flag|1,(dmabase+0x001f));
+ burst = IN_BYTE(dmabase+0x001f);
+ printk("%sCTIVE\n", (burst & 1) ? "A" : "INA");
+ }
#endif /* CONFIG_PDC202XX_BURST */
-
#ifdef CONFIG_PDC202XX_MASTER
- if (!(primary_mode & 1)) {
- printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ",
- name, primary_mode, (primary_mode|1));
- OUT_BYTE(primary_mode|1, high_16 + 0x001a);
- printk("%s\n", (IN_BYTE(high_16 + 0x001a) & 1) ? "MASTER" : "PCI");
- }
+ if (!(primary_mode & 1)) {
+ u8 tmp1 = 0;
+ printk("%s: FORCING PRIMARY MODE BIT "
+ "0x%02x -> 0x%02x ", name,
+ primary_mode, (primary_mode|1));
+ OUT_BYTE(primary_mode|1, (dmabase+0x001a));
+ tmp1 = IN_BYTE(dmabase+0x001a);
+ printk("%s\n", (tmp1 & 1) ? "MASTER" : "PCI");
+ }
- if (!(secondary_mode & 1)) {
- printk("%s: FORCING SECONDARY MODE BIT 0x%02x -> 0x%02x ",
- name, secondary_mode, (secondary_mode|1));
- OUT_BYTE(secondary_mode|1, high_16 + 0x001b);
- printk("%s\n", (IN_BYTE(high_16 + 0x001b) & 1) ? "MASTER" : "PCI");
- }
+ if (!(secondary_mode & 1)) {
+ u8 tmp2 = 0;
+ printk("%s: FORCING SECONDARY MODE BIT "
+ "0x%02x -> 0x%02x ", name,
+ secondary_mode, (secondary_mode|1));
+ OUT_BYTE(secondary_mode|1, (dmabase+0x001b));
+ tmp2 = IN_BYTE(dmabase+0x001b));
+ printk("%s\n", (tmp2 & 1) ? "MASTER" : "PCI");
+ }
#endif /* CONFIG_PDC202XX_MASTER */
-#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)
- if (!pdc202xx_proc) {
- pdc202xx_proc = 1;
- bmide_dev = dev;
- pdc202xx_display_info = &pdc202xx_get_info;
+ break;
}
-#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */
return dev->irq;
}
unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif)
{
- unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);
- unsigned short CIS;
-
- switch(hwif->pci_dev->device) {
- case PCI_DEVICE_ID_PROMISE_20276:
- case PCI_DEVICE_ID_PROMISE_20275:
- case PCI_DEVICE_ID_PROMISE_20269:
- case PCI_DEVICE_ID_PROMISE_20268:
- case PCI_DEVICE_ID_PROMISE_20270:
- OUT_BYTE(0x0b, (hwif->dma_base + 1));
- return (!(IN_BYTE((hwif->dma_base + 3)) & 0x04));
- /* check 80pin cable */
- default:
- pci_read_config_word(hwif->pci_dev, 0x50, &CIS);
- return (!(CIS & mask));
- /* check 80pin cable */
+ switch(hwif->pci_dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
+ case PCI_DEVICE_ID_PROMISE_20276:
+ case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
+ case PCI_DEVICE_ID_PROMISE_20269:
+ case PCI_DEVICE_ID_PROMISE_20268:
+ case PCI_DEVICE_ID_PROMISE_20270:
+ return !pdc202xx_new_cable_detect(hwif);
+ /* check 80pin cable */
+ default:
+ return !pdc202xx_old_cable_detect(hwif);
+ /* check 80pin cable */
}
}
void __init ide_init_pdc202xx (ide_hwif_t *hwif)
{
+ int newchip = 0;
+
hwif->tuneproc = &pdc202xx_tune_drive;
hwif->quirkproc = &pdc202xx_quirkproc;
- hwif->resetproc = &pdc202xx_reset;
+
+ hwif->drives[0].autotune = 1;
+ hwif->drives[1].autotune = 1;
+ hwif->autodma = 0;
switch(hwif->pci_dev->device) {
+ case PCI_DEVICE_ID_PROMISE_20277:
case PCI_DEVICE_ID_PROMISE_20276:
case PCI_DEVICE_ID_PROMISE_20275:
+ case PCI_DEVICE_ID_PROMISE_20271:
case PCI_DEVICE_ID_PROMISE_20269:
case PCI_DEVICE_ID_PROMISE_20268:
case PCI_DEVICE_ID_PROMISE_20270:
hwif->speedproc = &pdc202xx_new_tune_chipset;
+ hwif->resetproc = NULL;
+ newchip = 1;
break;
case PCI_DEVICE_ID_PROMISE_20267:
case PCI_DEVICE_ID_PROMISE_20265:
+ hwif->addressing = (hwif->channel) ? 0 : 1;
+ case PCI_DEVICE_ID_PROMISE_20263:
case PCI_DEVICE_ID_PROMISE_20262:
hwif->busproc = &pdc202xx_tristate;
+ hwif->resetproc = &pdc202xx_reset;
case PCI_DEVICE_ID_PROMISE_20246:
hwif->speedproc = &pdc202xx_tune_chipset;
default:
break;
}
-#undef CONFIG_PDC202XX_32_UNMASK
-#ifdef CONFIG_PDC202XX_32_UNMASK
- hwif->drives[0].io_32bit = 1;
- hwif->drives[1].io_32bit = 1;
- hwif->drives[0].unmask = 1;
- hwif->drives[1].unmask = 1;
-#endif /* CONFIG_PDC202XX_32_UNMASK */
+ if (!hwif->dma_base)
+ return;
#ifdef CONFIG_BLK_DEV_IDEDMA
- if (hwif->dma_base) {
- hwif->dmaproc = &pdc202xx_dmaproc;
- if (!noautodma)
- hwif->autodma = 1;
- } else {
- hwif->drives[0].autotune = 1;
- hwif->drives[1].autotune = 1;
- hwif->autodma = 0;
- }
+ if (newchip)
+ hwif->dmaproc = &pdc202xx_dmaproc_new;
+ else
+ hwif->dmaproc = &pdc202xx_dmaproc_old;
+# ifdef CONFIG_IDEDMA_AUTO
+ if (!noautodma)
+ hwif->autodma = 1;
+# endif /* CONFIG_IDEDMA_AUTO */
#else /* !CONFIG_BLK_DEV_IDEDMA */
hwif->drives[0].autotune = 1;
hwif->drives[1].autotune = 1;
diff -uNr linux-2.4.20/drivers/ide/rapide.c linux-2.4.20-ben5/drivers/ide/rapide.c
--- linux-2.4.20/drivers/ide/rapide.c 2001-10-11 18:14:32.000000000 +0200
+++ linux-2.4.20-ben5/drivers/ide/rapide.c 2003-01-30 11:52:55.000000000 +0100
@@ -40,6 +40,7 @@
}
hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206;
hw.irq = ec->irq;
+ hw.chipset = ide_generic;
return ide_register_hw(&hw, NULL);
}
diff -uNr linux-2.4.20/drivers/macintosh/Makefile linux-2.4.20-ben5/drivers/macintosh/Makefile
--- linux-2.4.20/drivers/macintosh/Makefile 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/Makefile 2003-01-30 11:55:58.000000000 +0100
@@ -35,6 +35,7 @@
obj-$(CONFIG_INPUT_ADBHID) += adbhid.o
obj-$(CONFIG_PPC_RTC) += rtc.o
obj-$(CONFIG_ANSLCD) += ans-lcd.o
+obj-$(CONFIG_I2C) += thermostat.o
obj-$(CONFIG_ADB_PMU) += via-pmu.o
obj-$(CONFIG_ADB_CUDA) += via-cuda.o
diff -uNr linux-2.4.20/drivers/macintosh/adb.c linux-2.4.20-ben5/drivers/macintosh/adb.c
--- linux-2.4.20/drivers/macintosh/adb.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/adb.c 2003-01-30 11:55:18.000000000 +0100
@@ -655,6 +655,7 @@
return 0;
}
+/* FIXME: Should wait completion, dequeue & delete pending requests */
static int adb_release(struct inode *inode, struct file *file)
{
struct adbdev_state *state = file->private_data;
diff -uNr linux-2.4.20/drivers/macintosh/apm_emu.c linux-2.4.20-ben5/drivers/macintosh/apm_emu.c
--- linux-2.4.20/drivers/macintosh/apm_emu.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/apm_emu.c 2003-01-30 11:54:01.000000000 +0100
@@ -436,40 +436,40 @@
int percentage = -1;
int time_units = -1;
int real_count = 0;
- int charge = -1;
- int current = 0;
int i;
char * p = buf;
char charging = 0;
+ long charge = -1;
+ long current = 0;
+ unsigned long btype = 0;
ac_line_status = ((pmu_power_flags & PMU_PWR_AC_PRESENT) != 0);
for (i=0; i 0) {
battery_status = 0x03;
battery_flag = 0x08;
} else if (percentage <= APM_CRITICAL) {
@@ -516,6 +516,7 @@
static int __init apm_emu_init(void)
{
struct proc_dir_entry *apm_proc;
+ int retval;
if (sys_ctrler != SYS_CTRLER_PMU) {
printk(KERN_INFO "apm_emu: Requires a machine with a PMU.\n");
@@ -523,10 +524,18 @@
}
apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info);
- if (apm_proc)
- SET_MODULE_OWNER(apm_proc);
+ if (!apm_proc) {
+ printk(KERN_ERR "apm_emu: create_proc_info_entry failed.\n");
+ return -ENOENT;
+ }
+ SET_MODULE_OWNER(apm_proc);
- misc_register(&apm_device);
+ retval = misc_register(&apm_device);
+ if (retval < 0) {
+ printk(KERN_ERR "apm_emu: misc_register failed\n");
+ remove_proc_entry("apm", NULL);
+ return retval;
+ }
pmu_register_sleep_notifier(&apm_sleep_notifier);
diff -uNr linux-2.4.20/drivers/macintosh/macio-adb.c linux-2.4.20-ben5/drivers/macintosh/macio-adb.c
--- linux-2.4.20/drivers/macintosh/macio-adb.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/macio-adb.c 2003-01-30 11:54:39.000000000 +0100
@@ -218,7 +218,6 @@
out_8(&adb->ctrl.r, DTB + CRE);
} else {
out_8(&adb->ctrl.r, DTB);
- req->complete = 1;
current_req = req->next;
complete = 1;
if (current_req)
@@ -238,7 +237,6 @@
for (i = 0; i < req->reply_len; ++i)
req->reply[i] = in_8(&adb->data[i].r);
}
- req->complete = 1;
current_req = req->next;
complete = 1;
if (current_req)
@@ -255,8 +253,16 @@
out_8(&adb->intr.r, 0);
}
spin_unlock(&macio_lock);
- if (complete && req && req->done)
- (*req->done)(req);
+ if (complete && req) {
+ void (*done)(struct adb_request *) = req->done;
+ mb();
+ req->complete = 1;
+ /* Here, we assume that if the request has a done member, the
+ * struct request will survive to setting req->complete to 1
+ */
+ if (done)
+ (*done)(req);
+ }
if (ibuf_len)
adb_input(ibuf, ibuf_len, regs, autopoll);
}
diff -uNr linux-2.4.20/drivers/macintosh/macserial.c linux-2.4.20-ben5/drivers/macintosh/macserial.c
--- linux-2.4.20/drivers/macintosh/macserial.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/macintosh/macserial.c 2003-01-30 11:54:27.000000000 +0100
@@ -1134,6 +1134,8 @@
*/
static void shutdown(struct mac_serial * info)
{
+ unsigned long flags;
+
OPNDBG("Shutting down serial port %d (irq %d)....\n", info->line,
info->irq);
@@ -1142,6 +1144,8 @@
return;
}
+ save_flags(flags); cli(); /* Disable interrupts */
+
if (info->has_dma) {
del_timer(&info->poll_dma_timer);
dbdma_reset(info->tx_dma);
@@ -1151,6 +1155,8 @@
}
disable_irq(info->irq);
+ restore_flags(flags);
+
info->pendregs[1] = info->curregs[1] = 0;
write_zsreg(info->zs_channel, 1, 0); /* no interrupts */
@@ -1980,6 +1986,7 @@
return;
}
info->flags |= ZILOG_CLOSING;
+ restore_flags(flags);
/*
* Save the termios structure, since this port may have
* separate termios for callout and dialin.
@@ -1994,11 +2001,8 @@
*/
OPNDBG("waiting end of Tx... (timeout:%d)\n", info->closing_wait);
tty->closing = 1;
- if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE) {
- restore_flags(flags);
+ if (info->closing_wait != ZILOG_CLOSING_WAIT_NONE)
tty_wait_until_sent(tty, info->closing_wait);
- save_flags(flags); cli();
- }
/*
* At this point we stop accepting input. To do this, we
@@ -2017,15 +2021,10 @@
* has completely drained.
*/
OPNDBG("waiting end of Rx...\n");
- restore_flags(flags);
rs_wait_until_sent(tty, info->timeout);
- save_flags(flags); cli();
}
shutdown(info);
- /* restore flags now since shutdown() will have disabled this port's
- specific irqs */
- restore_flags(flags);
if (tty->driver.flush_buffer)
tty->driver.flush_buffer(tty);
@@ -2880,7 +2879,7 @@
static int __init serial_console_setup(struct console *co, char *options)
{
struct mac_serial *info;
- int baud = 38400;
+ int baud = 57600; /*38400;*/
int bits = 8;
int parity = 'n';
int cflag = CREAD | HUPCL | CLOCAL;
diff -uNr linux-2.4.20/drivers/macintosh/thermostat.c linux-2.4.20-ben5/drivers/macintosh/thermostat.c
--- linux-2.4.20/drivers/macintosh/thermostat.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/thermostat.c 2003-01-30 11:54:52.000000000 +0100
@@ -0,0 +1,271 @@
+/*
+ * Device driver for the i2c thermostat found on some laptops
+ *
+ * Copyright (C) 2001 Benjamin Herrenschmidt
+ *
+ * Actually, there are 2 DS1775R1 on uninorth I2C busses
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define DEBUG
+
+#define I2C_THERMOSTAT_ADDR 0x49
+#define I2C_THERMOSTAT_ADDR2 0x48
+#define MAX_THERMOSTATS 4
+
+
+MODULE_AUTHOR("Benjamin Herrenschmidt ");
+MODULE_DESCRIPTION("Driver for DS1775 thermostat on Apple laptops");
+MODULE_LICENSE("GPL");
+EXPORT_NO_SYMBOLS;
+
+struct temp_range
+{
+ u8 high; /* Start the fan */
+ u8 low; /* Stop the fan */
+};
+
+struct apple_thermal_info {
+ u8 id; /* Implementation ID */
+ u8 fan_count; /* Number of fans */
+ u8 thermostat_count; /* Number of thermostats */
+ u8 unused[5];
+ struct temp_range ranges[4]; /* Temperature ranges (may be [])*/
+};
+
+struct thermostat {
+ struct i2c_client clt;
+ int th_num;
+ // more to come ?
+};
+
+static struct apple_thermal_info *thinfo;
+static struct thermostat* thermostats[MAX_THERMOSTATS];
+static int therm_count;
+
+static int attach_thermostat(struct i2c_adapter *adapter);
+static int detach_thermostat(struct i2c_client *client);
+
+/* What is this supposed to be ? registered ? I hate
+ * magic numbers like that ...
+ */
+#define I2C_DRIVERID_THERMOSTAT (0xDEAD)
+
+static struct i2c_driver thermostat_driver = {
+ name: "Apple Thermostat",
+ id: I2C_DRIVERID_THERMOSTAT,
+ flags: I2C_DF_NOTIFY,
+ attach_adapter: &attach_thermostat,
+ detach_client: &detach_thermostat,
+ command: NULL,
+ inc_use: NULL,
+ dec_use: NULL
+};
+
+static int
+write_reg(struct thermostat* th, int reg, u8* data, int len)
+{
+ u8 tmp[5];
+ int rc;
+
+ if (len > 4)
+ return -EINVAL;
+ tmp[0] = reg;
+ memcpy(&tmp[1], data, len);
+ rc = i2c_master_send(&th->clt, (const char *)tmp, len+1);
+ if (rc < 0)
+ return rc;
+ if (rc != (len+1))
+ return -ENODEV;
+ return 0;
+}
+
+static int
+read_reg(struct thermostat* th, int reg, u8* data, int len)
+{
+ u8 reg_addr;
+ int rc;
+
+ reg_addr = (u8)reg;
+ rc = i2c_master_send(&th->clt, ®_addr, 1);
+ if (rc < 0)
+ return rc;
+ if (rc != 1)
+ return -ENODEV;
+ rc = i2c_master_recv(&th->clt, (char *)data, len);
+ if (rc < 0)
+ return rc;
+ if (rc != len)
+ return -ENODEV;
+ return 0;
+}
+
+static int
+attach_one_thermostat(struct i2c_adapter *adapter, int addr, int num)
+{
+ struct thermostat* th;
+ int rc;
+ u16 t, tlo, thi;
+ u8 config;
+
+ if (therm_count >= MAX_THERMOSTATS) {
+ printk(KERN_WARNING "Skipped thermostat %d (%s:%x), max count reached !\n",
+ num, adapter->name, addr);
+ return -ENODEV;
+ }
+
+ th = (struct thermostat *)kmalloc(sizeof(struct thermostat), GFP_KERNEL);
+ if (!th)
+ return -ENOMEM;
+ th->clt.addr = addr;
+ th->clt.adapter = adapter;
+ th->clt.driver = &thermostat_driver;
+ th->clt.flags = 0;
+ th->clt.data = (void *)therm_count;
+ th->th_num = num;
+ strcpy(th->clt.name, "thermostat");
+
+ rc = read_reg(th, 1, &config, 1);
+ if (rc < 0) {
+ printk(KERN_ERR "Thermostat %d (%s:%x) failed to read config !\n",
+ num, adapter->name, addr);
+ kfree(th);
+ return -ENODEV;
+ }
+ printk(KERN_INFO "Thermostat %d (%s:%x), config: %02x\n",
+ num, adapter->name, addr, config);
+
+ rc = read_reg(th, 0, (u8 *)&t, 2);
+ if (rc < 0) {
+ printk(KERN_ERR "Thermostat %d (%s:%x) failed to read temp !\n",
+ num, adapter->name, addr);
+ kfree(th);
+ return -ENODEV;
+ }
+ printk(KERN_INFO "Thermostat %d (%s:%x), temp: %04x (about: %d degree C)\n",
+ num, adapter->name, addr, t, t>>8);
+
+ thermostats[therm_count++] = th;
+
+ if (i2c_attach_client(&th->clt)) {
+ printk(KERN_ERR "Thermostat %d (%s:%x), failed to attach client !\n",
+ num, adapter->name, addr);
+ thermostats[--therm_count] = NULL;
+ kfree(th);
+ return -ENODEV;
+ }
+
+ tlo = thi = 0;
+ rc = read_reg(th, 2, (u8 *)&tlo, 2);
+ if (rc < 0) {
+ printk(KERN_WARNING "Thermostat %d (%s:%x) failed to read low threshold !\n",
+ num, adapter->name, addr);
+ }
+ rc = read_reg(th, 3, (u8 *)&thi, 2);
+ if (rc < 0) {
+ printk(KERN_WARNING "Thermostat %d (%s:%x) failed to read high threshold !\n",
+ num, adapter->name, addr);
+ }
+ printk(KERN_INFO "Thermostat %d (%s:%x), tl: %04x (%d degree C), th: %04x (%d degree C)\n",
+ num, adapter->name, addr, tlo, tlo>>8, thi, thi>>8);
+ return 0;
+}
+
+static int
+attach_thermostat(struct i2c_adapter *adapter)
+{
+ unsigned long bus_no;
+ int rc;
+
+ if (strncmp(adapter->name, "uni-n", 5))
+ return 0;
+ bus_no = simple_strtoul(adapter->name + 6, NULL, 10);
+ rc = attach_one_thermostat(adapter, I2C_THERMOSTAT_ADDR, bus_no);
+ if (!rc && thinfo->thermostat_count > 2)
+ attach_one_thermostat(adapter, I2C_THERMOSTAT_ADDR2, bus_no+2);
+
+ return rc;
+}
+
+static int
+detach_thermostat(struct i2c_client *client)
+{
+ int index = (int)client->data;
+ struct thermostat* th;
+
+ if (index >= MAX_THERMOSTATS || !thermostats[index]) {
+ printk(KERN_ERR "Invalid client in deatch_thermostat()\n");
+ return -ENODEV;
+ }
+ th = thermostats[index];
+ i2c_detach_client(&th->clt);
+ thermostats[index] = NULL;
+
+ kfree(th);
+
+ return 0;
+}
+
+static int __init
+thermostat_init(void)
+{
+ struct device_node* np;
+
+ np = find_devices("power-mgt");
+ if (!np)
+ return -ENODEV;
+ thinfo = (struct apple_thermal_info *)get_property(np, "thermal-info", NULL);
+ if (!thinfo)
+ return -ENODEV;
+
+#ifdef DEBUG
+ printk(KERN_DEBUG " Thermal Infos found :\n");
+ printk(KERN_DEBUG " implementation id : %d\n", thinfo->id);
+ printk(KERN_DEBUG " fan_count : %d\n", thinfo->fan_count);
+ printk(KERN_DEBUG " thermostat_count : %d\n", thinfo->thermostat_count);
+ printk(KERN_DEBUG " ranges[0] : %d,%d\n",
+ thinfo->ranges[0].high, thinfo->ranges[0].low);
+ printk(KERN_DEBUG " ranges[1] : %d,%d\n",
+ thinfo->ranges[1].high, thinfo->ranges[1].low);
+ printk(KERN_DEBUG " ranges[2] : %d,%d\n",
+ thinfo->ranges[2].high, thinfo->ranges[2].low);
+ printk(KERN_DEBUG " ranges[3] : %d,%d\n",
+ thinfo->ranges[3].high, thinfo->ranges[3].low);
+#endif
+ /* Check against titaniums & ibooks.... */
+// if (machine_is_compatible("PowerBook3,1")) {
+ if (thinfo->id != 1 && thinfo->id != 2) {
+ printk(KERN_ERR "thermostat: design id %d unknown !\n", thinfo->id);
+ return -ENODEV;
+ }
+// } else {
+// printk(KERN_ERR "thermostat: unsupported machine type !\n");
+// return -ENODEV;
+// }
+
+ return i2c_add_driver(&thermostat_driver);
+}
+
+static void __exit
+thermostat_exit(void)
+{
+ i2c_del_driver(&thermostat_driver);
+}
+
+module_init(thermostat_init);
+module_exit(thermostat_exit);
diff -uNr linux-2.4.20/drivers/macintosh/via-cuda.c linux-2.4.20-ben5/drivers/macintosh/via-cuda.c
--- linux-2.4.20/drivers/macintosh/via-cuda.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/via-cuda.c 2003-01-30 11:52:46.000000000 +0100
@@ -175,8 +175,8 @@
/* for us by the main VIA driver in arch/m68k/mac/via.c */
#ifndef CONFIG_MAC
- via[IFR] = 0x7f; eieio(); /* clear interrupts by writing 1s */
- via[IER] = IER_SET|SR_INT; eieio(); /* enable interrupt from SR */
+ out_8(&via[IFR], 0x7f); /* clear interrupts by writing 1s */
+ out_8(&via[IER], IER_SET|SR_INT); /* enable interrupt from SR */
#endif
/* enable autopoll */
@@ -244,7 +244,8 @@
#endif /* CONFIG_ADB */
#define WAIT_FOR(cond, what) \
- do { \
+ do { \
+ int x; \
for (x = 1000; !(cond); --x) { \
if (x == 0) { \
printk("Timeout waiting for " what "\n"); \
@@ -257,40 +258,40 @@
static int
cuda_init_via()
{
- int x;
-
- via[DIRB] = (via[DIRB] | TACK | TIP) & ~TREQ; /* TACK & TIP out */
- via[B] |= TACK | TIP; /* negate them */
- via[ACR] = (via[ACR] & ~SR_CTRL) | SR_EXT; /* SR data in */
- eieio();
- x = via[SR]; eieio(); /* clear any left-over data */
+ out_8(&via[DIRB], (in_8(&via[DIRB]) | TACK | TIP) & ~TREQ); /* TACK & TIP out */
+ out_8(&via[B], in_8(&via[B]) | TACK | TIP); /* negate them */
+ out_8(&via[ACR] ,(in_8(&via[ACR]) & ~SR_CTRL) | SR_EXT); /* SR data in */
+ (void)in_8(&via[SR]); /* clear any left-over data */
#ifndef CONFIG_MAC
- via[IER] = 0x7f; eieio(); /* disable interrupts from VIA */
+ out_8(&via[IER], 0x7f); /* disable interrupts from VIA */
+ (void)in_8(&via[IER]);
#endif
- eieio();
/* delay 4ms and then clear any pending interrupt */
mdelay(4);
- x = via[SR]; eieio();
+ (void)in_8(&via[SR]);
+ out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
/* sync with the CUDA - assert TACK without TIP */
- via[B] &= ~TACK; eieio();
+ out_8(&via[B], in_8(&via[B]) & ~TACK);
/* wait for the CUDA to assert TREQ in response */
- WAIT_FOR((via[B] & TREQ) == 0, "CUDA response to sync");
+ WAIT_FOR((in_8(&via[B]) & TREQ) == 0, "CUDA response to sync");
/* wait for the interrupt and then clear it */
- WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (2)");
- x = via[SR]; eieio();
+ WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (2)");
+ (void)in_8(&via[SR]);
+ out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
/* finish the sync by negating TACK */
via[B] |= TACK; eieio();
/* wait for the CUDA to negate TREQ and the corresponding interrupt */
- WAIT_FOR(via[B] & TREQ, "CUDA response to sync (3)");
- WAIT_FOR(via[IFR] & SR_INT, "CUDA response to sync (4)");
- x = via[SR]; eieio();
- via[B] |= TIP; eieio(); /* should be unnecessary */
+ WAIT_FOR(in_8(&via[B]) & TREQ, "CUDA response to sync (3)");
+ WAIT_FOR(in_8(&via[IFR]) & SR_INT, "CUDA response to sync (4)");
+ (void)in_8(&via[SR]);
+ out_8(&via[IFR], in_8(&via[IFR]) & 0x7f);
+ out_8(&via[B], in_8(&via[B]) | TIP); /* should be unnecessary */
return 0;
}
@@ -413,55 +414,59 @@
req = current_req;
if (req == 0)
return;
- if ((via[B] & TREQ) == 0)
+ if ((in_8(&via[B]) & TREQ) == 0)
return; /* a byte is coming in from the CUDA */
/* set the shift register to shift out and send a byte */
- via[ACR] |= SR_OUT; eieio();
- via[SR] = req->data[0]; eieio();
- via[B] &= ~TIP;
+ out_8(&via[ACR], in_8(&via[ACR]) | SR_OUT);
+ out_8(&via[SR], req->data[0]);
+ out_8(&via[B], in_8(&via[B]) & ~TIP);
cuda_state = sent_first_byte;
}
void
cuda_poll()
{
- if (via[IFR] & SR_INT) {
- unsigned long flags;
+ unsigned long flags;
- /* cuda_interrupt only takes a normal lock, we disable
- * interrupts here to avoid re-entering and thus deadlocking.
- * An option would be to disable only the IRQ source with
- * disable_irq(), would that work on m68k ? --BenH
- */
- local_irq_save(flags);
- cuda_interrupt(0, 0, 0);
- local_irq_restore(flags);
- }
+ /* cuda_interrupt only takes a normal lock, we disable
+ * interrupts here to avoid re-entering and thus deadlocking.
+ * An option would be to disable only the IRQ source with
+ * disable_irq(), would that work on m68k ? --BenH
+ */
+ local_irq_save(flags);
+ cuda_interrupt(0, 0, 0);
+ local_irq_restore(flags);
}
static void
cuda_interrupt(int irq, void *arg, struct pt_regs *regs)
{
- int x, status;
+ int status;
struct adb_request *req = NULL;
unsigned char ibuf[16];
int ibuf_len = 0;
int complete = 0;
+ unsigned char virq;
- if ((via[IFR] & SR_INT) == 0)
- return;
-
spin_lock(&cuda_lock);
- status = (~via[B] & (TIP|TREQ)) | (via[ACR] & SR_OUT); eieio();
+
+ virq = in_8(&via[IFR]) & 0x7f;
+ out_8(&via[IFR], virq);
+ if ((virq & SR_INT) == 0) {
+ spin_unlock(&cuda_lock);
+ return;
+ }
+
+ status = (~in_8(&via[B]) & (TIP|TREQ)) | (in_8(&via[ACR]) & SR_OUT);
/* printk("cuda_interrupt: state=%d status=%x\n", cuda_state, status); */
switch (cuda_state) {
case idle:
/* CUDA has sent us the first byte of data - unsolicited */
if (status != TREQ)
printk("cuda: state=idle, status=%x\n", status);
- x = via[SR]; eieio();
- via[B] &= ~TIP; eieio();
+ (void)in_8(&via[SR]);
+ out_8(&via[B], in_8(&via[B]) & ~TIP);
cuda_state = reading;
reply_ptr = cuda_rbuf;
reading_reply = 0;
@@ -471,8 +476,8 @@
/* CUDA has sent us the first byte of data of a reply */
if (status != TREQ)
printk("cuda: state=awaiting_reply, status=%x\n", status);
- x = via[SR]; eieio();
- via[B] &= ~TIP; eieio();
+ (void)in_8(&via[SR]);
+ out_8(&via[B], in_8(&via[B]) & ~TIP);
cuda_state = reading;
reply_ptr = current_req->reply;
reading_reply = 1;
@@ -481,16 +486,16 @@
case sent_first_byte:
if (status == TREQ + TIP + SR_OUT) {
/* collision */
- via[ACR] &= ~SR_OUT; eieio();
- x = via[SR]; eieio();
- via[B] |= TIP | TACK; eieio();
+ out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+ (void)in_8(&via[SR]);
+ out_8(&via[B], in_8(&via[B]) | TIP | TACK);
cuda_state = idle;
} else {
/* assert status == TIP + SR_OUT */
if (status != TIP + SR_OUT)
printk("cuda: state=sent_first_byte status=%x\n", status);
- via[SR] = current_req->data[1]; eieio();
- via[B] ^= TACK; eieio();
+ out_8(&via[SR], current_req->data[1]);
+ out_8(&via[B], in_8(&via[B]) ^ TACK);
data_index = 2;
cuda_state = sending;
}
@@ -499,9 +504,9 @@
case sending:
req = current_req;
if (data_index >= req->nbytes) {
- via[ACR] &= ~SR_OUT; eieio();
- x = via[SR]; eieio();
- via[B] |= TACK | TIP; eieio();
+ out_8(&via[ACR], in_8(&via[ACR]) & ~SR_OUT);
+ (void)in_8(&via[SR]);
+ out_8(&via[B], in_8(&via[B]) | TACK | TIP);
req->sent = 1;
if (req->reply_expected) {
cuda_state = awaiting_reply;
@@ -513,27 +518,27 @@
cuda_start();
}
} else {
- via[SR] = req->data[data_index++]; eieio();
- via[B] ^= TACK; eieio();
+ out_8(&via[SR], req->data[data_index++]);
+ out_8(&via[B], in_8(&via[B]) ^ TACK);
}
break;
case reading:
- *reply_ptr++ = via[SR]; eieio();
+ *reply_ptr++ = in_8(&via[SR]);
if (status == TIP) {
/* that's all folks */
- via[B] |= TACK | TIP; eieio();
+ out_8(&via[B], in_8(&via[B]) | TACK | TIP);
cuda_state = read_done;
} else {
/* assert status == TIP | TREQ */
if (status != TIP + TREQ)
printk("cuda: state=reading status=%x\n", status);
- via[B] ^= TACK; eieio();
+ out_8(&via[B], in_8(&via[B]) ^ TACK);
}
break;
case read_done:
- x = via[SR]; eieio();
+ (void)in_8(&via[SR]);
if (reading_reply) {
req = current_req;
req->reply_len = reply_ptr - req->reply;
@@ -548,7 +553,6 @@
memmove(req->reply, req->reply + 2, req->reply_len);
}
}
- req->complete = 1;
current_req = req->next;
complete = 1;
} else {
@@ -563,7 +567,7 @@
memcpy(ibuf, cuda_rbuf, ibuf_len);
}
if (status == TREQ) {
- via[B] &= ~TIP; eieio();
+ out_8(&via[B], in_8(&via[B]) & ~TIP);
cuda_state = reading;
reply_ptr = cuda_rbuf;
reading_reply = 0;
@@ -577,8 +581,16 @@
printk("cuda_interrupt: unknown cuda_state %d?\n", cuda_state);
}
spin_unlock(&cuda_lock);
- if (complete && req && req->done)
- (*req->done)(req);
+ if (complete && req) {
+ void (*done)(struct adb_request *) = req->done;
+ mb();
+ req->complete = 1;
+ /* Here, we assume that if the request has a done member, the
+ * struct request will survive to setting req->complete to 1
+ */
+ if (done)
+ (*done)(req);
+ }
if (ibuf_len)
cuda_input(ibuf, ibuf_len, regs);
}
diff -uNr linux-2.4.20/drivers/macintosh/via-pmu.c linux-2.4.20-ben5/drivers/macintosh/via-pmu.c
--- linux-2.4.20/drivers/macintosh/via-pmu.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/macintosh/via-pmu.c 2003-01-30 11:55:33.000000000 +0100
@@ -345,11 +345,6 @@
} else
pmu_kind = PMU_UNKNOWN;
-#ifdef CONFIG_PMAC_PBOOK
- if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
- can_sleep = 1;
-#endif /* CONFIG_PMAC_PBOOK */
-
via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);
out_8(&via[IER], IER_CLR | 0x7f); /* disable all intrs */
@@ -410,6 +405,8 @@
bright_req_3.complete = 1;
#ifdef CONFIG_PMAC_PBOOK
batt_req.complete = 1;
+ if (pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0)
+ can_sleep = 1;
#endif
if (request_irq(vias->intrs[0].line, via_pmu_interrupt, 0, "VIA-PMU",
@@ -436,12 +433,20 @@
#ifdef CONFIG_PMAC_PBOOK
if (machine_is_compatible("AAPL,3400/2400") ||
- machine_is_compatible("AAPL,3500"))
+ machine_is_compatible("AAPL,3500")) {
+ int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_MODEL, 0);
pmu_battery_count = 1;
- else if (machine_is_compatible("AAPL,PowerBook1998") ||
- machine_is_compatible("PowerBook1,1"))
+ if (mb == PMAC_TYPE_COMET)
+ pmu_batteries[0].flags |= PMU_BATT_TYPE_COMET;
+ else
+ pmu_batteries[0].flags |= PMU_BATT_TYPE_HOOPER;
+ } else if (machine_is_compatible("AAPL,PowerBook1998") ||
+ machine_is_compatible("PowerBook1,1")) {
pmu_battery_count = 2;
- else {
+ pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+ pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
+ } else {
struct device_node* prim = find_devices("power-mgt");
u32 *prim_info = NULL;
if (prim)
@@ -449,6 +454,9 @@
if (prim_info) {
/* Other stuffs here yet unknown */
pmu_battery_count = (prim_info[6] >> 16) & 0xff;
+ pmu_batteries[0].flags |= PMU_BATT_TYPE_SMART;
+ if (pmu_battery_count > 1)
+ pmu_batteries[1].flags |= PMU_BATT_TYPE_SMART;
}
}
#endif /* CONFIG_PMAC_PBOOK */
@@ -558,148 +566,12 @@
#ifdef CONFIG_PMAC_PBOOK
-/*
- * WARNING ! This code probably needs some debugging... -- BenH.
+/* This new version of the code for 2400/3400/3500 powerbooks
+ * is inspired from the implementation in gkrellm-pmu
*/
-#ifdef NEW_OHARE_CODE
-static void __pmac
-done_battery_state_ohare(struct adb_request* req)
-{
- unsigned int bat_flags = 0;
- int current = 0;
- unsigned int capa, max, voltage, time;
- int lrange[] = { 0, 275, 850, 1680, 2325,
- 2765, 3160, 3500, 3830, 4115,
- 4360, 4585, 4795, 4990, 5170,
- 5340, 5510, 5710, 5930, 6150,
- 6370, 6500
- };
-
- if (req->reply[0] & 0x01)
- pmu_power_flags |= PMU_PWR_AC_PRESENT;
- else
- pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
-
- if (req->reply[0] & 0x04) {
- int vb, i, j, k, charge, pcharge;
- bat_flags |= PMU_BATT_PRESENT;
- vb = (req->reply[1] << 8) | req->reply[2];
- voltage = ((vb * 2650) + 726650)/100;
- vb *= 100;
- current = req->reply[5];
- if ((req->reply[0] & 0x01) == 0 && (current > 200))
- vb += (current - 200) * 15;
- else if (req->reply[0] & 0x02)
- vb = (vb - 2000);
- i = (33000 - vb) / 10;
- j = i - (i % 100);
- k = j/100;
- if (k <= 0)
- charge = 0;
- else if (k >= 21)
- charge = 650000;
- else
- charge = (lrange[k + 1] - lrange[k]) * (i - j) + (lrange[k] * 100);
- charge = (1000 - charge / 650) / 10;
- if (req->reply[0] & 0x40) {
- pcharge = (req->reply[6] << 8) + req->reply[7];
- if (pcharge > 6500)
- pcharge = 6500;
- pcharge *= 100;
- pcharge = (1000 - pcharge / 650) / 10;
- if (pcharge < charge)
- charge = pcharge;
- }
- capa = charge;
- max = 100;
- time = (charge * 16440) / current;
- current = -current;
-
- } else
- capa = max = current = voltage = time = 0;
-
- if (req->reply[0] & 0x02)
- bat_flags |= PMU_BATT_CHARGING;
-
- pmu_batteries[pmu_cur_battery].flags = bat_flags;
- pmu_batteries[pmu_cur_battery].charge = capa;
- pmu_batteries[pmu_cur_battery].max_charge = max;
- pmu_batteries[pmu_cur_battery].current = current;
- pmu_batteries[pmu_cur_battery].voltage = voltage;
- pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#else /* NEW_OHARE_CODE */
static void __pmac
done_battery_state_ohare(struct adb_request* req)
{
- unsigned int bat_flags = 0;
- int current = 0;
- unsigned int capa, max, voltage, time;
- int lrange[] = { 0, 275, 850, 1680, 2325,
- 2765, 3160, 3500, 3830, 4115,
- 4360, 4585, 4795, 4990, 5170,
- 5340, 5510, 5710, 5930, 6150,
- 6370, 6500
- };
-
- if (req->reply[0] & 0x01)
- pmu_power_flags |= PMU_PWR_AC_PRESENT;
- else
- pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
-
- if (req->reply[0] & 0x04) {
- int vb, i, j, charge, pcharge;
- bat_flags |= PMU_BATT_PRESENT;
- vb = (req->reply[1] << 8) | req->reply[2];
- voltage = ((vb * 2650) + 726650)/100;
- current = *((signed char *)&req->reply[5]);
- if ((req->reply[0] & 0x01) == 0 && (current > 200))
- vb += (current - 200) * 15;
- else if (req->reply[0] & 0x02)
- vb = (vb - 10) * 100;
- i = (33000 - vb) / 10;
- j = i - (i % 100);
- if (j <= 0)
- charge = 0;
- else if (j >= 21)
- charge = 650000;
- else
- charge = (lrange[j + 1] - lrange[j]) * (i - j) + (lrange[j] * 100);
- charge = (1000 - charge / 650) / 10;
- if (req->reply[0] & 0x40) {
- pcharge = (req->reply[6] << 8) + req->reply[7];
- if (pcharge > 6500)
- pcharge = 6500;
- pcharge *= 100;
- pcharge = (1000 - pcharge / 650) / 10;
- if (pcharge < charge)
- charge = pcharge;
- }
- capa = charge;
- max = 100;
- time = (charge * 274) / current;
- current = -current;
-
- } else
- capa = max = current = voltage = time = 0;
-
- if ((req->reply[0] & 0x02) && (current > 0))
- bat_flags |= PMU_BATT_CHARGING;
- if (req->reply[0] & 0x04) /* CHECK THIS ONE */
- bat_flags |= PMU_BATT_PRESENT;
-
- pmu_batteries[pmu_cur_battery].flags = bat_flags;
- pmu_batteries[pmu_cur_battery].charge = capa;
- pmu_batteries[pmu_cur_battery].max_charge = max;
- pmu_batteries[pmu_cur_battery].current = current;
- pmu_batteries[pmu_cur_battery].voltage = voltage;
- pmu_batteries[pmu_cur_battery].time_remaining = time;
-}
-#endif /* NEW_OHARE_CODE */
-
- static void __pmac
-done_battery_state_comet(struct adb_request* req)
-{
/* format:
* [0] : flags
* 0x01 : AC indicator
@@ -718,57 +590,62 @@
* [6][7] : pcharge
* --tkoba
*/
+ unsigned int bat_flags = PMU_BATT_TYPE_HOOPER;
+ long pcharge, charge, vb, vmax, lmax;
+ long vmax_charging, vmax_charged;
+ long current, voltage, time, max;
+ int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
+ NULL, PMAC_MB_INFO_MODEL, 0);
- unsigned int bat_flags = 0;
- int current = 0;
- unsigned int max = 100;
- unsigned int charge, voltage, time;
- int lrange[] = { 0, 600, 750, 900, 1000, 1080,
- 1180, 1250, 1300, 1340, 1360,
- 1390, 1420, 1440, 1470, 1490,
- 1520, 1550, 1580, 1610, 1650,
- 1700
- };
-
if (req->reply[0] & 0x01)
pmu_power_flags |= PMU_PWR_AC_PRESENT;
else
pmu_power_flags &= ~PMU_PWR_AC_PRESENT;
+
+ if (mb == PMAC_TYPE_COMET) {
+ vmax_charged = 189;
+ vmax_charging = 213;
+ lmax = 6500;
+ } else {
+ vmax_charged = 330;
+ vmax_charging = 330;
+ lmax = 6500;
+ }
+ vmax = vmax_charged;
- if (req->reply[0] & 0x04) { /* battery exist */
- int vb, i;
+ /* If battery installed */
+ if (req->reply[0] & 0x04) {
bat_flags |= PMU_BATT_PRESENT;
+ if (req->reply[0] & 0x02)
+ bat_flags |= PMU_BATT_CHARGING;
vb = (req->reply[1] << 8) | req->reply[2];
- voltage = ((vb * 2650) + 726650)/100;
- vb *= 10;
+ voltage = (vb * 265 + 72665) / 10;
current = req->reply[5];
- if ((req->reply[0] & 0x01) == 0 && (current > 200))
- vb += ((current - 200) * 3); /* vb = 500<->1800 */
- else if (req->reply[0] & 0x02)
- vb = ((vb - 800) * 1700/13)/100; /* in charging vb = 1300<->2130 */
-
- if (req->reply[0] & 0x20) { /* full charged */
- charge = max;
- } else {
- if (lrange[21] < vb)
- charge = max;
- else {
- if (vb < lrange[1])
- charge = 0;
- else {
- for (i=21; vb < lrange[i]; --i);
- charge = (i * 100)/21;
- }
- }
- if (charge > max) charge = max;
+ if ((req->reply[0] & 0x01) == 0) {
+ if (current > 200)
+ vb += ((current - 200) * 15)/100;
+ } else if (req->reply[0] & 0x02) {
+ vb = (vb * 97) / 100;
+ vmax = vmax_charging;
}
- time = (charge * 72);
+ charge = (100 * vb) / vmax;
+ if (req->reply[0] & 0x40) {
+ pcharge = (req->reply[6] << 8) + req->reply[7];
+ if (pcharge > lmax)
+ pcharge = lmax;
+ pcharge *= 100;
+ pcharge = 100 - pcharge / lmax;
+ if (pcharge < charge)
+ charge = pcharge;
+ }
+ if (current > 0)
+ time = (charge * 16440) / current;
+ else
+ time = 0;
+ max = 100;
current = -current;
} else
- max = current = voltage = time = 0;
-
- if (req->reply[0] & 0x02)
- bat_flags |= PMU_BATT_CHARGING;
+ charge = max = current = voltage = time = 0;
pmu_batteries[pmu_cur_battery].flags = bat_flags;
pmu_batteries[pmu_cur_battery].charge = charge;
@@ -800,7 +677,7 @@
* [8][9] : voltage
*/
- unsigned int bat_flags = 0;
+ unsigned int bat_flags = PMU_BATT_TYPE_SMART;
int current;
unsigned int capa, max, voltage;
@@ -858,17 +735,10 @@
{
if (!batt_req.complete)
return;
- if (pmu_kind == PMU_OHARE_BASED) {
- int mb = pmac_call_feature(PMAC_FTR_GET_MB_INFO,
- NULL, PMAC_MB_INFO_MODEL, 0);
-
- if (mb == PMAC_TYPE_COMET)
- pmu_request(&batt_req, done_battery_state_comet,
- 1, PMU_BATTERY_STATE);
- else
- pmu_request(&batt_req, done_battery_state_ohare,
- 1, PMU_BATTERY_STATE);
- } else
+ if (pmu_kind == PMU_OHARE_BASED)
+ pmu_request(&batt_req, done_battery_state_ohare,
+ 1, PMU_BATTERY_STATE);
+ else
pmu_request(&batt_req, done_battery_state_smart,
2, PMU_SMART_BATTERY_STATE, pmu_cur_battery+1);
}
@@ -1220,9 +1090,14 @@
static inline void
pmu_done(struct adb_request *req)
{
+ void (*done)(struct adb_request *) = req->done;
+ mb();
req->complete = 1;
- if (req->done)
- (*req->done)(req);
+ /* Here, we assume that if the request has a done member, the
+ * struct request will survive to setting req->complete to 1
+ */
+ if (done)
+ (*done)(req);
}
static void __openfirmware
diff -uNr linux-2.4.20/drivers/net/Makefile linux-2.4.20-ben5/drivers/net/Makefile
--- linux-2.4.20/drivers/net/Makefile 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/Makefile 2003-01-30 11:54:00.000000000 +0100
@@ -17,7 +17,7 @@
export-objs := 8390.o arlan.o aironet4500_core.o aironet4500_card.o \
ppp_async.o ppp_generic.o slhc.o pppox.o auto_irq.o \
- net_init.o mii.o
+ net_init.o mii.o sungem_phy.o
list-multi := rcpci.o
rcpci-objs := rcpci45.o rclanmtl.o
@@ -59,7 +59,7 @@
obj-$(CONFIG_SUNQE) += sunqe.o
obj-$(CONFIG_SUNBMAC) += sunbmac.o
obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o
-obj-$(CONFIG_SUNGEM) += sungem.o
+obj-$(CONFIG_SUNGEM) += sungem.o sungem_phy.o
obj-$(CONFIG_MACE) += mace.o
obj-$(CONFIG_BMAC) += bmac.o
diff -uNr linux-2.4.20/drivers/net/bmac.c linux-2.4.20-ben5/drivers/net/bmac.c
--- linux-2.4.20/drivers/net/bmac.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/bmac.c 2003-01-30 11:53:04.000000000 +0100
@@ -1403,7 +1403,7 @@
memset((char *) bp->tx_cmds, 0,
(N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
- /* init_timer(&bp->tx_timeout); */
+ init_timer(&bp->tx_timeout);
/* bp->timeout_active = 0; */
ret = request_irq(dev->irq, bmac_misc_intr, 0, "BMAC-misc", dev);
diff -uNr linux-2.4.20/drivers/net/gmac.c linux-2.4.20-ben5/drivers/net/gmac.c
--- linux-2.4.20/drivers/net/gmac.c 2002-11-29 00:53:13.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/gmac.c 2003-01-30 11:53:37.000000000 +0100
@@ -1622,6 +1622,7 @@
gm->of_node = gmac;
if (!request_OF_resource(gmac, 0, " (gmac)")) {
printk(KERN_ERR "GMAC: can't request IO resource !\n");
+ gm->of_node = NULL;
goto out_unreg;
}
dev->base_addr = gmac->addrs[0].address;
diff -uNr linux-2.4.20/drivers/net/mace.c linux-2.4.20-ben5/drivers/net/mace.c
--- linux-2.4.20/drivers/net/mace.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/mace.c 2003-01-30 11:54:32.000000000 +0100
@@ -1,6 +1,8 @@
/*
* Network device driver for the MACE ethernet controller on
* Apple Powermacs. Assumes it's under a DBDMA controller.
+ *
+ * MACE is beleived to be an AMD 79C940
*
* Copyright (C) 1996 Paul Mackerras.
*/
diff -uNr linux-2.4.20/drivers/net/ne2k-pci.c linux-2.4.20-ben5/drivers/net/ne2k-pci.c
--- linux-2.4.20/drivers/net/ne2k-pci.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/ne2k-pci.c 2003-01-30 11:53:05.000000000 +0100
@@ -69,8 +69,6 @@
#if defined(__powerpc__)
#define inl_le(addr) le32_to_cpu(inl(addr))
#define inw_le(addr) le16_to_cpu(inw(addr))
-#define insl insl_ns
-#define outsl outsl_ns
#endif
#define PFX DRV_NAME ": "
diff -uNr linux-2.4.20/drivers/net/pcnet32.c linux-2.4.20-ben5/drivers/net/pcnet32.c
--- linux-2.4.20/drivers/net/pcnet32.c 2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/pcnet32.c 2003-01-30 11:54:55.000000000 +0100
@@ -575,7 +575,7 @@
break;
case 0x2625:
chipname = "PCnet/FAST III 79C973"; /* PCI */
- fdx = 1; mii = 1;
+ fdx = 1; mii = 1; fset = 1;
break;
case 0x2626:
chipname = "PCnet/Home 79C978"; /* PCI */
@@ -618,6 +618,7 @@
if(fset)
{
+ printk(KERN_INFO PFX "Activating Tx error recovery on %s\n", chipname);
a->write_bcr(ioaddr, 18, (a->read_bcr(ioaddr, 18) | 0x0800));
a->write_csr(ioaddr, 80, (a->read_csr(ioaddr, 80) & 0x0C00) | 0x0c00);
dxsuflo = 1;
diff -uNr linux-2.4.20/drivers/net/sungem.c linux-2.4.20-ben5/drivers/net/sungem.c
--- linux-2.4.20/drivers/net/sungem.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/sungem.c 2003-01-30 11:54:31.000000000 +0100
@@ -10,10 +10,6 @@
* - Get rid of all those nasty mdelay's and replace them
* with schedule_timeout.
* - Implement WOL
- * - Currently, forced Gb mode is only supported on bcm54xx
- * PHY for which I use the SPD2 bit of the control register.
- * On m1011 PHY, I can't force as I don't have the specs, but
- * I can at least detect gigabit with autoneg.
*/
#include
@@ -63,6 +59,7 @@
#include
#endif
+#include "sungem_phy.h"
#include "sungem.h"
#define DEFAULT_MSG (NETIF_MSG_DRV | \
@@ -84,20 +81,12 @@
MODULE_PARM(gem_debug, "i");
MODULE_PARM_DESC(gem_debug, "bitmapped message enable number");
MODULE_PARM(link_mode, "i");
-MODULE_PARM_DESC(link_mode, "default link mode");
+MODULE_PARM_DESC(forced_speed, "force link speed (10,100,1000)");
+MODULE_PARM_DESC(forced_duplex, "force link duplex (0: half, 1: full)");
int gem_debug = -1;
-static int link_mode;
-
-static u16 link_modes[] __devinitdata = {
- BMCR_ANENABLE, /* 0 : autoneg */
- 0, /* 1 : 10bt half duplex */
- BMCR_SPEED100, /* 2 : 100bt half duplex */
- BMCR_SPD2, /* bcm54xx only */ /* 3 : 1000bt half duplex */
- BMCR_FULLDPLX, /* 4 : 10bt full duplex */
- BMCR_SPEED100|BMCR_FULLDPLX, /* 5 : 100bt full duplex */
- BMCR_SPD2|BMCR_FULLDPLX /* 6 : 1000bt full duplex */
-};
+static int forced_speed = -1;
+static int forced_duplex = -1;
#define GEM_MODULE_NAME "gem"
#define PFX GEM_MODULE_NAME ": "
@@ -119,12 +108,14 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_GMACP,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_GMAC2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{0, }
};
MODULE_DEVICE_TABLE(pci, gem_pci_tbl);
-static u16 __phy_read(struct gem *gp, int reg, int phy_addr)
+static u16 __phy_read(struct gem *gp, int phy_addr, int reg)
{
u32 cmd;
int limit = 10000;
@@ -150,12 +141,18 @@
return cmd & MIF_FRAME_DATA;
}
+static inline int _phy_read(struct net_device *dev, int mii_id, int reg)
+{
+ struct gem *gp = dev->priv;
+ return __phy_read(gp, mii_id, reg);
+}
+
static inline u16 phy_read(struct gem *gp, int reg)
{
- return __phy_read(gp, reg, gp->mii_phy_addr);
+ return __phy_read(gp, gp->mii_phy_addr, reg);
}
-static void __phy_write(struct gem *gp, int reg, u16 val, int phy_addr)
+static void __phy_write(struct gem *gp, int phy_addr, int reg, u16 val)
{
u32 cmd;
int limit = 10000;
@@ -177,9 +174,15 @@
}
}
+static inline void _phy_write(struct net_device *dev, int mii_id, int reg, int val)
+{
+ struct gem *gp = dev->priv;
+ __phy_write(gp, mii_id, reg, val & 0xffff);
+}
+
static inline void phy_write(struct gem *gp, int reg, u16 val)
{
- __phy_write(gp, reg, val, gp->mii_phy_addr);
+ __phy_write(gp, gp->mii_phy_addr, reg, val);
}
static void gem_handle_mif_event(struct gem *gp, u32 reg_val, u32 changed_bits)
@@ -228,10 +231,11 @@
if (pcs_miistat & PCS_MIISTAT_LS) {
printk(KERN_INFO "%s: PCS link is now up.\n",
dev->name);
+ netif_carrier_on(gp->dev);
} else {
printk(KERN_INFO "%s: PCS link is now down.\n",
dev->name);
-
+ netif_carrier_off(gp->dev);
/* If this happens and the link timer is not running,
* reset so we re-negotiate.
*/
@@ -1030,136 +1034,89 @@
}
-/* Link modes of the BCM5400 PHY */
-static int phy_BCM5400_link_table[8][3] = {
- { 0, 0, 0 }, /* No link */
- { 0, 0, 0 }, /* 10BT Half Duplex */
- { 1, 0, 0 }, /* 10BT Full Duplex */
- { 0, 1, 0 }, /* 100BT Half Duplex */
- { 0, 1, 0 }, /* 100BT Half Duplex */
- { 1, 1, 0 }, /* 100BT Full Duplex*/
- { 1, 0, 1 }, /* 1000BT */
- { 1, 0, 1 }, /* 1000BT */
-};
/* Must be invoked under gp->lock. */
+// XXX dbl check what that function should do when called on PCS PHY
static void gem_begin_auto_negotiation(struct gem *gp, struct ethtool_cmd *ep)
{
- u16 ctl;
+ u32 advertise;
+ int autoneg;
+ int forced_speed;
+ int forced_duplex;
+
+ /* Default advertise */
+ advertise = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
+ ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
+ if (gp->gigabit_capable)
+ advertise |= ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full;
+ autoneg = gp->want_autoneg;
+ forced_speed = gp->phy_mii.speed;
+ forced_duplex = gp->phy_mii.duplex;
/* Setup link parameters */
if (!ep)
goto start_aneg;
if (ep->autoneg == AUTONEG_ENABLE) {
- /* TODO: parse ep->advertising */
- gp->link_advertise |= (ADVERTISE_10HALF | ADVERTISE_10FULL);
- gp->link_advertise |= (ADVERTISE_100HALF | ADVERTISE_100FULL);
- /* Can I advertise gigabit here ? I'd need BCM PHY docs... */
- gp->link_cntl = BMCR_ANENABLE;
+ advertise = ep->advertising;
+ autoneg = 1;
} else {
- gp->link_cntl = 0;
- if (ep->speed == SPEED_100)
- gp->link_cntl |= BMCR_SPEED100;
- else if (ep->speed == SPEED_1000 && gp->gigabit_capable)
- /* Hrm... check if this is right... */
- gp->link_cntl |= BMCR_SPD2;
- if (ep->duplex == DUPLEX_FULL)
- gp->link_cntl |= BMCR_FULLDPLX;
+ autoneg = 0;
+ forced_speed = ep->speed;
+ forced_duplex = ep->duplex;
}
start_aneg:
- if (!gp->hw_running)
+ if (!gp->hw_running) {
+ gp->phy_mii.autoneg = gp->want_autoneg = autoneg;
+ gp->phy_mii.speed = forced_speed;
+ gp->phy_mii.duplex = forced_duplex;
return;
+ }
/* Configure PHY & start aneg */
- ctl = phy_read(gp, MII_BMCR);
- ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
- ctl |= gp->link_cntl;
- if (ctl & BMCR_ANENABLE) {
- ctl |= BMCR_ANRESTART;
+ gp->want_autoneg = autoneg;
+ if (autoneg) {
+ if (found_mii_phy(gp))
+ gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, advertise);
gp->lstate = link_aneg;
} else {
+ if (found_mii_phy(gp))
+ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, forced_speed,
+ forced_duplex);
gp->lstate = link_force_ok;
}
- phy_write(gp, MII_BMCR, ctl);
gp->timer_ticks = 0;
mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
}
-/* Must be invoked under gp->lock. */
-static void gem_read_mii_link_mode(struct gem *gp, int *fd, int *spd, int *pause)
-{
- u32 val;
-
- *fd = 0;
- *spd = 10;
- *pause = 0;
-
- if (gp->phy_mod == phymod_bcm5400 ||
- gp->phy_mod == phymod_bcm5401 ||
- gp->phy_mod == phymod_bcm5411) {
- int link_mode;
-
- val = phy_read(gp, MII_BCM5400_AUXSTATUS);
- link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
- MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
- *fd = phy_BCM5400_link_table[link_mode][0];
- *spd = phy_BCM5400_link_table[link_mode][2] ?
- 1000 :
- (phy_BCM5400_link_table[link_mode][1] ? 100 : 10);
- val = phy_read(gp, MII_LPA);
- if (val & LPA_PAUSE)
- *pause = 1;
- } else {
- val = phy_read(gp, MII_LPA);
-
- if (val & (LPA_10FULL | LPA_100FULL))
- *fd = 1;
- if (val & (LPA_100FULL | LPA_100HALF))
- *spd = 100;
-
- if (gp->phy_mod == phymod_m1011) {
- val = phy_read(gp, 0x0a);
- if (val & 0xc00)
- *spd = 1000;
- if (val & 0x800)
- *fd = 1;
- }
- }
-}
-
/* A link-up condition has occurred, initialize and enable the
* rest of the chip.
*
* Must be invoked under gp->lock.
*/
-static void gem_set_link_modes(struct gem *gp)
+static int gem_set_link_modes(struct gem *gp)
{
u32 val;
int full_duplex, speed, pause;
full_duplex = 0;
- speed = 10;
+ speed = SPEED_10;
pause = 0;
- if (gp->phy_type == phy_mii_mdio0 ||
- gp->phy_type == phy_mii_mdio1) {
- val = phy_read(gp, MII_BMCR);
- if (val & BMCR_ANENABLE)
- gem_read_mii_link_mode(gp, &full_duplex, &speed, &pause);
- else {
- if (val & BMCR_FULLDPLX)
- full_duplex = 1;
- if (val & BMCR_SPEED100)
- speed = 100;
- }
- } else {
+ if (found_mii_phy(gp)) {
+ if (gp->phy_mii.def->ops->read_link(&gp->phy_mii))
+ return 1;
+ full_duplex = (gp->phy_mii.duplex == DUPLEX_FULL);
+ speed = gp->phy_mii.speed;
+ pause = gp->phy_mii.pause;
+ } else if (gp->phy_type == phy_serialink ||
+ gp->phy_type == phy_serdes) {
u32 pcs_lpa = readl(gp->regs + PCS_MIILP);
if (pcs_lpa & PCS_MIIADV_FD)
full_duplex = 1;
- speed = 1000;
+ speed = SPEED_1000;
}
if (netif_msg_link(gp))
@@ -1183,7 +1140,7 @@
val |= MAC_XIFCFG_FLED;
}
- if (speed == 1000)
+ if (speed == SPEED_1000)
val |= (MAC_XIFCFG_GMII);
writel(val, gp->regs + MAC_XIFCFG);
@@ -1191,7 +1148,7 @@
/* If gigabit and half-duplex, enable carrier extension
* mode. Else, disable it.
*/
- if (speed == 1000 && !full_duplex) {
+ if (speed == SPEED_1000 && !full_duplex) {
val = readl(gp->regs + MAC_TXCFG);
writel(val | MAC_TXCFG_TCE, gp->regs + MAC_TXCFG);
@@ -1239,31 +1196,28 @@
writel(val, gp->regs + MAC_MCCFG);
gem_start_dma(gp);
+
+ return 0;
}
/* Must be invoked under gp->lock. */
static int gem_mdio_link_not_up(struct gem *gp)
{
- u16 val;
-
if (gp->lstate == link_force_ret) {
if (netif_msg_link(gp))
printk(KERN_INFO "%s: Autoneg failed again, keeping"
" forced mode\n", gp->dev->name);
- phy_write(gp, MII_BMCR, gp->link_fcntl);
+ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii,
+ gp->last_forced_speed, DUPLEX_HALF);
gp->timer_ticks = 5;
gp->lstate = link_force_ok;
} else if (gp->lstate == link_aneg) {
- val = phy_read(gp, MII_BMCR);
-
if (netif_msg_link(gp))
printk(KERN_INFO "%s: switching to forced 100bt\n",
gp->dev->name);
/* Try forced modes. */
- val &= ~(BMCR_ANRESTART | BMCR_ANENABLE);
- val &= ~(BMCR_FULLDPLX);
- val |= BMCR_SPEED100;
- phy_write(gp, MII_BMCR, val);
+ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_100,
+ DUPLEX_HALF);
gp->timer_ticks = 5;
gp->lstate = link_force_try;
} else {
@@ -1271,10 +1225,9 @@
* If already at 10Mbps, warn user about the
* situation every 10 ticks.
*/
- val = phy_read(gp, MII_BMCR);
- if (val & BMCR_SPEED100) {
- val &= ~BMCR_SPEED100;
- phy_write(gp, MII_BMCR, val);
+ if (gp->phy_mii.speed == SPEED_100) {
+ gp->phy_mii.def->ops->setup_forced(&gp->phy_mii, SPEED_10,
+ DUPLEX_HALF);
gp->timer_ticks = 5;
if (netif_msg_link(gp))
printk(KERN_INFO "%s: switching to forced 10bt\n",
@@ -1322,7 +1275,8 @@
static void gem_link_timer(unsigned long data)
{
struct gem *gp = (struct gem *) data;
-
+ int restart_aneg = 0;
+
if (!gp->hw_running)
return;
@@ -1334,62 +1288,8 @@
if (gp->reset_task_pending)
goto restart;
- if (gp->phy_type == phy_mii_mdio0 ||
- gp->phy_type == phy_mii_mdio1) {
- u16 val = phy_read(gp, MII_BMSR);
- u16 cntl = phy_read(gp, MII_BMCR);
- int up;
-
- /* When using autoneg, we really wait for ANEGCOMPLETE or we may
- * get a "transcient" incorrect link state
- */
- if (cntl & BMCR_ANENABLE)
- up = (val & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS)) == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS);
- else
- up = (val & BMSR_LSTATUS) != 0;
- if (up) {
- /* Ok, here we got a link. If we had it due to a forced
- * fallback, and we were configured for autoneg, we do
- * retry a short autoneg pass. If you know your hub is
- * broken, use ethtool ;)
- */
- if (gp->lstate == link_force_try && (gp->link_cntl & BMCR_ANENABLE)) {
- gp->lstate = link_force_ret;
- gp->link_fcntl = phy_read(gp, MII_BMCR);
- gp->timer_ticks = 5;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Got link after fallback, retrying"
- " autoneg once...\n", gp->dev->name);
- phy_write(gp, MII_BMCR,
- gp->link_fcntl | BMCR_ANENABLE | BMCR_ANRESTART);
- } else if (gp->lstate != link_up) {
- gp->lstate = link_up;
- if (gp->opened)
- gem_set_link_modes(gp);
- }
- } else {
- int restart = 0;
-
- /* If the link was previously up, we restart the
- * whole process
- */
- if (gp->lstate == link_up) {
- gp->lstate = link_down;
- if (netif_msg_link(gp))
- printk(KERN_INFO "%s: Link down\n",
- gp->dev->name);
- gp->reset_task_pending = 2;
- schedule_task(&gp->reset_task);
- restart = 1;
- } else if (++gp->timer_ticks > 10)
- restart = gem_mdio_link_not_up(gp);
-
- if (restart) {
- gem_begin_auto_negotiation(gp, NULL);
- goto out_unlock;
- }
- }
- } else {
+ if (gp->phy_type == phy_serialink ||
+ gp->phy_type == phy_serdes) {
u32 val = readl(gp->regs + PCS_MIISTAT);
if (!(val & PCS_MIISTAT_LS))
@@ -1397,11 +1297,56 @@
if ((val & PCS_MIISTAT_LS) != 0) {
gp->lstate = link_up;
+ netif_carrier_on(gp->dev);
if (gp->opened)
- gem_set_link_modes(gp);
+ (void)gem_set_link_modes(gp);
}
+ goto restart;
+ }
+ if (found_mii_phy(gp) && gp->phy_mii.def->ops->poll_link(&gp->phy_mii)) {
+ /* Ok, here we got a link. If we had it due to a forced
+ * fallback, and we were configured for autoneg, we do
+ * retry a short autoneg pass. If you know your hub is
+ * broken, use ethtool ;)
+ */
+ if (gp->lstate == link_force_try && gp->want_autoneg) {
+ gp->lstate = link_force_ret;
+ gp->last_forced_speed = gp->phy_mii.speed;
+ gp->timer_ticks = 5;
+ if (netif_msg_link(gp))
+ printk(KERN_INFO "%s: Got link after fallback, retrying"
+ " autoneg once...\n", gp->dev->name);
+ gp->phy_mii.def->ops->setup_aneg(&gp->phy_mii, gp->phy_mii.advertising);
+ } else if (gp->lstate != link_up) {
+ gp->lstate = link_up;
+ netif_carrier_on(gp->dev);
+ if (gp->opened && gem_set_link_modes(gp))
+ restart_aneg = 1;
+ }
+ } else {
+ /* If the link was previously up, we restart the
+ * whole process
+ */
+ if (gp->lstate == link_up) {
+ gp->lstate = link_down;
+ if (netif_msg_link(gp))
+ printk(KERN_INFO "%s: Link down\n",
+ gp->dev->name);
+ netif_carrier_off(gp->dev);
+ gp->reset_task_pending = 2;
+ schedule_task(&gp->reset_task);
+ restart_aneg = 1;
+ } else if (++gp->timer_ticks > 10) {
+ if (found_mii_phy(gp))
+ restart_aneg = gem_mdio_link_not_up(gp);
+ else
+ restart_aneg = 1;
+ }
+ }
+ if (restart_aneg) {
+ gem_begin_auto_negotiation(gp, NULL);
+ goto out_unlock;
}
-
restart:
mod_timer(&gp->link_timer, jiffies + ((12 * HZ) / 10));
out_unlock:
@@ -1504,150 +1449,10 @@
}
/* Must be invoked under gp->lock. */
-static int gem_reset_one_mii_phy(struct gem *gp, int phy_addr)
-{
- u16 val;
- int limit = 10000;
-
- val = __phy_read(gp, MII_BMCR, phy_addr);
- val &= ~BMCR_ISOLATE;
- val |= BMCR_RESET;
- __phy_write(gp, MII_BMCR, val, phy_addr);
-
- udelay(100);
-
- while (limit--) {
- val = __phy_read(gp, MII_BMCR, phy_addr);
- if ((val & BMCR_RESET) == 0)
- break;
- udelay(10);
- }
- if ((val & BMCR_ISOLATE) && limit > 0)
- __phy_write(gp, MII_BMCR, val & ~BMCR_ISOLATE, phy_addr);
-
- return (limit <= 0);
-}
-
-/* Must be invoked under gp->lock. */
-static void gem_init_bcm5201_phy(struct gem *gp)
-{
- u16 data;
-
- data = phy_read(gp, MII_BCM5201_MULTIPHY);
- data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
- phy_write(gp, MII_BCM5201_MULTIPHY, data);
-}
-
-/* Must be invoked under gp->lock. */
-static void gem_init_bcm5400_phy(struct gem *gp)
-{
- u16 data;
-
- /* Configure for gigabit full duplex */
- data = phy_read(gp, MII_BCM5400_AUXCONTROL);
- data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
- phy_write(gp, MII_BCM5400_AUXCONTROL, data);
-
- data = phy_read(gp, MII_BCM5400_GB_CONTROL);
- data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
- phy_write(gp, MII_BCM5400_GB_CONTROL, data);
-
- mdelay(10);
-
- /* Reset and configure cascaded 10/100 PHY */
- gem_reset_one_mii_phy(gp, 0x1f);
-
- data = __phy_read(gp, MII_BCM5201_MULTIPHY, 0x1f);
- data |= MII_BCM5201_MULTIPHY_SERIALMODE;
- __phy_write(gp, MII_BCM5201_MULTIPHY, data, 0x1f);
-
- data = phy_read(gp, MII_BCM5400_AUXCONTROL);
- data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
- phy_write(gp, MII_BCM5400_AUXCONTROL, data);
-}
-
-/* Must be invoked under gp->lock. */
-static void gem_init_bcm5401_phy(struct gem *gp)
-{
- u16 data;
- int rev;
-
- rev = phy_read(gp, MII_PHYSID2) & 0x000f;
- if (rev == 0 || rev == 3) {
- /* Some revisions of 5401 appear to need this
- * initialisation sequence to disable, according
- * to OF, "tap power management"
- *
- * WARNING ! OF and Darwin don't agree on the
- * register addresses. OF seem to interpret the
- * register numbers below as decimal
- *
- * Note: This should (and does) match tg3_init_5401phy_dsp
- * in the tg3.c driver. -DaveM
- */
- phy_write(gp, 0x18, 0x0c20);
- phy_write(gp, 0x17, 0x0012);
- phy_write(gp, 0x15, 0x1804);
- phy_write(gp, 0x17, 0x0013);
- phy_write(gp, 0x15, 0x1204);
- phy_write(gp, 0x17, 0x8006);
- phy_write(gp, 0x15, 0x0132);
- phy_write(gp, 0x17, 0x8006);
- phy_write(gp, 0x15, 0x0232);
- phy_write(gp, 0x17, 0x201f);
- phy_write(gp, 0x15, 0x0a20);
- }
-
- /* Configure for gigabit full duplex */
- data = phy_read(gp, MII_BCM5400_GB_CONTROL);
- data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
- phy_write(gp, MII_BCM5400_GB_CONTROL, data);
-
- mdelay(1);
-
- /* Reset and configure cascaded 10/100 PHY */
- gem_reset_one_mii_phy(gp, 0x1f);
-
- data = __phy_read(gp, MII_BCM5201_MULTIPHY, 0x1f);
- data |= MII_BCM5201_MULTIPHY_SERIALMODE;
- __phy_write(gp, MII_BCM5201_MULTIPHY, data, 0x1f);
-}
-
-/* Must be invoked under gp->lock. */
-static void gem_init_bcm5411_phy(struct gem *gp)
-{
- u16 data;
-
- /* Here's some more Apple black magic to setup
- * some voltage stuffs.
- */
- phy_write(gp, 0x1c, 0x8c23);
- phy_write(gp, 0x1c, 0x8ca3);
- phy_write(gp, 0x1c, 0x8c23);
-
- /* Here, Apple seems to want to reset it, do
- * it as well
- */
- phy_write(gp, MII_BMCR, BMCR_RESET);
-
- /* Start autoneg */
- phy_write(gp, MII_BMCR,
- (BMCR_ANENABLE | BMCR_FULLDPLX |
- BMCR_ANRESTART | BMCR_SPD2));
-
- data = phy_read(gp, MII_BCM5400_GB_CONTROL);
- data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
- phy_write(gp, MII_BCM5400_GB_CONTROL, data);
-}
-
-/* Must be invoked under gp->lock. */
static void gem_init_phy(struct gem *gp)
{
u32 mifcfg;
-
- if (!gp->wake_on_lan && gp->phy_mod == phymod_bcm5201)
- phy_write(gp, MII_BCM5201_INTERRUPT, 0);
-
+
/* Revert MIF CFG setting done on stop_phy */
mifcfg = readl(gp->regs + MIF_CFG);
mifcfg &= ~MIF_CFG_BBMODE;
@@ -1655,19 +1460,37 @@
#ifdef CONFIG_ALL_PPC
if (gp->pdev->vendor == PCI_VENDOR_ID_APPLE) {
- int i;
+ int i, j;
+ /* Those delay sucks, the HW seem to love them though, I'll
+ * serisouly consider breaking some locks here to be able
+ * to schedule instead
+ */
pmac_call_feature(PMAC_FTR_GMAC_PHY_RESET, gp->of_node, 0, 0);
- for (i = 0; i < 32; i++) {
- gp->mii_phy_addr = i;
- if (phy_read(gp, MII_BMCR) != 0xffff)
+ mdelay(10);
+ for (j = 0; j < 3; j++) {
+ /* Some PHYs used by apple have problem getting back to us,
+ * we _know_ it's actually at addr 0, that's a hack, but
+ * it helps to do that reset now. I suspect some motherboards
+ * don't wire the PHY reset line properly, thus the PHY doesn't
+ * come back with the above pmac_call_feature.
+ */
+ gp->mii_phy_addr = 0;
+ phy_write(gp, MII_BMCR, BMCR_RESET);
+ /* We should probably break some locks here and schedule... */
+ mdelay(10);
+ for (i = 0; i < 32; i++) {
+ gp->mii_phy_addr = i;
+ if (phy_read(gp, MII_BMCR) != 0xffff)
+ break;
+ }
+ if (i == 32) {
+ printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
+ gp->dev->name);
+ gp->mii_phy_addr = 0;
+ } else
break;
}
- if (i == 32) {
- printk(KERN_WARNING "%s: GMAC PHY not responding !\n",
- gp->dev->name);
- return;
- }
}
#endif /* CONFIG_ALL_PPC */
@@ -1690,79 +1513,14 @@
if (gp->phy_type == phy_mii_mdio0 ||
gp->phy_type == phy_mii_mdio1) {
- u32 phy_id;
- u16 val;
-
- /* Take PHY out of isloate mode and reset it. */
- gem_reset_one_mii_phy(gp, gp->mii_phy_addr);
-
- phy_id = (phy_read(gp, MII_PHYSID1) << 16 | phy_read(gp, MII_PHYSID2))
- & 0xfffffff0;
- printk(KERN_INFO "%s: MII PHY ID: %x ", gp->dev->name, phy_id);
- switch(phy_id) {
- case 0x406210:
- gp->phy_mod = phymod_bcm5201;
- gem_init_bcm5201_phy(gp);
- printk("BCM 5201\n");
- break;
-
- case 0x4061e0:
- printk("BCM 5221\n");
- gp->phy_mod = phymod_bcm5221;
- break;
-
- case 0x206040:
- printk("BCM 5400\n");
- gp->phy_mod = phymod_bcm5400;
- gem_init_bcm5400_phy(gp);
- gp->gigabit_capable = 1;
- break;
-
- case 0x206050:
- printk("BCM 5401\n");
- gp->phy_mod = phymod_bcm5401;
- gem_init_bcm5401_phy(gp);
- gp->gigabit_capable = 1;
- break;
-
- case 0x206070:
- printk("BCM 5411\n");
- gp->phy_mod = phymod_bcm5411;
- gem_init_bcm5411_phy(gp);
- gp->gigabit_capable = 1;
- break;
- case 0x1410c60:
- printk("M1011 (Marvel ?)\n");
- gp->phy_mod = phymod_m1011;
- gp->gigabit_capable = 1;
- break;
-
- case 0x18074c0:
- printk("Lucent\n");
- gp->phy_mod = phymod_generic;
- break;
-
- case 0x437420:
- printk("Enable Semiconductor\n");
- gp->phy_mod = phymod_generic;
- break;
-
- default:
- printk("Unknown (Using generic mode)\n");
- gp->phy_mod = phymod_generic;
- break;
- };
+ // XXX check for errors
+ mii_phy_probe(&gp->phy_mii, gp->mii_phy_addr);
- /* Init advertisement and enable autonegotiation. */
- val = phy_read(gp, MII_BMCR);
- val &= ~BMCR_ANENABLE;
- phy_write(gp, MII_BMCR, val);
- udelay(10);
-
- phy_write(gp, MII_ADVERTISE,
- phy_read(gp, MII_ADVERTISE) |
- (ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL));
+ gp->gigabit_capable = gp->phy_mii.def && (gp->phy_mii.def->features &
+ (SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)) != 0;
+ /* Init PHY */
+ if (gp->phy_mii.def && gp->phy_mii.def->ops->init)
+ gp->phy_mii.def->ops->init(&gp->phy_mii);
} else {
u32 val;
int limit;
@@ -1821,11 +1579,6 @@
writel(val, gp->regs + PCS_SCTRL);
gp->gigabit_capable = 1;
}
-
- /* BMCR_SPD2 is a broadcom 54xx specific thing afaik */
- if (gp->phy_mod != phymod_bcm5400 && gp->phy_mod != phymod_bcm5401 &&
- gp->phy_mod != phymod_bcm5411)
- gp->link_cntl &= ~BMCR_SPD2;
}
/* Must be invoked under gp->lock. */
@@ -1914,9 +1667,7 @@
{
unsigned char *e = &gp->dev->dev_addr[0];
- if (gp->pdev->vendor == PCI_VENDOR_ID_SUN &&
- gp->pdev->device == PCI_DEVICE_ID_SUN_GEM)
- writel(0x1bf0, gp->regs + MAC_SNDPAUSE);
+ writel(0x1bf0, gp->regs + MAC_SNDPAUSE);
writel(0x00, gp->regs + MAC_IPG0);
writel(0x08, gp->regs + MAC_IPG1);
@@ -2129,12 +1880,15 @@
/* Default aneg parameters */
gp->timer_ticks = 0;
gp->lstate = link_down;
+ netif_carrier_off(gp->dev);
/* Can I advertise gigabit here ? I'd need BCM PHY docs... */
gem_begin_auto_negotiation(gp, NULL);
} else {
- if (gp->lstate == link_up)
+ if (gp->lstate == link_up) {
+ netif_carrier_on(gp->dev);
gem_set_link_modes(gp);
+ }
}
}
@@ -2184,9 +1938,6 @@
{
u32 mifcfg;
- if (!gp->wake_on_lan && gp->phy_mod == phymod_bcm5201)
- phy_write(gp, MII_BCM5201_INTERRUPT, 0);
-
/* Make sure we aren't polling PHY status change. We
* don't currently use that feature though
*/
@@ -2194,9 +1945,6 @@
mifcfg &= ~MIF_CFG_POLL;
writel(mifcfg, gp->regs + MIF_CFG);
- /* Here's a strange hack used by both MacOS 9 and X */
- phy_write(gp, MII_LPA, phy_read(gp, MII_LPA));
-
if (gp->wake_on_lan) {
/* Setup wake-on-lan */
} else
@@ -2210,21 +1958,12 @@
gem_stop(gp);
writel(MAC_TXRST_CMD, gp->regs + MAC_TXRST);
writel(MAC_RXRST_CMD, gp->regs + MAC_RXRST);
- if (gp->phy_mod == phymod_bcm5400 || gp->phy_mod == phymod_bcm5401 ||
- gp->phy_mod == phymod_bcm5411) {
-#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
- phy_write(gp, MII_BMCR, BMCR_PDOWN);
-#endif
- } else if (gp->phy_mod == phymod_bcm5201 || gp->phy_mod == phymod_bcm5221) {
-#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
- u16 val = phy_read(gp, MII_BCM5201_AUXMODE2)
- phy_write(gp, MII_BCM5201_AUXMODE2,
- val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
-#endif
- phy_write(gp, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
- } else if (gp->phy_mod == phymod_m1011)
- phy_write(gp, MII_BMCR, BMCR_PDOWN);
+ }
+
+ if (found_mii_phy(gp) && gp->phy_mii.def->ops->suspend)
+ gp->phy_mii.def->ops->suspend(&gp->phy_mii, 0 /* wake on lan options */);
+ if (!gp->wake_on_lan) {
/* According to Apple, we must set the MDIO pins to this begnign
* state or we may 1) eat more current, 2) damage some PHYs
*/
@@ -2551,8 +2290,6 @@
static int gem_ethtool_ioctl(struct net_device *dev, void *ep_user)
{
struct gem *gp = dev->priv;
- u16 bmcr;
- int full_duplex, speed, pause;
struct ethtool_cmd ecmd;
if (copy_from_user(&ecmd, ep_user, sizeof(ecmd)))
@@ -2575,41 +2312,29 @@
}
case ETHTOOL_GSET:
- ecmd.supported =
+ if (gp->phy_type == phy_mii_mdio0 ||
+ gp->phy_type == phy_mii_mdio1) {
+ if (gp->phy_mii.def)
+ ecmd.supported = gp->phy_mii.def->features;
+ else
+ ecmd.supported = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full;
+
+ /* XXX hardcoded stuff for now */
+ ecmd.port = PORT_MII;
+ ecmd.transceiver = XCVR_EXTERNAL;
+ ecmd.phy_address = 0; /* XXX fixed PHYAD */
+
+ /* Record PHY settings if HW is on. */
+ spin_lock_irq(&gp->lock);
+ ecmd.autoneg = gp->want_autoneg;
+ ecmd.speed = gp->phy_mii.speed;
+ ecmd.duplex = gp->phy_mii.duplex;
+ spin_unlock_irq(&gp->lock);
+ } else { // XXX PCS ?
+ ecmd.supported =
(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII);
-
- if (gp->gigabit_capable)
- ecmd.supported |=
- (SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full);
-
- /* XXX hardcoded stuff for now */
- ecmd.port = PORT_MII;
- ecmd.transceiver = XCVR_EXTERNAL;
- ecmd.phy_address = 0; /* XXX fixed PHYAD */
-
- /* Record PHY settings if HW is on. */
- spin_lock_irq(&gp->lock);
- if (gp->hw_running) {
- bmcr = phy_read(gp, MII_BMCR);
- gem_read_mii_link_mode(gp, &full_duplex, &speed, &pause);
- } else
- bmcr = 0;
- spin_unlock_irq(&gp->lock);
- if (bmcr & BMCR_ANENABLE) {
- ecmd.autoneg = AUTONEG_ENABLE;
- ecmd.speed = speed == 10 ? SPEED_10 : (speed == 1000 ? SPEED_1000 : SPEED_100);
- ecmd.duplex = full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
- } else {
- ecmd.autoneg = AUTONEG_DISABLE;
- ecmd.speed =
- (bmcr & BMCR_SPEED100) ?
- SPEED_100 : SPEED_10;
- ecmd.duplex =
- (bmcr & BMCR_FULLDPLX) ?
- DUPLEX_FULL : DUPLEX_HALF;
+ SUPPORTED_Autoneg);
}
if (copy_to_user(ep_user, &ecmd, sizeof(ecmd)))
return -EFAULT;
@@ -2624,13 +2349,23 @@
ecmd.autoneg != AUTONEG_DISABLE)
return -EINVAL;
+ if (ecmd.autoneg == AUTONEG_ENABLE &&
+ ecmd.advertising == 0)
+ return -EINVAL;
+
if (ecmd.autoneg == AUTONEG_DISABLE &&
- ((ecmd.speed != SPEED_100 &&
+ ((ecmd.speed != SPEED_1000 &&
+ ecmd.speed != SPEED_100 &&
ecmd.speed != SPEED_10) ||
(ecmd.duplex != DUPLEX_HALF &&
ecmd.duplex != DUPLEX_FULL)))
return -EINVAL;
+ if (ecmd.autoneg == AUTONEG_DISABLE &&
+ ecmd.speed == SPEED_1000 &&
+ gp->gigabit_capable == 0)
+ return -EINVAL;
+
/* Apply settings and restart link process. */
spin_lock_irq(&gp->lock);
gem_begin_auto_negotiation(gp, &ecmd);
@@ -2639,7 +2374,7 @@
return 0;
case ETHTOOL_NWAY_RST:
- if ((gp->link_cntl & BMCR_ANENABLE) == 0)
+ if (!gp->want_autoneg)
return -EINVAL;
/* Restart link process. */
@@ -2743,15 +2478,21 @@
/* Fallthrough... */
case SIOCGMIIREG: /* Read MII PHY register. */
- data->val_out = __phy_read(gp, data->reg_num & 0x1f, data->phy_id & 0x1f);
- rc = 0;
+ if (!gp->hw_running)
+ rc = -EIO;
+ else {
+ data->val_out = __phy_read(gp, data->phy_id & 0x1f, data->reg_num & 0x1f);
+ rc = 0;
+ }
break;
case SIOCSMIIREG: /* Write MII PHY register. */
- if (!capable(CAP_NET_ADMIN)) {
+ if (!capable(CAP_NET_ADMIN))
rc = -EPERM;
- } else {
- __phy_write(gp, data->reg_num & 0x1f, data->val_in, data->phy_id & 0x1f);
+ else if (!gp->hw_running)
+ rc = -EIO;
+ else {
+ __phy_write(gp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
rc = 0;
}
break;
@@ -2953,13 +2694,9 @@
INIT_TQUEUE(&gp->pm_task, gem_pm_task, gp);
INIT_TQUEUE(&gp->reset_task, gem_reset_task, gp);
- /* Default link parameters */
- if (link_mode >= 0 && link_mode <= 6)
- gp->link_cntl = link_modes[link_mode];
- else
- gp->link_cntl = BMCR_ANENABLE;
gp->lstate = link_down;
gp->timer_ticks = 0;
+ netif_carrier_off(dev);
gp->regs = (unsigned long) ioremap(gemreg_base, gemreg_len);
if (gp->regs == 0UL) {
@@ -2980,15 +2717,33 @@
gem_stop(gp);
spin_unlock_irq(&gp->lock);
+ /* Fill up the mii_phy structure (even if we won't use it) */
+ gp->phy_mii.dev = dev;
+ gp->phy_mii.mdio_read = _phy_read;
+ gp->phy_mii.mdio_write = _phy_write;
+
+ /* Default link parameters */
+ if (forced_speed != -1 &&
+ forced_speed != SPEED_10 &&
+ forced_speed != SPEED_100 &&
+ forced_speed != SPEED_1000) {
+ forced_speed = -1;
+ printk(KERN_WARNING "forced_speed argument invalid, reverting to autoneg\n");
+ }
+ if (forced_speed < SPEED_10)
+ gp->want_autoneg = 1;
+ else {
+ gp->want_autoneg = 0;
+ gp->phy_mii.speed = forced_speed;
+ if (forced_duplex > 0)
+ gp->phy_mii.duplex = DUPLEX_FULL;
+ else
+ gp->phy_mii.duplex = DUPLEX_HALF;
+ }
+
if (gem_check_invariants(gp))
goto err_out_iounmap;
- spin_lock_irq(&gp->lock);
- gp->hw_running = 1;
- gem_init_phy(gp);
- gem_begin_auto_negotiation(gp, NULL);
- spin_unlock_irq(&gp->lock);
-
/* It is guarenteed that the returned buffer will be at least
* PAGE_SIZE aligned.
*/
@@ -3015,12 +2770,23 @@
printk(KERN_INFO "%s: Sun GEM (PCI) 10/100/1000BaseT Ethernet ",
dev->name);
-
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i],
i == 5 ? ' ' : ':');
printk("\n");
+ /* Detect & init PHY, start autoneg */
+ spin_lock_irq(&gp->lock);
+ gp->hw_running = 1;
+ gem_init_phy(gp);
+ gem_begin_auto_negotiation(gp, NULL);
+ spin_unlock_irq(&gp->lock);
+
+ if (gp->phy_type == phy_mii_mdio0 ||
+ gp->phy_type == phy_mii_mdio1)
+ printk(KERN_INFO "%s: Found %s PHY\n", dev->name,
+ gp->phy_mii.def ? gp->phy_mii.def->name : "no");
+
pci_set_drvdata(pdev, dev);
dev->open = gem_open;
diff -uNr linux-2.4.20/drivers/net/sungem.h linux-2.4.20-ben5/drivers/net/sungem.h
--- linux-2.4.20/drivers/net/sungem.h 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/sungem.h 2003-01-30 11:53:23.000000000 +0100
@@ -936,16 +936,6 @@
phy_serdes,
};
-enum gem_phy_model {
- phymod_generic,
- phymod_bcm5201,
- phymod_bcm5221,
- phymod_bcm5400,
- phymod_bcm5401,
- phymod_bcm5411,
- phymod_m1011,
-};
-
enum link_state {
link_down = 0, /* No link, will retry */
link_aneg, /* Autoneg in progress */
@@ -980,7 +970,8 @@
struct net_device_stats net_stats;
enum gem_phy_type phy_type;
- enum gem_phy_model phy_mod;
+ struct mii_phy phy_mii;
+
int tx_fifo_sz;
int rx_fifo_sz;
int rx_pause_off;
@@ -992,9 +983,8 @@
u32 swrst_base;
/* Autoneg & PHY control */
- int link_cntl;
- int link_advertise;
- int link_fcntl;
+ int want_autoneg;
+ int last_forced_speed;
enum link_state lstate;
struct timer_list link_timer;
int timer_ticks;
@@ -1014,6 +1004,9 @@
#endif
};
+#define found_mii_phy(gp) ((gp->phy_type == phy_mii_mdio0 || gp->phy_type == phy_mii_mdio1) \
+ && gp->phy_mii.def && gp->phy_mii.def->ops)
+
#define ALIGNED_RX_SKB_ADDR(addr) \
((((unsigned long)(addr) + (64UL - 1UL)) & ~(64UL - 1UL)) - (unsigned long)(addr))
static __inline__ struct sk_buff *gem_alloc_skb(int size, int gfp_flags)
diff -uNr linux-2.4.20/drivers/net/sungem_phy.c linux-2.4.20-ben5/drivers/net/sungem_phy.c
--- linux-2.4.20/drivers/net/sungem_phy.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/sungem_phy.c 2003-01-30 11:55:35.000000000 +0100
@@ -0,0 +1,783 @@
+/*
+ * PHY drivers for the sungem ethernet driver.
+ *
+ * This file could be shared with other drivers.
+ *
+ * (c) 2002, Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ *
+ * TODO:
+ * - Implement WOL
+ * - Add support for PHYs that provide an IRQ line
+ * - Eventually moved the entire polling state machine in
+ * there (out of the eth driver), so that it can easily be
+ * skipped on PHYs that implement it in hardware.
+ * - On LXT971 & BCM5201, Apple uses some chip specific regs
+ * to read the link status. Figure out why and if it makes
+ * sense to do the same (magic aneg ?)
+ * - Apple has some additional power management code for some
+ * Broadcom PHYs that they "hide" from the OpenSource version
+ * of darwin, still need to reverse engineer that
+ */
+
+#include
+
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "sungem_phy.h"
+
+/* Link modes of the BCM5400 PHY */
+static int phy_BCM5400_link_table[8][3] = {
+ { 0, 0, 0 }, /* No link */
+ { 0, 0, 0 }, /* 10BT Half Duplex */
+ { 1, 0, 0 }, /* 10BT Full Duplex */
+ { 0, 1, 0 }, /* 100BT Half Duplex */
+ { 0, 1, 0 }, /* 100BT Half Duplex */
+ { 1, 1, 0 }, /* 100BT Full Duplex*/
+ { 1, 0, 1 }, /* 1000BT */
+ { 1, 0, 1 }, /* 1000BT */
+};
+
+static inline int __phy_read(struct mii_phy* phy, int id, int reg)
+{
+ return phy->mdio_read(phy->dev, id, reg);
+}
+
+static inline void __phy_write(struct mii_phy* phy, int id, int reg, int val)
+{
+ phy->mdio_write(phy->dev, id, reg, val);
+}
+
+static inline int phy_read(struct mii_phy* phy, int reg)
+{
+ return phy->mdio_read(phy->dev, phy->mii_id, reg);
+}
+
+static inline void phy_write(struct mii_phy* phy, int reg, int val)
+{
+ phy->mdio_write(phy->dev, phy->mii_id, reg, val);
+}
+
+static int reset_one_mii_phy(struct mii_phy* phy, int phy_id)
+{
+ u16 val;
+ int limit = 10000;
+
+ val = __phy_read(phy, phy_id, MII_BMCR);
+ val &= ~BMCR_ISOLATE;
+ val |= BMCR_RESET;
+ __phy_write(phy, phy_id, MII_BMCR, val);
+
+ udelay(100);
+
+ while (limit--) {
+ val = __phy_read(phy, phy_id, MII_BMCR);
+ if ((val & BMCR_RESET) == 0)
+ break;
+ udelay(10);
+ }
+ if ((val & BMCR_ISOLATE) && limit > 0)
+ __phy_write(phy, phy_id, MII_BMCR, val & ~BMCR_ISOLATE);
+
+ return (limit <= 0);
+}
+
+static int bcm5201_init(struct mii_phy* phy)
+{
+ u16 data;
+
+ data = phy_read(phy, MII_BCM5201_MULTIPHY);
+ data &= ~MII_BCM5201_MULTIPHY_SUPERISOLATE;
+ phy_write(phy, MII_BCM5201_MULTIPHY, data);
+
+ return 0;
+}
+
+static int bcm5201_suspend(struct mii_phy* phy, int wol_options)
+{
+ if (!wol_options)
+ phy_write(phy, MII_BCM5201_INTERRUPT, 0);
+
+ /* Here's a strange hack used by both MacOS 9 and X */
+ phy_write(phy, MII_LPA, phy_read(phy, MII_LPA));
+
+ if (!wol_options) {
+#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
+ u16 val = phy_read(phy, MII_BCM5201_AUXMODE2)
+ phy_write(phy, MII_BCM5201_AUXMODE2,
+ val & ~MII_BCM5201_AUXMODE2_LOWPOWER);
+#endif
+ phy_write(phy, MII_BCM5201_MULTIPHY, MII_BCM5201_MULTIPHY_SUPERISOLATE);
+ }
+
+ return 0;
+}
+
+static int bcm5400_init(struct mii_phy* phy)
+{
+ u16 data;
+
+ /* Configure for gigabit full duplex */
+ data = phy_read(phy, MII_BCM5400_AUXCONTROL);
+ data |= MII_BCM5400_AUXCONTROL_PWR10BASET;
+ phy_write(phy, MII_BCM5400_AUXCONTROL, data);
+
+ data = phy_read(phy, MII_BCM5400_GB_CONTROL);
+ data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(phy, MII_BCM5400_GB_CONTROL, data);
+
+ mdelay(10);
+
+ /* Reset and configure cascaded 10/100 PHY */
+ (void)reset_one_mii_phy(phy, 0x1f);
+
+ data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
+ data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+ __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
+
+ data = phy_read(phy, MII_BCM5400_AUXCONTROL);
+ data &= ~MII_BCM5400_AUXCONTROL_PWR10BASET;
+ phy_write(phy, MII_BCM5400_AUXCONTROL, data);
+
+ return 0;
+}
+
+static int bcm5400_suspend(struct mii_phy* phy, int wol_options)
+{
+#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
+ phy_write(phy, MII_BMCR, BMCR_PDOWN);
+#endif
+ return 0;
+}
+
+static int bcm5401_init(struct mii_phy* phy)
+{
+ u16 data;
+ int rev;
+
+ rev = phy_read(phy, MII_PHYSID2) & 0x000f;
+ if (rev == 0 || rev == 3) {
+ /* Some revisions of 5401 appear to need this
+ * initialisation sequence to disable, according
+ * to OF, "tap power management"
+ *
+ * WARNING ! OF and Darwin don't agree on the
+ * register addresses. OF seem to interpret the
+ * register numbers below as decimal
+ *
+ * Note: This should (and does) match tg3_init_5401phy_dsp
+ * in the tg3.c driver. -DaveM
+ */
+ phy_write(phy, 0x18, 0x0c20);
+ phy_write(phy, 0x17, 0x0012);
+ phy_write(phy, 0x15, 0x1804);
+ phy_write(phy, 0x17, 0x0013);
+ phy_write(phy, 0x15, 0x1204);
+ phy_write(phy, 0x17, 0x8006);
+ phy_write(phy, 0x15, 0x0132);
+ phy_write(phy, 0x17, 0x8006);
+ phy_write(phy, 0x15, 0x0232);
+ phy_write(phy, 0x17, 0x201f);
+ phy_write(phy, 0x15, 0x0a20);
+ }
+
+ /* Configure for gigabit full duplex */
+ data = phy_read(phy, MII_BCM5400_GB_CONTROL);
+ data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(phy, MII_BCM5400_GB_CONTROL, data);
+
+ mdelay(10);
+
+ /* Reset and configure cascaded 10/100 PHY */
+ (void)reset_one_mii_phy(phy, 0x1f);
+
+ data = __phy_read(phy, 0x1f, MII_BCM5201_MULTIPHY);
+ data |= MII_BCM5201_MULTIPHY_SERIALMODE;
+ __phy_write(phy, 0x1f, MII_BCM5201_MULTIPHY, data);
+
+ return 0;
+}
+
+static int bcm5401_suspend(struct mii_phy* phy, int wol_options)
+{
+#if 0 /* Commented out in Darwin... someone has those dawn docs ? */
+ phy_write(phy, MII_BMCR, BMCR_PDOWN);
+#endif
+ return 0;
+}
+
+static int bcm5411_init(struct mii_phy* phy)
+{
+ u16 data;
+
+ /* Here's some more Apple black magic to setup
+ * some voltage stuffs.
+ */
+ phy_write(phy, 0x1c, 0x8c23);
+ phy_write(phy, 0x1c, 0x8ca3);
+ phy_write(phy, 0x1c, 0x8c23);
+
+ /* Here, Apple seems to want to reset it, do
+ * it as well
+ */
+ phy_write(phy, MII_BMCR, BMCR_RESET);
+ phy_write(phy, MII_BMCR, 0x1340);
+
+ data = phy_read(phy, MII_BCM5400_GB_CONTROL);
+ data |= MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP;
+ phy_write(phy, MII_BCM5400_GB_CONTROL, data);
+
+ mdelay(10);
+
+ /* Reset and configure cascaded 10/100 PHY */
+ (void)reset_one_mii_phy(phy, 0x1f);
+
+ return 0;
+}
+
+static int bcm5411_suspend(struct mii_phy* phy, int wol_options)
+{
+ phy_write(phy, MII_BMCR, BMCR_PDOWN);
+
+ return 0;
+}
+
+static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+ u16 ctl, adv;
+
+ phy->autoneg = 1;
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = 0;
+ phy->advertising = advertise;
+
+ /* Setup standard advertise */
+ adv = phy_read(phy, MII_ADVERTISE);
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+ if (advertise & ADVERTISED_10baseT_Half)
+ adv |= ADVERTISE_10HALF;
+ if (advertise & ADVERTISED_10baseT_Full)
+ adv |= ADVERTISE_10FULL;
+ if (advertise & ADVERTISED_100baseT_Half)
+ adv |= ADVERTISE_100HALF;
+ if (advertise & ADVERTISED_100baseT_Full)
+ adv |= ADVERTISE_100FULL;
+ phy_write(phy, MII_ADVERTISE, adv);
+
+ /* Setup 1000BT advertise */
+ adv = phy_read(phy, MII_1000BASETCONTROL);
+ adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP|MII_1000BASETCONTROL_HALFDUPLEXCAP);
+ if (advertise & SUPPORTED_1000baseT_Half)
+ adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
+ if (advertise & SUPPORTED_1000baseT_Full)
+ adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
+ phy_write(phy, MII_1000BASETCONTROL, adv);
+
+ /* Start/Restart aneg */
+ ctl = phy_read(phy, MII_BMCR);
+ ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int bcm54xx_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+ u16 ctl;
+
+ phy->autoneg = 0;
+ phy->speed = speed;
+ phy->duplex = fd;
+ phy->pause = 0;
+
+ ctl = phy_read(phy, MII_BMCR);
+ ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
+
+ /* First reset the PHY */
+ phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
+
+ /* Select speed & duplex */
+ switch(speed) {
+ case SPEED_10:
+ break;
+ case SPEED_100:
+ ctl |= BMCR_SPEED100;
+ break;
+ case SPEED_1000:
+ ctl |= BMCR_SPD2;
+ }
+ if (fd == DUPLEX_FULL)
+ ctl |= BMCR_FULLDPLX;
+
+ // XXX Should we set the sungem to GII now on 1000BT ?
+
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int bcm54xx_read_link(struct mii_phy *phy)
+{
+ int link_mode;
+ u16 val;
+
+ if (phy->autoneg) {
+ val = phy_read(phy, MII_BCM5400_AUXSTATUS);
+ link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
+ MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
+ phy->duplex = phy_BCM5400_link_table[link_mode][0] ? DUPLEX_FULL : DUPLEX_HALF;
+ phy->speed = phy_BCM5400_link_table[link_mode][2] ?
+ SPEED_1000 :
+ (phy_BCM5400_link_table[link_mode][1] ? SPEED_100 : SPEED_10);
+ val = phy_read(phy, MII_LPA);
+ phy->pause = ((val & LPA_PAUSE) != 0);
+ }
+ /* On non-aneg, we assume what we put in BMCR is the speed,
+ * though magic-aneg shouldn't prevent this case from occurring
+ */
+
+ return 0;
+}
+
+static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+ u16 ctl, adv;
+
+ phy->autoneg = 1;
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = 0;
+ phy->advertising = advertise;
+
+ /* Setup standard advertise */
+ adv = phy_read(phy, MII_ADVERTISE);
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+ if (advertise & ADVERTISED_10baseT_Half)
+ adv |= ADVERTISE_10HALF;
+ if (advertise & ADVERTISED_10baseT_Full)
+ adv |= ADVERTISE_10FULL;
+ if (advertise & ADVERTISED_100baseT_Half)
+ adv |= ADVERTISE_100HALF;
+ if (advertise & ADVERTISED_100baseT_Full)
+ adv |= ADVERTISE_100FULL;
+ phy_write(phy, MII_ADVERTISE, adv);
+
+ /* Setup 1000BT advertise & enable crossover detect
+ * XXX How do we advertise 1000BT ? Darwin source is
+ * confusing here, they read from specific control and
+ * write to control... Someone has specs for those
+ * beasts ?
+ */
+ adv = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
+ adv |= MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX;
+ adv &= ~(MII_1000BASETCONTROL_FULLDUPLEXCAP |
+ MII_1000BASETCONTROL_HALFDUPLEXCAP);
+ if (advertise & SUPPORTED_1000baseT_Half)
+ adv |= MII_1000BASETCONTROL_HALFDUPLEXCAP;
+ if (advertise & SUPPORTED_1000baseT_Full)
+ adv |= MII_1000BASETCONTROL_FULLDUPLEXCAP;
+ phy_write(phy, MII_1000BASETCONTROL, adv);
+
+ /* Start/Restart aneg */
+ ctl = phy_read(phy, MII_BMCR);
+ ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+ u16 ctl, ctl2;
+
+ phy->autoneg = 0;
+ phy->speed = speed;
+ phy->duplex = fd;
+ phy->pause = 0;
+
+ ctl = phy_read(phy, MII_BMCR);
+ ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_SPD2|BMCR_ANENABLE);
+ ctl |= BMCR_RESET;
+
+ /* Select speed & duplex */
+ switch(speed) {
+ case SPEED_10:
+ break;
+ case SPEED_100:
+ ctl |= BMCR_SPEED100;
+ break;
+ /* I'm not sure about the one below, again, Darwin source is
+ * quite confusing and I lack chip specs
+ */
+ case SPEED_1000:
+ ctl |= BMCR_SPD2;
+ }
+ if (fd == DUPLEX_FULL)
+ ctl |= BMCR_FULLDPLX;
+
+ /* Disable crossover. Again, the way Apple does it is strange,
+ * though I don't assume they are wrong ;)
+ */
+ ctl2 = phy_read(phy, MII_M1011_PHY_SPEC_CONTROL);
+ ctl2 &= ~(MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX |
+ MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX |
+ MII_1000BASETCONTROL_FULLDUPLEXCAP |
+ MII_1000BASETCONTROL_HALFDUPLEXCAP);
+ if (speed == SPEED_1000)
+ ctl2 |= (fd == DUPLEX_FULL) ?
+ MII_1000BASETCONTROL_FULLDUPLEXCAP :
+ MII_1000BASETCONTROL_HALFDUPLEXCAP;
+ phy_write(phy, MII_1000BASETCONTROL, ctl2);
+
+ // XXX Should we set the sungem to GII now on 1000BT ?
+
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int marvell_read_link(struct mii_phy *phy)
+{
+ u16 status;
+
+ if (phy->autoneg) {
+ status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS);
+ if ((status & MII_M1011_PHY_SPEC_STATUS_RESOLVED) == 0)
+ return -EAGAIN;
+ if (status & MII_M1011_PHY_SPEC_STATUS_1000)
+ phy->speed = SPEED_1000;
+ else if (status & MII_M1011_PHY_SPEC_STATUS_100)
+ phy->speed = SPEED_100;
+ else
+ phy->speed = SPEED_10;
+ if (status & MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX)
+ phy->duplex = DUPLEX_FULL;
+ else
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = 0; /* XXX Check against spec ! */
+ }
+ /* On non-aneg, we assume what we put in BMCR is the speed,
+ * though magic-aneg shouldn't prevent this case from occurring
+ */
+
+ return 0;
+}
+
+static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
+{
+ u16 ctl, adv;
+
+ phy->autoneg = 1;
+ phy->speed = SPEED_10;
+ phy->duplex = DUPLEX_HALF;
+ phy->pause = 0;
+ phy->advertising = advertise;
+
+ /* Setup standard advertise */
+ adv = phy_read(phy, MII_ADVERTISE);
+ adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4);
+ if (advertise & ADVERTISED_10baseT_Half)
+ adv |= ADVERTISE_10HALF;
+ if (advertise & ADVERTISED_10baseT_Full)
+ adv |= ADVERTISE_10FULL;
+ if (advertise & ADVERTISED_100baseT_Half)
+ adv |= ADVERTISE_100HALF;
+ if (advertise & ADVERTISED_100baseT_Full)
+ adv |= ADVERTISE_100FULL;
+ phy_write(phy, MII_ADVERTISE, adv);
+
+ /* Start/Restart aneg */
+ ctl = phy_read(phy, MII_BMCR);
+ ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int genmii_setup_forced(struct mii_phy *phy, int speed, int fd)
+{
+ u16 ctl;
+
+ phy->autoneg = 0;
+ phy->speed = speed;
+ phy->duplex = fd;
+ phy->pause = 0;
+
+ ctl = phy_read(phy, MII_BMCR);
+ ctl &= ~(BMCR_FULLDPLX|BMCR_SPEED100|BMCR_ANENABLE);
+
+ /* First reset the PHY */
+ phy_write(phy, MII_BMCR, ctl | BMCR_RESET);
+
+ /* Select speed & duplex */
+ switch(speed) {
+ case SPEED_10:
+ break;
+ case SPEED_100:
+ ctl |= BMCR_SPEED100;
+ break;
+ case SPEED_1000:
+ default:
+ return -EINVAL;
+ }
+ if (fd == DUPLEX_FULL)
+ ctl |= BMCR_FULLDPLX;
+ phy_write(phy, MII_BMCR, ctl);
+
+ return 0;
+}
+
+static int genmii_poll_link(struct mii_phy *phy)
+{
+ u16 status;
+
+ (void)phy_read(phy, MII_BMSR);
+ status = phy_read(phy, MII_BMSR);
+ if ((status & BMSR_LSTATUS) == 0)
+ return 0;
+ if (phy->autoneg && !(status & BMSR_ANEGCOMPLETE))
+ return 0;
+ return 1;
+}
+
+static int genmii_read_link(struct mii_phy *phy)
+{
+ u16 lpa;
+
+ if (phy->autoneg) {
+ lpa = phy_read(phy, MII_LPA);
+
+ if (lpa & (LPA_10FULL | LPA_100FULL))
+ phy->duplex = DUPLEX_FULL;
+ else
+ phy->duplex = DUPLEX_HALF;
+ if (lpa & (LPA_100FULL | LPA_100HALF))
+ phy->speed = SPEED_100;
+ else
+ phy->speed = SPEED_10;
+ phy->pause = 0;
+ }
+ /* On non-aneg, we assume what we put in BMCR is the speed,
+ * though magic-aneg shouldn't prevent this case from occurring
+ */
+
+ return 0;
+}
+
+
+#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
+ SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
+ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
+#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
+ SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
+
+/* Broadcom BCM 5201 */
+static struct mii_phy_ops bcm5201_phy_ops = {
+ init: bcm5201_init,
+ suspend: bcm5201_suspend,
+ setup_aneg: genmii_setup_aneg,
+ setup_forced: genmii_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: genmii_read_link,
+};
+
+static struct mii_phy_def bcm5201_phy_def = {
+ phy_id: 0x00406210,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5201",
+ features: MII_BASIC_FEATURES,
+ magic_aneg: 0,
+ ops: &bcm5201_phy_ops
+};
+
+/* Broadcom BCM 5221 */
+static struct mii_phy_ops bcm5221_phy_ops = {
+ suspend: bcm5201_suspend,
+ setup_aneg: genmii_setup_aneg,
+ setup_forced: genmii_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: genmii_read_link,
+};
+
+static struct mii_phy_def bcm5221_phy_def = {
+ phy_id: 0x004061e0,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5221",
+ features: MII_BASIC_FEATURES,
+ magic_aneg: 0,
+ ops: &bcm5221_phy_ops
+};
+
+/* Broadcom BCM 5400 */
+static struct mii_phy_ops bcm5400_phy_ops = {
+ init: bcm5400_init,
+ suspend: bcm5400_suspend,
+ setup_aneg: bcm54xx_setup_aneg,
+ setup_forced: bcm54xx_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5400_phy_def = {
+ phy_id: 0x00206040,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5400",
+ features: MII_GBIT_FEATURES,
+ magic_aneg: 1,
+ ops: &bcm5400_phy_ops
+};
+
+/* Broadcom BCM 5401 */
+static struct mii_phy_ops bcm5401_phy_ops = {
+ init: bcm5401_init,
+ suspend: bcm5401_suspend,
+ setup_aneg: bcm54xx_setup_aneg,
+ setup_forced: bcm54xx_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5401_phy_def = {
+ phy_id: 0x00206050,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5401",
+ features: MII_GBIT_FEATURES,
+ magic_aneg: 1,
+ ops: &bcm5401_phy_ops
+};
+
+/* Broadcom BCM 5411 */
+static struct mii_phy_ops bcm5411_phy_ops = {
+ init: bcm5411_init,
+ suspend: bcm5411_suspend,
+ setup_aneg: bcm54xx_setup_aneg,
+ setup_forced: bcm54xx_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5411_phy_def = {
+ phy_id: 0x00206070,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5411",
+ features: MII_GBIT_FEATURES,
+ magic_aneg: 1,
+ ops: &bcm5411_phy_ops
+};
+
+/* Broadcom BCM 5421 */
+static struct mii_phy_ops bcm5421_phy_ops = {
+ suspend: bcm5411_suspend,
+ setup_aneg: bcm54xx_setup_aneg,
+ setup_forced: bcm54xx_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: bcm54xx_read_link,
+};
+
+static struct mii_phy_def bcm5421_phy_def = {
+ phy_id: 0x002060e0,
+ phy_id_mask: 0xfffffff0,
+ name: "BCM5421",
+ features: MII_GBIT_FEATURES,
+ magic_aneg: 1,
+ ops: &bcm5421_phy_ops
+};
+
+/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
+ * I masked out the 8 last bits to get both, but some specs
+ * would be useful here) --BenH.
+ */
+static struct mii_phy_ops marvell_phy_ops = {
+ setup_aneg: marvell_setup_aneg,
+ setup_forced: marvell_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: marvell_read_link
+};
+
+static struct mii_phy_def marvell_phy_def = {
+ phy_id: 0x01410c00,
+ phy_id_mask: 0xffffff00,
+ name: "Marvell 88E1101",
+ features: MII_GBIT_FEATURES,
+ magic_aneg: 1,
+ ops: &marvell_phy_ops
+};
+
+/* Generic implementation for most 10/100 PHYs */
+static struct mii_phy_ops generic_phy_ops = {
+ setup_aneg: genmii_setup_aneg,
+ setup_forced: genmii_setup_forced,
+ poll_link: genmii_poll_link,
+ read_link: genmii_read_link
+};
+
+static struct mii_phy_def genmii_phy_def = {
+ phy_id: 0x00000000,
+ phy_id_mask: 0x00000000,
+ name: "Generic MII",
+ features: MII_BASIC_FEATURES,
+ magic_aneg: 0,
+ ops: &generic_phy_ops
+};
+
+static struct mii_phy_def* mii_phy_table[] = {
+ &bcm5201_phy_def,
+ &bcm5221_phy_def,
+ &bcm5400_phy_def,
+ &bcm5401_phy_def,
+ &bcm5411_phy_def,
+ &bcm5421_phy_def,
+ &marvell_phy_def,
+ &genmii_phy_def,
+ NULL
+};
+
+int mii_phy_probe(struct mii_phy *phy, int mii_id)
+{
+ int rc;
+ u32 id;
+ struct mii_phy_def* def;
+ int i;
+
+ phy->autoneg = 0;
+ phy->advertising = 0;
+ phy->mii_id = mii_id;
+ phy->speed = 0;
+ phy->duplex = 0;
+ phy->pause = 0;
+
+ /* Take PHY out of isloate mode and reset it. */
+ rc = reset_one_mii_phy(phy, mii_id);
+ if (rc)
+ return -ENODEV;
+
+ /* Read ID and find matching entry */
+ id = (phy_read(phy, MII_PHYSID1) << 16 | phy_read(phy, MII_PHYSID2))
+ & 0xfffffff0;
+ for (i=0; (def = mii_phy_table[i]) != NULL; i++)
+ if ((id & def->phy_id_mask) == def->phy_id)
+ break;
+ /* Should never be NULL (we have a generic entry), but... */
+ if (def == NULL)
+ return -ENODEV;
+
+ phy->def = def;
+
+ /* Setup default advertising */
+ phy->advertising = def->features;
+
+ return 0;
+}
+
+EXPORT_SYMBOL(mii_phy_probe);
+MODULE_LICENSE("GPL");
+
diff -uNr linux-2.4.20/drivers/net/sungem_phy.h linux-2.4.20-ben5/drivers/net/sungem_phy.h
--- linux-2.4.20/drivers/net/sungem_phy.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/sungem_phy.h 2003-01-30 11:53:34.000000000 +0100
@@ -0,0 +1,108 @@
+#ifndef __SUNGEM_PHY_H__
+#define __SUNGEM_PHY_H__
+
+struct mii_phy;
+
+/* Operations supported by any kind of PHY */
+struct mii_phy_ops
+{
+ int (*init)(struct mii_phy *phy);
+ int (*suspend)(struct mii_phy *phy, int wol_options);
+ int (*setup_aneg)(struct mii_phy *phy, u32 advertise);
+ int (*setup_forced)(struct mii_phy *phy, int speed, int fd);
+ int (*poll_link)(struct mii_phy *phy);
+ int (*read_link)(struct mii_phy *phy);
+};
+
+/* Structure used to statically define an mii/gii based PHY */
+struct mii_phy_def
+{
+ u32 phy_id; /* Concatenated ID1 << 16 | ID2 */
+ u32 phy_id_mask; /* Significant bits */
+ u32 features; /* Ethtool SUPPORTED_* defines */
+ int magic_aneg; /* Autoneg does all speed test for us */
+ const char* name;
+ const struct mii_phy_ops* ops;
+};
+
+/* An instance of a PHY, partially borrowed from mii_if_info */
+struct mii_phy
+{
+ struct mii_phy_def* def;
+ int advertising;
+ int mii_id;
+
+ /* 1: autoneg enabled, 0: disabled */
+ int autoneg;
+
+ /* forced speed & duplex (no autoneg)
+ * partner speed & duplex & pause (autoneg)
+ */
+ int speed;
+ int duplex;
+ int pause;
+
+ /* Provided by host chip */
+ struct net_device* dev;
+ int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
+ void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
+};
+
+/* Pass in a struct mii_phy with dev, mdio_read and mdio_write
+ * filled, the remaining fields will be filled on return
+ */
+extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
+
+
+/* MII definitions missing from mii.h */
+
+#define BMCR_SPD2 0x0040 /* Gigabit enable (bcm54xx) */
+#define LPA_PAUSE 0x0400
+
+/* More PHY registers (model specific) */
+
+/* MII BCM5201 MULTIPHY interrupt register */
+#define MII_BCM5201_INTERRUPT 0x1A
+#define MII_BCM5201_INTERRUPT_INTENABLE 0x4000
+
+#define MII_BCM5201_AUXMODE2 0x1B
+#define MII_BCM5201_AUXMODE2_LOWPOWER 0x0008
+
+#define MII_BCM5201_MULTIPHY 0x1E
+
+/* MII BCM5201 MULTIPHY register bits */
+#define MII_BCM5201_MULTIPHY_SERIALMODE 0x0002
+#define MII_BCM5201_MULTIPHY_SUPERISOLATE 0x0008
+
+/* MII BCM5400 1000-BASET Control register */
+#define MII_BCM5400_GB_CONTROL 0x09
+#define MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP 0x0200
+
+/* MII BCM5400 AUXCONTROL register */
+#define MII_BCM5400_AUXCONTROL 0x18
+#define MII_BCM5400_AUXCONTROL_PWR10BASET 0x0004
+
+/* MII BCM5400 AUXSTATUS register */
+#define MII_BCM5400_AUXSTATUS 0x19
+#define MII_BCM5400_AUXSTATUS_LINKMODE_MASK 0x0700
+#define MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT 8
+
+/* 1000BT control (Marvell & BCM54xx at least) */
+#define MII_1000BASETCONTROL 0x09
+#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
+#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
+
+/* Marvell 88E1011 PHY control */
+#define MII_M1011_PHY_SPEC_CONTROL 0x10
+#define MII_M1011_PHY_SPEC_CONTROL_MANUAL_MDIX 0x20
+#define MII_M1011_PHY_SPEC_CONTROL_AUTO_MDIX 0x40
+
+/* Marvell 88E1011 PHY status */
+#define MII_M1011_PHY_SPEC_STATUS 0x11
+#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
+#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
+#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
+#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
+#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
+
+#endif /* __SUNGEM_PHY_H__ */
diff -uNr linux-2.4.20/drivers/net/tg3.c linux-2.4.20-ben5/drivers/net/tg3.c
--- linux-2.4.20/drivers/net/tg3.c 2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/tg3.c 2003-01-30 11:52:35.000000000 +0100
@@ -163,6 +163,8 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ PCI_VENDOR_ID_ALTIMA, PCI_DEVICE_ID_ALTIMA_AC9100,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+ { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_TIGON3,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
{ 0, }
};
diff -uNr linux-2.4.20/drivers/net/tulip/tulip_core.c linux-2.4.20-ben5/drivers/net/tulip/tulip_core.c
--- linux-2.4.20/drivers/net/tulip/tulip_core.c 2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20-ben5/drivers/net/tulip/tulip_core.c 2003-01-30 11:52:55.000000000 +0100
@@ -472,6 +472,17 @@
} else
tulip_select_media(dev, 1);
+ /* check for Apple 100BaseTX card and disable loops */
+ if ((dev->dev_addr[0] == 0x00) &&
+ (dev->dev_addr[1] == 0x05) &&
+ (dev->dev_addr[2] == 0x02) &&
+ (tp->chip_id == DC21140)) {
+ outl(0x10f, ioaddr + CSR12);
+ iobarrier_rw();
+ outl(0x03, ioaddr + CSR12);
+ iobarrier_rw();
+ }
+
/* Start the chip's Tx to process setup frame. */
tulip_stop_rxtx(tp);
barrier();
diff -uNr linux-2.4.20/drivers/net/wireless/orinoco.c linux-2.4.20-ben5/drivers/net/wireless/orinoco.c
--- linux-2.4.20/drivers/net/wireless/orinoco.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/net/wireless/orinoco.c 2003-01-30 11:55:52.000000000 +0100
@@ -1978,7 +1978,13 @@
/* 802.2 header */
memcpy(&hdr.dsap, &encaps_hdr, sizeof(encaps_hdr));
-
+
+#if 0
+ /* AppleTalk hack (untested) */
+ if (ntohs(eh->h_proto) == 0x8137 || ntohs(eh->h_proto) == 0x80f3)
+ hdr.oui[2] = 0xf8;
+#endif
+
hdr.ethertype = eh->h_proto;
err = hermes_bap_pwrite(hw, USER_BAP, &hdr, sizeof(hdr),
txfid, HERMES_802_3_OFFSET);
diff -uNr linux-2.4.20/drivers/pci/pci.c linux-2.4.20-ben5/drivers/pci/pci.c
--- linux-2.4.20/drivers/pci/pci.c 2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20-ben5/drivers/pci/pci.c 2003-01-30 11:54:27.000000000 +0100
@@ -28,7 +28,7 @@
#include
#include /* isa_dma_bridge_buggy */
-#undef DEBUG
+#define DEBUG
#ifdef DEBUG
#define DBG(x...) printk(x)
@@ -1051,16 +1051,23 @@
unsigned int pos, reg, next;
u32 l, sz;
struct resource *res;
+ int is_kl = (dev->device == 0x22 && dev->vendor == 0x106b);
+ if (is_kl)
+ howmany = 1;
for(pos=0; posresource[pos];
res->name = dev->name;
reg = PCI_BASE_ADDRESS_0 + (pos << 2);
pci_read_config_dword(dev, reg, &l);
- pci_write_config_dword(dev, reg, ~0);
- pci_read_config_dword(dev, reg, &sz);
- pci_write_config_dword(dev, reg, l);
+ if (is_kl)
+ sz = 0x00080000;
+ else {
+ pci_write_config_dword(dev, reg, ~0);
+ pci_read_config_dword(dev, reg, &sz);
+ pci_write_config_dword(dev, reg, l);
+ }
if (!sz || sz == 0xffffffff)
continue;
if (l == 0xffffffff)
@@ -1295,7 +1302,7 @@
if (!pass)
return max;
pci_read_config_word(dev, PCI_COMMAND, &cr);
- pci_write_config_word(dev, PCI_COMMAND, 0x0000);
+ //pci_write_config_word(dev, PCI_COMMAND, 0x0000);
pci_write_config_word(dev, PCI_STATUS, 0xffff);
child = pci_add_new_bus(bus, dev, ++max);
diff -uNr linux-2.4.20/drivers/scsi/hosts.c linux-2.4.20-ben5/drivers/scsi/hosts.c
--- linux-2.4.20/drivers/scsi/hosts.c 2002-11-29 00:53:14.000000000 +0100
+++ linux-2.4.20-ben5/drivers/scsi/hosts.c 2003-01-30 11:55:33.000000000 +0100
@@ -81,8 +81,8 @@
struct Scsi_Host * scsi_hostlist;
struct Scsi_Device_Template * scsi_devicelist;
-int max_scsi_hosts;
-int next_scsi_host;
+int max_scsi_hosts; /* host_no for next new host */
+int next_scsi_host; /* count of registered scsi hosts */
void
scsi_unregister(struct Scsi_Host * sh){
@@ -107,21 +107,8 @@
if (shn) shn->host_registered = 0;
/* else {} : This should not happen, we should panic here... */
- /* If we are removing the last host registered, it is safe to reuse
- * its host number (this avoids "holes" at boot time) (DB)
- * It is also safe to reuse those of numbers directly below which have
- * been released earlier (to avoid some holes in numbering).
- */
- if(sh->host_no == max_scsi_hosts - 1) {
- while(--max_scsi_hosts >= next_scsi_host) {
- shpnt = scsi_hostlist;
- while(shpnt && shpnt->host_no != max_scsi_hosts - 1)
- shpnt = shpnt->next;
- if(shpnt)
- break;
- }
- }
next_scsi_host--;
+
kfree((char *) sh);
}
diff -uNr linux-2.4.20/drivers/scsi/sd.c linux-2.4.20-ben5/drivers/scsi/sd.c
--- linux-2.4.20/drivers/scsi/sd.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/scsi/sd.c 2003-01-30 11:54:31.000000000 +0100
@@ -668,7 +668,7 @@
* hard error.
*/
print_sense("sd", SCpnt);
- result = 0;
+ SCpnt->result = 0;
SCpnt->sense_buffer[0] = 0x0;
good_sectors = this_count;
break;
@@ -1448,7 +1448,7 @@
}
for (i = 0; i < N_USED_SD_MAJORS; i++) {
del_gendisk(&sd_gendisks[i]);
- blk_size[SD_MAJOR(i)] = NULL; /* XXX blksize_size actually? */
+ blksize_size[SD_MAJOR(i)] = NULL;
hardsect_size[SD_MAJOR(i)] = NULL;
read_ahead[SD_MAJOR(i)] = 0;
}
diff -uNr linux-2.4.20/drivers/sound/dmasound/Config.in linux-2.4.20-ben5/drivers/sound/dmasound/Config.in
--- linux-2.4.20/drivers/sound/dmasound/Config.in 2002-02-25 20:38:04.000000000 +0100
+++ linux-2.4.20-ben5/drivers/sound/dmasound/Config.in 2003-01-30 11:53:24.000000000 +0100
@@ -27,13 +27,27 @@
fi
# the new dmasound_pmac driver needs access to the i2c bus
+# and nvram.
if [ "$CONFIG_DMASOUND_PMAC" = "y" ] ; then
- define_tristate CONFIG_I2C y
- define_tristate CONFIG_I2C_KEYWEST y
+ if [ "$CONFIG_I2C" != "y" ]; then
+ define_tristate CONFIG_I2C y
+ fi
+ if [ "$CONFIG_I2C_KEYWEST" != "y" ]; then
+ define_tristate CONFIG_I2C_KEYWEST y
+ fi
+ if [ "$CONFIG_NVRAM" != "y" -a "$CONFIG_NVRAM" != "m" ]; then
+ define_tristate CONFIG_NVRAM y
+ fi
else
if [ "$CONFIG_DMASOUND_PMAC" = "m" ] ; then
- define_tristate CONFIG_I2C m
- define_tristate CONFIG_I2C_KEYWEST m
+ if [ "$CONFIG_I2C" != "y" -a "$CONFIG_I2C" != "m" ]; then
+ define_tristate CONFIG_I2C m
+ fi
+ if [ "$CONFIG_I2C_KEYWEST" != "y" -a "$CONFIG_I2C_KEYWEST" != "m" ]; then
+ define_tristate CONFIG_I2C_KEYWEST m
+ fi
+ if [ "$CONFIG_NVRAM" != "y" -a "$CONFIG_NVRAM" != "m" ]; then
+ define_tristate CONFIG_NVRAM y
+ fi
fi
fi
-
diff -uNr linux-2.4.20/drivers/sound/dmasound/Makefile linux-2.4.20-ben5/drivers/sound/dmasound/Makefile
--- linux-2.4.20/drivers/sound/dmasound/Makefile 2002-02-25 20:38:04.000000000 +0100
+++ linux-2.4.20-ben5/drivers/sound/dmasound/Makefile 2003-01-30 11:54:58.000000000 +0100
@@ -13,7 +13,8 @@
list-multi := dmasound_pmac.o
-dmasound_pmac-objs := dmasound_awacs.o trans_16.o tas3001c.o dac3550a.o
+dmasound_pmac-objs := dmasound_awacs.o trans_16.o dac3550a.o tas_common.o \
+ tas3001c.o tas3001c_tables.o tas3004.o tas3004_tables.o
obj-$(CONFIG_DMASOUND) += dmasound_core.o
obj-$(CONFIG_DMASOUND_ATARI) += dmasound_atari.o
diff -uNr linux-2.4.20/drivers/sound/dmasound/awacs_defs.h linux-2.4.20-ben5/drivers/sound/dmasound/awacs_defs.h
--- linux-2.4.20/drivers/sound/dmasound/awacs_defs.h 2002-02-25 20:38:04.000000000 +0100
+++ linux-2.4.20-ben5/drivers/sound/dmasound/awacs_defs.h 2003-01-30 11:55:57.000000000 +0100
@@ -168,8 +168,9 @@
#define RATE_LOW 1 /* HIGH = 48kHz, etc; LOW = 44.1kHz, etc. */
-
+/*******************/
/* Burgundy values */
+/*******************/
#define MASK_ADDR_BURGUNDY_INPSEL21 (0x11 << 12)
#define MASK_ADDR_BURGUNDY_INPSEL3 (0x12 << 12)
@@ -232,4 +233,19 @@
#define DEF_BURGUNDY_ATTENLINEOUT (0xCC)
#define DEF_BURGUNDY_ATTENHP (0xCC)
+/*********************/
+/* i2s layout values */
+/*********************/
+
+#define I2S_REG_INT_CTL 0x00
+#define I2S_REG_SERIAL_FORMAT 0x10
+#define I2S_REG_CODEC_MSG_OUT 0x20
+#define I2S_REG_CODEC_MSG_IN 0x30
+#define I2S_REG_FRAME_COUNT 0x40
+#define I2S_REG_FRAME_MATCH 0x50
+#define I2S_REG_DATAWORD_SIZES 0x60
+#define I2S_REG_PEAKLEVEL_SEL 0x70
+#define I2S_REG_PEAKLEVEL_IN0 0x80
+#define I2S_REG_PEAKLEVEL_IN1 0x90
+
#endif /* _AWACS_DEFS_H_ */
diff -uNr linux-2.4.20/drivers/sound/dmasound/dmasound_awacs.c linux-2.4.20-ben5/drivers/sound/dmasound/dmasound_awacs.c
--- linux-2.4.20/drivers/sound/dmasound/dmasound_awacs.c 2002-08-03 02:39:44.000000000 +0200
+++ linux-2.4.20-ben5/drivers/sound/dmasound/dmasound_awacs.c 2003-01-30 11:56:01.000000000 +0100
@@ -45,7 +45,14 @@
* 01/02/2002 [0.7] - BenH
* - all sort of minor bits went in since the latest update, I
* bumped the version number for that reason
-*/
+ *
+ * 07/26/2002 [0.8] - BenH
+ * - More minor bits since last changelog (I should be more careful
+ * with those)
+ * - Support for snapper & better tumbler integration by Toby Sargeant
+ * - Headphone detect for scremer by Julien Blache
+ * - More tumbler fixed by Andreas Schwab
+ */
/* GENERAL FIXME/TODO: check that the assumptions about what is written to
mac-io is valid for DACA & Tumbler.
@@ -88,10 +95,14 @@
#include "awacs_defs.h"
#include "dmasound.h"
+#include "tas3001c.h"
+#include "tas3004.h"
+#include "tas_common.h"
#define DMASOUND_AWACS_REVISION 0
#define DMASOUND_AWACS_EDITION 7
+#define AWACS_SNAPPER 110 /* fake revision # for snapper */
#define AWACS_BURGUNDY 100 /* fake revision # for burgundy */
#define AWACS_TUMBLER 90 /* fake revision # for tumbler */
#define AWACS_DACA 80 /* fake revision # for daca (ibook) */
@@ -102,11 +113,13 @@
*/
static int awacs_irq, awacs_tx_irq, awacs_rx_irq;
static volatile struct awacs_regs *awacs;
+static volatile u32 *i2s;
static volatile struct dbdma_regs *awacs_txdma, *awacs_rxdma;
static int awacs_rate_index;
static int awacs_subframe;
static int awacs_spkr_vol;
static struct device_node* awacs_node;
+static struct device_node* i2s_node;
static char awacs_name[64];
static int awacs_revision;
@@ -163,6 +176,8 @@
static int cd_lev = 0x6363 ; /* 99 % */
static int line_lev = 0 ;
+static int hdp_connected = 0;
+
/*
* Stuff for outputting a beep. The values range from -327 to +327
* so we can multiply by an amplitude in the range 0..100 to get a
@@ -293,19 +308,6 @@
extern int daca_enter_sleep(void);
extern int daca_leave_sleep(void);
-extern int tas_init(void);
-extern int tas_cleanup(void);
-extern int tumbler_set_volume(uint left_vol, uint right_vol);
-extern void tumbler_get_volume(uint * left_vol, uint *right_vol);
-extern void tumbler_set_treble(int treble);
-extern void tumbler_get_treble(int *treble);
-extern void tumbler_set_bass(int bass);
-extern void tumbler_get_bass(int *bass);
-extern void tumbler_set_pcm_lvl(int pcm_lvl);
-extern void tumbler_get_pcm_lvl(int *pcm_lvl);
-extern int tumbler_enter_sleep(void);
-extern int tumbler_leave_sleep(void);
-
#define TRY_LOCK() \
if ((rc = down_interruptible(&dmasound_sem)) != 0) \
return rc;
@@ -332,7 +334,7 @@
}
-/*** AE - TUMBLER START *********************************************************/
+/*** AE - TUMBLER / SNAPPER START ************************************************/
int gpio_audio_reset, gpio_audio_reset_pol;
@@ -394,17 +396,22 @@
return ((pmac_call_feature(PMAC_FTR_READ_GPIO, NULL, gpio_addr, 0) & 0x02) !=0);
}
+/*
+ * Headphone interrupt via GPIO (Tumbler, Snapper, DACA)
+ */
static void
headphone_intr(int irq, void *devid, struct pt_regs *regs)
{
if (read_audio_gpio(gpio_headphone_detect) == gpio_headphone_detect_pol) {
printk(KERN_INFO "Audio jack plugged, muting speakers.\n");
- write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
write_audio_gpio(gpio_headphone_mute, !gpio_headphone_mute_pol);
+ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
+ tas_output_device_change(sound_device_id,TAS_OUTPUT_HEADPHONES,0);
} else {
printk(KERN_INFO "Audio jack unplugged, enabling speakers.\n");
write_audio_gpio(gpio_amp_mute, !gpio_amp_mute_pol);
write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
+ tas_output_device_change(sound_device_id,TAS_OUTPUT_INTERNAL_SPKR,0);
}
}
@@ -412,7 +419,7 @@
/* Initialize tumbler */
static int
-awacs_tumbler_init(void)
+tas_dmasound_init(void)
{
setup_audio_gpio(
"audio-hw-reset",
@@ -469,15 +476,124 @@
static int
-awacs_tumbler_cleanup(void)
+tas_dmasound_cleanup(void)
{
if (gpio_headphone_irq)
free_irq(gpio_headphone_irq, 0);
return 0;
}
+/* We don't support 48k yet */
+static int tas_freqs[1] = { 44100 } ;
+static int tas_freqs_ok[1] = { 1 } ;
-/*** AE - TUMBLER END *********************************************************/
+/* don't know what to do really - just have to leave it where
+ * OF left things
+*/
+
+static int
+tas_set_frame_rate(void)
+{
+ if (i2s) {
+ out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
+ out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
+ }
+ dmasound.hard.speed = 44100 ;
+ awacs_rate_index = 0 ;
+ return 44100 ;
+}
+
+static int
+tas_mixer_ioctl(u_int cmd, u_long arg)
+{
+ int data;
+ int rc;
+
+ rc=tas_device_ioctl(cmd, arg);
+ if (rc != -EINVAL) {
+ return rc;
+ }
+
+ if ((cmd & ~0xff) == MIXER_WRITE(0) &&
+ tas_supported_mixers() & (1<<(cmd & 0xff))) {
+ rc = get_user(data, (int *)(arg));
+ if (rc<0) return rc;
+ tas_set_mixer_level(cmd & 0xff, data);
+ tas_get_mixer_level(cmd & 0xff, &data);
+ return ioctl_return2((int *)(arg), data);
+ }
+ if ((cmd & ~0xff) == MIXER_READ(0) &&
+ tas_supported_mixers() & (1<<(cmd & 0xff))) {
+ tas_get_mixer_level(cmd & 0xff, &data);
+ return ioctl_return2((int *)(arg), data);
+ }
+
+ switch(cmd) {
+ case SOUND_MIXER_READ_DEVMASK:
+ data = tas_supported_mixers() | SOUND_MASK_SPEAKER;
+ rc = IOCTL_OUT(arg, data);
+ break;
+ case SOUND_MIXER_READ_STEREODEVS:
+ data = tas_stereo_mixers();
+ rc = IOCTL_OUT(arg, data);
+ break;
+ case SOUND_MIXER_READ_CAPS:
+ rc = IOCTL_OUT(arg, 0);
+ break;
+ case SOUND_MIXER_READ_RECMASK:
+ data = 0;
+ rc = IOCTL_OUT(arg, data);
+ break;
+ case SOUND_MIXER_READ_RECSRC:
+ data = 0;
+ rc = IOCTL_OUT(arg, data);
+ break;
+ case SOUND_MIXER_WRITE_RECSRC:
+ IOCTL_IN(arg, data);
+ data =0;
+ rc = IOCTL_OUT(arg, data);
+ break;
+ case SOUND_MIXER_WRITE_SPEAKER: /* really bell volume */
+ IOCTL_IN(arg, data);
+ beep_vol = data & 0xff;
+ /* fall through */
+ case SOUND_MIXER_READ_SPEAKER:
+ rc = IOCTL_OUT(arg, (beep_vol<<8) | beep_vol);
+ break;
+ case SOUND_MIXER_OUTMASK:
+ case SOUND_MIXER_OUTSRC:
+ default:
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static void __init
+tas_init_frame_rates(unsigned int *prop, unsigned int l)
+{
+ int i ;
+ if (prop) {
+ for (i=0; i<1; i++)
+ tas_freqs_ok[i] = 0;
+ for (l /= sizeof(int); l > 0; --l) {
+ unsigned int r = *prop++;
+ /* Apple 'Fixed' format */
+ if (r >= 0x10000)
+ r >>= 16;
+ for (i = 0; i < 1; ++i) {
+ if (r == tas_freqs[i]) {
+ tas_freqs_ok[i] = 1;
+ break;
+ }
+ }
+ }
+ }
+ /* else we assume that all the rates are available */
+}
+
+
+/*** AE - TUMBLER / SNAPPER END ************************************************/
@@ -509,8 +625,10 @@
static int __init PMacIrqInit(void)
{
- if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0)
- || request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
+ if (awacs)
+ if (request_irq(awacs_irq, pmac_awacs_intr, 0, "Built-in Sound misc", 0))
+ return 0;
+ if (request_irq(awacs_tx_irq, pmac_awacs_tx_intr, 0, "Built-in Sound out", 0)
|| request_irq(awacs_rx_irq, pmac_awacs_rx_intr, 0, "Built-in Sound in", 0))
return 0;
return 1;
@@ -523,23 +641,28 @@
DBDMA_DO_STOP(awacs_txdma);
DBDMA_DO_STOP(awacs_rxdma);
- /* disable interrupts from awacs interface */
- out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
-
+ if (awacs)
+ /* disable interrupts from awacs interface */
+ out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
+
/* Switch off the sound clock */
pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
/* Make sure proper bits are set on pismo & tipb */
- if (machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) {
+ if ((machine_is_compatible("PowerBook3,1") ||
+ machine_is_compatible("PowerBook3,2")) && awacs) {
awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
awacs_write(MASK_ADDR1 | awacs_reg[1]);
wait_ms(200);
}
- free_irq(awacs_irq, 0);
+ if (awacs)
+ free_irq(awacs_irq, 0);
free_irq(awacs_tx_irq, 0);
free_irq(awacs_rx_irq, 0);
- /* all OF versions I've seen use this value */
- iounmap((void *)awacs);
+
+ if (awacs)
+ iounmap((void *)awacs);
+ if (i2s)
+ iounmap((void *)i2s);
iounmap((void *)awacs_txdma);
iounmap((void *)awacs_rxdma);
@@ -555,7 +678,9 @@
kfree(beep_dbdma_cmd_space);
if (beep_buf) {
kfree(beep_buf);
+#ifdef CONFIG_VT
kd_mksound = orig_mksound;
+#endif
}
#ifdef CONFIG_PMAC_PBOOK
pmu_unregister_sleep_notifier(&awacs_sleep_notifier);
@@ -569,26 +694,16 @@
DBDMA_DO_STOP(awacs_txdma);
}
-static int tumbler_freqs[2] = { 48000, 44100 } ;
-static int tumbler_freqs_ok[2] = { 1, 1 } ;
-
-/* don't know what to do really - just have to leave it where
- * OF left things
-*/
-
-static int tumbler_set_frame_rate(void)
-{
- dmasound.hard.speed = 44100 ;
- awacs_rate_index = 0 ;
- return 44100 ;
-}
-
/* don't know what to do really - just have to leave it where
* OF left things
*/
static int daca_set_frame_rate(void)
{
+ if (i2s) {
+ out_le32(i2s + (I2S_REG_SERIAL_FORMAT >> 2), 0x41190000);
+ out_le32(i2s + (I2S_REG_DATAWORD_SIZES >> 2), 0x02000200);
+ }
dmasound.hard.speed = 44100 ;
awacs_rate_index = 0 ;
return 44100 ;
@@ -599,7 +714,8 @@
};
static int awacs_freqs_ok[8] = { 1, 1, 1, 1, 1, 1, 1, 1 };
-static int awacs_set_frame_rate(int desired, int catch_r)
+static int
+awacs_set_frame_rate(int desired, int catch_r)
{
int tolerance, i = 8 ;
/*
@@ -623,13 +739,9 @@
return dmasound.hard.speed;
}
-static int burgundy_frame_rates = 1 ;
-static int burgundy_set_frame_rate(void)
+static int
+burgundy_set_frame_rate(void)
{
-#ifdef DEBUG_DMASOUND
-if (burgundy_frame_rates > 1)
- printk("dmasound_pmac: warning Burgundy had more than one frame rate\n");
-#endif
awacs_rate_index = 0 ;
awacs_reg[1] = (awacs_reg[1] & ~MASK_SAMPLERATE) ;
/* XXX disable error interrupt on burgundy for now */
@@ -637,24 +749,24 @@
return 44100 ;
}
-static int set_frame_rate(int desired, int catch_r)
+static int
+set_frame_rate(int desired, int catch_r)
{
switch (awacs_revision) {
case AWACS_BURGUNDY:
- dmasound.hard.speed =
- burgundy_set_frame_rate();
+ dmasound.hard.speed = burgundy_set_frame_rate();
break ;
case AWACS_TUMBLER:
- dmasound.hard.speed =
- tumbler_set_frame_rate();
+ case AWACS_SNAPPER:
+ dmasound.hard.speed = tas_set_frame_rate();
break ;
case AWACS_DACA:
dmasound.hard.speed =
daca_set_frame_rate();
break ;
default:
- dmasound.hard.speed =
- awacs_set_frame_rate(desired, catch_r);
+ dmasound.hard.speed = awacs_set_frame_rate(desired,
+ catch_r);
break ;
}
return dmasound.hard.speed ;
@@ -704,11 +816,13 @@
dmasound.trans_write = &transAwacsExpand;
dmasound.trans_read = &transAwacsNormalRead;
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
-
+ if (awacs) {
+ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+ out_le32(&awacs->byteswap, BS_VAL);
+ else
+ out_le32(&awacs->byteswap, 0);
+ }
+
expand_bal = -dmasound.soft.speed;
}
@@ -793,7 +907,20 @@
static int PMacSetVolume(int volume)
{
- return awacs_volume_setter(volume, 2, MASK_AMUTE, 6);
+ printk(KERN_WARNING "Bogus call to PMacSetVolume !\n");
+ return 0;
+}
+
+static void awacs_setup_for_beep(int speed)
+{
+ out_le32(&awacs->control,
+ (in_le32(&awacs->control) & ~0x1f00)
+ | ((speed > 0 ? speed : awacs_rate_index) << 8));
+
+ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE) && speed == -1)
+ out_le32(&awacs->byteswap, BS_VAL);
+ else
+ out_le32(&awacs->byteswap, 0);
}
static void __PMacPlay(void)
@@ -816,15 +943,8 @@
out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
while ( (in_le32(&awacs_txdma->status) & RUN) && count--)
udelay(1);
- /* FIXME: check that this is OK for other chip sets */
- out_le32(&awacs->control,
- (in_le32(&awacs->control) & ~0x1f00)
- | (awacs_rate_index << 8));
-
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
+ if (awacs)
+ awacs_setup_for_beep(-1);
out_le32(&awacs_txdma->cmdptr,
virt_to_bus(&(awacs_tx_cmds[next_frg])));
@@ -925,6 +1045,7 @@
{
int i = write_sq.front;
int stat;
+ int i_nowrap = write_sq.front;
volatile struct dbdma_cmd *cp;
/* != 0 when we are dealing with a DEAD xfer */
static int emergency_in_use = 0 ;
@@ -981,6 +1102,7 @@
emergency_in_use = 0 ; /* done that */
--write_sq.count;
--write_sq.active;
+ i_nowrap++;
if (++i >= write_sq.max_count)
i = 0;
}
@@ -993,7 +1115,7 @@
}
/* if we used some data up then wake the writer to supply some more*/
- if (i != write_sq.front)
+ if (i_nowrap != write_sq.front)
WAKE_UP(write_sq.action_queue);
write_sq.front = i;
@@ -1090,9 +1212,26 @@
pmac_awacs_intr(int irq, void *devid, struct pt_regs *regs)
{
int ctrl = in_le32(&awacs->control);
+ int status = in_le32(&awacs->codec_stat);
+ int r1;
- if (ctrl & MASK_PORTCHG) {
- /* do something when headphone is plugged/unplugged? */
+ if (ctrl & MASK_PORTCHG) {
+ /* tested on Screamer, should work on others too */
+ if (awacs_revision == AWACS_SCREAMER) {
+ if (((status & MASK_HDPCONN) >> 3) && (hdp_connected == 0)) {
+ hdp_connected = 1;
+
+ r1 = awacs_reg[1] | MASK_SPKMUTE;
+ awacs_reg[1] = r1;
+ awacs_write(r1 | MASK_ADDR_MUTE);
+ } else if (((status & MASK_HDPCONN) >> 3 == 0) && (hdp_connected == 1)) {
+ hdp_connected = 0;
+
+ r1 = awacs_reg[1] & ~MASK_SPKMUTE;
+ awacs_reg[1] = r1;
+ awacs_write(r1 | MASK_ADDR_MUTE);
+ }
+ }
}
if (ctrl & MASK_CNTLERR) {
int err = (in_le32(&awacs->codec_stat) & MASK_ERRCODE) >> 16;
@@ -1108,7 +1247,7 @@
awacs_write(int val)
{
int count = 300 ;
- if (awacs_revision >= AWACS_DACA)
+ if (awacs_revision >= AWACS_DACA || !awacs)
return ;
while ((in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) && count--)
@@ -1131,14 +1270,8 @@
out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
while ((in_le32(&awacs_txdma->status) & RUN) && count--)
udelay(1);
- /* FIXME: check this is OK for DACA, Tumbler */
- out_le32(&awacs->control,
- (in_le32(&awacs->control) & ~0x1f00)
- | (awacs_rate_index << 8));
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
+ if (awacs)
+ awacs_setup_for_beep(-1);
beep_playing = 0;
}
restore_flags(flags);
@@ -1233,11 +1366,8 @@
out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16);
while ((in_le32(&awacs_txdma->status) & RUN) && count--)
udelay(1); /* timeout > 2 samples at lowest rate*/
- /* FIXME: check this is OK on DACA, Tumbler */
- out_le32(&awacs->control,
- (in_le32(&awacs->control) & ~0x1f00)
- | (beep_speed << 8));
- out_le32(&awacs->byteswap, 0); /* force BE */
+ if (awacs)
+ awacs_setup_for_beep(beep_speed);
out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd));
(void)in_le32(&awacs_txdma->status);
out_le32(&awacs_txdma->control, RUN | (RUN << 16));
@@ -1263,10 +1393,12 @@
awacs_write(awacs_reg[1] + MASK_ADDR1);
awacs_write(awacs_reg[7] + MASK_ADDR7);
}
- if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
- out_le32(&awacs->byteswap, BS_VAL);
- else
- out_le32(&awacs->byteswap, 0);
+ if (awacs) {
+ if (hw_can_byteswap && (dmasound.hard.format == AFMT_S16_LE))
+ out_le32(&awacs->byteswap, BS_VAL);
+ else
+ out_le32(&awacs->byteswap, 0);
+ }
}
#ifdef CONFIG_PMAC_PBOOK
@@ -1293,9 +1425,18 @@
/* stop rx - if going - a bit of a daft user... but */
out_le32(&awacs_rxdma->control, (RUN|WAKE|FLUSH << 16));
/* deny interrupts */
+ if (awacs)
+ disable_irq(awacs_irq);
+ disable_irq(awacs_tx_irq);
+ disable_irq(awacs_rx_irq);
+ /* Chip specific sleep code */
switch (awacs_revision) {
case AWACS_TUMBLER:
- tumbler_enter_sleep(); /* Stub for now */
+ case AWACS_SNAPPER:
+ write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
+ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
+ tas_enter_sleep();
+ write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
break ;
case AWACS_DACA:
daca_enter_sleep();
@@ -1308,17 +1449,14 @@
out_le32(&awacs->control, 0x11) ;
break ;
}
- disable_irq(awacs_irq);
- disable_irq(awacs_tx_irq);
- disable_irq(awacs_rx_irq);
/* Disable sound clock */
pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 0);
/* According to Darwin, we do that after turning off the sound
* chip clock. All this will have to be cleaned up once we properly
* parse the OF sound-objects
*/
- if (machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) {
+ if ((machine_is_compatible("PowerBook3,1") ||
+ machine_is_compatible("PowerBook3,2")) && awacs) {
awacs_reg[1] |= MASK_PAROUT0 | MASK_PAROUT1;
awacs_write(MASK_ADDR1 | awacs_reg[1]);
wait_ms(200);
@@ -1327,8 +1465,8 @@
case PBOOK_WAKE:
/* Enable sound clock */
pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, awacs_node, 0, 1);
- if (machine_is_compatible("PowerBook3,1") ||
- machine_is_compatible("PowerBook3,2")) {
+ if ((machine_is_compatible("PowerBook3,1") ||
+ machine_is_compatible("PowerBook3,2")) && awacs) {
wait_ms(100);
awacs_reg[1] &= ~(MASK_PAROUT0 | MASK_PAROUT1);
awacs_write(MASK_ADDR1 | awacs_reg[1]);
@@ -1338,8 +1476,15 @@
/* restore settings */
switch (awacs_revision) {
case AWACS_TUMBLER:
+ case AWACS_SNAPPER:
+ write_audio_gpio(gpio_headphone_mute, gpio_headphone_mute_pol);
+ write_audio_gpio(gpio_amp_mute, gpio_amp_mute_pol);
+ write_audio_gpio(gpio_audio_reset, gpio_audio_reset_pol);
+ wait_ms(100);
+ write_audio_gpio(gpio_audio_reset, !gpio_audio_reset_pol);
+ wait_ms(150);
+ tas_leave_sleep(); /* Stub for now */
headphone_intr(0,0,0);
- tumbler_leave_sleep(); /* Stub for now */
break;
case AWACS_DACA:
wait_ms(10); /* Check this !!! */
@@ -1354,17 +1499,20 @@
break ;
}
/* Recalibrate chip */
- if (awacs_revision == AWACS_SCREAMER)
+ if (awacs_revision == AWACS_SCREAMER && awacs)
awacs_recalibrate();
/* Make sure dma is stopped */
PMacSilence();
- enable_irq(awacs_irq);
+ if (awacs)
+ enable_irq(awacs_irq);
enable_irq(awacs_tx_irq);
enable_irq(awacs_rx_irq);
- /* OK, allow ints back again */
- out_le32(&awacs->control, MASK_IEPC
- | (awacs_rate_index << 8) | 0x11
- | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
+ if (awacs) {
+ /* OK, allow ints back again */
+ out_le32(&awacs->control, MASK_IEPC
+ | (awacs_rate_index << 8) | 0x11
+ | (awacs_revision < AWACS_DACA ? MASK_IEE: 0));
+ }
if (macio_base && is_pbook_g3) {
/* FIXME: should restore the setup we had...*/
out_8(macio_base + 0x37, 3);
@@ -1952,7 +2100,7 @@
case SOUND_MIXER_READ_SPEAKER:
data = awacs_burgundy_rcb(MASK_ADDR_BURGUNDY_ATTENSPEAKER);
data = (((data & 0xf)*100)/16) + ((((data>>4)*100)/16)<<8);
- rc = IOCTL_OUT(arg, ~data);
+ rc = IOCTL_OUT(arg, (~data) & 0x0000ffff);
break;
case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
IOCTL_IN(arg, data);
@@ -2007,89 +2155,6 @@
return rc;
}
-static int tumbler_mixer_ioctl(u_int cmd, u_long arg)
-{
- int data;
- int rc;
-
- /* We are, we are, we are... Tumbler (and very dumb) */
- /* Ok, we're not THAT dumb anymore, but still pretty dumb :-) */
-
- switch(cmd) {
- case SOUND_MIXER_READ_DEVMASK:
- data = SOUND_MASK_VOLUME | SOUND_MASK_ALTPCM |
- SOUND_MASK_BASS | SOUND_MASK_TREBLE |
- SOUND_MASK_PCM;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECMASK:
- data = 0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_RECSRC:
- data = 0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_RECSRC:
- IOCTL_IN(arg, data);
- data =0;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_STEREODEVS:
- data = SOUND_MASK_VOLUME | SOUND_MASK_PCM;
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_READ_CAPS:
- rc = IOCTL_OUT(arg, 0);
- break;
- case SOUND_MIXER_WRITE_BASS:
- IOCTL_IN(arg, data);
- tumbler_set_bass(data);
- /* Fall through */
- case SOUND_MIXER_READ_BASS:
- tumbler_get_bass(&data);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_TREBLE:
- IOCTL_IN(arg, data);
- tumbler_set_treble(data);
- /* Fall through */
- case SOUND_MIXER_READ_TREBLE:
- tumbler_get_treble(&data);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_PCM:
- IOCTL_IN(arg, data);
- tumbler_set_pcm_lvl(data);
- /* Fall through */
- case SOUND_MIXER_READ_PCM:
- tumbler_get_pcm_lvl(&data);
- IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_VOLUME:
- IOCTL_IN(arg, data);
- tumbler_set_volume(data, data);
- /* Fall through */
- case SOUND_MIXER_READ_VOLUME:
- tumbler_get_volume(& data, &data);
- rc = IOCTL_OUT(arg, data);
- break;
- case SOUND_MIXER_WRITE_ALTPCM: /* really bell volume */
- IOCTL_IN(arg, data);
- beep_vol = data & 0xff;
- /* fall through */
- case SOUND_MIXER_READ_ALTPCM:
- rc = IOCTL_OUT(arg, beep_vol);
- break;
- case SOUND_MIXER_OUTMASK:
- case SOUND_MIXER_OUTSRC:
- default:
- rc = -EINVAL;
- }
-
- return rc;
-}
-
static int daca_mixer_ioctl(u_int cmd, u_long arg)
{
int data;
@@ -2154,7 +2219,8 @@
rc = daca_mixer_ioctl(cmd, arg);
break;
case AWACS_TUMBLER:
- rc = tumbler_mixer_ioctl(cmd, arg);
+ case AWACS_SNAPPER:
+ rc = tas_mixer_ioctl(cmd, arg);
break ;
default: /* ;-)) */
rc = awacs_mixer_ioctl(cmd, arg);
@@ -2171,7 +2237,9 @@
case AWACS_TUMBLER:
printk("AE-Init tumbler mixer\n");
break ;
-
+ case AWACS_SNAPPER:
+ printk("AE-Init snapper mixer\n");
+ break ;
case AWACS_DACA:
case AWACS_BURGUNDY:
break ; /* don't know yet */
@@ -2362,12 +2430,12 @@
len += sprintf(b,"44100 ") ;
break ;
case AWACS_TUMBLER:
- for (i=0; i<2; i++){
- if (tumbler_freqs_ok[i])
- len += sprintf(b+len,"%d ", tumbler_freqs[i]) ;
+ case AWACS_SNAPPER:
+ for (i=0; i<1; i++){
+ if (tas_freqs_ok[i])
+ len += sprintf(b+len,"%d ", tas_freqs[i]) ;
}
break ;
-
case AWACS_AWACS:
case AWACS_SCREAMER:
default:
@@ -2469,8 +2537,8 @@
code that looks for chip properties knows how to go about it.
*/
-static struct device_node
-__init *get_snd_io_node(void)
+static struct device_node* __init
+get_snd_io_node(void)
{
struct device_node *np = NULL;
@@ -2491,7 +2559,7 @@
* this seems to be what iBooks (& Tumbler) have.
*/
if (np == NULL)
- np = find_devices("i2s-a");
+ np = i2s_node = find_devices("i2s-a");
/* if we didn't find this - perhaps we are on an early model
* which _only_ has an 'awacs' node
@@ -2511,8 +2579,8 @@
we have to deduce the info other ways for these.
*/
-static struct device_node
-__init *get_snd_info_node(struct device_node *io)
+static struct device_node* __init
+get_snd_info_node(struct device_node *io)
{
struct device_node *info;
@@ -2526,8 +2594,8 @@
/* Find out what type of codec we have.
*/
-static int
-__init get_codec_type(struct device_node *info)
+static int __init
+get_codec_type(struct device_node *info)
{
/* already set if pre-davbus model and info will be NULL */
int codec = awacs_revision ;
@@ -2544,14 +2612,16 @@
codec = AWACS_DACA;
if (device_is_compatible(info, "tumbler"))
codec = AWACS_TUMBLER;
+ if (device_is_compatible(info, "snapper"))
+ codec = AWACS_SNAPPER;
}
return codec ;
}
/* find out what type, if any, of expansion card we have
*/
-static void
-__init get_expansion_type(void)
+static void __init
+get_expansion_type(void)
{
if (find_devices("perch") != NULL)
has_perch = 1;
@@ -2569,8 +2639,8 @@
* Set dmasound.mach.max_dsp_rate on the basis of these routines.
*/
-static void
-__init init_awacs_frame_rates(unsigned int *prop, unsigned int l)
+static void __init
+awacs_init_frame_rates(unsigned int *prop, unsigned int l)
{
int i ;
if (prop) {
@@ -2592,31 +2662,8 @@
/* else we assume that all the rates are available */
}
-static void
-__init init_tumbler_frame_rates(unsigned int *prop, unsigned int l)
-{
- int i ;
- if (prop) {
- for (i=0; i<2; i++)
- tumbler_freqs_ok[i] = 0;
- for (l /= sizeof(int); l > 0; --l) {
- unsigned int r = *prop++;
- /* Apple 'Fixed' format */
- if (r >= 0x10000)
- r >>= 16;
- for (i = 0; i < 2; ++i) {
- if (r == tumbler_freqs[i]) {
- tumbler_freqs_ok[i] = 1;
- break;
- }
- }
- }
- }
- /* else we assume that all the rates are available */
-}
-
-static void
-__init init_burgundy_frame_rates(unsigned int *prop, unsigned int l)
+static void __init
+burgundy_init_frame_rates(unsigned int *prop, unsigned int l)
{
int temp[9] ;
int i = 0 ;
@@ -2641,8 +2688,8 @@
#endif
}
-static void
-__init init_daca_frame_rates(unsigned int *prop, unsigned int l)
+static void __init
+daca_init_frame_rates(unsigned int *prop, unsigned int l)
{
int temp[9] ;
int i = 0 ;
@@ -2668,21 +2715,22 @@
#endif
}
-static void
-__init init_frame_rates(unsigned int *prop, unsigned int l)
+static void __init
+init_frame_rates(unsigned int *prop, unsigned int l)
{
- switch (awacs_revision){
+ switch (awacs_revision) {
case AWACS_TUMBLER:
- init_tumbler_frame_rates(prop, l);
+ case AWACS_SNAPPER:
+ tas_init_frame_rates(prop, l);
break ;
case AWACS_DACA:
- init_daca_frame_rates(prop, l);
+ daca_init_frame_rates(prop, l);
break ;
case AWACS_BURGUNDY:
- init_burgundy_frame_rates(prop, l);
+ burgundy_init_frame_rates(prop, l);
break ;
- default: /* ;-))) */
- init_awacs_frame_rates(prop, l);
+ default:
+ awacs_init_frame_rates(prop, l);
break ;
}
}
@@ -2690,11 +2738,11 @@
/* find things/machines that can't do mac-io byteswap
*/
-static void
-__init set_hw_byteswap(struct device_node *io)
+static void __init
+set_hw_byteswap(struct device_node *io)
{
struct device_node *mio ;
- unsigned int *p, kl = 0 ;
+ unsigned int kl = 0 ;
/* if seems that Keylargo can't byte-swap */
@@ -2741,9 +2789,11 @@
if( beep_dbdma_cmd_space ) kfree(beep_dbdma_cmd_space) ;
return -ENOMEM ;
}
+#ifdef CONFIG_VT
/* OK, we should be safe to claim the mksound vector now */
orig_mksound = kd_mksound;
kd_mksound = awacs_mksound;
+#endif
return 0 ;
}
@@ -2839,23 +2889,26 @@
}
/* all OF versions I've seen use this value */
- awacs = (volatile struct awacs_regs *)
- ioremap(io->addrs[0].address, 0x1000);
+ if (i2s_node)
+ i2s = (u32 *)ioremap(io->addrs[0].address, 0x1000);
+ else
+ awacs = (volatile struct awacs_regs *)
+ ioremap(io->addrs[0].address, 0x1000);
awacs_txdma = (volatile struct dbdma_regs *)
ioremap(io->addrs[1].address, 0x100);
awacs_rxdma = (volatile struct dbdma_regs *)
ioremap(io->addrs[2].address, 0x100);
-#ifdef CONFIG_PMAC_PBOOK
/* first of all make sure that the chip is powered up....*/
pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, io, 0, 1);
- if (awacs_revision == AWACS_SCREAMER)
+ if (awacs_revision == AWACS_SCREAMER && awacs)
awacs_recalibrate();
-#endif
+
awacs_irq = io->intrs[0].line;
awacs_tx_irq = io->intrs[1].line;
awacs_rx_irq = io->intrs[2].line;
+ /* Hack for legacy crap that will be killed someday */
awacs_node = io;
/* if we have an awacs or screamer - probe the chip to make
@@ -2906,8 +2959,9 @@
/* if it's there use it to set up frame rates */
init_frame_rates(prop, l) ;
}
-
- out_le32(&awacs->control, 0x11); /* set everything quiesent */
+
+ if (awacs)
+ out_le32(&awacs->control, 0x11); /* set everything quiesent */
set_hw_byteswap(io) ; /* figure out if the h/w can do it */
@@ -2942,9 +2996,20 @@
#ifdef CONFIG_KMOD
request_module("i2c-keywest");
#endif /* CONFIG_KMOD */
- awacs_tumbler_init();
- tas_init();
+ tas_register_driver(&tas3001c_hooks);
+ tas_init(I2C_DRIVERID_TAS3001C, I2C_DRIVERNAME_TAS3001C);
+ tas_dmasound_init();
+ tas_post_init();
break ;
+ case AWACS_SNAPPER:
+#ifdef CONFIG_KMOD
+ request_module("i2c-keywest");
+#endif /* CONFIG_KMOD */
+ tas_register_driver(&tas3004_hooks);
+ tas_init(I2C_DRIVERID_TAS3004,I2C_DRIVERNAME_TAS3004);
+ tas_dmasound_init();
+ tas_post_init();
+ break;
case AWACS_DACA:
#ifdef CONFIG_KMOD
request_module("i2c-keywest");
@@ -3028,11 +3093,15 @@
dmasound.mach.hardware_afmts = AFMT_S16_BE ;
/* shut out chips that do output only.
- may need to extend this to machines which have no inputs - even tho'
- they use screamer - IIRC one of the powerbooks is like this.
- */
+ * may need to extend this to machines which have no inputs - even tho'
+ * they use screamer - IIRC one of the powerbooks is like this.
+ *
+ * FIXME: Actually, some TUMBLER and SNAPPER do have inputs...
+ */
- if (awacs_revision != AWACS_TUMBLER && awacs_revision != AWACS_DACA) {
+ if (awacs_revision != AWACS_TUMBLER &&
+ awacs_revision != AWACS_SNAPPER &&
+ awacs_revision != AWACS_DACA) {
dmasound.mach.capabilities = DSP_CAP_DUPLEX ;
dmasound.mach.record = PMacRecord ;
}
@@ -3050,6 +3119,9 @@
case AWACS_TUMBLER:
sprintf(awacs_name, "PowerMac Tumbler ") ;
break ;
+ case AWACS_SNAPPER:
+ sprintf(awacs_name, "PowerMac Snapper ") ;
+ break ;
case AWACS_SCREAMER:
sprintf(awacs_name, "PowerMac Screamer ") ;
break ;
@@ -3066,7 +3138,8 @@
{
switch (awacs_revision) {
case AWACS_TUMBLER:
- awacs_tumbler_cleanup();
+ case AWACS_SNAPPER:
+ tas_dmasound_cleanup();
tas_cleanup();
break ;
case AWACS_DACA:
@@ -3081,3 +3154,10 @@
module_init(dmasound_awacs_init);
module_exit(dmasound_awacs_cleanup);
+/*
+ * Local Variables:
+ * tab-width: 8
+ * indent-tabs-mode: t
+ * c-basic-offset: 8
+ * End:
+ */
diff -uNr linux-2.4.20/drivers/sound/dmasound/tas3001c.c linux-2.4.20-ben5/drivers/sound/dmasound/tas3001c.c
--- linux-2.4.20/drivers/sound/dmasound/tas3001c.c 2002-02-25 20:38:05.000000000 +0100
+++ linux-2.4.20-ben5/drivers/sound/dmasound/tas3001c.c 2003-01-30 11:52:58.000000000 +0100
@@ -1,38 +1,17 @@
/*
- * Driver for the i2c/i2s based TA3001C sound chip used
- * on some Apple hardware. Also known as "tumbler".
+ * Driver for the i2c/i2s based TA3004 sound chip used
+ * on some Apple hardware. Also known as "snapper".
*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- *
- * Modified by Christopher C. Chimelis :
+ * Tobias Sargeant
+ * Based upon, tas3001c.c by Christopher C. Chimelis :
*
* TODO:
* -----
- * * Enable DRC since the TiBook speakers are less than good
* * Enable control over input line 2 (is this connected?)
- * * Play with the dual six-stage cascading biquad filtering to see how
- * we can use it to our advantage (currently not implemented)
- * * Reorganise driver a bit to make it cleaner and easier to work with
- * (read: use the header file more :-P)
- * * Implement sleep support
- *
- * Version 0.4:
- * ------------
- * * Balance control finally works (can someone document OSS better please?)
- * * Moved to a struct for common values referenced in the driver
- * * Put stubs in for sleep/wake-up support for now. This will take some
- * experimentation to make sure that the timing is right, since the
- * TAS hardware requires specific timing while enabling low-power mode.
- * I may cheat for now and just reset the chip on wake-up, but I'd rather
- * not if I don't have to.
- *
- * Version 0.3:
- * ------------
- * * Fixed volume control
- * * Added bass and treble control
- * * Added PCM line level control (mixer 1 in the TAS manual)
+ * * Implement sleep support (at least mute everything and
+ * * set gains to minimum during sleep)
+ * * Look into some of Darwin's tweaks regarding the mute
+ * * lines (delays & different behaviour on some HW)
*
*/
@@ -45,403 +24,854 @@
#include
#include
#include
+#include
#include
#include