Browse Source

Automatic merge of /spare/repo/linux-2.6/.git branch HEAD

20 years ago
parent
commit
ae20ea8525
100 changed files with 2707 additions and 876 deletions
  1. 2 3
      CREDITS
  2. 124 32
      Documentation/DocBook/libata.tmpl
  3. 128 0
      Documentation/cpu-freq/cpufreq-stats.txt
  4. 1 2
      Documentation/cpusets.txt
  5. 205 0
      Documentation/dvb/README.flexcop
  6. 24 45
      Documentation/dvb/bt8xx.txt
  7. 219 0
      Documentation/dvb/ci.txt
  8. 2 2
      Documentation/dvb/get_dvb_firmware
  9. 20 0
      Documentation/feature-removal-schedule.txt
  10. 2 4
      Documentation/filesystems/sysfs-pci.txt
  11. 0 21
      Documentation/power/devices.txt
  12. 2 2
      Documentation/powerpc/hvcs.txt
  13. 3 0
      Documentation/x86_64/boot-options.txt
  14. 8 2
      MAINTAINERS
  15. 2 2
      Makefile
  16. 2 5
      arch/alpha/kernel/osf_sys.c
  17. 1 1
      arch/arm/mach-s3c2410/clock.c
  18. 4 2
      arch/arm/mach-s3c2410/s3c2440.c
  19. 10 11
      arch/arm/mm/Kconfig
  20. 0 80
      arch/arm/mm/copypage-v4mc.S
  21. 111 0
      arch/arm/mm/copypage-v4mc.c
  22. 6 22
      arch/arm/mm/copypage-v6.c
  23. 35 2
      arch/arm/mm/flush.c
  24. 19 8
      arch/arm/mm/mm-armv.c
  25. 1 1
      arch/h8300/kernel/process.c
  26. 1 1
      arch/i386/Kconfig
  27. 7 5
      arch/i386/kernel/cpu/amd.c
  28. 4 0
      arch/i386/kernel/cpu/common.c
  29. 13 1
      arch/i386/kernel/cpu/cpufreq/Kconfig
  30. 1 0
      arch/i386/kernel/cpu/cpufreq/Makefile
  31. 53 5
      arch/i386/kernel/cpu/cpufreq/longhaul.c
  32. 8 3
      arch/i386/kernel/cpu/cpufreq/powernow-k7.c
  33. 76 37
      arch/i386/kernel/cpu/cpufreq/powernow-k8.c
  34. 15 0
      arch/i386/kernel/cpu/cpufreq/powernow-k8.h
  35. 186 0
      arch/i386/kernel/cpu/cpufreq/sc520_freq.c
  36. 6 0
      arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
  37. 3 3
      arch/i386/kernel/cpu/cpufreq/speedstep-lib.c
  38. 3 0
      arch/i386/kernel/cpu/cpufreq/speedstep-smi.c
  39. 1 1
      arch/i386/kernel/cpu/intel_cacheinfo.c
  40. 2 0
      arch/i386/kernel/setup.c
  41. 4 1
      arch/i386/kernel/smpboot.c
  42. 4 2
      arch/i386/kernel/timers/common.c
  43. 20 0
      arch/i386/kernel/timers/timer_tsc.c
  44. 8 9
      arch/i386/mach-voyager/voyager_smp.c
  45. 6 4
      arch/i386/mm/ioremap.c
  46. 1 1
      arch/i386/pci/fixup.c
  47. 0 5
      arch/i386/pci/irq.c
  48. 0 1
      arch/ia64/ia32/ia32_ioctl.c
  49. 1 1
      arch/ia64/ia32/sys_ia32.c
  50. 2 2
      arch/ia64/kernel/entry.S
  51. 4 4
      arch/ia64/kernel/mca.c
  52. 1 2
      arch/ia64/kernel/minstate.h
  53. 160 15
      arch/ia64/kernel/perfmon.c
  54. 17 3
      arch/ia64/kernel/ptrace.c
  55. 1 1
      arch/ia64/kernel/smpboot.c
  56. 0 7
      arch/ia64/kernel/sys_ia64.c
  57. 2 0
      arch/ia64/sn/kernel/setup.c
  58. 12 5
      arch/m68knommu/kernel/process.c
  59. 48 7
      arch/mips/vr41xx/common/pmu.c
  60. 2 2
      arch/ppc/Kconfig
  61. 2 1
      arch/ppc/boot/images/Makefile
  62. 92 25
      arch/ppc/configs/mpc8555_cds_defconfig
  63. 9 6
      arch/ppc/kernel/head_44x.S
  64. 14 1
      arch/ppc/kernel/head_fsl_booke.S
  65. 3 1
      arch/ppc/kernel/setup.c
  66. 1 6
      arch/ppc/kernel/traps.c
  67. 5 2
      arch/ppc/lib/string.S
  68. 1 0
      arch/ppc/mm/init.c
  69. 0 1
      arch/ppc/platforms/83xx/mpc834x_sys.c
  70. 6 1
      arch/ppc/platforms/83xx/mpc834x_sys.h
  71. 3 0
      arch/ppc/platforms/85xx/mpc8540_ads.c
  72. 141 2
      arch/ppc/platforms/85xx/mpc85xx_cds_common.c
  73. 3 0
      arch/ppc/platforms/85xx/mpc85xx_cds_common.h
  74. 3 0
      arch/ppc/platforms/85xx/sbc8560.c
  75. 22 14
      arch/ppc/platforms/pmac_cpufreq.c
  76. 18 23
      arch/ppc/platforms/pq2ads.h
  77. 2 2
      arch/ppc/syslib/Makefile
  78. 1 1
      arch/ppc/syslib/ipic.c
  79. 0 193
      arch/ppc/syslib/m8260_pci.c
  80. 0 76
      arch/ppc/syslib/m8260_pci.h
  81. 5 5
      arch/ppc/syslib/m8260_pci_erratum9.c
  82. 9 2
      arch/ppc/syslib/m8260_setup.c
  83. 383 0
      arch/ppc/syslib/m82xx_pci.c
  84. 92 0
      arch/ppc/syslib/m82xx_pci.h
  85. 1 0
      arch/ppc/syslib/mpc83xx_devices.c
  86. 1 0
      arch/ppc/syslib/mpc85xx_devices.c
  87. 1 5
      arch/ppc/syslib/open_pic.c
  88. 28 0
      arch/ppc/syslib/ppc83xx_setup.c
  89. 16 0
      arch/ppc/syslib/ppc85xx_setup.c
  90. 10 0
      arch/ppc/syslib/prom_init.c
  91. 0 9
      arch/ppc64/kernel/entry.S
  92. 5 5
      arch/ppc64/kernel/head.S
  93. 22 0
      arch/ppc64/kernel/iSeries_setup.c
  94. 3 5
      arch/ppc64/kernel/idle.c
  95. 65 20
      arch/ppc64/kernel/mf.c
  96. 0 8
      arch/ppc64/kernel/pSeries_reconfig.c
  97. 21 7
      arch/ppc64/kernel/pmac_smp.c
  98. 0 3
      arch/ppc64/kernel/process.c
  99. 115 39
      arch/ppc64/kernel/prom_init.c
  100. 1 38
      arch/ppc64/kernel/rtc.c

+ 2 - 3
CREDITS

@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061
 S: USA
 S: USA
 
 
 N: Randy Dunlap
 N: Randy Dunlap
-E: rddunlap@osdl.org
+E: rdunlap@xenotime.net
 W: http://www.xenotime.net/linux/linux.html
 W: http://www.xenotime.net/linux/linux.html
 W: http://www.linux-usb.org
 W: http://www.linux-usb.org
 D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
 D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers
 D: x86 SMP, ACPI, bootflag hacking
 D: x86 SMP, ACPI, bootflag hacking
-S: 12725 SW Millikan Way, Suite 400
-S: Beaverton, Oregon 97005
+S: (ask for current address)
 S: USA
 S: USA
 
 
 N: Bob Dunlop
 N: Bob Dunlop

+ 124 - 32
Documentation/DocBook/libata.tmpl

@@ -14,7 +14,7 @@
   </authorgroup>
   </authorgroup>
 
 
   <copyright>
   <copyright>
-   <year>2003</year>
+   <year>2003-2005</year>
    <holder>Jeff Garzik</holder>
    <holder>Jeff Garzik</holder>
   </copyright>
   </copyright>
 
 
@@ -44,30 +44,38 @@
 
 
 <toc></toc>
 <toc></toc>
 
 
-  <chapter id="libataThanks">
-     <title>Thanks</title>
+  <chapter id="libataIntroduction">
+     <title>Introduction</title>
   <para>
   <para>
-  The bulk of the ATA knowledge comes thanks to long conversations with
-  Andre Hedrick (www.linux-ide.org).
+  libATA is a library used inside the Linux kernel to support ATA host
+  controllers and devices.  libATA provides an ATA driver API, class
+  transports for ATA and ATAPI devices, and SCSI&lt;-&gt;ATA translation
+  for ATA devices according to the T10 SAT specification.
   </para>
   </para>
   <para>
   <para>
-  Thanks to Alan Cox for pointing out similarities 
-  between SATA and SCSI, and in general for motivation to hack on
-  libata.
-  </para>
-  <para>
-  libata's device detection
-  method, ata_pio_devchk, and in general all the early probing was
-  based on extensive study of Hale Landis's probe/reset code in his
-  ATADRVR driver (www.ata-atapi.com).
+  This Guide documents the libATA driver API, library functions, library
+  internals, and a couple sample ATA low-level drivers.
   </para>
   </para>
   </chapter>
   </chapter>
 
 
   <chapter id="libataDriverApi">
   <chapter id="libataDriverApi">
      <title>libata Driver API</title>
      <title>libata Driver API</title>
+     <para>
+     struct ata_port_operations is defined for every low-level libata
+     hardware driver, and it controls how the low-level driver
+     interfaces with the ATA and SCSI layers.
+     </para>
+     <para>
+     FIS-based drivers will hook into the system with ->qc_prep() and
+     ->qc_issue() high-level hooks.  Hardware which behaves in a manner
+     similar to PCI IDE hardware may utilize several generic helpers,
+     defining at a bare minimum the bus I/O addresses of the ATA shadow
+     register blocks.
+     </para>
      <sect1>
      <sect1>
         <title>struct ata_port_operations</title>
         <title>struct ata_port_operations</title>
 
 
+	<sect2><title>Disable ATA port</title>
 	<programlisting>
 	<programlisting>
 void (*port_disable) (struct ata_port *);
 void (*port_disable) (struct ata_port *);
 	</programlisting>
 	</programlisting>
@@ -78,6 +86,9 @@ void (*port_disable) (struct ata_port *);
 	unplug).
 	unplug).
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Post-IDENTIFY device configuration</title>
 	<programlisting>
 	<programlisting>
 void (*dev_config) (struct ata_port *, struct ata_device *);
 void (*dev_config) (struct ata_port *, struct ata_device *);
 	</programlisting>
 	</programlisting>
@@ -88,6 +99,9 @@ void (*dev_config) (struct ata_port *, struct ata_device *);
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	issue of SET FEATURES - XFER MODE, and prior to operation.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Set PIO/DMA mode</title>
 	<programlisting>
 	<programlisting>
 void (*set_piomode) (struct ata_port *, struct ata_device *);
 void (*set_piomode) (struct ata_port *, struct ata_device *);
 void (*set_dmamode) (struct ata_port *, struct ata_device *);
 void (*set_dmamode) (struct ata_port *, struct ata_device *);
@@ -108,6 +122,9 @@ void (*post_set_mode) (struct ata_port *ap);
 	->set_dma_mode() is only called if DMA is possible.
 	->set_dma_mode() is only called if DMA is possible.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Taskfile read/write</title>
 	<programlisting>
 	<programlisting>
 void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
 void (*tf_load) (struct ata_port *ap, struct ata_taskfile *tf);
 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
 void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
@@ -120,6 +137,9 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
 	taskfile register values.
 	taskfile register values.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>ATA command execute</title>
 	<programlisting>
 	<programlisting>
 void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	</programlisting>
 	</programlisting>
@@ -129,17 +149,37 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
 	->tf_load(), to be initiated in hardware.
 	->tf_load(), to be initiated in hardware.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Per-cmd ATAPI DMA capabilities filter</title>
+	<programlisting>
+int (*check_atapi_dma) (struct ata_queued_cmd *qc);
+	</programlisting>
+
+	<para>
+Allow low-level driver to filter ATA PACKET commands, returning a status
+indicating whether or not it is OK to use DMA for the supplied PACKET
+command.
+	</para>
+
+	</sect2>
+
+	<sect2><title>Read specific ATA shadow registers</title>
 	<programlisting>
 	<programlisting>
 u8   (*check_status)(struct ata_port *ap);
 u8   (*check_status)(struct ata_port *ap);
-void (*dev_select)(struct ata_port *ap, unsigned int device);
+u8   (*check_altstatus)(struct ata_port *ap);
+u8   (*check_err)(struct ata_port *ap);
 	</programlisting>
 	</programlisting>
 
 
 	<para>
 	<para>
-	Reads the Status ATA shadow register from hardware.  On some
-	hardware, this has the side effect of clearing the interrupt
-	condition.
+	Reads the Status/AltStatus/Error ATA shadow register from
+	hardware.  On some hardware, reading the Status register has
+	the side effect of clearing the interrupt condition.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Select ATA device on bus</title>
 	<programlisting>
 	<programlisting>
 void (*dev_select)(struct ata_port *ap, unsigned int device);
 void (*dev_select)(struct ata_port *ap, unsigned int device);
 	</programlisting>
 	</programlisting>
@@ -147,9 +187,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device);
 	<para>
 	<para>
 	Issues the low-level hardware command(s) that causes one of N
 	Issues the low-level hardware command(s) that causes one of N
 	hardware devices to be considered 'selected' (active and
 	hardware devices to be considered 'selected' (active and
-	available for use) on the ATA bus.
+	available for use) on the ATA bus.  This generally has no
+meaning on FIS-based devices.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Reset ATA bus</title>
 	<programlisting>
 	<programlisting>
 void (*phy_reset) (struct ata_port *ap);
 void (*phy_reset) (struct ata_port *ap);
 	</programlisting>
 	</programlisting>
@@ -162,17 +206,31 @@ void (*phy_reset) (struct ata_port *ap);
 	functions ata_bus_reset() or sata_phy_reset() for this hook.
 	functions ata_bus_reset() or sata_phy_reset() for this hook.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Control PCI IDE BMDMA engine</title>
 	<programlisting>
 	<programlisting>
 void (*bmdma_setup) (struct ata_queued_cmd *qc);
 void (*bmdma_setup) (struct ata_queued_cmd *qc);
 void (*bmdma_start) (struct ata_queued_cmd *qc);
 void (*bmdma_start) (struct ata_queued_cmd *qc);
+void (*bmdma_stop) (struct ata_port *ap);
+u8   (*bmdma_status) (struct ata_port *ap);
 	</programlisting>
 	</programlisting>
 
 
 	<para>
 	<para>
-	When setting up an IDE BMDMA transaction, these hooks arm
-	(->bmdma_setup) and fire (->bmdma_start) the hardware's DMA
-	engine.
+When setting up an IDE BMDMA transaction, these hooks arm
+(->bmdma_setup), fire (->bmdma_start), and halt (->bmdma_stop)
+the hardware's DMA engine.  ->bmdma_status is used to read the standard
+PCI IDE DMA Status register.
 	</para>
 	</para>
 
 
+	<para>
+These hooks are typically either no-ops, or simply not implemented, in
+FIS-based drivers.
+	</para>
+
+	</sect2>
+
+	<sect2><title>High-level taskfile hooks</title>
 	<programlisting>
 	<programlisting>
 void (*qc_prep) (struct ata_queued_cmd *qc);
 void (*qc_prep) (struct ata_queued_cmd *qc);
 int (*qc_issue) (struct ata_queued_cmd *qc);
 int (*qc_issue) (struct ata_queued_cmd *qc);
@@ -190,20 +248,26 @@ int (*qc_issue) (struct ata_queued_cmd *qc);
 	->qc_issue is used to make a command active, once the hardware
 	->qc_issue is used to make a command active, once the hardware
 	and S/G tables have been prepared.  IDE BMDMA drivers use the
 	and S/G tables have been prepared.  IDE BMDMA drivers use the
 	helper function ata_qc_issue_prot() for taskfile protocol-based
 	helper function ata_qc_issue_prot() for taskfile protocol-based
-	dispatch.  More advanced drivers roll their own ->qc_issue
-	implementation, using this as the "issue new ATA command to
-	hardware" hook.
+	dispatch.  More advanced drivers implement their own ->qc_issue.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Timeout (error) handling</title>
 	<programlisting>
 	<programlisting>
 void (*eng_timeout) (struct ata_port *ap);
 void (*eng_timeout) (struct ata_port *ap);
 	</programlisting>
 	</programlisting>
 
 
 	<para>
 	<para>
-	This is a high level error handling function, called from the
-	error handling thread, when a command times out.
+This is a high level error handling function, called from the
+error handling thread, when a command times out.  Most newer
+hardware will implement its own error handling code here.  IDE BMDMA
+drivers may use the helper function ata_eng_timeout().
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Hardware interrupt handling</title>
 	<programlisting>
 	<programlisting>
 irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
 irqreturn_t (*irq_handler)(int, void *, struct pt_regs *);
 void (*irq_clear) (struct ata_port *);
 void (*irq_clear) (struct ata_port *);
@@ -216,6 +280,9 @@ void (*irq_clear) (struct ata_port *);
 	is quiet.
 	is quiet.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>SATA phy read/write</title>
 	<programlisting>
 	<programlisting>
 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
 void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -227,6 +294,9 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
 	if ->phy_reset hook called the sata_phy_reset() helper function.
 	if ->phy_reset hook called the sata_phy_reset() helper function.
 	</para>
 	</para>
 
 
+	</sect2>
+
+	<sect2><title>Init and shutdown</title>
 	<programlisting>
 	<programlisting>
 int (*port_start) (struct ata_port *ap);
 int (*port_start) (struct ata_port *ap);
 void (*port_stop) (struct ata_port *ap);
 void (*port_stop) (struct ata_port *ap);
@@ -240,15 +310,17 @@ void (*host_stop) (struct ata_host_set *host_set);
 	tasks.  
 	tasks.  
 	</para>
 	</para>
 	<para>
 	<para>
-	->host_stop() is called when the rmmod or hot unplug process
-	begins.  The hook must stop all hardware interrupts, DMA
-	engines, etc.
-	</para>
-	<para>
 	->port_stop() is called after ->host_stop().  It's sole function
 	->port_stop() is called after ->host_stop().  It's sole function
 	is to release DMA/memory resources, now that they are no longer
 	is to release DMA/memory resources, now that they are no longer
 	actively being used.
 	actively being used.
 	</para>
 	</para>
+	<para>
+	->host_stop() is called after all ->port_stop() calls
+have completed.  The hook must finalize hardware shutdown, release DMA
+and other resources, etc.
+	</para>
+
+	</sect2>
 
 
      </sect1>
      </sect1>
   </chapter>
   </chapter>
@@ -279,4 +351,24 @@ void (*host_stop) (struct ata_host_set *host_set);
 !Idrivers/scsi/sata_sil.c
 !Idrivers/scsi/sata_sil.c
   </chapter>
   </chapter>
 
 
+  <chapter id="libataThanks">
+     <title>Thanks</title>
+  <para>
+  The bulk of the ATA knowledge comes thanks to long conversations with
+  Andre Hedrick (www.linux-ide.org), and long hours pondering the ATA
+  and SCSI specifications.
+  </para>
+  <para>
+  Thanks to Alan Cox for pointing out similarities 
+  between SATA and SCSI, and in general for motivation to hack on
+  libata.
+  </para>
+  <para>
+  libata's device detection
+  method, ata_pio_devchk, and in general all the early probing was
+  based on extensive study of Hale Landis's probe/reset code in his
+  ATADRVR driver (www.ata-atapi.com).
+  </para>
+  </chapter>
+
 </book>
 </book>

+ 128 - 0
Documentation/cpu-freq/cpufreq-stats.txt

@@ -0,0 +1,128 @@
+
+     CPU frequency and voltage scaling statictics in the Linux(TM) kernel
+
+
+             L i n u x    c p u f r e q - s t a t s   d r i v e r
+
+                       - information for users -
+
+
+             Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
+
+Contents
+1. Introduction
+2. Statistics Provided (with example)
+3. Configuring cpufreq-stats
+
+
+1. Introduction
+
+cpufreq-stats is a driver that provices CPU frequency statistics for each CPU.
+This statistics is provided in /sysfs as a bunch of read_only interfaces. This
+interface (when configured) will appear in a seperate directory under cpufreq
+in /sysfs (<sysfs root>/devices/system/cpu/cpuX/cpufreq/stats/) for each CPU.
+Various statistics will form read_only files under this directory.
+
+This driver is designed to be independent of any particular cpufreq_driver
+that may be running on your CPU. So, it will work with any cpufreq_driver.
+
+
+2. Statistics Provided (with example)
+
+cpufreq stats provides following statistics (explained in detail below).
+-  time_in_state
+-  total_trans
+-  trans_table
+
+All the statistics will be from the time the stats driver has been inserted 
+to the time when a read of a particular statistic is done. Obviously, stats 
+driver will not have any information about the the frequcny transitions before
+the stats driver insertion.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # ls -l
+total 0
+drwxr-xr-x  2 root root    0 May 14 16:06 .
+drwxr-xr-x  3 root root    0 May 14 15:58 ..
+-r--r--r--  1 root root 4096 May 14 16:06 time_in_state
+-r--r--r--  1 root root 4096 May 14 16:06 total_trans
+-r--r--r--  1 root root 4096 May 14 16:06 trans_table
+--------------------------------------------------------------------------------
+
+-  time_in_state
+This gives the amount of time spent in each of the frequencies supported by
+this CPU. The cat output will have "<frequency> <time>" pair in each line, which
+will mean this CPU spent <time> usertime units of time at <frequency>. Output
+will have one line for each of the supported freuencies. usertime units here 
+is 10mS (similar to other time exported in /proc).
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat time_in_state 
+3600000 2089
+3400000 136
+3200000 34
+3000000 67
+2800000 172488
+--------------------------------------------------------------------------------
+
+
+-  total_trans
+This gives the total number of frequency transitions on this CPU. The cat 
+output will have a single count which is the total number of frequency
+transitions.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat total_trans
+20
+--------------------------------------------------------------------------------
+
+-  trans_table
+This will give a fine grained information about all the CPU frequency
+transitions. The cat output here is a two dimensional matrix, where an entry
+<i,j> (row i, column j) represents the count of number of transitions from 
+Freq_i to Freq_j. Freq_i is in descending order with increasing rows and 
+Freq_j is in descending order with increasing columns. The output here also 
+contains the actual freq values for each row and column for better readability.
+
+--------------------------------------------------------------------------------
+<mysystem>:/sys/devices/system/cpu/cpu0/cpufreq/stats # cat trans_table
+   From  :    To
+         :   3600000   3400000   3200000   3000000   2800000 
+  3600000:         0         5         0         0         0 
+  3400000:         4         0         2         0         0 
+  3200000:         0         1         0         2         0 
+  3000000:         0         0         1         0         3 
+  2800000:         0         0         0         2         0 
+--------------------------------------------------------------------------------
+
+
+3. Configuring cpufreq-stats
+
+To configure cpufreq-stats in your kernel
+Config Main Menu
+	Power management options (ACPI, APM)  --->
+		CPU Frequency scaling  --->
+			[*] CPU Frequency scaling
+			<*>   CPU frequency translation statistics 
+			[*]     CPU frequency translation statistics details
+
+
+"CPU Frequency scaling" (CONFIG_CPU_FREQ) should be enabled to configure
+cpufreq-stats.
+
+"CPU frequency translation statistics" (CONFIG_CPU_FREQ_STAT) provides the
+basic statistics which includes time_in_state and total_trans.
+
+"CPU frequency translation statistics details" (CONFIG_CPU_FREQ_STAT_DETAILS)
+provides fine grained cpufreq stats by trans_table. The reason for having a
+seperate config option for trans_table is:
+- trans_table goes against the traditional /sysfs rule of one value per
+  interface. It provides a whole bunch of value in a 2 dimensional matrix
+  form.
+
+Once these two options are enabled and your CPU supports cpufrequency, you
+will be able to see the CPU frequency statistics in /sysfs.
+
+
+
+

+ 1 - 2
Documentation/cpusets.txt

@@ -252,8 +252,7 @@ in a tasks processor placement.
 There is an exception to the above.  If hotplug funtionality is used
 There is an exception to the above.  If hotplug funtionality is used
 to remove all the CPUs that are currently assigned to a cpuset,
 to remove all the CPUs that are currently assigned to a cpuset,
 then the kernel will automatically update the cpus_allowed of all
 then the kernel will automatically update the cpus_allowed of all
-tasks attached to CPUs in that cpuset with the online CPUs of the
-nearest parent cpuset that still has some CPUs online.  When memory
+tasks attached to CPUs in that cpuset to allow all CPUs.  When memory
 hotplug functionality for removing Memory Nodes is available, a
 hotplug functionality for removing Memory Nodes is available, a
 similar exception is expected to apply there as well.  In general,
 similar exception is expected to apply there as well.  In general,
 the kernel prefers to violate cpuset placement, over starving a task
 the kernel prefers to violate cpuset placement, over starving a task

+ 205 - 0
Documentation/dvb/README.flexcop

@@ -0,0 +1,205 @@
+This README escorted the skystar2-driver rewriting procedure. It describes the
+state of the new flexcop-driver set and some internals are written down here
+too.
+
+This document hopefully describes things about the flexcop and its
+device-offsprings. Goal was to write an easy-to-write and easy-to-read set of
+drivers based on the skystar2.c and other information.
+
+Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been
+touched and rewritten.
+
+History & News
+==============
+  2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana)
+
+
+
+
+General coding processing
+=========================
+
+We should proceed as follows (as long as no one complains):
+
+0) Think before start writing code!
+
+1) rewriting the skystar2.c with the help of the flexcop register descriptions
+and splitting up the files to a pci-bus-part and a flexcop-part.
+The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the
+device-specific part and b2c2-flexcop.ko for the common flexcop-functions.
+
+2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c
+and other pci drivers)
+
+3) make some beautification (see 'Improvements when rewriting (refactoring) is
+done')
+
+4) Testing the new driver and maybe substitute the skystar2.c with it, to reach
+a wider tester audience.
+
+5) creating an usb-bus-part using the already written flexcop code for the pci
+card.
+
+Idea: create a kernel-object for the flexcop and export all important
+functions. This option saves kernel-memory, but maybe a lot of functions have
+to be exported to kernel namespace.
+
+
+Current situation
+=================
+
+0) Done :)
+1) Done (some minor issues left)
+2) Done
+3) Not ready yet, more information is necessary
+4) next to be done (see the table below)
+5) USB driver is working (yes, there are some minor issues)
+
+What seems to be ready?
+-----------------------
+
+1) Rewriting
+1a) i2c is cut off from the flexcop-pci.c and seems to work
+1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c
+1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c
+1e) eeprom (reading MAC address)
+1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me))
+1f) misc. register accesses for reading parameters (e.g. resetting, revision)
+1g) pid/mac filter (flexcop-hw-filter.c)
+1i) dvb-stuff initialization in flexcop.c (done)
+1h) dma stuff (now just using the size-irq, instead of all-together, to be done)
+1j) remove flexcop initialization from flexcop-pci.c completely (done)
+1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO')
+1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from
+non-static where possible, moved code to proper places)
+
+2) Search for errors in the leftover of flexcop-pci.c (partially done)
+5a) add MAC address reading
+5c) feeding of ISOC data to the software demux (format of the isochronous data
+and speed optimization, no real error) (thanks to Vadim Catana)
+
+What to do in the near future?
+--------------------------------------
+(no special order here)
+
+5) USB driver
+5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting)
+
+Testing changes
+---------------
+
+O             = item is working
+P             = item is partially working
+X             = item is not working
+N             = item does not apply here
+<empty field> = item need to be examined
+
+       | PCI                               | USB
+item   | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312
+-------+-------+---------+---------+-------+-------+---------+---------+-------
+1a)    | O     |         |         |       | N     | N       | N       | N
+1b)    | O     |         |         |       |       |         | O       |
+1c)    | N     | N       |         |       | N     | N       | O       |
+1d)    |                 O                 |                 O
+1e)    |                 O                 |                 O
+1f)    |                                   P
+1g)    |                                   O
+1h)    |                 P                 |
+1i)    |                 O                 |                 N
+1j)    |                 O                 |                 N
+1l)    |                 O                 |                 N
+2)     |                 O                 |                 N
+5a)    |                 N                 |                 O
+5b)*   |                 N                 |
+5c)    |                 N                 |                 O
+
+* - not done yet
+
+Known bugs and problems and TODO
+--------------------------------
+
+1g/h/l) when pid filtering is enabled on the pci card
+
+DMA usage currently:
+  The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first
+  address and triggers an IRQ when it's full and starts writing to the second
+  address. When the second address is full, the IRQ is triggered again, and
+  the flexcop writes to first address again, and so on.
+  The buffersize of each address is currently 640*188 bytes.
+
+  Problem is, when using hw-pid-filtering and doing some low-bandwidth
+  operation (like scanning) the buffers won't be filled enough to trigger
+  the IRQ. That's why:
+
+  When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ
+  is triggered.  Is the current write address of DMA1 different to the one
+  during the last IRQ, then the data is passed to the demuxer.
+
+  There is an additional DMA-IRQ-method: packet count IRQ. This isn't
+  implemented correctly yet.
+
+  The solution is to disable HW PID filtering, but I don't know how the DVB
+  API software demux behaves on slow systems with 45MBit/s TS.
+
+Solved bugs :)
+--------------
+1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't
+working)
+SOLUTION: also index 0 was affected, because net_translation is done for
+these indexes by default
+
+5b) isochronous transfer does only work in the first attempt (for the Sky2PC
+USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really
+woke up again (don't know if this need fixes, see
+flexcop-fe-tuner.c:flexcop_sleep)
+
+NEWS: when the driver is loaded and unloaded and loaded again (w/o doing
+anything in the while the driver is loaded the first time), no transfers take
+place anymore.
+
+Improvements when rewriting (refactoring) is done
+=================================================
+
+- split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control
+  (enable sleeping for other demods than dvb-s)
+- add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA)
+
+Debugging
+---------
+- add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it
+  with this flexcop, this is important, because i2c is now using the
+  flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for
+  that, please tell us so).
+
+Everything which is identical in the following table, can be put into a common
+flexcop-module.
+
+                  PCI                  USB
+-------------------------------------------------------------------------------
+Different:
+Register access:  accessing IO memory  USB control message
+I2C bus:          I2C bus of the FC    USB control message
+Data transfer:    DMA                  isochronous transfer
+EEPROM transfer:  through i2c bus      not clear yet
+
+Identical:
+Streaming:                 accessing registers
+PID Filtering:             accessing registers
+Sram destinations:         accessing registers
+Tuner/Demod:                     I2C bus
+DVB-stuff:            can be written for common use
+
+Acknowledgements (just for the rewriting part)
+================
+
+Bjarne Steinsbo thought a lot in the first place of the pci part for this code
+sharing idea.
+
+Andreas Oberritter for providing a recent PCI initialization template
+(pluto2.c).
+
+Boleslaw Ciesielski for pointing out a problem with firmware loader.
+
+Vadim Catana for correcting the USB transfer.
+
+comments, critics and ideas to linux-dvb@linuxtv.org.

+ 24 - 45
Documentation/dvb/bt8xx.txt

@@ -17,74 +17,53 @@ Because of this, you need to enable
 "Device drivers" => "Multimedia devices"
 "Device drivers" => "Multimedia devices"
   => "Video For Linux" => "BT848 Video For Linux"
   => "Video For Linux" => "BT848 Video For Linux"
 
 
+Furthermore you need to enable
+"Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices"
+  => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards"
+
 2) Loading Modules
 2) Loading Modules
 ==================
 ==================
 
 
 In general you need to load the bttv driver, which will handle the gpio and
 In general you need to load the bttv driver, which will handle the gpio and
-i2c communication for us. Next you need the common dvb-bt8xx device driver
-and one frontend driver.
-
-The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT 
-CARD ID!
-
-(If you don't get your card running and you suspect that the card id you're
-using is wrong, have a look at "bttv-cards.c" for a list of possible card
-ids.)
-
-Pay attention to failures when you load the frontend drivers
-(e.g. dmesg, /var/log/messages).
+i2c communication for us, plus the common dvb-bt8xx device driver.
+The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and
+TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver.
 
 
 3a) Nebula / Pinnacle PCTV
 3a) Nebula / Pinnacle PCTV
 --------------------------
 --------------------------
 
 
-   $ modprobe bttv i2c_hw=1 card=0x68
-   $ modprobe dvb-bt8xx
-   
-For Nebula cards use the "nxt6000" frontend driver:
-   $ modprobe nxt6000
+   $ modprobe bttv (normally bttv is being loaded automatically by kmod)
+   $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading)
 
 
-For Pinnacle PCTV cards use the "cx24110" frontend driver:
-   $ modprobe cx24110
 
 
-3b) TwinHan
------------
+3b) TwinHan and Clones
+--------------------------
 
 
    $ modprobe bttv i2c_hw=1 card=0x71
    $ modprobe bttv i2c_hw=1 card=0x71
    $ modprobe dvb-bt8xx
    $ modprobe dvb-bt8xx
    $ modprobe dst
    $ modprobe dst
 
 
-The value 0x71 will override the PCI type detection for dvb-bt8xx, which 
-is necessary for TwinHan cards.#
+The value 0x71 will override the PCI type detection for dvb-bt8xx,
+which  is necessary for TwinHan cards.
 
 
-If you're having an older card (blue color circuit) and card=0x71 locks your
-machine, try using 0x68, too. If that does not work, ask on the DVB mailing list.
+If you're having an older card (blue color circuit) and card=0x71 locks
+your machine, try using 0x68, too. If that does not work, ask on the
+mailing list.
 
 
-The DST module takes a couple of useful parameters, in case the
-dst drivers fails to detect your type of card correctly.
+The DST module takes a couple of useful parameters.
 
 
-dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable).
+verbose takes values 0 to 5. These values control the verbosity level.
 
 
-dst_type_flags takes bit combined values:
-1 = new tuner type packets. You can use this if your card is detected
-    and you have debug and you continually see the tuner packets not
-    working (make sure not a basic problem like dish alignment etc.)
+debug takes values 0 and 1. You can either disable or enable debugging.
 
 
-2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly
-    breaking up in one half continually, and crc fails a lot, then
-    this is worth a try (or trying to turn off)
+dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card.
+0x20 means it has a Conditional Access slot.
 
 
-4 = has symdiv. Some cards, mostly without new tuner packets, require
-    a symbol division algorithm. Doesn't apply to terrestial TV.
-
-You can also specify a value to have the autodetected values turned off
-(e.g. 0). The autodected values are determined bythe cards 'response
+The autodected values are determined bythe cards 'response
 string' which you can see in your logs e.g.
 string' which you can see in your logs e.g.
 
 
-dst_check_ci: recognize DST-MOT
-
-or 
+dst_get_device_id: Recognise [DSTMCI]
 
 
-dst_check_ci: unable to recognize DSTXCI or STXCI
 
 
 --
 --
-Authors: Richard Walker, Jamie Honan, Michael Hunold
+Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham

+ 219 - 0
Documentation/dvb/ci.txt

@@ -0,0 +1,219 @@
+* For the user
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+NOTE: This document describes the usage of the high level CI API as
+in accordance to the Linux DVB API. This is a not a documentation for the,
+existing low level CI API.
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To utilize the High Level CI capabilities,
+
+(1*) This point is valid only for the Twinhan/clones
+  For the Twinhan/Twinhan clones, the dst_ca module handles the CI
+  hardware handling.This module is loaded automatically if a CI
+  (Common Interface, that holds the CAM (Conditional Access Module)
+  is detected.
+
+(2) one requires a userspace application, ca_zap. This small userland
+  application is in charge of sending the descrambling related information
+  to the CAM.
+
+This application requires the following to function properly as of now.
+
+	(a) Tune to a valid channel, with szap.
+	  eg: $ szap -c channels.conf -r "TMC" -x
+
+	(b) a channels.conf containing a valid PMT PID
+
+	  eg: TMC:11996:h:0:27500:278:512:650:321
+
+	  here 278 is a valid PMT PID. the rest of the values are the
+	  same ones that szap uses.
+
+	(c) after running a szap, you have to run ca_zap, for the
+	  descrambler to function,
+
+	  eg: $ ca_zap patched_channels.conf "TMC"
+
+	  The patched means a patch to apply to scan, such that scan can
+	  generate a channels.conf_with pmt, which has this PMT PID info
+	  (NOTE: szap cannot use this channels.conf with the PMT_PID)
+
+
+	(d) Hopeflly Enjoy your favourite subscribed channel as you do with
+	  a FTA card.
+
+(3) Currently ca_zap, and dst_test, both are meant for demonstration
+  purposes only, they can become full fledged applications if necessary.
+
+
+* Cards that fall in this category
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+At present the cards that fall in this category are the Twinhan and it's
+clones, these cards are available as VVMER, Tomato, Hercules, Orange and
+so on.
+
+* CI modules that are supported
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The CI module support is largely dependant upon the firmware on the cards
+Some cards do support almost all of the available CI modules. There is
+nothing much that can be done in order to make additional CI modules
+working with these cards.
+
+Modules that have been tested by this driver at present are
+
+(1) Irdeto 1 and 2 from SCM
+(2) Viaccess from SCM
+(3) Dragoncam
+
+* The High level CI API
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* For the programmer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+With the High Level CI approach any new card with almost any random
+architecture can be implemented with this style, the definitions
+insidethe switch statement can be easily adapted for any card, thereby
+eliminating the need for any additional ioctls.
+
+The disadvantage is that the driver/hardware has to manage the rest. For
+the application programmer it would be as simple as sending/receiving an
+array to/from the CI ioctls as defined in the Linux DVB API. No changes
+have been made in the API to accomodate this feature.
+
+
+* Why the need for another CI interface ?
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This is one of the most commonly asked question. Well a nice question.
+Strictly speaking this is not a new interface.
+
+The CI interface is defined in the DVB API in ca.h as
+
+typedef struct ca_slot_info {
+	int num;               /* slot number */
+
+	int type;              /* CA interface this slot supports */
+#define CA_CI            1     /* CI high level interface */
+#define CA_CI_LINK       2     /* CI link layer level interface */
+#define CA_CI_PHYS       4     /* CI physical layer level interface */
+#define CA_DESCR         8     /* built-in descrambler */
+#define CA_SC          128     /* simple smart card interface */
+
+	unsigned int flags;
+#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */
+#define CA_CI_MODULE_READY   2
+} ca_slot_info_t;
+
+
+
+This CI interface follows the CI high level interface, which is not
+implemented by most applications. Hence this area is revisited.
+
+This CI interface is quite different in the case that it tries to
+accomodate all other CI based devices, that fall into the other categories
+
+This means that this CI interface handles the EN50221 style tags in the
+Application layer only and no session management is taken care of by the
+application. The driver/hardware will take care of all that.
+
+This interface is purely an EN50221 interface exchanging APDU's. This
+means that no session management, link layer or a transport layer do
+exist in this case in the application to driver communication. It is
+as simple as that. The driver/hardware has to take care of that.
+
+
+With this High Level CI interface, the interface can be defined with the
+regular ioctls.
+
+All these ioctls are also valid for the High level CI interface
+
+#define CA_RESET          _IO('o', 128)
+#define CA_GET_CAP        _IOR('o', 129, ca_caps_t)
+#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t)
+#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t)
+#define CA_GET_MSG        _IOR('o', 132, ca_msg_t)
+#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t)
+#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t)
+#define CA_SET_PID        _IOW('o', 135, ca_pid_t)
+
+
+On querying the device, the device yields information thus
+
+CA_GET_SLOT_INFO
+----------------------------
+Command = [info]
+APP: Number=[1]
+APP: Type=[1]
+APP: flags=[1]
+APP: CI High level interface
+APP: CA/CI Module Present
+
+CA_GET_CAP
+----------------------------
+Command = [caps]
+APP: Slots=[1]
+APP: Type=[1]
+APP: Descrambler keys=[16]
+APP: Type=[1]
+
+CA_SEND_MSG
+----------------------------
+Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1]
+Found CA descriptor @ program level
+
+(20) ES type=[2] ES pid=[201]  ES length =[0 (0x0)]
+(25) ES type=[4] ES pid=[301]  ES length =[0 (0x0)]
+ca_message length is 25 (0x19) bytes
+EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00]
+
+
+Not all ioctl's are implemented in the driver from the API, the other
+features of the hardware that cannot be implemented by the API are achieved
+using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is
+used to exchange the data to maintain compatibility with other hardware.
+
+
+/* a message to/from a CI-CAM */
+typedef struct ca_msg {
+	unsigned int index;
+	unsigned int type;
+	unsigned int length;
+	unsigned char msg[256];
+} ca_msg_t;
+
+
+The flow of data can be described thus,
+
+
+
+
+
+	App (User)
+	-----
+	parse
+	  |
+	  |
+	  v
+	en50221 APDU (package)
+   --------------------------------------
+   |	  |				| High Level CI driver
+   |	  |				|
+   |	  v				|
+   |	en50221 APDU (unpackage)	|
+   |	  |				|
+   |	  |				|
+   |	  v				|
+   |	sanity checks			|
+   |	  |				|
+   |	  |				|
+   |	  v				|
+   |	do (H/W dep)			|
+   --------------------------------------
+	  |    Hardware
+	  |
+	  v
+
+
+
+
+The High Level CI interface uses the EN50221 DVB standard, following a
+standard ensures futureproofness.

+ 2 - 2
Documentation/dvb/get_dvb_firmware

@@ -107,7 +107,7 @@ sub tda10045 {
 sub tda10046 {
 sub tda10046 {
     my $sourcefile = "tt_budget_217g.zip";
     my $sourcefile = "tt_budget_217g.zip";
     my $url = "http://www.technotrend.de/new/217g/$sourcefile";
     my $url = "http://www.technotrend.de/new/217g/$sourcefile";
-    my $hash = "a25b579e37109af60f4a36c37893957c";
+    my $hash = "6a7e1e2f2644b162ff0502367553c72d";
     my $outfile = "dvb-fe-tda10046.fw";
     my $outfile = "dvb-fe-tda10046.fw";
     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
     my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
 
 
@@ -115,7 +115,7 @@ sub tda10046 {
 
 
     wgetfile($sourcefile, $url);
     wgetfile($sourcefile, $url);
     unzip($sourcefile, $tmpdir);
     unzip($sourcefile, $tmpdir);
-    extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24479, "$tmpdir/fwtmp");
+    extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp");
     verify("$tmpdir/fwtmp", $hash);
     verify("$tmpdir/fwtmp", $hash);
     copy("$tmpdir/fwtmp", $outfile);
     copy("$tmpdir/fwtmp", $outfile);
 
 

+ 20 - 0
Documentation/feature-removal-schedule.txt

@@ -63,3 +63,23 @@ Why:	Outside of Linux, the only implementations of anything even
 	people, who might be using implementations that I am not aware
 	people, who might be using implementations that I am not aware
 	of, to adjust to this upcoming change.
 	of, to adjust to this upcoming change.
 Who:	Paul E. McKenney <paulmck@us.ibm.com>
 Who:	Paul E. McKenney <paulmck@us.ibm.com>
+
+---------------------------
+
+What:	IEEE1394 Audio and Music Data Transmission Protocol driver,
+	Connection Management Procedures driver
+When:	November 2005
+Files:	drivers/ieee1394/{amdtp,cmp}*
+Why:	These are incomplete, have never worked, and are better implemented
+	in userland via raw1394 (see http://freebob.sourceforge.net/ for
+	example.)
+Who:	Jody McIntyre <scjody@steamballoon.com>
+
+---------------------------
+
+What:	raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN
+When:	November 2005
+Why:	Deprecated in favour of the new ioctl-based rawiso interface, which is
+	more efficient.  You should really be using libraw1394 for raw1394
+	access anyway.
+Who:	Jody McIntyre <scjody@steamballoon.com>

+ 2 - 4
Documentation/filesystems/sysfs-pci.txt

@@ -7,7 +7,6 @@ that support it.  For example, a given bus might look like this:
      |-- 0000:17:00.0
      |-- 0000:17:00.0
      |   |-- class
      |   |-- class
      |   |-- config
      |   |-- config
-     |   |-- detach_state
      |   |-- device
      |   |-- device
      |   |-- irq
      |   |-- irq
      |   |-- local_cpus
      |   |-- local_cpus
@@ -19,7 +18,7 @@ that support it.  For example, a given bus might look like this:
      |   |-- subsystem_device
      |   |-- subsystem_device
      |   |-- subsystem_vendor
      |   |-- subsystem_vendor
      |   `-- vendor
      |   `-- vendor
-     `-- detach_state
+     `-- ...
 
 
 The topmost element describes the PCI domain and bus number.  In this case,
 The topmost element describes the PCI domain and bus number.  In this case,
 the domain number is 0000 and the bus number is 17 (both values are in hex).
 the domain number is 0000 and the bus number is 17 (both values are in hex).
@@ -31,7 +30,6 @@ files, each with their own function.
        ----		   --------
        ----		   --------
        class		   PCI class (ascii, ro)
        class		   PCI class (ascii, ro)
        config		   PCI config space (binary, rw)
        config		   PCI config space (binary, rw)
-       detach_state	   connection status (bool, rw)
        device		   PCI device (ascii, ro)
        device		   PCI device (ascii, ro)
        irq		   IRQ number (ascii, ro)
        irq		   IRQ number (ascii, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
        local_cpus	   nearby CPU mask (cpumask, ro)
@@ -85,4 +83,4 @@ useful return codes should be provided.
 
 
 Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
 Legacy resources are protected by the HAVE_PCI_LEGACY define.  Platforms
 wishing to support legacy functionality should define it and provide
 wishing to support legacy functionality should define it and provide
-pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.
+pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions.

+ 0 - 21
Documentation/power/devices.txt

@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event
 #READY_AFTER_RESUME
 #READY_AFTER_RESUME
 #
 #
 
 
-Driver Detach Power Management
-
-The kernel now supports the ability to place a device in a low-power
-state when it is detached from its driver, which happens when its
-module is removed. 
-
-Each device contains a 'detach_state' file in its sysfs directory
-which can be used to control this state. Reading from this file
-displays what the current detach state is set to. This is 0 (On) by
-default. A user may write a positive integer value to this file in the
-range of 1-4 inclusive. 
-
-A value of 1-3 will indicate the device should be placed in that
-low-power state, which will cause ->suspend() to be called for that
-device. A value of 4 indicates that the device should be shutdown, so
-->shutdown() will be called for that device. 
-
-The driver is responsible for reinitializing the device when the
-module is re-inserted during it's ->probe() (or equivalent) method. 
-The driver core will not call any extra functions when binding the
-device to the driver. 
 
 
 pm_message_t meaning
 pm_message_t meaning
 
 

+ 2 - 2
Documentation/powerpc/hvcs.txt

@@ -347,8 +347,8 @@ address that is created by firmware.  An example vty-server sysfs entry
 looks like the following:
 looks like the following:
 
 
 	Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
 	Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls
-	.   current_vty   devspec  name          partner_vtys
-	..  detach_state  index    partner_clcs  vterm_state
+	.   current_vty   devspec       name          partner_vtys
+	..  index         partner_clcs  vterm_state
 
 
 Each entry is provided, by default with a "name" attribute.  Reading the
 Each entry is provided, by default with a "name" attribute.  Reading the
 "name" attribute will reveal the device type as shown in the following
 "name" attribute will reveal the device type as shown in the following

+ 3 - 0
Documentation/x86_64/boot-options.txt

@@ -25,6 +25,9 @@ APICs
 
 
    noapictimer	 Don't set up the APIC timer
    noapictimer	 Don't set up the APIC timer
 
 
+   no_timer_check Don't check the IO-APIC timer. This can work around
+		 problems with incorrect timer initialization on some boards.
+
 Early Console
 Early Console
 
 
    syntax: earlyprintk=vga
    syntax: earlyprintk=vga

+ 8 - 2
MAINTAINERS

@@ -239,6 +239,12 @@ L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.linux-usb.org/SpeedTouch/
 W:	http://www.linux-usb.org/SpeedTouch/
 S:	Maintained
 S:	Maintained
 
 
+ALI1563 I2C DRIVER
+P:	Rudolf Marek
+M:	r.marek@sh.cvut.cz
+L:	sensors@stimpy.netroedge.com
+S:	Maintained
+
 ALPHA PORT
 ALPHA PORT
 P:	Richard Henderson
 P:	Richard Henderson
 M:	rth@twiddle.net
 M:	rth@twiddle.net
@@ -1023,8 +1029,8 @@ W:	http://www.ia64-linux.org/
 S:	Maintained
 S:	Maintained
 
 
 SN-IA64 (Itanium) SUB-PLATFORM
 SN-IA64 (Itanium) SUB-PLATFORM
-P:	Jesse Barnes
-M:	jbarnes@sgi.com
+P:	Greg Edwards
+M:	edwardsg@sgi.com
 L:	linux-altix@sgi.com
 L:	linux-altix@sgi.com
 L:	linux-ia64@vger.kernel.org
 L:	linux-ia64@vger.kernel.org
 W:	http://www.sgi.com/altix
 W:	http://www.sgi.com/altix

+ 2 - 2
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 12
 SUBLEVEL = 12
-EXTRAVERSION =-rc4
+EXTRAVERSION =-rc5
 NAME=Woozy Numbat
 NAME=Woozy Numbat
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*
@@ -530,7 +530,7 @@ endif
 include $(srctree)/arch/$(ARCH)/Makefile
 include $(srctree)/arch/$(ARCH)/Makefile
 
 
 # arch Makefile may override CC so keep this after arch Makefile is included
 # arch Makefile may override CC so keep this after arch Makefile is included
-NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
 CHECKFLAGS     += $(NOSTDINC_FLAGS)
 CHECKFLAGS     += $(NOSTDINC_FLAGS)
 
 
 # warn about C99 declaration after statement
 # warn about C99 declaration after statement

+ 2 - 5
arch/alpha/kernel/osf_sys.c

@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai
 	if (get_tv32(&tmp, sleep))
 	if (get_tv32(&tmp, sleep))
 		goto fault;
 		goto fault;
 
 
-	ticks = tmp.tv_usec;
-	ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ);
-	ticks += tmp.tv_sec * HZ;
+	ticks = timeval_to_jiffies(&tmp);
 
 
 	current->state = TASK_INTERRUPTIBLE;
 	current->state = TASK_INTERRUPTIBLE;
 	ticks = schedule_timeout(ticks);
 	ticks = schedule_timeout(ticks);
 
 
 	if (remain) {
 	if (remain) {
-		tmp.tv_sec = ticks / HZ;
-		tmp.tv_usec = ticks % HZ;
+		jiffies_to_timeval(ticks, &tmp);
 		if (put_tv32(remain, &tmp))
 		if (put_tv32(remain, &tmp))
 			goto fault;
 			goto fault;
 	}
 	}

+ 1 - 1
arch/arm/mach-s3c2410/clock.c

@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev)
 {
 {
 	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
 	unsigned long upllcon = __raw_readl(S3C2410_UPLLCON);
 
 
-	s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2;
+	s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate);
 
 
 	printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
 	printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n",
 	       print_mhz(s3c2440_clk_upll.rate));
 	       print_mhz(s3c2440_clk_upll.rate));

+ 4 - 2
arch/arm/mach-s3c2410/s3c2440.c

@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size)
 
 
 	iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
 	iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc));
 	iotable_init(mach_desc, size);
 	iotable_init(mach_desc, size);
+
 	/* rename any peripherals used differing from the s3c2410 */
 	/* rename any peripherals used differing from the s3c2410 */
 
 
-	s3c_device_i2c.name = "s3c2440-i2c";
+	s3c_device_i2c.name  = "s3c2440-i2c";
+	s3c_device_nand.name = "s3c2440-nand";
 
 
 	/* change irq for watchdog */
 	/* change irq for watchdog */
 
 
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal)
 		break;
 		break;
 
 
 	case S3C2440_CLKDIVN_HDIVN_2:
 	case S3C2440_CLKDIVN_HDIVN_2:
-		hdiv = 1;
+		hdiv = 2;
 		break;
 		break;
 
 
 	case S3C2440_CLKDIVN_HDIVN_4_8:
 	case S3C2440_CLKDIVN_HDIVN_4_8:

+ 10 - 11
arch/arm/mm/Kconfig

@@ -412,21 +412,20 @@ config CPU_BPREDICT_DISABLE
 
 
 config TLS_REG_EMUL
 config TLS_REG_EMUL
 	bool
 	bool
-	default y if (SMP || CPU_32v6) && (CPU_32v5 || CPU_32v4 || CPU_32v3)
+	default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3)
 	help
 	help
-	  We might be running on an ARMv6+ processor which should have the TLS
-	  register but for some reason we can't use it, or maybe an SMP system
-	  using a pre-ARMv6 processor (there are apparently a few prototypes
-	  like that in existence) and therefore access to that register must
-	  be emulated.
+	  An SMP system using a pre-ARMv6 processor (there are apparently
+	  a few prototypes like that in existence) and therefore access to
+	  that required register must be emulated.
 
 
 config HAS_TLS_REG
 config HAS_TLS_REG
 	bool
 	bool
-	depends on CPU_32v6
-	default y if !TLS_REG_EMUL
+	depends on !TLS_REG_EMUL
+	default y if SMP || CPU_32v7
 	help
 	help
 	  This selects support for the CP15 thread register.
 	  This selects support for the CP15 thread register.
-	  It is defined to be available on ARMv6 or later.  If a particular
-	  ARMv6 or later CPU doesn't support it then it must omc;ide "select
-	  TLS_REG_EMUL" along with its other caracteristics.
+	  It is defined to be available on some ARMv6 processors (including
+	  all SMP capable ARMv6's) or later processors.  User space may
+	  assume directly accessing that register and always obtain the
+	  expected value only on ARMv7 and above.
 
 

+ 0 - 80
arch/arm/mm/copypage-v4mc.S

@@ -1,80 +0,0 @@
-/*
- *  linux/arch/arm/lib/copy_page-armv4mc.S
- *
- *  Copyright (C) 1995-2001 Russell King
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- *  ASM optimised string functions
- */
-#include <linux/linkage.h>
-#include <linux/init.h>
-#include <asm/constants.h>
-
-	.text
-	.align	5
-/*
- * ARMv4 mini-dcache optimised copy_user_page
- *
- * We flush the destination cache lines just before we write the data into the
- * corresponding address.  Since the Dcache is read-allocate, this removes the
- * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
- * and merged as appropriate.
- *
- * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
- * instruction.  If your processor does not supply this, you have to write your
- * own copy_user_page that does the right thing.
- */
-ENTRY(v4_mc_copy_user_page)
-	stmfd	sp!, {r4, lr}			@ 2
-	mov	r4, r0
-	mov	r0, r1
-	bl	map_page_minicache
-	mov	r1, #PAGE_SZ/64			@ 1
-	ldmia	r0!, {r2, r3, ip, lr}		@ 4
-1:	mcr	p15, 0, r4, c7, c6, 1		@ 1   invalidate D line
-	stmia	r4!, {r2, r3, ip, lr}		@ 4
-	ldmia	r0!, {r2, r3, ip, lr}		@ 4+1
-	stmia	r4!, {r2, r3, ip, lr}		@ 4
-	ldmia	r0!, {r2, r3, ip, lr}		@ 4
-	mcr	p15, 0, r4, c7, c6, 1		@ 1   invalidate D line
-	stmia	r4!, {r2, r3, ip, lr}		@ 4
-	ldmia	r0!, {r2, r3, ip, lr}		@ 4
-	subs	r1, r1, #1			@ 1
-	stmia	r4!, {r2, r3, ip, lr}		@ 4
-	ldmneia	r0!, {r2, r3, ip, lr}		@ 4
-	bne	1b				@ 1
-	ldmfd	sp!, {r4, pc}			@ 3
-
-	.align	5
-/*
- * ARMv4 optimised clear_user_page
- *
- * Same story as above.
- */
-ENTRY(v4_mc_clear_user_page)
-	str	lr, [sp, #-4]!
-	mov	r1, #PAGE_SZ/64			@ 1
-	mov	r2, #0				@ 1
-	mov	r3, #0				@ 1
-	mov	ip, #0				@ 1
-	mov	lr, #0				@ 1
-1:	mcr	p15, 0, r0, c7, c6, 1		@ 1   invalidate D line
-	stmia	r0!, {r2, r3, ip, lr}		@ 4
-	stmia	r0!, {r2, r3, ip, lr}		@ 4
-	mcr	p15, 0, r0, c7, c6, 1		@ 1   invalidate D line
-	stmia	r0!, {r2, r3, ip, lr}		@ 4
-	stmia	r0!, {r2, r3, ip, lr}		@ 4
-	subs	r1, r1, #1			@ 1
-	bne	1b				@ 1
-	ldr	pc, [sp], #4
-
-	__INITDATA
-
-	.type	v4_mc_user_fns, #object
-ENTRY(v4_mc_user_fns)
-	.long	v4_mc_clear_user_page
-	.long	v4_mc_copy_user_page
-	.size	v4_mc_user_fns, . - v4_mc_user_fns

+ 111 - 0
arch/arm/mm/copypage-v4mc.c

@@ -0,0 +1,111 @@
+/*
+ *  linux/arch/arm/lib/copypage-armv4mc.S
+ *
+ *  Copyright (C) 1995-2005 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This handles the mini data cache, as found on SA11x0 and XScale
+ * processors.  When we copy a user page page, we map it in such a way
+ * that accesses to this page will not touch the main data cache, but
+ * will be cached in the mini data cache.  This prevents us thrashing
+ * the main data cache on page faults.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/tlbflush.h>
+
+/*
+ * 0xffff8000 to 0xffffffff is reserved for any ARM architecture
+ * specific hacks for copying pages efficiently.
+ */
+#define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \
+				  L_PTE_CACHEABLE)
+
+#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+
+static DEFINE_SPINLOCK(minicache_lock);
+
+/*
+ * ARMv4 mini-dcache optimised copy_user_page
+ *
+ * We flush the destination cache lines just before we write the data into the
+ * corresponding address.  Since the Dcache is read-allocate, this removes the
+ * Dcache aliasing issue.  The writes will be forwarded to the write buffer,
+ * and merged as appropriate.
+ *
+ * Note: We rely on all ARMv4 processors implementing the "invalidate D line"
+ * instruction.  If your processor does not supply this, you have to write your
+ * own copy_user_page that does the right thing.
+ */
+static void __attribute__((naked))
+mc_copy_user_page(void *from, void *to)
+{
+	asm volatile(
+	"stmfd	sp!, {r4, lr}			@ 2\n\
+	mov	r4, %2				@ 1\n\
+	ldmia	%0!, {r2, r3, ip, lr}		@ 4\n\
+1:	mcr	p15, 0, %1, c7, c6, 1		@ 1   invalidate D line\n\
+	stmia	%1!, {r2, r3, ip, lr}		@ 4\n\
+	ldmia	%0!, {r2, r3, ip, lr}		@ 4+1\n\
+	stmia	%1!, {r2, r3, ip, lr}		@ 4\n\
+	ldmia	%0!, {r2, r3, ip, lr}		@ 4\n\
+	mcr	p15, 0, %1, c7, c6, 1		@ 1   invalidate D line\n\
+	stmia	%1!, {r2, r3, ip, lr}		@ 4\n\
+	ldmia	%0!, {r2, r3, ip, lr}		@ 4\n\
+	subs	r4, r4, #1			@ 1\n\
+	stmia	%1!, {r2, r3, ip, lr}		@ 4\n\
+	ldmneia	%0!, {r2, r3, ip, lr}		@ 4\n\
+	bne	1b				@ 1\n\
+	ldmfd	sp!, {r4, pc}			@ 3"
+	:
+	: "r" (from), "r" (to), "I" (PAGE_SIZE / 64));
+}
+
+void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr)
+{
+	spin_lock(&minicache_lock);
+
+	set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot));
+	flush_tlb_kernel_page(0xffff8000);
+
+	mc_copy_user_page((void *)0xffff8000, kto);
+
+	spin_unlock(&minicache_lock);
+}
+
+/*
+ * ARMv4 optimised clear_user_page
+ */
+void __attribute__((naked))
+v4_mc_clear_user_page(void *kaddr, unsigned long vaddr)
+{
+	asm volatile(
+	"str	lr, [sp, #-4]!\n\
+	mov	r1, %0				@ 1\n\
+	mov	r2, #0				@ 1\n\
+	mov	r3, #0				@ 1\n\
+	mov	ip, #0				@ 1\n\
+	mov	lr, #0				@ 1\n\
+1:	mcr	p15, 0, r0, c7, c6, 1		@ 1   invalidate D line\n\
+	stmia	r0!, {r2, r3, ip, lr}		@ 4\n\
+	stmia	r0!, {r2, r3, ip, lr}		@ 4\n\
+	mcr	p15, 0, r0, c7, c6, 1		@ 1   invalidate D line\n\
+	stmia	r0!, {r2, r3, ip, lr}		@ 4\n\
+	stmia	r0!, {r2, r3, ip, lr}		@ 4\n\
+	subs	r1, r1, #1			@ 1\n\
+	bne	1b				@ 1\n\
+	ldr	pc, [sp], #4"
+	:
+	: "I" (PAGE_SIZE / 64));
+}
+
+struct cpu_user_fns v4_mc_user_fns __initdata = {
+	.cpu_clear_user_page	= v4_mc_clear_user_page, 
+	.cpu_copy_user_page	= v4_mc_copy_user_page,
+};

+ 6 - 22
arch/arm/mm/copypage-v6.c

@@ -26,8 +26,8 @@
 #define to_address	(0xffffc000)
 #define to_address	(0xffffc000)
 #define to_pgprot	PAGE_KERNEL
 #define to_pgprot	PAGE_KERNEL
 
 
-static pte_t *from_pte;
-static pte_t *to_pte;
+#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+
 static DEFINE_SPINLOCK(v6_lock);
 static DEFINE_SPINLOCK(v6_lock);
 
 
 #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
 #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT)
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd
 	 */
 	 */
 	spin_lock(&v6_lock);
 	spin_lock(&v6_lock);
 
 
-	set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
-	set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
+	set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot));
+	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot));
 
 
 	from = from_address + (offset << PAGE_SHIFT);
 	from = from_address + (offset << PAGE_SHIFT);
 	to   = to_address + (offset << PAGE_SHIFT);
 	to   = to_address + (offset << PAGE_SHIFT);
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr)
 	 */
 	 */
 	spin_lock(&v6_lock);
 	spin_lock(&v6_lock);
 
 
-	set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
+	set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot));
 	flush_tlb_kernel_page(to);
 	flush_tlb_kernel_page(to);
 	clear_page((void *)to);
 	clear_page((void *)to);
 
 
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = {
 static int __init v6_userpage_init(void)
 static int __init v6_userpage_init(void)
 {
 {
 	if (cache_is_vipt_aliasing()) {
 	if (cache_is_vipt_aliasing()) {
-		pgd_t *pgd;
-		pmd_t *pmd;
-
-		pgd = pgd_offset_k(from_address);
-		pmd = pmd_alloc(&init_mm, pgd, from_address);
-		if (!pmd)
-			BUG();
-		from_pte = pte_alloc_kernel(&init_mm, pmd, from_address);
-		if (!from_pte)
-			BUG();
-
-		to_pte = pte_alloc_kernel(&init_mm, pmd, to_address);
-		if (!to_pte)
-			BUG();
-
 		cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
 		cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing;
 		cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
 		cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing;
 	}
 	}
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-__initcall(v6_userpage_init);
-
+core_initcall(v6_userpage_init);

+ 35 - 2
arch/arm/mm/flush.c

@@ -13,6 +13,29 @@
 
 
 #include <asm/cacheflush.h>
 #include <asm/cacheflush.h>
 #include <asm/system.h>
 #include <asm/system.h>
+#include <asm/tlbflush.h>
+
+#ifdef CONFIG_CPU_CACHE_VIPT
+#define ALIAS_FLUSH_START	0xffff4000
+
+#define TOP_PTE(x)	pte_offset_kernel(top_pmd, x)
+
+static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
+{
+	unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
+
+	set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL));
+	flush_tlb_kernel_page(to);
+
+	asm(	"mcrr	p15, 0, %1, %0, c14\n"
+	"	mcrr	p15, 0, %1, %0, c5\n"
+	    :
+	    : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES)
+	    : "cc");
+}
+#else
+#define flush_pfn_alias(pfn,vaddr)	do { } while (0)
+#endif
 
 
 static void __flush_dcache_page(struct address_space *mapping, struct page *page)
 static void __flush_dcache_page(struct address_space *mapping, struct page *page)
 {
 {
@@ -36,6 +59,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
 	if (!mapping)
 	if (!mapping)
 		return;
 		return;
 
 
+	/*
+	 * This is a page cache page.  If we have a VIPT cache, we
+	 * only need to do one flush - which would be at the relevant
+	 * userspace colour, which is congruent with page->index.
+	 */
+	if (cache_is_vipt()) {
+		if (cache_is_vipt_aliasing())
+			flush_pfn_alias(page_to_pfn(page),
+					page->index << PAGE_CACHE_SHIFT);
+		return;
+	}
+
 	/*
 	/*
 	 * There are possible user space mappings of this page:
 	 * There are possible user space mappings of this page:
 	 * - VIVT cache: we need to also write back and invalidate all user
 	 * - VIVT cache: we need to also write back and invalidate all user
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page
 			continue;
 			continue;
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
 		offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT;
 		flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
 		flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page));
-		if (cache_is_vipt())
-			break;
 	}
 	}
 	flush_dcache_mmap_unlock(mapping);
 	flush_dcache_mmap_unlock(mapping);
 }
 }

+ 19 - 8
arch/arm/mm/mm-armv.c

@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel;
 
 
 EXPORT_SYMBOL(pgprot_kernel);
 EXPORT_SYMBOL(pgprot_kernel);
 
 
+pmd_t *top_pmd;
+
 struct cachepolicy {
 struct cachepolicy {
 	const char	policy[16];
 	const char	policy[16];
 	unsigned int	cr_mask;
 	unsigned int	cr_mask;
@@ -142,6 +144,16 @@ __setup("noalign", noalign_setup);
 
 
 #define FIRST_KERNEL_PGD_NR	(FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
 #define FIRST_KERNEL_PGD_NR	(FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
 
 
+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt)
+{
+	return pmd_offset(pgd, virt);
+}
+
+static inline pmd_t *pmd_off_k(unsigned long virt)
+{
+	return pmd_off(pgd_offset_k(virt), virt);
+}
+
 /*
 /*
  * need to get a 16k page for level 1
  * need to get a 16k page for level 1
  */
  */
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd)
 		return;
 		return;
 
 
 	/* pgd is always present and good */
 	/* pgd is always present and good */
-	pmd = (pmd_t *)pgd;
+	pmd = pmd_off(pgd, 0);
 	if (pmd_none(*pmd))
 	if (pmd_none(*pmd))
 		goto free;
 		goto free;
 	if (pmd_bad(*pmd)) {
 	if (pmd_bad(*pmd)) {
@@ -246,9 +258,8 @@ free:
 static inline void
 static inline void
 alloc_init_section(unsigned long virt, unsigned long phys, int prot)
 alloc_init_section(unsigned long virt, unsigned long phys, int prot)
 {
 {
-	pmd_t *pmdp;
+	pmd_t *pmdp = pmd_off_k(virt);
 
 
-	pmdp = pmd_offset(pgd_offset_k(virt), virt);
 	if (virt & (1 << 20))
 	if (virt & (1 << 20))
 		pmdp++;
 		pmdp++;
 
 
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot)
 static inline void
 static inline void
 alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
 alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot)
 {
 {
-	pmd_t *pmdp;
+	pmd_t *pmdp = pmd_off_k(virt);
 	pte_t *ptep;
 	pte_t *ptep;
 
 
-	pmdp = pmd_offset(pgd_offset_k(virt), virt);
-
 	if (pmd_none(*pmdp)) {
 	if (pmd_none(*pmdp)) {
 		unsigned long pmdval;
 		unsigned long pmdval;
 		ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
 		ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg
  */
  */
 static inline void clear_mapping(unsigned long virt)
 static inline void clear_mapping(unsigned long virt)
 {
 {
-	pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
+	pmd_clear(pmd_off_k(virt));
 }
 }
 
 
 struct mem_types {
 struct mem_types {
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode)
 			 PMD_TYPE_SECT;
 			 PMD_TYPE_SECT;
 		if (cpu_arch <= CPU_ARCH_ARMv5)
 		if (cpu_arch <= CPU_ARCH_ARMv5)
 			pmdval |= PMD_BIT4;
 			pmdval |= PMD_BIT4;
-		pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT);
+		pmd = pmd_off(pgd, i << PGDIR_SHIFT);
 		pmd[0] = __pmd(pmdval);
 		pmd[0] = __pmd(pmdval);
 		pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
 		pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
 		flush_pmd_entry(pmd);
 		flush_pmd_entry(pmd);
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi)
 
 
 	flush_cache_all();
 	flush_cache_all();
 	flush_tlb_all();
 	flush_tlb_all();
+
+	top_pmd = pmd_off_k(0xffff0000);
 }
 }
 
 
 /*
 /*

+ 1 - 1
arch/h8300/kernel/process.c

@@ -54,7 +54,7 @@ asmlinkage void ret_from_fork(void);
 void default_idle(void)
 void default_idle(void)
 {
 {
 	while(1) {
 	while(1) {
-		if (need_resched()) {
+		if (!need_resched()) {
 			local_irq_enable();
 			local_irq_enable();
 			__asm__("sleep");
 			__asm__("sleep");
 			local_irq_disable();
 			local_irq_disable();

+ 1 - 1
arch/i386/Kconfig

@@ -1163,7 +1163,7 @@ config PCI_DIRECT
 
 
 config PCI_MMCONFIG
 config PCI_MMCONFIG
 	bool
 	bool
-	depends on PCI && (PCI_GOMMCONFIG || (PCI_GOANY && ACPI))
+	depends on PCI && ACPI && (PCI_GOMMCONFIG || PCI_GOANY)
 	select ACPI_BOOT
 	select ACPI_BOOT
 	default y
 	default y
 
 

+ 7 - 5
arch/i386/kernel/cpu/amd.c

@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret");
 
 
 static void __init init_amd(struct cpuinfo_x86 *c)
 static void __init init_amd(struct cpuinfo_x86 *c)
 {
 {
-#ifdef CONFIG_X86_SMP
-	int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
-#endif
 	u32 l, h;
 	u32 l, h;
 	int mbytes = num_physpages >> (20-PAGE_SHIFT);
 	int mbytes = num_physpages >> (20-PAGE_SHIFT);
 	int r;
 	int r;
@@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c)
 			c->x86_num_cores = 1;
 			c->x86_num_cores = 1;
 	}
 	}
 
 
-#ifdef CONFIG_X86_SMP
+#ifdef CONFIG_X86_HT
 	/*
 	/*
 	 * On a AMD dual core setup the lower bits of the APIC id
 	 * On a AMD dual core setup the lower bits of the APIC id
 	 * distingush the cores.  Assumes number of cores is a power
 	 * distingush the cores.  Assumes number of cores is a power
 	 * of two.
 	 * of two.
 	 */
 	 */
 	if (c->x86_num_cores > 1) {
 	if (c->x86_num_cores > 1) {
-		cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+		int cpu = smp_processor_id();
+		unsigned bits = 0;
+		while ((1 << bits) < c->x86_num_cores)
+			bits++;
+		cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
+		phys_proc_id[cpu] >>= bits;
 		printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
 		printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
 		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
 		       cpu, c->x86_num_cores, cpu_core_id[cpu]);
 	}
 	}

+ 4 - 0
arch/i386/kernel/cpu/common.c

@@ -243,6 +243,10 @@ static void __init early_cpu_detect(void)
 	}
 	}
 
 
 	early_intel_workaround(c);
 	early_intel_workaround(c);
+
+#ifdef CONFIG_X86_HT
+	phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;
+#endif
 }
 }
 
 
 void __init generic_identify(struct cpuinfo_x86 * c)
 void __init generic_identify(struct cpuinfo_x86 * c)

+ 13 - 1
arch/i386/kernel/cpu/cpufreq/Kconfig

@@ -23,7 +23,7 @@ config X86_ACPI_CPUFREQ
 	  If in doubt, say N.
 	  If in doubt, say N.
 
 
 config ELAN_CPUFREQ
 config ELAN_CPUFREQ
-	tristate "AMD Elan"
+	tristate "AMD Elan SC400 and SC410"
 	select CPU_FREQ_TABLE
 	select CPU_FREQ_TABLE
 	depends on X86_ELAN
 	depends on X86_ELAN
 	---help---
 	---help---
@@ -38,6 +38,18 @@ config ELAN_CPUFREQ
 
 
 	  If in doubt, say N.
 	  If in doubt, say N.
 
 
+config SC520_CPUFREQ
+	tristate "AMD Elan SC520"
+	select CPU_FREQ_TABLE
+	depends on X86_ELAN
+	---help---
+	  This adds the CPUFreq driver for AMD Elan SC520 processor.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
+
 config X86_POWERNOW_K6
 config X86_POWERNOW_K6
 	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
 	tristate "AMD Mobile K6-2/K6-3 PowerNow!"
 	select CPU_FREQ_TABLE
 	select CPU_FREQ_TABLE

+ 1 - 0
arch/i386/kernel/cpu/cpufreq/Makefile

@@ -3,6 +3,7 @@ obj-$(CONFIG_X86_POWERNOW_K7)		+= powernow-k7.o
 obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o
 obj-$(CONFIG_X86_POWERNOW_K8)		+= powernow-k8.o
 obj-$(CONFIG_X86_LONGHAUL)		+= longhaul.o
 obj-$(CONFIG_X86_LONGHAUL)		+= longhaul.o
 obj-$(CONFIG_ELAN_CPUFREQ)		+= elanfreq.o
 obj-$(CONFIG_ELAN_CPUFREQ)		+= elanfreq.o
+obj-$(CONFIG_SC520_CPUFREQ)		+= sc520_freq.o
 obj-$(CONFIG_X86_LONGRUN)		+= longrun.o  
 obj-$(CONFIG_X86_LONGRUN)		+= longrun.o  
 obj-$(CONFIG_X86_GX_SUSPMOD)		+= gx-suspmod.o
 obj-$(CONFIG_X86_GX_SUSPMOD)		+= gx-suspmod.o
 obj-$(CONFIG_X86_SPEEDSTEP_ICH)		+= speedstep-ich.o
 obj-$(CONFIG_X86_SPEEDSTEP_ICH)		+= speedstep-ich.o

+ 53 - 5
arch/i386/kernel/cpu/cpufreq/longhaul.c

@@ -29,6 +29,7 @@
 #include <linux/cpufreq.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string.h>
+#include <linux/pci.h>
 
 
 #include <asm/msr.h>
 #include <asm/msr.h>
 #include <asm/timex.h>
 #include <asm/timex.h>
@@ -119,7 +120,13 @@ static int longhaul_get_cpu_mult(void)
 static void do_powersaver(union msr_longhaul *longhaul,
 static void do_powersaver(union msr_longhaul *longhaul,
 			unsigned int clock_ratio_index)
 			unsigned int clock_ratio_index)
 {
 {
+	struct pci_dev *dev;
+	unsigned long flags;
+	unsigned int tmp_mask;
 	int version;
 	int version;
+	int i;
+	u16 pci_cmd;
+	u16 cmd_state[64];
 
 
 	switch (cpu_model) {
 	switch (cpu_model) {
 	case CPU_EZRA_T:
 	case CPU_EZRA_T:
@@ -137,17 +144,58 @@ static void do_powersaver(union msr_longhaul *longhaul,
 	longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
 	longhaul->bits.SoftBusRatio4 = (clock_ratio_index & 0x10) >> 4;
 	longhaul->bits.EnableSoftBusRatio = 1;
 	longhaul->bits.EnableSoftBusRatio = 1;
 	longhaul->bits.RevisionKey = 0;
 	longhaul->bits.RevisionKey = 0;
-	local_irq_disable();
-	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
+
+	preempt_disable();
+	local_irq_save(flags);
+
+	/*
+	 * get current pci bus master state for all devices
+	 * and clear bus master bit
+	 */
+	dev = NULL;
+	i = 0;
+	do {
+		dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+		if (dev != NULL) {
+			pci_read_config_word(dev, PCI_COMMAND, &pci_cmd);
+			cmd_state[i++] = pci_cmd;
+			pci_cmd &= ~PCI_COMMAND_MASTER;
+			pci_write_config_word(dev, PCI_COMMAND, pci_cmd);
+		}
+	} while (dev != NULL);
+
+	tmp_mask=inb(0x21);	/* works on C3. save mask. */
+	outb(0xFE,0x21);	/* TMR0 only */
+	outb(0xFF,0x80);	/* delay */
+
 	local_irq_enable();
 	local_irq_enable();
+
+	__hlt();
+	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
 	__hlt();
 	__hlt();
 
 
+	local_irq_disable();
+
+	outb(tmp_mask,0x21);	/* restore mask */
+
+	/* restore pci bus master state for all devices */
+	dev = NULL;
+	i = 0;
+	do {
+		dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev);
+		if (dev != NULL) {
+			pci_cmd = cmd_state[i++];
+			pci_write_config_byte(dev, PCI_COMMAND, pci_cmd);
+		}
+	} while (dev != NULL);
+	local_irq_restore(flags);
+	preempt_enable();
+
+	/* disable bus ratio bit */
 	rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
 	rdmsrl(MSR_VIA_LONGHAUL, longhaul->val);
 	longhaul->bits.EnableSoftBusRatio = 0;
 	longhaul->bits.EnableSoftBusRatio = 0;
 	longhaul->bits.RevisionKey = version;
 	longhaul->bits.RevisionKey = version;
-	local_irq_disable();
 	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
 	wrmsrl(MSR_VIA_LONGHAUL, longhaul->val);
-	local_irq_enable();
 }
 }
 
 
 /**
 /**
@@ -578,7 +626,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy)
 		longhaul_setup_voltagescaling();
 		longhaul_setup_voltagescaling();
 
 
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
 	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+	policy->cpuinfo.transition_latency = 200000;	/* nsec */
 	policy->cur = calc_speed(longhaul_get_cpu_mult());
 	policy->cur = calc_speed(longhaul_get_cpu_mult());
 
 
 	ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);
 	ret = cpufreq_frequency_table_cpuinfo(policy, longhaul_table);

+ 8 - 3
arch/i386/kernel/cpu/cpufreq/powernow-k7.c

@@ -23,6 +23,7 @@
 #include <linux/dmi.h>
 #include <linux/dmi.h>
 
 
 #include <asm/msr.h>
 #include <asm/msr.h>
+#include <asm/timer.h>
 #include <asm/timex.h>
 #include <asm/timex.h>
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <asm/system.h>
@@ -586,13 +587,17 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
 
 
 	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 	rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
 
 
-	/* A K7 with powernow technology is set to max frequency by BIOS */
-	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.MFID];
+	/* recalibrate cpu_khz */
+	result = recalibrate_cpu_khz();
+	if (result)
+		return result;
+
+	fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
 	if (!fsb) {
 	if (!fsb) {
 		printk(KERN_WARNING PFX "can not determine bus frequency\n");
 		printk(KERN_WARNING PFX "can not determine bus frequency\n");
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
-	dprintk("FSB: %3d.%03d MHz\n", fsb/1000, fsb%1000);
+	dprintk("FSB: %3dMHz\n", fsb/1000);
 
 
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 	if (dmi_check_system(powernow_dmi_table) || acpi_force) {
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");
 		printk (KERN_INFO PFX "PSB/PST known to be broken.  Trying ACPI instead\n");

+ 76 - 37
arch/i386/kernel/cpu/cpufreq/powernow-k8.c

@@ -4,7 +4,7 @@
  *  GNU general public license version 2. See "COPYING" or
  *  GNU general public license version 2. See "COPYING" or
  *  http://www.gnu.org/licenses/gpl.html
  *  http://www.gnu.org/licenses/gpl.html
  *
  *
- *  Support : paul.devriendt@amd.com
+ *  Support : mark.langsdorf@amd.com
  *
  *
  *  Based on the powernow-k7.c module written by Dave Jones.
  *  Based on the powernow-k7.c module written by Dave Jones.
  *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
  *  (C) 2003 Dave Jones <davej@codemonkey.org.uk> on behalf of SuSE Labs
@@ -15,12 +15,13 @@
  *
  *
  *  Valuable input gratefully received from Dave Jones, Pavel Machek,
  *  Valuable input gratefully received from Dave Jones, Pavel Machek,
  *  Dominik Brodowski, and others.
  *  Dominik Brodowski, and others.
+ *  Originally developed by Paul Devriendt.
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  Processor information obtained from Chapter 9 (Power and Thermal Management)
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
  *  Opteron Processors" available for download from www.amd.com
  *  Opteron Processors" available for download from www.amd.com
  *
  *
  *  Tables for specific CPUs can be infrerred from
  *  Tables for specific CPUs can be infrerred from
- *	http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
+ *     http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
  */
  */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
@@ -30,6 +31,7 @@
 #include <linux/cpufreq.h>
 #include <linux/cpufreq.h>
 #include <linux/slab.h>
 #include <linux/slab.h>
 #include <linux/string.h>
 #include <linux/string.h>
+#include <linux/cpumask.h>
 
 
 #include <asm/msr.h>
 #include <asm/msr.h>
 #include <asm/io.h>
 #include <asm/io.h>
@@ -42,7 +44,7 @@
 
 
 #define PFX "powernow-k8: "
 #define PFX "powernow-k8: "
 #define BFX PFX "BIOS error: "
 #define BFX PFX "BIOS error: "
-#define VERSION "version 1.00.09e"
+#define VERSION "version 1.40.2"
 #include "powernow-k8.h"
 #include "powernow-k8.h"
 
 
 /* serialize freq changes  */
 /* serialize freq changes  */
@@ -50,6 +52,10 @@ static DECLARE_MUTEX(fidvid_sem);
 
 
 static struct powernow_k8_data *powernow_data[NR_CPUS];
 static struct powernow_k8_data *powernow_data[NR_CPUS];
 
 
+#ifndef CONFIG_SMP
+static cpumask_t cpu_core_map[1];
+#endif
+
 /* Return a frequency in MHz, given an input fid */
 /* Return a frequency in MHz, given an input fid */
 static u32 find_freq_from_fid(u32 fid)
 static u32 find_freq_from_fid(u32 fid)
 {
 {
@@ -274,11 +280,18 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
 {
 {
 	u32 rvosteps = data->rvo;
 	u32 rvosteps = data->rvo;
 	u32 savefid = data->currfid;
 	u32 savefid = data->currfid;
+	u32 maxvid, lo;
 
 
 	dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
 	dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n",
 		smp_processor_id(),
 		smp_processor_id(),
 		data->currfid, data->currvid, reqvid, data->rvo);
 		data->currfid, data->currvid, reqvid, data->rvo);
 
 
+	rdmsr(MSR_FIDVID_STATUS, lo, maxvid);
+	maxvid = 0x1f & (maxvid >> 16);
+	dprintk("ph1 maxvid=0x%x\n", maxvid);
+	if (reqvid < maxvid) /* lower numbers are higher voltages */
+		reqvid = maxvid;
+
 	while (data->currvid > reqvid) {
 	while (data->currvid > reqvid) {
 		dprintk("ph1: curr 0x%x, req vid 0x%x\n",
 		dprintk("ph1: curr 0x%x, req vid 0x%x\n",
 			data->currvid, reqvid);
 			data->currvid, reqvid);
@@ -286,8 +299,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid
 			return 1;
 			return 1;
 	}
 	}
 
 
-	while ((rvosteps > 0)  && ((data->rvo + data->currvid) > reqvid)) {
-		if (data->currvid == 0) {
+	while ((rvosteps > 0) && ((data->rvo + data->currvid) > reqvid)) {
+		if (data->currvid == maxvid) {
 			rvosteps = 0;
 			rvosteps = 0;
 		} else {
 		} else {
 			dprintk("ph1: changing vid for rvo, req 0x%x\n",
 			dprintk("ph1: changing vid for rvo, req 0x%x\n",
@@ -671,7 +684,7 @@ static int find_psb_table(struct powernow_k8_data *data)
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * BIOS and Kernel Developer's Guide, which is available on
 	 * www.amd.com
 	 * www.amd.com
 	 */
 	 */
-	printk(KERN_ERR PFX "BIOS error - no PSB\n");
+	printk(KERN_INFO PFX "BIOS error - no PSB or ACPI _PSS objects\n");
 	return -ENODEV;
 	return -ENODEV;
 }
 }
 
 
@@ -695,7 +708,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 	struct cpufreq_frequency_table *powernow_table;
 	struct cpufreq_frequency_table *powernow_table;
 
 
 	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
 	if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
-		dprintk("register performance failed\n");
+		dprintk("register performance failed: bad ACPI data\n");
 		return -EIO;
 		return -EIO;
 	}
 	}
 
 
@@ -746,22 +759,23 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
 			continue;
 			continue;
 		}
 		}
 
 
- 		if (fid < HI_FID_TABLE_BOTTOM) {
- 			if (cntlofreq) {
- 				/* if both entries are the same, ignore this
- 				 * one... 
- 				 */
- 				if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
- 				    (powernow_table[i].index != powernow_table[cntlofreq].index)) {
- 					printk(KERN_ERR PFX "Too many lo freq table entries\n");
- 					goto err_out_mem;
- 				}
-				
- 				dprintk("double low frequency table entry, ignoring it.\n");
- 				powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
- 				continue;
- 			} else
- 				cntlofreq = i;
+		/* verify only 1 entry from the lo frequency table */
+		if (fid < HI_FID_TABLE_BOTTOM) {
+			if (cntlofreq) {
+				/* if both entries are the same, ignore this
+				 * one... 
+				 */
+				if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
+				    (powernow_table[i].index != powernow_table[cntlofreq].index)) {
+					printk(KERN_ERR PFX "Too many lo freq table entries\n");
+					goto err_out_mem;
+				}
+
+				dprintk("double low frequency table entry, ignoring it.\n");
+				powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
+				continue;
+			} else
+				cntlofreq = i;
 		}
 		}
 
 
 		if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
 		if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
@@ -816,7 +830,7 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
 {
 {
 	u32 fid;
 	u32 fid;
 	u32 vid;
 	u32 vid;
-	int res;
+	int res, i;
 	struct cpufreq_freqs freqs;
 	struct cpufreq_freqs freqs;
 
 
 	dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
 	dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
@@ -841,7 +855,8 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
 	}
 	}
 
 
 	if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
 	if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) {
-		printk("ignoring illegal change in lo freq table-%x to 0x%x\n",
+		printk(KERN_ERR PFX
+		       "ignoring illegal change in lo freq table-%x to 0x%x\n",
 		       data->currfid, fid);
 		       data->currfid, fid);
 		return 1;
 		return 1;
 	}
 	}
@@ -850,18 +865,20 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
 		smp_processor_id(), fid, vid);
 		smp_processor_id(), fid, vid);
 
 
 	freqs.cpu = data->cpu;
 	freqs.cpu = data->cpu;
-
 	freqs.old = find_khz_freq_from_fid(data->currfid);
 	freqs.old = find_khz_freq_from_fid(data->currfid);
 	freqs.new = find_khz_freq_from_fid(fid);
 	freqs.new = find_khz_freq_from_fid(fid);
-	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+	}
 
 
-	down(&fidvid_sem);
 	res = transition_fid_vid(data, fid, vid);
 	res = transition_fid_vid(data, fid, vid);
-	up(&fidvid_sem);
 
 
 	freqs.new = find_khz_freq_from_fid(data->currfid);
 	freqs.new = find_khz_freq_from_fid(data->currfid);
-	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-
+	for_each_cpu_mask(i, cpu_core_map[data->cpu]) {
+		freqs.cpu = i;
+		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+        }
 	return res;
 	return res;
 }
 }
 
 
@@ -874,6 +891,7 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
 	u32 checkvid = data->currvid;
 	u32 checkvid = data->currvid;
 	unsigned int newstate;
 	unsigned int newstate;
 	int ret = -EIO;
 	int ret = -EIO;
+	int i;
 
 
 	/* only run on specific CPU from here on */
 	/* only run on specific CPU from here on */
 	oldmask = current->cpus_allowed;
 	oldmask = current->cpus_allowed;
@@ -902,22 +920,41 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
 		data->currfid, data->currvid);
 		data->currfid, data->currvid);
 
 
 	if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
 	if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
-		printk(KERN_ERR PFX
-		       "error - out of sync, fid 0x%x 0x%x, vid 0x%x 0x%x\n",
-		       checkfid, data->currfid, checkvid, data->currvid);
+		printk(KERN_INFO PFX
+			"error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
+			checkfid, data->currfid, checkvid, data->currvid);
 	}
 	}
 
 
 	if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
 	if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
 		goto err_out;
 		goto err_out;
 
 
+	down(&fidvid_sem);
+
+	for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+		/* make sure the sibling is initialized */
+		if (!powernow_data[i]) {
+                        ret = 0;
+                        up(&fidvid_sem);
+                        goto err_out;
+                }
+	}
+
 	powernow_k8_acpi_pst_values(data, newstate);
 	powernow_k8_acpi_pst_values(data, newstate);
 
 
 	if (transition_frequency(data, newstate)) {
 	if (transition_frequency(data, newstate)) {
 		printk(KERN_ERR PFX "transition frequency failed\n");
 		printk(KERN_ERR PFX "transition frequency failed\n");
 		ret = 1;
 		ret = 1;
+		up(&fidvid_sem);
 		goto err_out;
 		goto err_out;
 	}
 	}
 
 
+	/* Update all the fid/vids of our siblings */
+	for_each_cpu_mask(i, cpu_core_map[pol->cpu]) {
+		powernow_data[i]->currvid = data->currvid;
+		powernow_data[i]->currfid = data->currfid;
+	}	
+	up(&fidvid_sem);
+
 	pol->cur = find_khz_freq_from_fid(data->currfid);
 	pol->cur = find_khz_freq_from_fid(data->currfid);
 	ret = 0;
 	ret = 0;
 
 
@@ -962,7 +999,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
 		 */
 		 */
 
 
 		if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
 		if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
-			printk(KERN_INFO PFX "MP systems not supported by PSB BIOS structure\n");
+			printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
 			kfree(data);
 			kfree(data);
 			return -ENODEV;
 			return -ENODEV;
 		}
 		}
@@ -1003,6 +1040,7 @@ static int __init powernowk8_cpu_init(struct cpufreq_policy *pol)
 	schedule();
 	schedule();
 
 
 	pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
 	pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	pol->cpus = cpu_core_map[pol->cpu];
 
 
 	/* Take a crude guess here. 
 	/* Take a crude guess here. 
 	 * That guess was in microseconds, so multiply with 1000 */
 	 * That guess was in microseconds, so multiply with 1000 */
@@ -1069,7 +1107,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
 		return 0;
 		return 0;
 	}
 	}
 	preempt_disable();
 	preempt_disable();
-
+	
 	if (query_current_values_with_pending_wait(data))
 	if (query_current_values_with_pending_wait(data))
 		goto out;
 		goto out;
 
 
@@ -1127,9 +1165,10 @@ static void __exit powernowk8_exit(void)
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 	cpufreq_unregister_driver(&cpufreq_amd64_driver);
 }
 }
 
 
-MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com>");
+MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com.");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver.");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 late_initcall(powernowk8_init);
 late_initcall(powernowk8_init);
 module_exit(powernowk8_exit);
 module_exit(powernowk8_exit);
+

+ 15 - 0
arch/i386/kernel/cpu/cpufreq/powernow-k8.h

@@ -174,3 +174,18 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
 static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
 
 
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
 static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
+
+#ifndef for_each_cpu_mask
+#define for_each_cpu_mask(i,mask) for (i=0;i<1;i++)
+#endif
+                                                                                
+#ifdef CONFIG_SMP
+static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
+{
+}
+#else
+static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
+{
+	cpu_set(0, cpu_sharedcore_mask[0]);
+}
+#endif

+ 186 - 0
arch/i386/kernel/cpu/cpufreq/sc520_freq.c

@@ -0,0 +1,186 @@
+/*
+ *	sc520_freq.c: cpufreq driver for the AMD Elan sc520
+ *
+ *	Copyright (C) 2005 Sean Young <sean@mess.org>
+ *
+ *	This program is free software; you can redistribute it and/or
+ *	modify it under the terms of the GNU General Public License
+ *	as published by the Free Software Foundation; either version
+ *	2 of the License, or (at your option) any later version.
+ *
+ *	Based on elanfreq.c
+ *
+ *	2005-03-30: - initial revision
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/delay.h>
+#include <linux/cpufreq.h>
+
+#include <asm/msr.h>
+#include <asm/timex.h>
+#include <asm/io.h>
+
+#define MMCR_BASE	0xfffef000	/* The default base address */
+#define OFFS_CPUCTL	0x2   /* CPU Control Register */
+
+static __u8 __iomem *cpuctl;
+
+#define dprintk(msg...) cpufreq_debug_printk(CPUFREQ_DEBUG_DRIVER, "sc520_freq", msg)
+
+static struct cpufreq_frequency_table sc520_freq_table[] = {
+	{0x01,	100000},
+	{0x02,	133000},
+	{0,	CPUFREQ_TABLE_END},
+};
+
+static unsigned int sc520_freq_get_cpu_frequency(unsigned int cpu)
+{
+	u8 clockspeed_reg = *cpuctl;
+
+	switch (clockspeed_reg & 0x03) {
+	default:
+		printk(KERN_ERR "sc520_freq: error: cpuctl register has unexpected value %02x\n", clockspeed_reg);
+	case 0x01:
+		return 100000;
+	case 0x02:
+		return 133000;
+	}
+}
+
+static void sc520_freq_set_cpu_state (unsigned int state)
+{
+
+	struct cpufreq_freqs	freqs;
+	u8 clockspeed_reg;
+
+	freqs.old = sc520_freq_get_cpu_frequency(0);
+	freqs.new = sc520_freq_table[state].frequency;
+	freqs.cpu = 0; /* AMD Elan is UP */
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+	dprintk("attempting to set frequency to %i kHz\n",
+			sc520_freq_table[state].frequency);
+
+	local_irq_disable();
+
+	clockspeed_reg = *cpuctl & ~0x03;
+	*cpuctl = clockspeed_reg | sc520_freq_table[state].index;
+
+	local_irq_enable();
+
+	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+};
+
+static int sc520_freq_verify (struct cpufreq_policy *policy)
+{
+	return cpufreq_frequency_table_verify(policy, &sc520_freq_table[0]);
+}
+
+static int sc520_freq_target (struct cpufreq_policy *policy,
+			    unsigned int target_freq,
+			    unsigned int relation)
+{
+	unsigned int newstate = 0;
+
+	if (cpufreq_frequency_table_target(policy, sc520_freq_table, target_freq, relation, &newstate))
+		return -EINVAL;
+
+	sc520_freq_set_cpu_state(newstate);
+
+	return 0;
+}
+
+
+/*
+ *	Module init and exit code
+ */
+
+static int sc520_freq_cpu_init(struct cpufreq_policy *policy)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+	int result;
+
+	/* capability check */
+	if (c->x86_vendor != X86_VENDOR_AMD ||
+	    c->x86 != 4 || c->x86_model != 9)
+		return -ENODEV;
+
+	/* cpuinfo and default policy values */
+	policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+	policy->cpuinfo.transition_latency = 1000000; /* 1ms */
+	policy->cur = sc520_freq_get_cpu_frequency(0);
+
+	result = cpufreq_frequency_table_cpuinfo(policy, sc520_freq_table);
+	if (result)
+		return (result);
+
+	cpufreq_frequency_table_get_attr(sc520_freq_table, policy->cpu);
+
+	return 0;
+}
+
+
+static int sc520_freq_cpu_exit(struct cpufreq_policy *policy)
+{
+	cpufreq_frequency_table_put_attr(policy->cpu);
+	return 0;
+}
+
+
+static struct freq_attr* sc520_freq_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
+
+static struct cpufreq_driver sc520_freq_driver = {
+	.get	= sc520_freq_get_cpu_frequency,
+	.verify	= sc520_freq_verify,
+	.target	= sc520_freq_target,
+	.init	= sc520_freq_cpu_init,
+	.exit	= sc520_freq_cpu_exit,
+	.name	= "sc520_freq",
+	.owner	= THIS_MODULE,
+	.attr	= sc520_freq_attr,
+};
+
+
+static int __init sc520_freq_init(void)
+{
+	struct cpuinfo_x86 *c = cpu_data;
+
+	/* Test if we have the right hardware */
+	if(c->x86_vendor != X86_VENDOR_AMD ||
+				c->x86 != 4 || c->x86_model != 9) {
+		dprintk("no Elan SC520 processor found!\n");
+		return -ENODEV;
+	}
+	cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1);
+	if(!cpuctl) {
+		printk(KERN_ERR "sc520_freq: error: failed to remap memory\n");
+		return -ENOMEM;
+	}
+
+	return cpufreq_register_driver(&sc520_freq_driver);
+}
+
+
+static void __exit sc520_freq_exit(void)
+{
+	cpufreq_unregister_driver(&sc520_freq_driver);
+	iounmap(cpuctl);
+}
+
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Sean Young <sean@mess.org>");
+MODULE_DESCRIPTION("cpufreq driver for AMD's Elan sc520 CPU");
+
+module_init(sc520_freq_init);
+module_exit(sc520_freq_exit);
+

+ 6 - 0
arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c

@@ -54,6 +54,8 @@ enum {
 	CPU_DOTHAN_A1,
 	CPU_DOTHAN_A1,
 	CPU_DOTHAN_A2,
 	CPU_DOTHAN_A2,
 	CPU_DOTHAN_B0,
 	CPU_DOTHAN_B0,
+	CPU_MP4HT_D0,
+	CPU_MP4HT_E0,
 };
 };
 
 
 static const struct cpu_id cpu_ids[] = {
 static const struct cpu_id cpu_ids[] = {
@@ -61,6 +63,8 @@ static const struct cpu_id cpu_ids[] = {
 	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
 	[CPU_DOTHAN_A1]	= { 6, 13, 1 },
 	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
 	[CPU_DOTHAN_A2]	= { 6, 13, 2 },
 	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
 	[CPU_DOTHAN_B0]	= { 6, 13, 6 },
+	[CPU_MP4HT_D0]	= {15,  3, 4 },
+	[CPU_MP4HT_E0]	= {15,  4, 1 },
 };
 };
 #define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))
 #define N_IDS	(sizeof(cpu_ids)/sizeof(cpu_ids[0]))
 
 
@@ -226,6 +230,8 @@ static struct cpu_model models[] =
 	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_A1], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_A2], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
 	{ &cpu_ids[CPU_DOTHAN_B0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_D0], NULL, 0, NULL },
+	{ &cpu_ids[CPU_MP4HT_E0], NULL, 0, NULL },
 
 
 	{ NULL, }
 	{ NULL, }
 };
 };

+ 3 - 3
arch/i386/kernel/cpu/cpufreq/speedstep-lib.c

@@ -336,7 +336,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 	if (!prev_speed)
 	if (!prev_speed)
 		return -EIO;
 		return -EIO;
 
 
-	dprintk("previous seped is %u\n", prev_speed);
+	dprintk("previous speed is %u\n", prev_speed);
 	
 	
 	local_irq_save(flags);
 	local_irq_save(flags);
 
 
@@ -348,7 +348,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	dprintk("low seped is %u\n", *low_speed);
+	dprintk("low speed is %u\n", *low_speed);
 
 
 	/* switch to high state */
 	/* switch to high state */
 	set_state(SPEEDSTEP_HIGH);
 	set_state(SPEEDSTEP_HIGH);
@@ -358,7 +358,7 @@ unsigned int speedstep_get_freqs(unsigned int processor,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	dprintk("high seped is %u\n", *high_speed);
+	dprintk("high speed is %u\n", *high_speed);
 
 
 	if (*low_speed == *high_speed) {
 	if (*low_speed == *high_speed) {
 		ret = -ENODEV;
 		ret = -ENODEV;

+ 3 - 0
arch/i386/kernel/cpu/cpufreq/speedstep-smi.c

@@ -357,6 +357,9 @@ static int __init speedstep_init(void)
 	case SPEEDSTEP_PROCESSOR_PIII_C:
 	case SPEEDSTEP_PROCESSOR_PIII_C:
 	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
 	case SPEEDSTEP_PROCESSOR_PIII_C_EARLY:
 		break;
 		break;
+	case SPEEDSTEP_PROCESSOR_P4M:
+		printk(KERN_INFO "speedstep-smi: you're trying to use this cpufreq driver on a Pentium 4-based CPU. Most likely it will not work.\n");
+		break;
 	default:
 	default:
 		speedstep_processor = 0;
 		speedstep_processor = 0;
 	}
 	}

+ 1 - 1
arch/i386/kernel/cpu/intel_cacheinfo.c

@@ -118,7 +118,7 @@ struct _cpuid4_info {
 };
 };
 
 
 #define MAX_CACHE_LEAVES		4
 #define MAX_CACHE_LEAVES		4
-static unsigned short __devinitdata	num_cache_leaves;
+static unsigned short			num_cache_leaves;
 
 
 static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 static int __devinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
 {
 {

+ 2 - 0
arch/i386/kernel/setup.c

@@ -1502,11 +1502,13 @@ void __init setup_arch(char **cmdline_p)
 	if (efi_enabled)
 	if (efi_enabled)
 		efi_map_memmap();
 		efi_map_memmap();
 
 
+#ifdef CONFIG_ACPI_BOOT
 	/*
 	/*
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 * Parse the ACPI tables for possible boot-time SMP configuration.
 	 */
 	 */
 	acpi_boot_table_init();
 	acpi_boot_table_init();
 	acpi_boot_init();
 	acpi_boot_init();
+#endif
 
 
 #ifdef CONFIG_X86_LOCAL_APIC
 #ifdef CONFIG_X86_LOCAL_APIC
 	if (smp_found_config)
 	if (smp_found_config)

+ 4 - 1
arch/i386/kernel/smpboot.c

@@ -888,6 +888,7 @@ void *xquad_portio;
 
 
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
 cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
+EXPORT_SYMBOL(cpu_core_map);
 
 
 static void __init smp_boot_cpus(unsigned int max_cpus)
 static void __init smp_boot_cpus(unsigned int max_cpus)
 {
 {
@@ -1073,8 +1074,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
 			cpu_set(cpu, cpu_sibling_map[cpu]);
 			cpu_set(cpu, cpu_sibling_map[cpu]);
 		}
 		}
 
 
-		if (siblings != smp_num_siblings)
+		if (siblings != smp_num_siblings) {
 			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
 			printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings);
+			smp_num_siblings = siblings;
+		}
 
 
 		if (c->x86_num_cores > 1) {
 		if (c->x86_num_cores > 1) {
 			for (i = 0; i < NR_CPUS; i++) {
 			for (i = 0; i < NR_CPUS; i++) {

+ 4 - 2
arch/i386/kernel/timers/common.c

@@ -6,6 +6,7 @@
 #include <linux/timex.h>
 #include <linux/timex.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
 #include <linux/jiffies.h>
 #include <linux/jiffies.h>
+#include <linux/module.h>
 
 
 #include <asm/io.h>
 #include <asm/io.h>
 #include <asm/timer.h>
 #include <asm/timer.h>
@@ -24,7 +25,7 @@
 
 
 #define CALIBRATE_TIME	(5 * 1000020/HZ)
 #define CALIBRATE_TIME	(5 * 1000020/HZ)
 
 
-unsigned long __init calibrate_tsc(void)
+unsigned long calibrate_tsc(void)
 {
 {
 	mach_prepare_counter();
 	mach_prepare_counter();
 
 
@@ -139,7 +140,7 @@ bad_calibration:
 #endif
 #endif
 
 
 /* calculate cpu_khz */
 /* calculate cpu_khz */
-void __init init_cpu_khz(void)
+void init_cpu_khz(void)
 {
 {
 	if (cpu_has_tsc) {
 	if (cpu_has_tsc) {
 		unsigned long tsc_quotient = calibrate_tsc();
 		unsigned long tsc_quotient = calibrate_tsc();
@@ -158,3 +159,4 @@ void __init init_cpu_khz(void)
 		}
 		}
 	}
 	}
 }
 }
+

+ 20 - 0
arch/i386/kernel/timers/timer_tsc.c

@@ -320,6 +320,26 @@ core_initcall(cpufreq_tsc);
 static inline void cpufreq_delayed_get(void) { return; }
 static inline void cpufreq_delayed_get(void) { return; }
 #endif 
 #endif 
 
 
+int recalibrate_cpu_khz(void)
+{
+#ifndef CONFIG_SMP
+	unsigned long cpu_khz_old = cpu_khz;
+
+	if (cpu_has_tsc) {
+		init_cpu_khz();
+		cpu_data[0].loops_per_jiffy =
+		    cpufreq_scale(cpu_data[0].loops_per_jiffy,
+			          cpu_khz_old,
+				  cpu_khz);
+		return 0;
+	} else
+		return -ENODEV;
+#else
+	return -ENODEV;
+#endif
+}
+EXPORT_SYMBOL(recalibrate_cpu_khz);
+
 static void mark_offset_tsc(void)
 static void mark_offset_tsc(void)
 {
 {
 	unsigned long lost,delay;
 	unsigned long lost,delay;

+ 8 - 9
arch/i386/mach-voyager/voyager_smp.c

@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
 static void vic_enable_cpi(void);
 static void vic_enable_cpi(void);
 static void do_boot_cpu(__u8 cpuid);
 static void do_boot_cpu(__u8 cpuid);
 static void do_quad_bootstrap(void);
 static void do_quad_bootstrap(void);
-static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
 
 
 int hard_smp_processor_id(void);
 int hard_smp_processor_id(void);
 
 
@@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
 	}
 	}
 }
 }
 
 
+static inline void
+wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+{
+	irq_enter();
+	smp_local_timer_interrupt(regs);
+	irq_exit();
+}
+
 static inline void
 static inline void
 send_one_CPI(__u8 cpu, __u8 cpi)
 send_one_CPI(__u8 cpu, __u8 cpi)
 {
 {
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
 	smp_local_timer_interrupt(regs);
 	smp_local_timer_interrupt(regs);
 }
 }
 
 
-static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
-{
-	irq_enter();
-	smp_local_timer_interrupt(regs);
-	irq_exit();
-}
-
 /* local (per CPU) timer interrupt.  It does both profiling and
 /* local (per CPU) timer interrupt.  It does both profiling and
  * process statistics/rescheduling.
  * process statistics/rescheduling.
  *
  *

+ 6 - 4
arch/i386/mm/ioremap.c

@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr)
 			addr < phys_to_virt(ISA_END_ADDRESS))
 			addr < phys_to_virt(ISA_END_ADDRESS))
 		return;
 		return;
 
 
-	p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
+	write_lock(&vmlist_lock);
+	p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr));
 	if (!p) { 
 	if (!p) { 
-		printk("__iounmap: bad address %p\n", addr);
-		return;
+		printk("iounmap: bad address %p\n", addr);
+		goto out_unlock;
 	}
 	}
 
 
 	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
 	if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
-		/* p->size includes the guard page, but cpa doesn't like that */
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 		change_page_attr(virt_to_page(__va(p->phys_addr)),
 				 p->size >> PAGE_SHIFT,
 				 p->size >> PAGE_SHIFT,
 				 PAGE_KERNEL);
 				 PAGE_KERNEL);
 		global_flush_tlb();
 		global_flush_tlb();
 	} 
 	} 
+out_unlock:
+	write_unlock(&vmlist_lock);
 	kfree(p); 
 	kfree(p); 
 }
 }
 
 

+ 1 - 1
arch/i386/pci/fixup.c

@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci
 #define MAX_PCIEROOT	6
 #define MAX_PCIEROOT	6
 static int quirk_aspm_offset[MAX_PCIEROOT << 3];
 static int quirk_aspm_offset[MAX_PCIEROOT << 3];
 
 
-#define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b)
+#define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7))
 
 
 static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
 static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value)
 {
 {

+ 0 - 5
arch/i386/pci/irq.c

@@ -1029,7 +1029,6 @@ void pcibios_penalize_isa_irq(int irq)
 static int pirq_enable_irq(struct pci_dev *dev)
 static int pirq_enable_irq(struct pci_dev *dev)
 {
 {
 	u8 pin;
 	u8 pin;
-	extern int via_interrupt_line_quirk;
 	struct pci_dev *temp_dev;
 	struct pci_dev *temp_dev;
 
 
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 	pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
@@ -1084,10 +1083,6 @@ static int pirq_enable_irq(struct pci_dev *dev)
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		printk(KERN_WARNING "PCI: No IRQ known for interrupt pin %c of device %s.%s\n",
 		       'A' + pin, pci_name(dev), msg);
 		       'A' + pin, pci_name(dev), msg);
 	}
 	}
-	/* VIA bridges use interrupt line for apic/pci steering across
-	   the V-Link */
-	else if (via_interrupt_line_quirk)
-		pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq & 15);
 	return 0;
 	return 0;
 }
 }
 
 

+ 0 - 1
arch/ia64/ia32/ia32_ioctl.c

@@ -13,7 +13,6 @@
   
   
 #define	INCLUDES
 #define	INCLUDES
 #include "compat_ioctl.c"
 #include "compat_ioctl.c"
-#include <asm/ioctl32.h>
 
 
 #define IOCTL_NR(a)	((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
 #define IOCTL_NR(a)	((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
 
 

+ 1 - 1
arch/ia64/ia32/sys_ia32.c

@@ -2427,7 +2427,7 @@ sys32_epoll_wait(int epfd, struct epoll_event32 __user * events, int maxevents,
 {
 {
 	struct epoll_event *events64 = NULL;
 	struct epoll_event *events64 = NULL;
 	mm_segment_t old_fs = get_fs();
 	mm_segment_t old_fs = get_fs();
-	int error, numevents, size;
+	int numevents, size;
 	int evt_idx;
 	int evt_idx;
 	int do_free_pages = 0;
 	int do_free_pages = 0;
 
 

+ 2 - 2
arch/ia64/kernel/entry.S

@@ -1182,7 +1182,7 @@ ENTRY(notify_resume_user)
 	;;
 	;;
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 (pNonSys) mov out2=0				// out2==0 => not a syscall
 	.fframe 16
 	.fframe 16
-	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
+	.spillsp ar.unat, 16
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	st8 [out1]=loc1,-8			// save ar.pfs, out1=&sigscratch
 	.body
 	.body
@@ -1208,7 +1208,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
 	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	adds out2=8,sp				// out2=&sigscratch->ar_pfs
 	;;
 	;;
 	.fframe 16
 	.fframe 16
-	.spillpsp ar.unat, 16			// (note that offset is relative to psp+0x10!)
+	.spillsp ar.unat, 16
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [sp]=r9,-16				// allocate space for ar.unat and save it
 	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	st8 [out2]=loc1,-8			// save ar.pfs, out2=&sigscratch
 	.body
 	.body

+ 4 - 4
arch/ia64/kernel/mca.c

@@ -1103,8 +1103,6 @@ ia64_mca_cpe_int_caller(int cpe_irq, void *arg, struct pt_regs *ptregs)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-#endif /* CONFIG_ACPI */
-
 /*
 /*
  *  ia64_mca_cpe_poll
  *  ia64_mca_cpe_poll
  *
  *
@@ -1122,6 +1120,8 @@ ia64_mca_cpe_poll (unsigned long dummy)
 	platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
 	platform_send_ipi(first_cpu(cpu_online_map), IA64_CPEP_VECTOR, IA64_IPI_DM_INT, 0);
 }
 }
 
 
+#endif /* CONFIG_ACPI */
+
 /*
 /*
  * C portion of the OS INIT handler
  * C portion of the OS INIT handler
  *
  *
@@ -1390,8 +1390,7 @@ ia64_mca_init(void)
 	register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 	register_percpu_irq(IA64_MCA_WAKEUP_VECTOR, &mca_wkup_irqaction);
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
-	/* Setup the CPEI/P vector and handler */
-	cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
+	/* Setup the CPEI/P handler */
 	register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 	register_percpu_irq(IA64_CPEP_VECTOR, &mca_cpep_irqaction);
 #endif
 #endif
 
 
@@ -1436,6 +1435,7 @@ ia64_mca_late_init(void)
 
 
 #ifdef CONFIG_ACPI
 #ifdef CONFIG_ACPI
 	/* Setup the CPEI/P vector and handler */
 	/* Setup the CPEI/P vector and handler */
+	cpe_vector = acpi_request_vector(ACPI_INTERRUPT_CPEI);
 	init_timer(&cpe_poll_timer);
 	init_timer(&cpe_poll_timer);
 	cpe_poll_timer.function = ia64_mca_cpe_poll;
 	cpe_poll_timer.function = ia64_mca_cpe_poll;
 
 

+ 1 - 2
arch/ia64/kernel/minstate.h

@@ -41,7 +41,7 @@
 (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
 (pKStk) addl r3=THIS_CPU(ia64_mca_data),r3;;							\
 (pKStk) ld8 r3 = [r3];;										\
 (pKStk) ld8 r3 = [r3];;										\
 (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
 (pKStk) addl r3=IA64_MCA_CPU_INIT_STACK_OFFSET,r3;;						\
-(pKStk) addl sp=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
+(pKStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r3;						\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 (pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 (pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
 	;;											\
@@ -50,7 +50,6 @@
 (pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 (pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 (pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
 (pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
 	;;											\
 	;;											\
-(pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
 (pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 (pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 	;;											\
 	;;											\
 (pUStk)	mov r18=ar.bsp;										\
 (pUStk)	mov r18=ar.bsp;										\

+ 160 - 15
arch/ia64/kernel/perfmon.c

@@ -11,7 +11,7 @@
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
  * Version Perfmon-2.x is a rewrite of perfmon-1.x
  * by Stephane Eranian, Hewlett Packard Co.
  * by Stephane Eranian, Hewlett Packard Co.
  *
  *
- * Copyright (C) 1999-2003, 2005  Hewlett Packard Co
+ * Copyright (C) 1999-2005  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
  *
  *
@@ -497,6 +497,9 @@ typedef struct {
 static pfm_stats_t		pfm_stats[NR_CPUS];
 static pfm_stats_t		pfm_stats[NR_CPUS];
 static pfm_session_t		pfm_sessions;	/* global sessions information */
 static pfm_session_t		pfm_sessions;	/* global sessions information */
 
 
+static spinlock_t pfm_alt_install_check = SPIN_LOCK_UNLOCKED;
+static pfm_intr_handler_desc_t  *pfm_alt_intr_handler;
+
 static struct proc_dir_entry 	*perfmon_dir;
 static struct proc_dir_entry 	*perfmon_dir;
 static pfm_uuid_t		pfm_null_uuid = {0,};
 static pfm_uuid_t		pfm_null_uuid = {0,};
 
 
@@ -606,6 +609,7 @@ DEFINE_PER_CPU(unsigned long, pfm_syst_info);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
 DEFINE_PER_CPU(struct task_struct *, pmu_owner);
 DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
 DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
 DEFINE_PER_CPU(unsigned long, pmu_activation_number);
 DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+EXPORT_PER_CPU_SYMBOL_GPL(pfm_syst_info);
 
 
 
 
 /* forward declaration */
 /* forward declaration */
@@ -1325,7 +1329,7 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
 error_conflict:
 error_conflict:
 	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
 	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
   		pfm_sessions.pfs_sys_session[cpu]->pid,
   		pfm_sessions.pfs_sys_session[cpu]->pid,
-		smp_processor_id()));
+		cpu));
 abort:
 abort:
 	UNLOCK_PFS(flags);
 	UNLOCK_PFS(flags);
 
 
@@ -5555,26 +5559,32 @@ pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
 	int ret;
 	int ret;
 
 
 	this_cpu = get_cpu();
 	this_cpu = get_cpu();
-	min      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
-	max      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
+	if (likely(!pfm_alt_intr_handler)) {
+		min = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
+		max = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
 
 
-	start_cycles = ia64_get_itc();
+		start_cycles = ia64_get_itc();
 
 
-	ret = pfm_do_interrupt_handler(irq, arg, regs);
+		ret = pfm_do_interrupt_handler(irq, arg, regs);
 
 
-	total_cycles = ia64_get_itc();
+		total_cycles = ia64_get_itc();
 
 
-	/*
-	 * don't measure spurious interrupts
-	 */
-	if (likely(ret == 0)) {
-		total_cycles -= start_cycles;
+		/*
+		 * don't measure spurious interrupts
+		 */
+		if (likely(ret == 0)) {
+			total_cycles -= start_cycles;
 
 
-		if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
-		if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
+			if (total_cycles < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = total_cycles;
+			if (total_cycles > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = total_cycles;
 
 
-		pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+			pfm_stats[this_cpu].pfm_ovfl_intr_cycles += total_cycles;
+		}
+	}
+	else {
+		(*pfm_alt_intr_handler->handler)(irq, arg, regs);
 	}
 	}
+
 	put_cpu_no_resched();
 	put_cpu_no_resched();
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -6425,6 +6435,141 @@ static struct irqaction perfmon_irqaction = {
 	.name    = "perfmon"
 	.name    = "perfmon"
 };
 };
 
 
+static void
+pfm_alt_save_pmu_state(void *data)
+{
+	struct pt_regs *regs;
+
+	regs = ia64_task_regs(current);
+
+	DPRINT(("called\n"));
+
+	/*
+	 * should not be necessary but
+	 * let's take not risk
+	 */
+	pfm_clear_psr_up();
+	pfm_clear_psr_pp();
+	ia64_psr(regs)->pp = 0;
+
+	/*
+	 * This call is required
+	 * May cause a spurious interrupt on some processors
+	 */
+	pfm_freeze_pmu();
+
+	ia64_srlz_d();
+}
+
+void
+pfm_alt_restore_pmu_state(void *data)
+{
+	struct pt_regs *regs;
+
+	regs = ia64_task_regs(current);
+
+	DPRINT(("called\n"));
+
+	/*
+	 * put PMU back in state expected
+	 * by perfmon
+	 */
+	pfm_clear_psr_up();
+	pfm_clear_psr_pp();
+	ia64_psr(regs)->pp = 0;
+
+	/*
+	 * perfmon runs with PMU unfrozen at all times
+	 */
+	pfm_unfreeze_pmu();
+
+	ia64_srlz_d();
+}
+
+int
+pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+	int ret, i;
+	int reserve_cpu;
+
+	/* some sanity checks */
+	if (hdl == NULL || hdl->handler == NULL) return -EINVAL;
+
+	/* do the easy test first */
+	if (pfm_alt_intr_handler) return -EBUSY;
+
+	/* one at a time in the install or remove, just fail the others */
+	if (!spin_trylock(&pfm_alt_install_check)) {
+		return -EBUSY;
+	}
+
+	/* reserve our session */
+	for_each_online_cpu(reserve_cpu) {
+		ret = pfm_reserve_session(NULL, 1, reserve_cpu);
+		if (ret) goto cleanup_reserve;
+	}
+
+	/* save the current system wide pmu states */
+	ret = on_each_cpu(pfm_alt_save_pmu_state, NULL, 0, 1);
+	if (ret) {
+		DPRINT(("on_each_cpu() failed: %d\n", ret));
+		goto cleanup_reserve;
+	}
+
+	/* officially change to the alternate interrupt handler */
+	pfm_alt_intr_handler = hdl;
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return 0;
+
+cleanup_reserve:
+	for_each_online_cpu(i) {
+		/* don't unreserve more than we reserved */
+		if (i >= reserve_cpu) break;
+
+		pfm_unreserve_session(NULL, 1, i);
+	}
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pfm_install_alt_pmu_interrupt);
+
+int
+pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *hdl)
+{
+	int i;
+	int ret;
+
+	if (hdl == NULL) return -EINVAL;
+
+	/* cannot remove someone else's handler! */
+	if (pfm_alt_intr_handler != hdl) return -EINVAL;
+
+	/* one at a time in the install or remove, just fail the others */
+	if (!spin_trylock(&pfm_alt_install_check)) {
+		return -EBUSY;
+	}
+
+	pfm_alt_intr_handler = NULL;
+
+	ret = on_each_cpu(pfm_alt_restore_pmu_state, NULL, 0, 1);
+	if (ret) {
+		DPRINT(("on_each_cpu() failed: %d\n", ret));
+	}
+
+	for_each_online_cpu(i) {
+		pfm_unreserve_session(NULL, 1, i);
+	}
+
+	spin_unlock(&pfm_alt_install_check);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(pfm_remove_alt_pmu_interrupt);
+
 /*
 /*
  * perfmon initialization routine, called from the initcall() table
  * perfmon initialization routine, called from the initcall() table
  */
  */

+ 17 - 3
arch/ia64/kernel/ptrace.c

@@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt,
 			unsigned long cfm)
 			unsigned long cfm)
 {
 {
 	struct unw_frame_info info, prev_info;
 	struct unw_frame_info info, prev_info;
-	unsigned long ip, pr;
+	unsigned long ip, sp, pr;
 
 
 	unw_init_from_blocked_task(&info, child);
 	unw_init_from_blocked_task(&info, child);
 	while (1) {
 	while (1) {
 		prev_info = info;
 		prev_info = info;
 		if (unw_unwind(&info) < 0)
 		if (unw_unwind(&info) < 0)
 			return;
 			return;
-		if (unw_get_rp(&info, &ip) < 0)
+
+		unw_get_sp(&info, &sp);
+		if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
+		    < IA64_PT_REGS_SIZE) {
+			dprintk("ptrace.%s: ran off the top of the kernel "
+				"stack\n", __FUNCTION__);
+			return;
+		}
+		if (unw_get_pr (&prev_info, &pr) < 0) {
+			unw_get_rp(&prev_info, &ip);
+			dprintk("ptrace.%s: failed to read "
+				"predicate register (ip=0x%lx)\n",
+				__FUNCTION__, ip);
 			return;
 			return;
-		if (ip < FIXADDR_USER_END)
+		}
+		if (unw_is_intr_frame(&info)
+		    && (pr & (1UL << PRED_USER_STACK)))
 			break;
 			break;
 	}
 	}
 
 

+ 1 - 1
arch/ia64/kernel/smpboot.c

@@ -624,7 +624,7 @@ static struct {
 	__u16   thread_id;
 	__u16   thread_id;
 	__u16   proc_fixed_addr;
 	__u16   proc_fixed_addr;
 	__u8    valid;
 	__u8    valid;
-}mt_info[NR_CPUS] __devinit;
+} mt_info[NR_CPUS] __devinitdata;
 
 
 #ifdef CONFIG_HOTPLUG_CPU
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void
 static inline void

+ 0 - 7
arch/ia64/kernel/sys_ia64.c

@@ -182,13 +182,6 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
 		}
 		}
 	}
 	}
 
 
-	/*
-	 * A zero mmap always succeeds in Linux, independent of whether or not the
-	 * remaining arguments are valid.
-	 */
-	if (len == 0)
-		goto out;
-
 	/* Careful about overflows.. */
 	/* Careful about overflows.. */
 	len = PAGE_ALIGN(len);
 	len = PAGE_ALIGN(len);
 	if (!len || len > TASK_SIZE) {
 	if (!len || len > TASK_SIZE) {

+ 2 - 0
arch/ia64/sn/kernel/setup.c

@@ -271,6 +271,8 @@ void __init sn_setup(char **cmdline_p)
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
 	extern void sn_cpu_init(void);
 	extern void sn_cpu_init(void);
 
 
+	ia64_sn_plat_set_error_handling_features();
+
 	/*
 	/*
 	 * If the generic code has enabled vga console support - lets
 	 * If the generic code has enabled vga console support - lets
 	 * get rid of it again. This is a kludge for the fact that ACPI
 	 * get rid of it again. This is a kludge for the fact that ACPI

+ 12 - 5
arch/m68knommu/kernel/process.c

@@ -45,11 +45,13 @@ asmlinkage void ret_from_fork(void);
  */
  */
 void default_idle(void)
 void default_idle(void)
 {
 {
-	while(1) {
-		if (need_resched())
-			__asm__("stop #0x2000" : : : "cc");
-		schedule();
+	local_irq_disable();
+ 	while (!need_resched()) {
+		/* This stop will re-enable interrupts */
+ 		__asm__("stop #0x2000" : : : "cc");
+		local_irq_disable();
 	}
 	}
+	local_irq_enable();
 }
 }
 
 
 void (*idle)(void) = default_idle;
 void (*idle)(void) = default_idle;
@@ -63,7 +65,12 @@ void (*idle)(void) = default_idle;
 void cpu_idle(void)
 void cpu_idle(void)
 {
 {
 	/* endless idle loop with no priority at all */
 	/* endless idle loop with no priority at all */
-	idle();
+	while (1) {
+		idle();
+		preempt_enable_no_resched();
+		schedule();
+		preempt_disable();
+	}
 }
 }
 
 
 void machine_restart(char * __unused)
 void machine_restart(char * __unused)

+ 48 - 7
arch/mips/vr41xx/common/pmu.c

@@ -1,7 +1,7 @@
 /*
 /*
  *  pmu.c, Power Management Unit routines for NEC VR4100 series.
  *  pmu.c, Power Management Unit routines for NEC VR4100 series.
  *
  *
- *  Copyright (C) 2003-2004  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
+ *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
  *
  *
  *  This program is free software; you can redistribute it and/or modify
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
  *  it under the terms of the GNU General Public License as published by
@@ -17,7 +17,9 @@
  *  along with this program; if not, write to the Free Software
  *  along with this program; if not, write to the Free Software
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
  */
+#include <linux/errno.h>
 #include <linux/init.h>
 #include <linux/init.h>
+#include <linux/ioport.h>
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/smp.h>
 #include <linux/smp.h>
 #include <linux/types.h>
 #include <linux/types.h>
@@ -27,20 +29,31 @@
 #include <asm/reboot.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
 #include <asm/system.h>
 
 
-#define PMUCNT2REG	KSEG1ADDR(0x0f0000c6)
+#define PMU_TYPE1_BASE	0x0b0000a0UL
+#define PMU_TYPE1_SIZE	0x0eUL
+
+#define PMU_TYPE2_BASE	0x0f0000c0UL
+#define PMU_TYPE2_SIZE	0x10UL
+
+#define PMUCNT2REG	0x06
  #define SOFTRST	0x0010
  #define SOFTRST	0x0010
 
 
+static void __iomem *pmu_base;
+
+#define pmu_read(offset)		readw(pmu_base + (offset))
+#define pmu_write(offset, value)	writew((value), pmu_base + (offset))
+
 static inline void software_reset(void)
 static inline void software_reset(void)
 {
 {
-	uint16_t val;
+	uint16_t pmucnt2;
 
 
 	switch (current_cpu_data.cputype) {
 	switch (current_cpu_data.cputype) {
 	case CPU_VR4122:
 	case CPU_VR4122:
 	case CPU_VR4131:
 	case CPU_VR4131:
 	case CPU_VR4133:
 	case CPU_VR4133:
-		val = readw(PMUCNT2REG);
-		val |= SOFTRST;
-		writew(val, PMUCNT2REG);
+		pmucnt2 = pmu_read(PMUCNT2REG);
+		pmucnt2 |= SOFTRST;
+		pmu_write(PMUCNT2REG, pmucnt2);
 		break;
 		break;
 	default:
 	default:
 		break;
 		break;
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void)
 
 
 static int __init vr41xx_pmu_init(void)
 static int __init vr41xx_pmu_init(void)
 {
 {
+	unsigned long start, size;
+
+	switch (current_cpu_data.cputype) {
+	case CPU_VR4111:
+	case CPU_VR4121:
+		start = PMU_TYPE1_BASE;
+		size = PMU_TYPE1_SIZE;
+		break;
+	case CPU_VR4122:
+	case CPU_VR4131:
+	case CPU_VR4133:
+		start = PMU_TYPE2_BASE;
+		size = PMU_TYPE2_SIZE;
+		break;
+	default:
+		printk("Unexpected CPU of NEC VR4100 series\n");
+		return -ENODEV;
+	}
+
+	if (request_mem_region(start, size, "PMU") == NULL)
+		return -EBUSY;
+
+	pmu_base = ioremap(start, size);
+	if (pmu_base == NULL) {
+		release_mem_region(start, size);
+		return -EBUSY;
+	}
+
 	_machine_restart = vr41xx_restart;
 	_machine_restart = vr41xx_restart;
 	_machine_halt = vr41xx_halt;
 	_machine_halt = vr41xx_halt;
 	_machine_power_off = vr41xx_power_off;
 	_machine_power_off = vr41xx_power_off;
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void)
 	return 0;
 	return 0;
 }
 }
 
 
-early_initcall(vr41xx_pmu_init);
+core_initcall(vr41xx_pmu_init);

+ 2 - 2
arch/ppc/Kconfig

@@ -1143,12 +1143,12 @@ config PCI_QSPAN
 
 
 config PCI_8260
 config PCI_8260
 	bool
 	bool
-	depends on PCI && 8260 && !8272
+	depends on PCI && 8260
 	default y
 	default y
 
 
 config 8260_PCI9
 config 8260_PCI9
 	bool "  Enable workaround for MPC826x erratum PCI 9"
 	bool "  Enable workaround for MPC826x erratum PCI 9"
-	depends on PCI_8260
+	depends on PCI_8260 && !ADS8272
 	default y
 	default y
 
 
 choice
 choice

+ 2 - 1
arch/ppc/boot/images/Makefile

@@ -22,7 +22,8 @@ targets += uImage
 $(obj)/uImage: $(obj)/vmlinux.gz
 $(obj)/uImage: $(obj)/vmlinux.gz
 	$(Q)rm -f $@
 	$(Q)rm -f $@
 	$(call if_changed,uimage)
 	$(call if_changed,uimage)
-	@echo '  Image: $@' $(if $(wildcard $@),'is ready','not made')
+	@echo -n '  Image: $@ '
+	@if [ -f $@ ]; then echo 'is ready' ; else echo 'not made'; fi
 
 
 # Files generated that shall be removed upon make clean
 # Files generated that shall be removed upon make clean
 clean-files	:= sImage vmapus vmlinux* miboot* zImage* uImage
 clean-files	:= sImage vmapus vmlinux* miboot* zImage* uImage

+ 92 - 25
arch/ppc/configs/mpc8555_cds_defconfig

@@ -1,7 +1,7 @@
 #
 #
 # Automatically generated make config: don't edit
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.11-rc1
-# Thu Jan 20 01:25:35 2005
+# Linux kernel version: 2.6.12-rc4
+# Tue May 17 11:56:01 2005
 #
 #
 CONFIG_MMU=y
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_GENERIC_HARDIRQS=y
@@ -11,6 +11,7 @@ CONFIG_HAVE_DEC_LOCK=y
 CONFIG_PPC=y
 CONFIG_PPC=y
 CONFIG_PPC32=y
 CONFIG_PPC32=y
 CONFIG_GENERIC_NVRAM=y
 CONFIG_GENERIC_NVRAM=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
 
 
 #
 #
 # Code maturity level options
 # Code maturity level options
@@ -18,6 +19,7 @@ CONFIG_GENERIC_NVRAM=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_EXPERIMENTAL=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
 
 
 #
 #
 # General setup
 # General setup
@@ -29,12 +31,14 @@ CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_SYSCTL=y
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_AUDIT is not set
-CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 # CONFIG_HOTPLUG is not set
 CONFIG_KOBJECT_UEVENT=y
 CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 CONFIG_EMBEDDED=y
 # CONFIG_KALLSYMS is not set
 # CONFIG_KALLSYMS is not set
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_FUTEX=y
 # CONFIG_EPOLL is not set
 # CONFIG_EPOLL is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -44,6 +48,7 @@ CONFIG_CC_ALIGN_LABELS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_LOOPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_CC_ALIGN_JUMPS=0
 # CONFIG_TINY_SHMEM is not set
 # CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
 
 
 #
 #
 # Loadable module support
 # Loadable module support
@@ -62,10 +67,12 @@ CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_E500=y
 CONFIG_E500=y
 CONFIG_BOOKE=y
 CONFIG_BOOKE=y
 CONFIG_FSL_BOOKE=y
 CONFIG_FSL_BOOKE=y
+# CONFIG_PHYS_64BIT is not set
 CONFIG_SPE=y
 CONFIG_SPE=y
 CONFIG_MATH_EMULATION=y
 CONFIG_MATH_EMULATION=y
 # CONFIG_CPU_FREQ is not set
 # CONFIG_CPU_FREQ is not set
 CONFIG_PPC_GEN550=y
 CONFIG_PPC_GEN550=y
+# CONFIG_PM is not set
 CONFIG_85xx=y
 CONFIG_85xx=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_PPC_INDIRECT_PCI_BE=y
 
 
@@ -76,6 +83,7 @@ CONFIG_PPC_INDIRECT_PCI_BE=y
 CONFIG_MPC8555_CDS=y
 CONFIG_MPC8555_CDS=y
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_MPC8560_ADS is not set
 # CONFIG_SBC8560 is not set
 # CONFIG_SBC8560 is not set
+# CONFIG_STX_GP3 is not set
 CONFIG_MPC8555=y
 CONFIG_MPC8555=y
 CONFIG_85xx_PCI2=y
 CONFIG_85xx_PCI2=y
 
 
@@ -90,6 +98,7 @@ CONFIG_CPM2=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_BINFMT_MISC is not set
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_CMDLINE_BOOL is not set
+CONFIG_ISA_DMA_API=y
 
 
 #
 #
 # Bus options
 # Bus options
@@ -104,10 +113,6 @@ CONFIG_PCI_NAMES=y
 #
 #
 # CONFIG_PCCARD is not set
 # CONFIG_PCCARD is not set
 
 
-#
-# PC-card bridges
-#
-
 #
 #
 # Advanced setup
 # Advanced setup
 #
 #
@@ -180,7 +185,59 @@ CONFIG_IOSCHED_CFQ=y
 #
 #
 # ATA/ATAPI/MFM/RLL support
 # ATA/ATAPI/MFM/RLL support
 #
 #
-# CONFIG_IDE is not set
+CONFIG_IDE=y
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_IDE_SATA is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_IDE_TASK_IOCTL is not set
+
+#
+# IDE chipset support/bugfixes
+#
+CONFIG_IDE_GENERIC=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_IDEPCI_SHARE_IRQ=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_BLK_DEV_GENERIC=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+# CONFIG_BLK_DEV_IDEDMA_FORCED is not set
+CONFIG_IDEDMA_PCI_AUTO=y
+# CONFIG_IDEDMA_ONLYDISK is not set
+# CONFIG_BLK_DEV_AEC62XX is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_AMD74XX is not set
+# CONFIG_BLK_DEV_CMD64X is not set
+# CONFIG_BLK_DEV_TRIFLEX is not set
+# CONFIG_BLK_DEV_CY82C693 is not set
+# CONFIG_BLK_DEV_CS5520 is not set
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_SC1200 is not set
+# CONFIG_BLK_DEV_PIIX is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_PDC202XX_OLD is not set
+# CONFIG_BLK_DEV_PDC202XX_NEW is not set
+# CONFIG_BLK_DEV_SVWKS is not set
+# CONFIG_BLK_DEV_SIIMAGE is not set
+# CONFIG_BLK_DEV_SLC90E66 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+CONFIG_BLK_DEV_VIA82CXXX=y
+# CONFIG_IDE_ARM is not set
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_IDEDMA_IVB is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_HD is not set
 
 
 #
 #
 # SCSI device support
 # SCSI device support
@@ -220,7 +277,6 @@ CONFIG_NET=y
 #
 #
 CONFIG_PACKET=y
 CONFIG_PACKET=y
 # CONFIG_PACKET_MMAP is not set
 # CONFIG_PACKET_MMAP is not set
-# CONFIG_NETLINK_DEV is not set
 CONFIG_UNIX=y
 CONFIG_UNIX=y
 # CONFIG_NET_KEY is not set
 # CONFIG_NET_KEY is not set
 CONFIG_INET=y
 CONFIG_INET=y
@@ -369,14 +425,6 @@ CONFIG_INPUT=y
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVDEV is not set
 # CONFIG_INPUT_EVBUG is not set
 # CONFIG_INPUT_EVBUG is not set
 
 
-#
-# Input I/O drivers
-#
-# CONFIG_GAMEPORT is not set
-CONFIG_SOUND_GAMEPORT=y
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_I8042 is not set
-
 #
 #
 # Input Device Drivers
 # Input Device Drivers
 #
 #
@@ -386,6 +434,13 @@ CONFIG_SOUND_GAMEPORT=y
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
 # CONFIG_INPUT_MISC is not set
 # CONFIG_INPUT_MISC is not set
 
 
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+CONFIG_SOUND_GAMEPORT=y
+
 #
 #
 # Character devices
 # Character devices
 #
 #
@@ -406,6 +461,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_CPM is not set
 # CONFIG_SERIAL_CPM is not set
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_LEGACY_PTY_COUNT=256
@@ -433,6 +489,11 @@ CONFIG_GEN_RTC=y
 # CONFIG_DRM is not set
 # CONFIG_DRM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_RAW_DRIVER is not set
 
 
+#
+# TPM devices
+#
+# CONFIG_TCG_TPM is not set
+
 #
 #
 # I2C support
 # I2C support
 #
 #
@@ -456,11 +517,11 @@ CONFIG_I2C_CHARDEV=y
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_AMD8111 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I801 is not set
 # CONFIG_I2C_I810 is not set
 # CONFIG_I2C_I810 is not set
+# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_ISA is not set
 # CONFIG_I2C_ISA is not set
 CONFIG_I2C_MPC=y
 CONFIG_I2C_MPC=y
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_NFORCE2 is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PIIX4 is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_I2C_SAVAGE4 is not set
 # CONFIG_SCx200_ACB is not set
 # CONFIG_SCx200_ACB is not set
@@ -483,7 +544,9 @@ CONFIG_I2C_MPC=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCHER is not set
+# CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
 # CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_IT87 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM63 is not set
 # CONFIG_SENSORS_LM75 is not set
 # CONFIG_SENSORS_LM75 is not set
@@ -494,9 +557,11 @@ CONFIG_I2C_MPC=y
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM85 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM87 is not set
 # CONFIG_SENSORS_LM90 is not set
 # CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_MAX1619 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_PC87360 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SIS5595 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_W83781D is not set
 # CONFIG_SENSORS_W83781D is not set
@@ -506,10 +571,12 @@ CONFIG_I2C_MPC=y
 #
 #
 # Other I2C Chip support
 # Other I2C Chip support
 #
 #
+# CONFIG_SENSORS_DS1337 is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_EEPROM is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_PCF8591 is not set
 # CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_RTC8564 is not set
+# CONFIG_SENSORS_M41T00 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -538,7 +605,6 @@ CONFIG_I2C_MPC=y
 # Graphics support
 # Graphics support
 #
 #
 # CONFIG_FB is not set
 # CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
 
 
 #
 #
 # Sound
 # Sound
@@ -548,13 +614,9 @@ CONFIG_I2C_MPC=y
 #
 #
 # USB support
 # USB support
 #
 #
-# CONFIG_USB is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_OHCI=y
-
-#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
-#
+# CONFIG_USB is not set
 
 
 #
 #
 # USB Gadget Support
 # USB Gadget Support
@@ -585,6 +647,10 @@ CONFIG_JBD=y
 CONFIG_FS_MBCACHE=y
 CONFIG_FS_MBCACHE=y
 # CONFIG_REISERFS_FS is not set
 # CONFIG_REISERFS_FS is not set
 # CONFIG_JFS_FS is not set
 # CONFIG_JFS_FS is not set
+
+#
+# XFS support
+#
 # CONFIG_XFS_FS is not set
 # CONFIG_XFS_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_MINIX_FS is not set
 # CONFIG_ROMFS_FS is not set
 # CONFIG_ROMFS_FS is not set
@@ -646,7 +712,6 @@ CONFIG_NFS_FS=y
 # CONFIG_NFSD is not set
 # CONFIG_NFSD is not set
 CONFIG_ROOT_NFS=y
 CONFIG_ROOT_NFS=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD=y
-# CONFIG_EXPORTFS is not set
 CONFIG_SUNRPC=y
 CONFIG_SUNRPC=y
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_KRB5 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
 # CONFIG_RPCSEC_GSS_SPKM3 is not set
@@ -698,7 +763,9 @@ CONFIG_CRC32=y
 #
 #
 # Kernel hacking
 # Kernel hacking
 #
 #
+# CONFIG_PRINTK_TIME is not set
 # CONFIG_DEBUG_KERNEL is not set
 # CONFIG_DEBUG_KERNEL is not set
+CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_KGDB_CONSOLE is not set
 # CONFIG_KGDB_CONSOLE is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 # CONFIG_SERIAL_TEXT_DEBUG is not set
 
 

+ 9 - 6
arch/ppc/kernel/head_44x.S

@@ -330,8 +330,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 
@@ -464,8 +465,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 
@@ -533,8 +535,9 @@ interrupt_base:
 	/* If we are faulting a kernel address, we have to use the
 	/* If we are faulting a kernel address, we have to use the
 	 * kernel page tables.
 	 * kernel page tables.
 	 */
 	 */
-	andis.	r11, r10, 0x8000
-	beq	3f
+	lis	r11, TASK_SIZE@h
+	cmplw	r10, r11
+	blt+	3f
 	lis	r11, swapper_pg_dir@h
 	lis	r11, swapper_pg_dir@h
 	ori	r11, r11, swapper_pg_dir@l
 	ori	r11, r11, swapper_pg_dir@l
 
 

+ 14 - 1
arch/ppc/kernel/head_fsl_booke.S

@@ -232,7 +232,8 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	tlbwe
 	tlbwe
 
 
 /* 7. Jump to KERNELBASE mapping */
 /* 7. Jump to KERNELBASE mapping */
-	li	r7,0
+	lis	r7,MSR_KERNEL@h
+	ori	r7,r7,MSR_KERNEL@l
 	bl	1f			/* Find our address */
 	bl	1f			/* Find our address */
 1:	mflr	r9
 1:	mflr	r9
 	rlwimi	r6,r9,0,20,31
 	rlwimi	r6,r9,0,20,31
@@ -293,6 +294,18 @@ skpinv:	addi	r6,r6,1				/* Increment */
 	mtspr	SPRN_HID0, r2
 	mtspr	SPRN_HID0, r2
 #endif
 #endif
 
 
+#if !defined(CONFIG_BDI_SWITCH)
+	/*
+	 * The Abatron BDI JTAG debugger does not tolerate others
+	 * mucking with the debug registers.
+	 */
+	lis	r2,DBCR0_IDM@h
+	mtspr	SPRN_DBCR0,r2
+	/* clear any residual debug events */
+	li	r2,-1
+	mtspr	SPRN_DBSR,r2
+#endif
+
 	/*
 	/*
 	 * This is where the main kernel code starts.
 	 * This is where the main kernel code starts.
 	 */
 	 */

+ 3 - 1
arch/ppc/kernel/setup.c

@@ -499,7 +499,7 @@ static int __init set_preferred_console(void)
 {
 {
 	struct device_node *prom_stdout;
 	struct device_node *prom_stdout;
 	char *name;
 	char *name;
-	int offset;
+	int offset = 0;
 
 
 	if (of_stdout_device == NULL)
 	if (of_stdout_device == NULL)
 		return -ENODEV;
 		return -ENODEV;
@@ -753,6 +753,8 @@ void __init setup_arch(char **cmdline_p)
 	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
 	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
 	*cmdline_p = cmd_line;
 	*cmdline_p = cmd_line;
 
 
+	parse_early_param();
+
 	/* set up the bootmem stuff with available memory */
 	/* set up the bootmem stuff with available memory */
 	do_init_bootmem();
 	do_init_bootmem();
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);
 	if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab);

+ 1 - 6
arch/ppc/kernel/traps.c

@@ -408,12 +408,7 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
 
 
 	/* Early out if we are an invalid form of lswx */
 	/* Early out if we are an invalid form of lswx */
 	if ((instword & INST_STRING_MASK) == INST_LSWX)
 	if ((instword & INST_STRING_MASK) == INST_LSWX)
-		if ((rA >= rT) || (NB_RB >= rT) || (rT == rA) || (rT == NB_RB))
-			return -EINVAL;
-
-	/* Early out if we are an invalid form of lswi */
-	if ((instword & INST_STRING_MASK) == INST_LSWI)
-		if ((rA >= rT) || (rT == rA))
+		if ((rT == rA) || (rT == NB_RB))
 			return -EINVAL;
 			return -EINVAL;
 
 
 	EA = (rA == 0) ? 0 : regs->gpr[rA];
 	EA = (rA == 0) ? 0 : regs->gpr[rA];

+ 5 - 2
arch/ppc/lib/string.S

@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user)
 #ifdef CONFIG_8xx
 #ifdef CONFIG_8xx
 	/* Don't use prefetch on 8xx */
 	/* Don't use prefetch on 8xx */
 	mtctr	r0
 	mtctr	r0
+	li	r0,0
 53:	COPY_16_BYTES_WITHEX(0)
 53:	COPY_16_BYTES_WITHEX(0)
 	bdnz	53b
 	bdnz	53b
 
 
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user)
 /* or write fault in cacheline loop */
 /* or write fault in cacheline loop */
 105:	li	r9,1
 105:	li	r9,1
 92:	li	r3,LG_CACHELINE_BYTES
 92:	li	r3,LG_CACHELINE_BYTES
-	b	99f
+	mfctr	r8
+	add	r0,r0,r8
+	b	106f
 /* read fault in final word loop */
 /* read fault in final word loop */
 108:	li	r9,0
 108:	li	r9,0
 	b	93f
 	b	93f
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user)
  * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
  * r5 + (ctr << r3), and r9 is 0 for read or 1 for write.
  */
  */
 99:	mfctr	r0
 99:	mfctr	r0
-	slw	r3,r0,r3
+106:	slw	r3,r0,r3
 	add.	r3,r3,r5
 	add.	r3,r3,r5
 	beq	120f			/* shouldn't happen */
 	beq	120f			/* shouldn't happen */
 	cmpwi	0,r9,0
 	cmpwi	0,r9,0

+ 1 - 0
arch/ppc/mm/init.c

@@ -179,6 +179,7 @@ void free_initmem(void)
 	if (!have_of)
 	if (!have_of)
 		FREESEC(openfirmware);
 		FREESEC(openfirmware);
  	printk("\n");
  	printk("\n");
+	ppc_md.progress = NULL;
 #undef FREESEC
 #undef FREESEC
 }
 }
 
 

+ 0 - 1
arch/ppc/platforms/83xx/mpc834x_sys.c

@@ -127,7 +127,6 @@ mpc834x_sys_map_io(void)
 {
 {
 	/* we steal the lowest ioremap addr for virt space */
 	/* we steal the lowest ioremap addr for virt space */
 	io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
 	io_block_mapping(VIRT_IMMRBAR, immrbar, 1024*1024, _PAGE_IO);
-	io_block_mapping(BCSR_VIRT_ADDR, BCSR_PHYS_ADDR, BCSR_SIZE, _PAGE_IO);
 }
 }
 
 
 int
 int

+ 6 - 1
arch/ppc/platforms/83xx/mpc834x_sys.h

@@ -26,9 +26,14 @@
 #define VIRT_IMMRBAR		((uint)0xfe000000)
 #define VIRT_IMMRBAR		((uint)0xfe000000)
 
 
 #define BCSR_PHYS_ADDR		((uint)0xf8000000)
 #define BCSR_PHYS_ADDR		((uint)0xf8000000)
-#define BCSR_VIRT_ADDR		((uint)0xfe100000)
 #define BCSR_SIZE		((uint)(32 * 1024))
 #define BCSR_SIZE		((uint)(32 * 1024))
 
 
+#define BCSR_MISC_REG2_OFF	0x07
+#define BCSR_MISC_REG2_PORESET	0x01
+
+#define BCSR_MISC_REG3_OFF	0x08
+#define BCSR_MISC_REG3_CNFLOCK	0x80
+
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 /* PCI interrupt controller */
 /* PCI interrupt controller */
 #define PIRQA        MPC83xx_IRQ_IRQ4
 #define PIRQA        MPC83xx_IRQ_IRQ4

+ 3 - 0
arch/ppc/platforms/85xx/mpc8540_ads.c

@@ -210,6 +210,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("mpc8540ads_init(): exit", 0);
 		ppc_md.progress("mpc8540ads_init(): exit", 0);

+ 141 - 2
arch/ppc/platforms/85xx/mpc85xx_cds_common.c

@@ -44,6 +44,7 @@
 #include <asm/machdep.h>
 #include <asm/machdep.h>
 #include <asm/prom.h>
 #include <asm/prom.h>
 #include <asm/open_pic.h>
 #include <asm/open_pic.h>
+#include <asm/i8259.h>
 #include <asm/bootinfo.h>
 #include <asm/bootinfo.h>
 #include <asm/pci-bridge.h>
 #include <asm/pci-bridge.h>
 #include <asm/mpc85xx.h>
 #include <asm/mpc85xx.h>
@@ -181,6 +182,7 @@ void __init
 mpc85xx_cds_init_IRQ(void)
 mpc85xx_cds_init_IRQ(void)
 {
 {
 	bd_t *binfo = (bd_t *) __res;
 	bd_t *binfo = (bd_t *) __res;
+	int i;
 
 
 	/* Determine the Physical Address of the OpenPIC regs */
 	/* Determine the Physical Address of the OpenPIC regs */
 	phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
 	phys_addr_t OpenPIC_PAddr = binfo->bi_immr_base + MPC85xx_OPENPIC_OFFSET;
@@ -198,6 +200,15 @@ mpc85xx_cds_init_IRQ(void)
 	 */
 	 */
 	openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
 	openpic_init(MPC85xx_OPENPIC_IRQ_OFFSET);
 
 
+#ifdef CONFIG_PCI
+	openpic_hookup_cascade(PIRQ0A, "82c59 cascade", i8259_irq);
+
+	for (i = 0; i < NUM_8259_INTERRUPTS; i++)
+		irq_desc[i].handler = &i8259_pic;
+
+	i8259_init(0);
+#endif
+
 #ifdef CONFIG_CPM2
 #ifdef CONFIG_CPM2
 	/* Setup CPM2 PIC */
 	/* Setup CPM2 PIC */
         cpm2_init_IRQ();
         cpm2_init_IRQ();
@@ -231,7 +242,7 @@ mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
 			 * interrupt on slot */
 			 * interrupt on slot */
 		{
 		{
 			{ 0, 1, 2, 3 }, /* 16 - PMC */
 			{ 0, 1, 2, 3 }, /* 16 - PMC */
-			{ 3, 0, 0, 0 }, /* 17 P2P (Tsi320) */
+			{ 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */
 			{ 0, 1, 2, 3 }, /* 18 - Slot 1 */
 			{ 0, 1, 2, 3 }, /* 18 - Slot 1 */
 			{ 1, 2, 3, 0 }, /* 19 - Slot 2 */
 			{ 1, 2, 3, 0 }, /* 19 - Slot 2 */
 			{ 2, 3, 0, 1 }, /* 20 - Slot 3 */
 			{ 2, 3, 0, 1 }, /* 20 - Slot 3 */
@@ -280,13 +291,135 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
 			return PCIBIOS_DEVICE_NOT_FOUND;
 			return PCIBIOS_DEVICE_NOT_FOUND;
 #endif
 #endif
 	/* We explicitly do not go past the Tundra 320 Bridge */
 	/* We explicitly do not go past the Tundra 320 Bridge */
-	if (bus == 1)
+	if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 	if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL))
 		return PCIBIOS_DEVICE_NOT_FOUND;
 		return PCIBIOS_DEVICE_NOT_FOUND;
 	else
 	else
 		return PCIBIOS_SUCCESSFUL;
 		return PCIBIOS_SUCCESSFUL;
 }
 }
+
+void __init
+mpc85xx_cds_enable_via(struct pci_controller *hose)
+{
+	u32 pci_class;
+	u16 vid, did;
+
+	early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+	if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	/* Configure P2P so that we can reach bus 1 */
+	early_write_config_byte(hose, 0, 0x88, PCI_PRIMARY_BUS, 0);
+	early_write_config_byte(hose, 0, 0x88, PCI_SECONDARY_BUS, 1);
+	early_write_config_byte(hose, 0, 0x88, PCI_SUBORDINATE_BUS, 0xff);
+
+	early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+	early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+
+	if ((vid != PCI_VENDOR_ID_VIA) ||
+			(did != PCI_DEVICE_ID_VIA_82C686))
+		return;
+
+	/* Enable USB and IDE functions */
+	early_write_config_byte(hose, 1, 0x10, 0x48, 0x08);
+}
+
+void __init
+mpc85xx_cds_fixup_via(struct pci_controller *hose)
+{
+	u32 pci_class;
+	u16 vid, did;
+
+	early_read_config_dword(hose, 0, 0x88, PCI_CLASS_REVISION, &pci_class);
+	if ((pci_class >> 16) != PCI_CLASS_BRIDGE_PCI)
+		return;
+
+	/*
+	 * Force the backplane P2P bridge to have a window
+	 * open from 0x00000000-0x00001fff in PCI I/O space.
+	 * This allows legacy I/O (i8259, etc) on the VIA
+	 * southbridge to be accessed.
+	 */
+	early_write_config_byte(hose, 0, 0x88, PCI_IO_BASE, 0x00);
+	early_write_config_word(hose, 0, 0x88, PCI_IO_BASE_UPPER16, 0x0000);
+	early_write_config_byte(hose, 0, 0x88, PCI_IO_LIMIT, 0x10);
+	early_write_config_word(hose, 0, 0x88, PCI_IO_LIMIT_UPPER16, 0x0000);
+
+	early_read_config_word(hose, 1, 0x10, PCI_VENDOR_ID, &vid);
+	early_read_config_word(hose, 1, 0x10, PCI_DEVICE_ID, &did);
+	if ((vid != PCI_VENDOR_ID_VIA) ||
+			(did != PCI_DEVICE_ID_VIA_82C686))
+		return;
+
+	/*
+	 * Since the P2P window was forced to cover the fixed
+	 * legacy I/O addresses, it is necessary to manually
+	 * place the base addresses for the IDE and USB functions
+	 * within this window.
+	 */
+	/* Function 1, IDE */
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_0, 0x1ff8);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_1, 0x1ff4);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_2, 0x1fe8);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_3, 0x1fe4);
+	early_write_config_dword(hose, 1, 0x11, PCI_BASE_ADDRESS_4, 0x1fd0);
+
+	/* Function 2, USB ports 0-1 */
+	early_write_config_dword(hose, 1, 0x12, PCI_BASE_ADDRESS_4, 0x1fa0);
+
+	/* Function 3, USB ports 2-3 */
+	early_write_config_dword(hose, 1, 0x13, PCI_BASE_ADDRESS_4, 0x1f80);
+
+	/* Function 5, Power Management */
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_0, 0x1e00);
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_1, 0x1dfc);
+	early_write_config_dword(hose, 1, 0x15, PCI_BASE_ADDRESS_2, 0x1df8);
+
+	/* Function 6, AC97 Interface */
+	early_write_config_dword(hose, 1, 0x16, PCI_BASE_ADDRESS_0, 0x1c00);
+}
+
+void __init
+mpc85xx_cds_pcibios_fixup(void)
+{
+        struct pci_dev *dev = NULL;
+	u_char		c;
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_1, NULL))) {
+                /*
+                 * U-Boot does not set the enable bits
+                 * for the IDE device. Force them on here.
+                 */
+                pci_read_config_byte(dev, 0x40, &c);
+                c |= 0x03; /* IDE: Chip Enable Bits */
+                pci_write_config_byte(dev, 0x40, c);
+
+		/*
+		 * Since only primary interface works, force the
+		 * IDE function to standard primary IDE interrupt
+		 * w/ 8259 offset
+		 */
+                dev->irq = 14;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
+        }
+
+	/*
+	 * Force legacy USB interrupt routing
+	 */
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, NULL))) {
+                dev->irq = 10;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10);
+        }
+
+        if ((dev = pci_find_device(PCI_VENDOR_ID_VIA,
+                                        PCI_DEVICE_ID_VIA_82C586_2, dev))) {
+                dev->irq = 11;
+                pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11);
+        }
+}
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 TODC_ALLOC();
 TODC_ALLOC();
@@ -328,6 +461,9 @@ mpc85xx_cds_setup_arch(void)
 	loops_per_jiffy = freq / HZ;
 	loops_per_jiffy = freq / HZ;
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
+	/* VIA IDE configuration */
+        ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
+
 	/* setup PCI host bridges */
 	/* setup PCI host bridges */
 	mpc85xx_setup_hose();
 	mpc85xx_setup_hose();
 #endif
 #endif
@@ -459,6 +595,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif /* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = mpc85xx_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("mpc85xx_cds_init(): exit", 0);
 		ppc_md.progress("mpc85xx_cds_init(): exit", 0);

+ 3 - 0
arch/ppc/platforms/85xx/mpc85xx_cds_common.h

@@ -77,4 +77,7 @@
 
 
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
 #define MPC85XX_PCI2_IO_SIZE         0x01000000
 
 
+#define NR_8259_INTS		     16
+#define CPM_IRQ_OFFSET		     NR_8259_INTS
+
 #endif /* __MACH_MPC85XX_CDS_H__ */
 #endif /* __MACH_MPC85XX_CDS_H__ */

+ 3 - 0
arch/ppc/platforms/85xx/sbc8560.c

@@ -221,6 +221,9 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 #if defined(CONFIG_SERIAL_8250) && defined(CONFIG_SERIAL_TEXT_DEBUG)
 	ppc_md.progress = gen550_progress;
 	ppc_md.progress = gen550_progress;
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
 #endif	/* CONFIG_SERIAL_8250 && CONFIG_SERIAL_TEXT_DEBUG */
+#if defined(CONFIG_SERIAL_8250) && defined(CONFIG_KGDB)
+	ppc_md.early_serial_map = sbc8560_early_serial_map;
+#endif	/* CONFIG_SERIAL_8250 && CONFIG_KGDB */
 
 
 	if (ppc_md.progress)
 	if (ppc_md.progress)
 		ppc_md.progress("sbc8560_init(): exit", 0);
 		ppc_md.progress("sbc8560_init(): exit", 0);

+ 22 - 14
arch/ppc/platforms/pmac_cpufreq.c

@@ -85,14 +85,11 @@ static int no_schedule;
 static int has_cpu_l2lve;
 static int has_cpu_l2lve;
 
 
 
 
-#define PMAC_CPU_LOW_SPEED	1
-#define PMAC_CPU_HIGH_SPEED	0
-
 /* There are only two frequency states for each processor. Values
 /* There are only two frequency states for each processor. Values
  * are in kHz for the time being.
  * are in kHz for the time being.
  */
  */
-#define CPUFREQ_HIGH                  PMAC_CPU_HIGH_SPEED
-#define CPUFREQ_LOW                   PMAC_CPU_LOW_SPEED
+#define CPUFREQ_HIGH                  0
+#define CPUFREQ_LOW                   1
 
 
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 	{CPUFREQ_HIGH, 		0},
 	{CPUFREQ_HIGH, 		0},
@@ -100,6 +97,11 @@ static struct cpufreq_frequency_table pmac_cpu_freqs[] = {
 	{0,			CPUFREQ_TABLE_END},
 	{0,			CPUFREQ_TABLE_END},
 };
 };
 
 
+static struct freq_attr* pmac_cpu_freqs_attr[] = {
+	&cpufreq_freq_attr_scaling_available_freqs,
+	NULL,
+};
+
 static inline void local_delay(unsigned long ms)
 static inline void local_delay(unsigned long ms)
 {
 {
 	if (no_schedule)
 	if (no_schedule)
@@ -269,6 +271,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
 #ifdef DEBUG_FREQ
 #ifdef DEBUG_FREQ
 	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 	printk(KERN_DEBUG "HID1, before: %x\n", mfspr(SPRN_HID1));
 #endif
 #endif
+	pmu_suspend();
+
 	/* Disable all interrupt sources on openpic */
 	/* Disable all interrupt sources on openpic */
  	pic_prio = openpic_get_priority();
  	pic_prio = openpic_get_priority();
 	openpic_set_priority(0xf);
 	openpic_set_priority(0xf);
@@ -343,6 +347,8 @@ static int __pmac pmu_set_cpu_speed(int low_speed)
 	debug_calc_bogomips();
 	debug_calc_bogomips();
 #endif
 #endif
 
 
+	pmu_resume();
+
 	preempt_enable();
 	preempt_enable();
 
 
 	return 0;
 	return 0;
@@ -355,7 +361,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 	static unsigned long prev_l3cr;
 	static unsigned long prev_l3cr;
 
 
 	freqs.old = cur_freq;
 	freqs.old = cur_freq;
-	freqs.new = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+	freqs.new = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 	freqs.cpu = smp_processor_id();
 	freqs.cpu = smp_processor_id();
 
 
 	if (freqs.old == freqs.new)
 	if (freqs.old == freqs.new)
@@ -363,7 +369,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 
 
 	if (notify)
 	if (notify)
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
 		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
-	if (speed_mode == PMAC_CPU_LOW_SPEED &&
+	if (speed_mode == CPUFREQ_LOW &&
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 		l3cr = _get_L3CR();
 		l3cr = _get_L3CR();
 		if (l3cr & L3CR_L3E) {
 		if (l3cr & L3CR_L3E) {
@@ -371,8 +377,8 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 			_set_L3CR(0);
 			_set_L3CR(0);
 		}
 		}
 	}
 	}
-	set_speed_proc(speed_mode == PMAC_CPU_LOW_SPEED);
-	if (speed_mode == PMAC_CPU_HIGH_SPEED &&
+	set_speed_proc(speed_mode == CPUFREQ_LOW);
+	if (speed_mode == CPUFREQ_HIGH &&
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 	    cpu_has_feature(CPU_FTR_L3CR)) {
 		l3cr = _get_L3CR();
 		l3cr = _get_L3CR();
 		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
 		if ((prev_l3cr & L3CR_L3E) && l3cr != prev_l3cr)
@@ -380,7 +386,7 @@ static int __pmac do_set_cpu_speed(int speed_mode, int notify)
 	}
 	}
 	if (notify)
 	if (notify)
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 		cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
-	cur_freq = (speed_mode == PMAC_CPU_HIGH_SPEED) ? hi_freq : low_freq;
+	cur_freq = (speed_mode == CPUFREQ_HIGH) ? hi_freq : low_freq;
 
 
 	return 0;
 	return 0;
 }
 }
@@ -423,7 +429,8 @@ static int __pmac pmac_cpufreq_cpu_init(struct cpufreq_policy *policy)
 	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
 	policy->cpuinfo.transition_latency	= CPUFREQ_ETERNAL;
 	policy->cur = cur_freq;
 	policy->cur = cur_freq;
 
 
-	return cpufreq_frequency_table_cpuinfo(policy, &pmac_cpu_freqs[0]);
+	cpufreq_frequency_table_get_attr(pmac_cpu_freqs, policy->cpu);
+	return cpufreq_frequency_table_cpuinfo(policy, pmac_cpu_freqs);
 }
 }
 
 
 static u32 __pmac read_gpio(struct device_node *np)
 static u32 __pmac read_gpio(struct device_node *np)
@@ -457,7 +464,7 @@ static int __pmac pmac_cpufreq_suspend(struct cpufreq_policy *policy, u32 state)
 	no_schedule = 1;
 	no_schedule = 1;
 	sleep_freq = cur_freq;
 	sleep_freq = cur_freq;
 	if (cur_freq == low_freq)
 	if (cur_freq == low_freq)
-		do_set_cpu_speed(PMAC_CPU_HIGH_SPEED, 0);
+		do_set_cpu_speed(CPUFREQ_HIGH, 0);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -473,8 +480,8 @@ static int __pmac pmac_cpufreq_resume(struct cpufreq_policy *policy)
 	 * is that we force a switch to whatever it was, which is
 	 * is that we force a switch to whatever it was, which is
 	 * probably high speed due to our suspend() routine
 	 * probably high speed due to our suspend() routine
 	 */
 	 */
-	do_set_cpu_speed(sleep_freq == low_freq ? PMAC_CPU_LOW_SPEED
-			 : PMAC_CPU_HIGH_SPEED, 0);
+	do_set_cpu_speed(sleep_freq == low_freq ?
+			 CPUFREQ_LOW : CPUFREQ_HIGH, 0);
 
 
 	no_schedule = 0;
 	no_schedule = 0;
 	return 0;
 	return 0;
@@ -488,6 +495,7 @@ static struct cpufreq_driver pmac_cpufreq_driver = {
 	.suspend	= pmac_cpufreq_suspend,
 	.suspend	= pmac_cpufreq_suspend,
 	.resume		= pmac_cpufreq_resume,
 	.resume		= pmac_cpufreq_resume,
 	.flags		= CPUFREQ_PM_NO_WARN,
 	.flags		= CPUFREQ_PM_NO_WARN,
+	.attr		= pmac_cpu_freqs_attr,
 	.name		= "powermac",
 	.name		= "powermac",
 	.owner		= THIS_MODULE,
 	.owner		= THIS_MODULE,
 };
 };

+ 18 - 23
arch/ppc/platforms/pq2ads.h

@@ -49,10 +49,10 @@
 /* PCI interrupt controller */
 /* PCI interrupt controller */
 #define PCI_INT_STAT_REG	0xF8200000
 #define PCI_INT_STAT_REG	0xF8200000
 #define PCI_INT_MASK_REG	0xF8200004
 #define PCI_INT_MASK_REG	0xF8200004
-#define PIRQA			(NR_SIU_INTS + 0)
-#define PIRQB			(NR_SIU_INTS + 1)
-#define PIRQC			(NR_SIU_INTS + 2)
-#define PIRQD			(NR_SIU_INTS + 3)
+#define PIRQA			(NR_CPM_INTS + 0)
+#define PIRQB			(NR_CPM_INTS + 1)
+#define PIRQC			(NR_CPM_INTS + 2)
+#define PIRQD			(NR_CPM_INTS + 3)
 
 
 /*
 /*
  * PCI memory map definitions for MPC8266ADS-PCI.
  * PCI memory map definitions for MPC8266ADS-PCI.
@@ -68,28 +68,23 @@
  *	0x00000000-0x1FFFFFFF	0x00000000-0x1FFFFFFF	MPC8266 local memory
  *	0x00000000-0x1FFFFFFF	0x00000000-0x1FFFFFFF	MPC8266 local memory
  */
  */
 
 
-/* window for a PCI master to access MPC8266 memory */
-#define PCI_SLV_MEM_LOCAL	0x00000000	/* Local base */
-#define PCI_SLV_MEM_BUS		0x00000000	/* PCI base */
+/* All the other PCI memory map definitions reside at syslib/m82xx_pci.h
+   Here we should redefine what is unique for this board */
+#define M82xx_PCI_SLAVE_MEM_LOCAL	0x00000000	/* Local base */
+#define M82xx_PCI_SLAVE_MEM_BUS		0x00000000	/* PCI base */
+#define M82xx_PCI_SLAVE_MEM_SIZE	0x10000000	/* 256 Mb */
 
 
-/* window for the processor to access PCI memory with prefetching */
-#define PCI_MSTR_MEM_LOCAL	0x80000000	/* Local base */
-#define PCI_MSTR_MEM_BUS	0x80000000	/* PCI base   */
-#define PCI_MSTR_MEM_SIZE	0x20000000	/* 512MB */
+#define M82xx_PCI_SLAVE_SEC_WND_SIZE	~(0x40000000 - 1U)	/* 2 x 512Mb  */
+#define M82xx_PCI_SLAVE_SEC_WND_BASE	0x80000000		/* PCI Memory base */
 
 
-/* window for the processor to access PCI memory without prefetching */
-#define PCI_MSTR_MEMIO_LOCAL	0xA0000000	/* Local base */
-#define PCI_MSTR_MEMIO_BUS	0xA0000000	/* PCI base   */
-#define PCI_MSTR_MEMIO_SIZE	0x20000000	/* 512MB */
+#if defined(CONFIG_ADS8272)
+#define PCI_INT_TO_SIU 	SIU_INT_IRQ2
+#elif defined(CONFIG_PQ2FADS)
+#define PCI_INT_TO_SIU 	SIU_INT_IRQ6
+#else
+#warning PCI Bridge will be without interrupts support
+#endif
 
 
-/* window for the processor to access PCI I/O */
-#define PCI_MSTR_IO_LOCAL	0xF4000000	/* Local base */
-#define PCI_MSTR_IO_BUS         0x00000000	/* PCI base   */
-#define PCI_MSTR_IO_SIZE        0x04000000	/* 64MB */
-
-#define _IO_BASE		PCI_MSTR_IO_LOCAL
-#define _ISA_MEM_BASE		PCI_MSTR_MEMIO_LOCAL
-#define PCI_DRAM_OFFSET		PCI_SLV_MEM_BUS
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 #endif /* __MACH_ADS8260_DEFS */
 #endif /* __MACH_ADS8260_DEFS */

+ 2 - 2
arch/ppc/syslib/Makefile

@@ -81,7 +81,7 @@ obj-$(CONFIG_SBC82xx)		+= todc_time.o
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 obj-$(CONFIG_SPRUCE)		+= cpc700_pic.o indirect_pci.o pci_auto.o \
 				   todc_time.o
 				   todc_time.o
 obj-$(CONFIG_8260)		+= m8260_setup.o
 obj-$(CONFIG_8260)		+= m8260_setup.o
-obj-$(CONFIG_PCI_8260)		+= m8260_pci.o indirect_pci.o
+obj-$(CONFIG_PCI_8260)		+= m82xx_pci.o indirect_pci.o pci_auto.o
 obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
 obj-$(CONFIG_8260_PCI9)		+= m8260_pci_erratum9.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 obj-$(CONFIG_CPM2)		+= cpm2_common.o cpm2_pic.o
 ifeq ($(CONFIG_PPC_GEN550),y)
 ifeq ($(CONFIG_PPC_GEN550),y)
@@ -97,7 +97,7 @@ obj-$(CONFIG_MPC10X_OPENPIC)	+= open_pic.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_40x)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
 obj-$(CONFIG_BOOKE)		+= dcr.o
 obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
 obj-$(CONFIG_85xx)		+= open_pic.o ppc85xx_common.o ppc85xx_setup.o \
-					ppc_sys.o mpc85xx_sys.o \
+					ppc_sys.o i8259.o mpc85xx_sys.o \
 					mpc85xx_devices.o
 					mpc85xx_devices.o
 ifeq ($(CONFIG_85xx),y)
 ifeq ($(CONFIG_85xx),y)
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o
 obj-$(CONFIG_PCI)		+= indirect_pci.o pci_auto.o

+ 1 - 1
arch/ppc/syslib/ipic.c

@@ -479,7 +479,7 @@ void __init ipic_init(phys_addr_t phys_addr,
 	temp = 0;
 	temp = 0;
 	for (i = 0 ; i < senses_count ; i++) {
 	for (i = 0 ; i < senses_count ; i++) {
 		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
 		if ((senses[i] & IRQ_SENSE_MASK) == IRQ_SENSE_EDGE) {
-			temp |= 1 << (16 - i);
+			temp |= 1 << (15 - i);
 			if (i != 0)
 			if (i != 0)
 				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
 				irq_desc[i + irq_offset + MPC83xx_IRQ_EXT1 - 1].status = 0;
 			else
 			else

+ 0 - 193
arch/ppc/syslib/m8260_pci.c

@@ -1,193 +0,0 @@
-/*
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * (C) Copyright 2004 Red Hat, Inc.
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
-
-#include <asm/byteorder.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/immap_cpm2.h>
-#include <asm/mpc8260.h>
-
-#include "m8260_pci.h"
-
-
-/* PCI bus configuration registers.
- */
-
-static void __init m8260_setup_pci(struct pci_controller *hose)
-{
-	volatile cpm2_map_t *immap = cpm2_immr;
-	unsigned long pocmr;
-	u16 tempShort;
-
-#ifndef CONFIG_ATC 	/* already done in U-Boot */
-	/* 
-	 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), 
-	 * and local bus for PCI (SIUMCR [LBPC]).
-	 */
-	immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000;
-#endif
-
-	/* Make PCI lowest priority */
-	/* Each 4 bits is a device bus request  and the MS 4bits 
-	   is highest priority */
-	/* Bus               4bit value 
-	   ---               ----------
-	   CPM high          0b0000
-	   CPM middle        0b0001
-	   CPM low           0b0010
-	   PCI reguest       0b0011
-	   Reserved          0b0100
-	   Reserved          0b0101
-	   Internal Core     0b0110
-	   External Master 1 0b0111
-	   External Master 2 0b1000
-	   External Master 3 0b1001
-	   The rest are reserved */
-	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
-
-	/* Park bus on core while modifying PCI Bus accesses */
-	immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6;
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI space. This 
-	 * window is set up using the first SIU PCIBR registers.
-	 */
-	immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK;
-	immap->im_memctl.memc_pcibr0 =	MPC826x_PCI_BASE | PCIBR_ENABLE;
-
-	/* Disable machine check on no response or target abort */
-	immap->im_pci.pci_emr = cpu_to_le32(0x1fe7);
-	/* Release PCI RST (by default the PCI RST signal is held low)  */
-	immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
-
-	/* give it some time */
-	mdelay(1);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI Memory (prefetch) 
-	 * space. This window is set up using the first set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12);
-	immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI Memory (non-prefetch) 
-	 * space. This window is set up using the second set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12);
-	immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE);
-
-	/* 
-	 * Set up master window that allows the CPU to access PCI IO space. This window
-	 * is set up using the third set of Outbound ATU registers.
-	 */
-	immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12);
-	immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12);
-	pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO);
-
-	/* 
-	 * Set up slave window that allows PCI masters to access MPC826x local memory. 
-	 * This window is set up using the first set of Inbound ATU registers
-	 */
-
-	immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12);
-	immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12);
-	pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff;
-	immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN);
-
-	/* See above for description - puts PCI request as highest priority */
-	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
-
-	/* Park the bus on the PCI */
-	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
-
-	/* Host mode - specify the bridge as a host-PCI bridge */
-	early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST);
-
-	/* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */
-	early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort);
-	early_write_config_word(hose, 0, 0, PCI_COMMAND,
-				tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
-}
-
-void __init m8260_find_bridges(void)
-{
-	extern int pci_assign_all_busses;
-	struct pci_controller * hose;
-
-	pci_assign_all_busses = 1;
-
-	hose = pcibios_alloc_controller();
-
-	if (!hose)
-		return;
-
-	ppc_md.pci_swizzle = common_swizzle;
-
-	hose->first_busno = 0;
-	hose->bus_offset = 0;
-	hose->last_busno = 0xff;
-
-	setup_m8260_indirect_pci(hose, 
-				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
-				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
-
-	m8260_setup_pci(hose);
-        hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET;
-
-        hose->io_base_virt = ioremap(MPC826x_PCI_IO_BASE,
-                                        MPC826x_PCI_IO_SIZE);
-        isa_io_base = (unsigned long) hose->io_base_virt;
- 
-        /* setup resources */
-        pci_init_resource(&hose->mem_resources[0],
-			  MPC826x_PCI_LOWER_MEM,
-			  MPC826x_PCI_UPPER_MEM,
-			  IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
-
-        pci_init_resource(&hose->mem_resources[1],
-			  MPC826x_PCI_LOWER_MMIO,
-			  MPC826x_PCI_UPPER_MMIO,
-			  IORESOURCE_MEM, "PCI memory");
-
-        pci_init_resource(&hose->io_resource,
-			  MPC826x_PCI_LOWER_IO,
-			  MPC826x_PCI_UPPER_IO,
-			  IORESOURCE_IO, "PCI I/O");
-}

+ 0 - 76
arch/ppc/syslib/m8260_pci.h

@@ -1,76 +0,0 @@
-
-#ifndef _PPC_KERNEL_M8260_PCI_H
-#define _PPC_KERNEL_M8260_PCI_H
-
-#include <asm/m8260_pci.h>
-
-/*
- *   Local->PCI map (from CPU)                             controlled by
- *   MPC826x master window
- *
- *   0x80000000 - 0xBFFFFFFF    Total CPU2PCI space        PCIBR0
- *                       
- *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
- *   0xA0000000 - 0xAFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
- *   0xB0000000 - 0xB0FFFFFF    32-bit PCI IO              (Outbound ATU #3)
- *                      
- *   PCI->Local map (from PCI)
- *   MPC826x slave window                                  controlled by
- *
- *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
- */
-
-/* 
- * Slave window that allows PCI masters to access MPC826x local memory. 
- * This window is set up using the first set of Inbound ATU registers
- */
-
-#ifndef MPC826x_PCI_SLAVE_MEM_LOCAL
-#define MPC826x_PCI_SLAVE_MEM_LOCAL	(((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_BUS	(((struct bd_info *)__res)->bi_memstart)
-#define MPC826x_PCI_SLAVE_MEM_SIZE	(((struct bd_info *)__res)->bi_memsize)
-#endif
-
-/* 
- * This is the window that allows the CPU to access PCI address space.
- * It will be setup with the SIU PCIBR0 register. All three PCI master
- * windows, which allow the CPU to access PCI prefetch, non prefetch,
- * and IO space (see below), must all fit within this window. 
- */
-#ifndef MPC826x_PCI_BASE
-#define MPC826x_PCI_BASE	0x80000000
-#define MPC826x_PCI_MASK	0xc0000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MEM
-#define MPC826x_PCI_LOWER_MEM  0x80000000
-#define MPC826x_PCI_UPPER_MEM  0x9fffffff
-#define MPC826x_PCI_MEM_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_MMIO
-#define MPC826x_PCI_LOWER_MMIO  0xa0000000
-#define MPC826x_PCI_UPPER_MMIO  0xafffffff
-#define MPC826x_PCI_MMIO_OFFSET 0x00000000
-#endif
-
-#ifndef MPC826x_PCI_LOWER_IO
-#define MPC826x_PCI_LOWER_IO   0x00000000
-#define MPC826x_PCI_UPPER_IO   0x00ffffff
-#define MPC826x_PCI_IO_BASE    0xb0000000
-#define MPC826x_PCI_IO_SIZE    0x01000000
-#endif
-
-#ifndef _IO_BASE
-#define _IO_BASE isa_io_base
-#endif
-
-#ifdef CONFIG_8260_PCI9
-struct pci_controller;
-extern void setup_m8260_indirect_pci(struct pci_controller* hose,
-				     u32 cfg_addr, u32 cfg_data);
-#else
-#define setup_m8260_indirect_pci setup_indirect_pci
-#endif
-
-#endif /* _PPC_KERNEL_M8260_PCI_H */

+ 5 - 5
arch/ppc/syslib/m8260_pci_erratum9.c

@@ -31,7 +31,7 @@
 #include <asm/immap_cpm2.h>
 #include <asm/immap_cpm2.h>
 #include <asm/cpm2.h>
 #include <asm/cpm2.h>
 
 
-#include "m8260_pci.h"
+#include "m82xx_pci.h"
 
 
 #ifdef CONFIG_8260_PCI9
 #ifdef CONFIG_8260_PCI9
 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
 /*#include <asm/mpc8260_pci9.h>*/ /* included in asm/io.h */
@@ -248,11 +248,11 @@ EXPORT_SYMBOL(idma_pci9_read_le);
 
 
 static inline int is_pci_mem(unsigned long addr)
 static inline int is_pci_mem(unsigned long addr)
 {
 {
-	if (addr >= MPC826x_PCI_LOWER_MMIO &&
-	    addr <= MPC826x_PCI_UPPER_MMIO)
+	if (addr >= M82xx_PCI_LOWER_MMIO &&
+		addr <= M82xx_PCI_UPPER_MMIO)
 		return 1;
 		return 1;
-	if (addr >= MPC826x_PCI_LOWER_MEM &&
-	    addr <= MPC826x_PCI_UPPER_MEM)
+	if (addr >= M82xx_PCI_LOWER_MEM &&
+		addr <= M82xx_PCI_UPPER_MEM)
 		return 1;
 		return 1;
 	return 0;
 	return 0;
 }
 }

+ 9 - 2
arch/ppc/syslib/m8260_setup.c

@@ -34,7 +34,8 @@
 unsigned char __res[sizeof(bd_t)];
 unsigned char __res[sizeof(bd_t)];
 
 
 extern void cpm2_reset(void);
 extern void cpm2_reset(void);
-extern void m8260_find_bridges(void);
+extern void pq2_find_bridges(void);
+extern void pq2pci_init_irq(void);
 extern void idma_pci9_init(void);
 extern void idma_pci9_init(void);
 
 
 /* Place-holder for board-specific init */
 /* Place-holder for board-specific init */
@@ -56,7 +57,7 @@ m8260_setup_arch(void)
 	idma_pci9_init();
 	idma_pci9_init();
 #endif
 #endif
 #ifdef CONFIG_PCI_8260
 #ifdef CONFIG_PCI_8260
-	m8260_find_bridges();
+	pq2_find_bridges();
 #endif
 #endif
 #ifdef CONFIG_BLK_DEV_INITRD
 #ifdef CONFIG_BLK_DEV_INITRD
 	if (initrd_start)
 	if (initrd_start)
@@ -173,6 +174,12 @@ m8260_init_IRQ(void)
 	 * in case the boot rom changed something on us.
 	 * in case the boot rom changed something on us.
 	 */
 	 */
 	cpm2_immr->im_intctl.ic_siprr = 0x05309770;
 	cpm2_immr->im_intctl.ic_siprr = 0x05309770;
+
+#if defined(CONFIG_PCI) && (defined(CONFIG_ADS8272) || defined(CONFIG_PQ2FADS))
+ 	/* Initialize stuff for the 82xx CPLD IC and install demux  */
+ 	pq2pci_init_irq();
+#endif
+
 }
 }
 
 
 /*
 /*

+ 383 - 0
arch/ppc/syslib/m82xx_pci.c

@@ -0,0 +1,383 @@
+/*
+ *
+ * (C) Copyright 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2004 Red Hat, Inc.
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+#include <asm/pci-bridge.h>
+#include <asm/immap_cpm2.h>
+#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+
+#include "m82xx_pci.h"
+
+/*
+ * Interrupt routing
+ */
+
+static inline int
+pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
+{
+	static char pci_irq_table[][4] =
+	/*
+	 *	PCI IDSEL/INTPIN->INTLINE
+	 * 	  A      B      C      D
+	 */
+	{
+		{ PIRQA, PIRQB, PIRQC, PIRQD },	/* IDSEL 22 - PCI slot 0 */
+		{ PIRQD, PIRQA, PIRQB, PIRQC },	/* IDSEL 23 - PCI slot 1 */
+		{ PIRQC, PIRQD, PIRQA, PIRQB },	/* IDSEL 24 - PCI slot 2 */
+	};
+
+	const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
+	return PCI_IRQ_TABLE_LOOKUP;
+}
+
+static void
+pq2pci_mask_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_unmask_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_mask_and_ack(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
+	return;
+}
+
+static void
+pq2pci_end_irq(unsigned int irq)
+{
+	int bit = irq - NR_CPM_INTS;
+
+	*(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
+	return;
+}
+
+struct hw_interrupt_type pq2pci_ic = {
+	"PQ2 PCI",
+	NULL,
+	NULL,
+	pq2pci_unmask_irq,
+	pq2pci_mask_irq,
+	pq2pci_mask_and_ack,
+	pq2pci_end_irq,
+	0
+};
+
+static irqreturn_t
+pq2pci_irq_demux(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long stat, mask, pend;
+	int bit;
+
+	for(;;) {
+		stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
+		mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
+		pend = stat & ~mask & 0xf0000000;
+		if (!pend)
+			break;
+		for (bit = 0; pend != 0; ++bit, pend <<= 1) {
+			if (pend & 0x80000000)
+				__do_IRQ(NR_CPM_INTS + bit, regs);
+		}
+	}
+
+	return IRQ_HANDLED;
+}
+
+static struct irqaction pq2pci_irqaction = {
+	.handler = pq2pci_irq_demux,
+	.flags 	 = SA_INTERRUPT,
+	.mask	 = CPU_MASK_NONE,
+	.name	 = "PQ2 PCI cascade",
+};
+
+
+void
+pq2pci_init_irq(void)
+{
+	int irq;
+	volatile cpm2_map_t *immap = cpm2_immr;
+#if defined CONFIG_ADS8272
+	/* configure chip select for PCI interrupt controller */
+	immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
+	immap->im_memctl.memc_or3 = 0xffff8010;
+#elif defined CONFIG_PQ2FADS
+	immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
+	immap->im_memctl.memc_or8 = 0xffff8010;
+#endif
+	for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
+		irq_desc[irq].handler = &pq2pci_ic;
+
+	/* make PCI IRQ level sensitive */
+	immap->im_intctl.ic_siexr &=
+		~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
+
+	/* mask all PCI interrupts */
+	*(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
+
+	/* install the demultiplexer for the PCI cascade interrupt */
+	setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
+	return;
+}
+
+static int
+pq2pci_exclude_device(u_char bus, u_char devfn)
+{
+	return PCIBIOS_SUCCESSFUL;
+}
+
+/* PCI bus configuration registers.
+ */
+static void
+pq2ads_setup_pci(struct pci_controller *hose)
+{
+	__u32 val;
+	volatile cpm2_map_t *immap = cpm2_immr;
+	bd_t* binfo = (bd_t*) __res;
+	u32 sccr = immap->im_clkrst.car_sccr;
+	uint pci_div,freq,time;
+		/* PCI int lowest prio */
+	/* Each 4 bits is a device bus request	and the MS 4bits
+	 is highest priority */
+	/* Bus                4bit value
+	   ---                ----------
+	   CPM high      	0b0000
+	   CPM middle           0b0001
+	   CPM low       	0b0010
+	   PCI reguest          0b0011
+	   Reserved      	0b0100
+	   Reserved      	0b0101
+	   Internal Core     	0b0110
+	   External Master 1 	0b0111
+	   External Master 2 	0b1000
+	   External Master 3 	0b1001
+	   The rest are reserved
+	 */
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
+	/* park bus on core */
+	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
+	/*
+	 * Set up master windows that allow the CPU to access PCI space. These
+	 * windows are set up using the two SIU PCIBR registers.
+	 */
+
+	immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
+	immap->im_memctl.memc_pcibr0  = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
+
+#ifdef M82xx_PCI_SEC_WND_SIZE
+	immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
+	immap->im_memctl.memc_pcibr1  = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
+#endif
+
+#if defined CONFIG_ADS8272
+	immap->im_siu_conf.siu_82xx.sc_siumcr =
+		(immap->im_siu_conf.siu_82xx.sc_siumcr &
+		~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
+		SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
+		SIUMCR_LBPC11 | SIUMCR_APPC11 |
+		SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
+		SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
+		SIUMCR_APPC10 | SIUMCR_CS10PC00 |
+		SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
+
+#elif defined CONFIG_PQ2FADS
+	/*
+	 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
+	 * and local bus for PCI (SIUMCR [LBPC]).
+	 */
+	immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.sc_siumcr &
+				~(SIUMCR_L2PC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
+				SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10;
+#endif
+	/* Enable PCI  */
+	immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
+
+	pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
+			( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
+	freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
+	time = (int)666666/freq;
+	/* due to PCI Local Bus spec, some devices needs to wait such a long
+	time after RST 	deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
+	printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
+	(time==1) ? "0.5 seconds":"1 second" );
+
+	{
+		int i;
+		for(i=0;i<(500*time);i++)
+			udelay(1000);
+	}
+
+	/* setup ATU registers */
+	immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
+				((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
+
+	/* Set-up non-prefetchable window */
+	immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
+
+	/* Set-up prefetchable window */
+	immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
+		(~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
+	immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
+	immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
+
+ 	/* Inbound transactions from PCI memory space */
+	immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
+					((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
+	immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS  >> PITA_ADDR_SHIFT);
+	immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
+
+#if defined CONFIG_ADS8272
+	/* PCI int highest prio */
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
+#elif defined CONFIG_PQ2FADS
+	immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
+#endif
+	/* park bus on PCI */
+	immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
+
+	/* Enable bus mastering and inbound memory transactions */
+	early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
+	val &= 0xffff0000;
+	val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
+	early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
+
+}
+
+void __init pq2_find_bridges(void)
+{
+	extern int pci_assign_all_busses;
+	struct pci_controller * hose;
+	int host_bridge;
+
+	pci_assign_all_busses = 1;
+
+	hose = pcibios_alloc_controller();
+
+	if (!hose)
+		return;
+
+	ppc_md.pci_swizzle = common_swizzle;
+
+	hose->first_busno = 0;
+	hose->bus_offset = 0;
+	hose->last_busno = 0xff;
+
+#ifdef CONFIG_ADS8272
+	hose->set_cfg_type = 1;
+#endif
+
+	setup_m8260_indirect_pci(hose,
+				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
+				 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
+
+	/* Make sure it is a supported bridge */
+	early_read_config_dword(hose,
+				0,
+				PCI_DEVFN(0,0),
+				PCI_VENDOR_ID,
+				&host_bridge);
+	switch (host_bridge) {
+		case PCI_DEVICE_ID_MPC8265:
+			break;
+		case PCI_DEVICE_ID_MPC8272:
+			break;
+		default:
+			printk("Attempting to use unrecognized host bridge ID"
+				" 0x%08x.\n", host_bridge);
+			break;
+	}
+
+	pq2ads_setup_pci(hose);
+
+	hose->io_space.start =	M82xx_PCI_LOWER_IO;
+	hose->io_space.end = M82xx_PCI_UPPER_IO;
+	hose->mem_space.start = M82xx_PCI_LOWER_MEM;
+	hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
+	hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
+
+	isa_io_base =
+	(unsigned long) ioremap(M82xx_PCI_IO_BASE,
+					M82xx_PCI_IO_SIZE);
+	hose->io_base_virt = (void *) isa_io_base;
+
+	/* setup resources */
+	pci_init_resource(&hose->mem_resources[0],
+			M82xx_PCI_LOWER_MEM,
+			M82xx_PCI_UPPER_MEM,
+			IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
+
+	pci_init_resource(&hose->mem_resources[1],
+			M82xx_PCI_LOWER_MMIO,
+			M82xx_PCI_UPPER_MMIO,
+			IORESOURCE_MEM, "PCI memory");
+
+	pci_init_resource(&hose->io_resource,
+			M82xx_PCI_LOWER_IO,
+			M82xx_PCI_UPPER_IO,
+			IORESOURCE_IO | 1, "PCI I/O");
+
+	ppc_md.pci_exclude_device = pq2pci_exclude_device;
+	hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
+
+	ppc_md.pci_map_irq = pq2pci_map_irq;
+	ppc_md.pcibios_fixup = NULL;
+	ppc_md.pcibios_fixup_bus = NULL;
+
+}

+ 92 - 0
arch/ppc/syslib/m82xx_pci.h

@@ -0,0 +1,92 @@
+
+#ifndef _PPC_KERNEL_M82XX_PCI_H
+#define _PPC_KERNEL_M82XX_PCI_H
+
+#include <asm/m8260_pci.h>
+/*
+ *   Local->PCI map (from CPU)                             controlled by
+ *   MPC826x master window
+ *
+ *   0xF6000000 - 0xF7FFFFFF    IO space
+ *   0x80000000 - 0xBFFFFFFF    CPU2PCI memory space       PCIBR0
+ *
+ *   0x80000000 - 0x9FFFFFFF    PCI Mem with prefetch      (Outbound ATU #1)
+ *   0xA0000000 - 0xBFFFFFFF    PCI Mem w/o  prefetch      (Outbound ATU #2)
+ *   0xF6000000 - 0xF7FFFFFF    32-bit PCI IO              (Outbound ATU #3)
+ *
+ *   PCI->Local map (from PCI)
+ *   MPC826x slave window                                  controlled by
+ *
+ *   0x00000000 - 0x07FFFFFF    MPC826x local memory       (Inbound ATU #1)
+ */
+
+/*
+ * Slave window that allows PCI masters to access MPC826x local memory.
+ * This window is set up using the first set of Inbound ATU registers
+ */
+
+#ifndef M82xx_PCI_SLAVE_MEM_LOCAL
+#define M82xx_PCI_SLAVE_MEM_LOCAL	(((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_BUS		(((struct bd_info *)__res)->bi_memstart)
+#define M82xx_PCI_SLAVE_MEM_SIZE	(((struct bd_info *)__res)->bi_memsize)
+#endif
+
+/*
+ * This is the window that allows the CPU to access PCI address space.
+ * It will be setup with the SIU PCIBR0 register. All three PCI master
+ * windows, which allow the CPU to access PCI prefetch, non prefetch,
+ * and IO space (see below), must all fit within this window.
+ */
+
+#ifndef M82xx_PCI_LOWER_MEM
+#define M82xx_PCI_LOWER_MEM		0x80000000
+#define M82xx_PCI_UPPER_MEM		0x9fffffff
+#define M82xx_PCI_MEM_OFFSET		0x00000000
+#define M82xx_PCI_MEM_SIZE		0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_MMIO
+#define M82xx_PCI_LOWER_MMIO		0xa0000000
+#define M82xx_PCI_UPPER_MMIO		0xafffffff
+#define M82xx_PCI_MMIO_OFFSET		0x00000000
+#define M82xx_PCI_MMIO_SIZE		0x20000000
+#endif
+
+#ifndef M82xx_PCI_LOWER_IO
+#define M82xx_PCI_LOWER_IO		0x00000000
+#define M82xx_PCI_UPPER_IO		0x01ffffff
+#define M82xx_PCI_IO_BASE		0xf6000000
+#define M82xx_PCI_IO_SIZE		0x02000000
+#endif
+
+#ifndef M82xx_PCI_PRIM_WND_SIZE
+#define M82xx_PCI_PRIM_WND_SIZE 	~(M82xx_PCI_IO_SIZE - 1U)
+#define M82xx_PCI_PRIM_WND_BASE		(M82xx_PCI_IO_BASE)
+#endif
+
+#ifndef M82xx_PCI_SEC_WND_SIZE
+#define M82xx_PCI_SEC_WND_SIZE 		~(M82xx_PCI_MEM_SIZE + M82xx_PCI_MMIO_SIZE - 1U)
+#define M82xx_PCI_SEC_WND_BASE 		(M82xx_PCI_LOWER_MEM)
+#endif
+
+#ifndef POTA_ADDR_SHIFT
+#define POTA_ADDR_SHIFT		12
+#endif
+
+#ifndef PITA_ADDR_SHIFT
+#define PITA_ADDR_SHIFT		12
+#endif
+
+#ifndef _IO_BASE
+#define _IO_BASE isa_io_base
+#endif
+
+#ifdef CONFIG_8260_PCI9
+struct pci_controller;
+extern void setup_m8260_indirect_pci(struct pci_controller* hose,
+					u32 cfg_addr, u32 cfg_data);
+#else
+#define setup_m8260_indirect_pci setup_indirect_pci
+#endif
+
+#endif /* _PPC_KERNEL_M8260_PCI_H */

+ 1 - 0
arch/ppc/syslib/mpc83xx_devices.c

@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
 	},
 	},
+	{ },
 };
 };
 
 
 struct platform_device ppc_sys_platform_devices[] = {
 struct platform_device ppc_sys_platform_devices[] = {

+ 1 - 0
arch/ppc/syslib/mpc85xx_devices.c

@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.iotype		= UPIO_MEM,
 		.iotype		= UPIO_MEM,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
 		.flags		= UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ,
 	},
 	},
+	{ },
 };
 };
 
 
 struct platform_device ppc_sys_platform_devices[] = {
 struct platform_device ppc_sys_platform_devices[] = {

+ 1 - 5
arch/ppc/syslib/open_pic.c

@@ -275,7 +275,7 @@ static void __init openpic_enable_sie(void)
 }
 }
 #endif
 #endif
 
 
-#if defined(CONFIG_EPIC_SERIAL_MODE) || defined(CONFIG_PM)
+#if defined(CONFIG_EPIC_SERIAL_MODE)
 static void openpic_reset(void)
 static void openpic_reset(void)
 {
 {
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
 	openpic_setfield(&OpenPIC->Global.Global_Configuration0,
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec)
  */
  */
 void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
 void openpic_cause_IPI(u_int ipi, cpumask_t cpumask)
 {
 {
-	cpumask_t phys;
 	DECL_THIS_CPU;
 	DECL_THIS_CPU;
 
 
 	CHECK_THIS_CPU;
 	CHECK_THIS_CPU;
 	check_arg_ipi(ipi);
 	check_arg_ipi(ipi);
-	phys = physmask(cpumask);
 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
 	openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi),
 		      cpus_addr(physmask(cpumask))[0]);
 		      cpus_addr(physmask(cpumask))[0]);
 }
 }
@@ -995,8 +993,6 @@ int openpic_resume(struct sys_device *sysdev)
 		return 0;
 		return 0;
 	}
 	}
 
 
-	openpic_reset();
-
 	/* OpenPIC sometimes seem to need some time to be fully back up... */
 	/* OpenPIC sometimes seem to need some time to be fully back up... */
 	do {
 	do {
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);

+ 28 - 0
arch/ppc/syslib/ppc83xx_setup.c

@@ -29,6 +29,7 @@
 #include <asm/mmu.h>
 #include <asm/mmu.h>
 #include <asm/ppc_sys.h>
 #include <asm/ppc_sys.h>
 #include <asm/kgdb.h>
 #include <asm/kgdb.h>
+#include <asm/delay.h>
 
 
 #include <syslib/ppc83xx_setup.h>
 #include <syslib/ppc83xx_setup.h>
 
 
@@ -117,7 +118,34 @@ mpc83xx_early_serial_map(void)
 void
 void
 mpc83xx_restart(char *cmd)
 mpc83xx_restart(char *cmd)
 {
 {
+	volatile unsigned char __iomem *reg;
+	unsigned char tmp;
+
+	reg = ioremap(BCSR_PHYS_ADDR, BCSR_SIZE);
+
 	local_irq_disable();
 	local_irq_disable();
+
+	/*
+	 * Unlock the BCSR bits so a PRST will update the contents.
+	 * Otherwise the reset asserts but doesn't clear.
+	 */
+	tmp = in_8(reg + BCSR_MISC_REG3_OFF);
+	tmp |= BCSR_MISC_REG3_CNFLOCK; /* low true, high false */
+	out_8(reg + BCSR_MISC_REG3_OFF, tmp);
+
+	/*
+	 * Trigger a reset via a low->high transition of the
+	 * PORESET bit.
+	 */
+	tmp = in_8(reg + BCSR_MISC_REG2_OFF);
+	tmp &= ~BCSR_MISC_REG2_PORESET;
+	out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
+	udelay(1);
+
+	tmp |= BCSR_MISC_REG2_PORESET;
+	out_8(reg + BCSR_MISC_REG2_OFF, tmp);
+
 	for(;;);
 	for(;;);
 }
 }
 
 

+ 16 - 0
arch/ppc/syslib/ppc85xx_setup.c

@@ -132,6 +132,12 @@ mpc85xx_halt(void)
 }
 }
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
+
+#if defined(CONFIG_MPC8555_CDS)
+extern void mpc85xx_cds_enable_via(struct pci_controller *hose);
+extern void mpc85xx_cds_fixup_via(struct pci_controller *hose);
+#endif
+
 static void __init
 static void __init
 mpc85xx_setup_pci1(struct pci_controller *hose)
 mpc85xx_setup_pci1(struct pci_controller *hose)
 {
 {
@@ -302,8 +308,18 @@ mpc85xx_setup_hose(void)
 
 
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 	ppc_md.pci_exclude_device = mpc85xx_exclude_device;
 
 
+#if defined(CONFIG_MPC8555_CDS)
+	/* Pre pciauto_bus_scan VIA init */
+	mpc85xx_cds_enable_via(hose_a);
+#endif
+
 	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 	hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
 
 
+#if defined(CONFIG_MPC8555_CDS)
+	/* Post pciauto_bus_scan VIA fixup */
+	mpc85xx_cds_fixup_via(hose_a);
+#endif
+
 #ifdef CONFIG_85xx_PCI2
 #ifdef CONFIG_85xx_PCI2
 	hose_b = pcibios_alloc_controller();
 	hose_b = pcibios_alloc_controller();
 
 

+ 10 - 0
arch/ppc/syslib/prom_init.c

@@ -626,8 +626,18 @@ inspect_node(phandle node, struct device_node *dad,
 	l = call_prom("package-to-path", 3, 1, node,
 	l = call_prom("package-to-path", 3, 1, node,
 		      mem_start, mem_end - mem_start);
 		      mem_start, mem_end - mem_start);
 	if (l >= 0) {
 	if (l >= 0) {
+		char *p, *ep;
+
 		np->full_name = PTRUNRELOC((char *) mem_start);
 		np->full_name = PTRUNRELOC((char *) mem_start);
 		*(char *)(mem_start + l) = 0;
 		*(char *)(mem_start + l) = 0;
+		/* Fixup an Apple bug where they have bogus \0 chars in the
+		 * middle of the path in some properties
+		 */
+		for (p = (char *)mem_start, ep = p + l; p < ep; p++)
+			if ((*p) == '\0') {
+				memmove(p, p+1, ep - p);
+				ep--;
+			}
 		mem_start = ALIGNUL(mem_start + l + 1);
 		mem_start = ALIGNUL(mem_start + l + 1);
 	}
 	}
 
 

+ 0 - 9
arch/ppc64/kernel/entry.S

@@ -436,15 +436,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
 	REST_8GPRS(14, r1)
 	REST_8GPRS(14, r1)
 	REST_10GPRS(22, r1)
 	REST_10GPRS(22, r1)
 
 
-#ifdef CONFIG_PPC_ISERIES
-	clrrdi	r7,r1,THREAD_SHIFT	/* get current_thread_info() */
-	ld	r7,TI_FLAGS(r7)		/* Get run light flag */
-	mfspr	r9,CTRLF
-	srdi	r7,r7,TIF_RUN_LIGHT
-	insrdi	r9,r7,1,63		/* Insert run light into CTRL */
-	mtspr	CTRLT,r9
-#endif
-
 	/* convert old thread to its task_struct for return value */
 	/* convert old thread to its task_struct for return value */
 	addi	r3,r3,-THREAD
 	addi	r3,r3,-THREAD
 	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */
 	ld	r7,_NIP(r1)	/* Return to _switch caller in new task */

+ 5 - 5
arch/ppc64/kernel/head.S

@@ -626,10 +626,10 @@ system_reset_iSeries:
 	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
 	lhz	r24,PACAPACAINDEX(r13)	/* Get processor # */
 	cmpwi	0,r24,0			/* Are we processor 0? */
 	cmpwi	0,r24,0			/* Are we processor 0? */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
 	beq	.__start_initialization_iSeries	/* Start up the first processor */
-	mfspr	r4,CTRLF
-	li	r5,RUNLATCH		/* Turn off the run light */
+	mfspr	r4,SPRN_CTRLF
+	li	r5,CTRL_RUNLATCH	/* Turn off the run light */
 	andc	r4,r4,r5
 	andc	r4,r4,r5
-	mtspr	CTRLT,r4
+	mtspr	SPRN_CTRLT,r4
 
 
 1:
 1:
 	HMT_LOW
 	HMT_LOW
@@ -2082,9 +2082,9 @@ _GLOBAL(hmt_start_secondary)
 	mfspr	r4, HID0
 	mfspr	r4, HID0
 	ori	r4, r4, 0x1
 	ori	r4, r4, 0x1
 	mtspr	HID0, r4
 	mtspr	HID0, r4
-	mfspr	r4, CTRLF
+	mfspr	r4, SPRN_CTRLF
 	oris	r4, r4, 0x40
 	oris	r4, r4, 0x40
-	mtspr	CTRLT, r4
+	mtspr	SPRN_CTRLT, r4
 	blr
 	blr
 #endif
 #endif
 
 

+ 22 - 0
arch/ppc64/kernel/iSeries_setup.c

@@ -852,6 +852,28 @@ static int __init iSeries_src_init(void)
 
 
 late_initcall(iSeries_src_init);
 late_initcall(iSeries_src_init);
 
 
+static int set_spread_lpevents(char *str)
+{
+	unsigned long i;
+	unsigned long val = simple_strtoul(str, NULL, 0);
+
+	/*
+	 * The parameter is the number of processors to share in processing
+	 * lp events.
+	 */
+	if (( val > 0) && (val <= NR_CPUS)) {
+		for (i = 1; i < val; ++i)
+			paca[i].lpqueue_ptr = paca[0].lpqueue_ptr;
+
+		printk("lpevent processing spread over %ld processors\n", val);
+	} else {
+		printk("invalid spread_lpevents %ld\n", val);
+	}
+
+	return 1;
+}
+__setup("spread_lpevents=", set_spread_lpevents);
+
 void __init iSeries_early_setup(void)
 void __init iSeries_early_setup(void)
 {
 {
 	iSeries_fixup_klimit();
 	iSeries_fixup_klimit();

+ 3 - 5
arch/ppc64/kernel/idle.c

@@ -75,13 +75,9 @@ static int iSeries_idle(void)
 {
 {
 	struct paca_struct *lpaca;
 	struct paca_struct *lpaca;
 	long oldval;
 	long oldval;
-	unsigned long CTRL;
 
 
 	/* ensure iSeries run light will be out when idle */
 	/* ensure iSeries run light will be out when idle */
-	clear_thread_flag(TIF_RUN_LIGHT);
-	CTRL = mfspr(CTRLF);
-	CTRL &= ~RUNLATCH;
-	mtspr(CTRLT, CTRL);
+	ppc64_runlatch_off();
 
 
 	lpaca = get_paca();
 	lpaca = get_paca();
 
 
@@ -111,7 +107,9 @@ static int iSeries_idle(void)
 			}
 			}
 		}
 		}
 
 
+		ppc64_runlatch_on();
 		schedule();
 		schedule();
+		ppc64_runlatch_off();
 	}
 	}
 
 
 	return 0;
 	return 0;

+ 65 - 20
arch/ppc64/kernel/mf.c

@@ -1,7 +1,7 @@
 /*
 /*
   * mf.c
   * mf.c
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
-  * Copyright (C) 2004 Stephen Rothwell  IBM Corporation
+  * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
   *
   *
   * This modules exists as an interface between a Linux secondary partition
   * This modules exists as an interface between a Linux secondary partition
   * running on an iSeries and the primary partition's Virtual Service
   * running on an iSeries and the primary partition's Virtual Service
@@ -36,10 +36,12 @@
 
 
 #include <asm/time.h>
 #include <asm/time.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
+#include <asm/paca.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/ItSpCommArea.h>
 #include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iSeries/ItLpQueue.h>
 
 
 /*
 /*
  * This is the structure layout for the Machine Facilites LPAR event
  * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
 	complete(&rtc->com);
 	complete(&rtc->com);
 }
 }
 
 
-int mf_get_rtc(struct rtc_time *tm)
+static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
 {
 {
-	struct ce_msg_comp_data ce_complete;
-	struct rtc_time_data rtc_data;
-	int rc;
-
-	memset(&ce_complete, 0, sizeof(ce_complete));
-	memset(&rtc_data, 0, sizeof(rtc_data));
-	init_completion(&rtc_data.com);
-	ce_complete.handler = &get_rtc_time_complete;
-	ce_complete.token = &rtc_data;
-	rc = signal_ce_msg_simple(0x40, &ce_complete);
-	if (rc)
-		return rc;
-	wait_for_completion(&rtc_data.com);
 	tm->tm_wday = 0;
 	tm->tm_wday = 0;
 	tm->tm_yday = 0;
 	tm->tm_yday = 0;
 	tm->tm_isdst = 0;
 	tm->tm_isdst = 0;
-	if (rtc_data.rc) {
+	if (rc) {
 		tm->tm_sec = 0;
 		tm->tm_sec = 0;
 		tm->tm_min = 0;
 		tm->tm_min = 0;
 		tm->tm_hour = 0;
 		tm->tm_hour = 0;
 		tm->tm_mday = 15;
 		tm->tm_mday = 15;
 		tm->tm_mon = 5;
 		tm->tm_mon = 5;
 		tm->tm_year = 52;
 		tm->tm_year = 52;
-		return rtc_data.rc;
+		return rc;
 	}
 	}
 
 
-	if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
-	    (rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
+	if ((ce_msg[2] == 0xa9) ||
+	    (ce_msg[2] == 0xaf)) {
 		/* TOD clock is not set */
 		/* TOD clock is not set */
 		tm->tm_sec = 1;
 		tm->tm_sec = 1;
 		tm->tm_min = 1;
 		tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
 		mf_set_rtc(tm);
 		mf_set_rtc(tm);
 	}
 	}
 	{
 	{
-		u8 *ce_msg = rtc_data.ce_msg.ce_msg;
 		u8 year = ce_msg[5];
 		u8 year = ce_msg[5];
 		u8 sec = ce_msg[6];
 		u8 sec = ce_msg[6];
 		u8 min = ce_msg[7];
 		u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
 	return 0;
 	return 0;
 }
 }
 
 
+int mf_get_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	init_completion(&rtc_data.com);
+	ce_complete.handler = &get_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	wait_for_completion(&rtc_data.com);
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
+struct boot_rtc_time_data {
+	int busy;
+	struct ce_msg_data ce_msg;
+	int rc;
+};
+
+static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+{
+	struct boot_rtc_time_data *rtc = token;
+
+	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+	rtc->rc = 0;
+	rtc->busy = 0;
+}
+
+int mf_get_boot_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct boot_rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	rtc_data.busy = 1;
+	ce_complete.handler = &get_boot_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	/* We need to poll here as we are not yet taking interrupts */
+	while (rtc_data.busy) {
+		extern unsigned long lpevent_count;
+		struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
+		if (lpq && ItLpQueue_isLpIntPending(lpq))
+			lpevent_count += ItLpQueue_process(lpq, NULL);
+	}
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
 int mf_set_rtc(struct rtc_time *tm)
 int mf_set_rtc(struct rtc_time *tm)
 {
 {
 	char ce_time[12];
 	char ce_time[12];

+ 0 - 8
arch/ppc64/kernel/pSeries_reconfig.c

@@ -47,14 +47,6 @@ static void remove_node_proc_entries(struct device_node *np)
 		remove_proc_entry(pp->name, np->pde);
 		remove_proc_entry(pp->name, np->pde);
 		pp = pp->next;
 		pp = pp->next;
 	}
 	}
-
-	/* Assuming that symlinks have the same parent directory as
-	 * np->pde.
-	 */
-	if (np->name_link)
-		remove_proc_entry(np->name_link->name, parent->pde);
-	if (np->addr_link)
-		remove_proc_entry(np->addr_link->name, parent->pde);
 	if (np->pde)
 	if (np->pde)
 		remove_proc_entry(np->pde->name, parent->pde);
 		remove_proc_entry(np->pde->name, parent->pde);
 }
 }

+ 21 - 7
arch/ppc64/kernel/pmac_smp.c

@@ -68,6 +68,7 @@ extern struct smp_ops_t *smp_ops;
 
 
 static void (*pmac_tb_freeze)(int freeze);
 static void (*pmac_tb_freeze)(int freeze);
 static struct device_node *pmac_tb_clock_chip_host;
 static struct device_node *pmac_tb_clock_chip_host;
+static u8 pmac_tb_pulsar_addr;
 static DEFINE_SPINLOCK(timebase_lock);
 static DEFINE_SPINLOCK(timebase_lock);
 static unsigned long timebase;
 static unsigned long timebase;
 
 
@@ -106,12 +107,9 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
 	u8 data;
 	u8 data;
 	int rc;
 	int rc;
 
 
-	/* Strangely, the device-tree says address is 0xd2, but darwin
-	 * accesses 0xd0 ...
-	 */
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_combined);
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-			       0xd4 | pmac_low_i2c_read,
+			       pmac_tb_pulsar_addr | pmac_low_i2c_read,
 			       0x2e, &data, 1);
 			       0x2e, &data, 1);
 	if (rc != 0)
 	if (rc != 0)
 		goto bail;
 		goto bail;
@@ -120,7 +118,7 @@ static void smp_core99_pulsar_tb_freeze(int freeze)
 
 
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
 	pmac_low_i2c_setmode(pmac_tb_clock_chip_host, pmac_low_i2c_mode_stdsub);
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
 	rc = pmac_low_i2c_xfer(pmac_tb_clock_chip_host,
-			       0xd4 | pmac_low_i2c_write,
+			       pmac_tb_pulsar_addr | pmac_low_i2c_write,
 			       0x2e, &data, 1);
 			       0x2e, &data, 1);
  bail:
  bail:
 	if (rc != 0) {
 	if (rc != 0) {
@@ -185,6 +183,12 @@ static int __init smp_core99_probe(void)
 	if (ncpus <= 1)
 	if (ncpus <= 1)
 		return 1;
 		return 1;
 
 
+	/* HW sync only on these platforms */
+	if (!machine_is_compatible("PowerMac7,2") &&
+	    !machine_is_compatible("PowerMac7,3") &&
+	    !machine_is_compatible("RackMac3,1"))
+		goto nohwsync;
+
 	/* Look for the clock chip */
 	/* Look for the clock chip */
 	for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
 	for (cc = NULL; (cc = of_find_node_by_name(cc, "i2c-hwclock")) != NULL;) {
 		struct device_node *p = of_get_parent(cc);
 		struct device_node *p = of_get_parent(cc);
@@ -198,11 +202,18 @@ static int __init smp_core99_probe(void)
 			goto next;
 			goto next;
 		switch (*reg) {
 		switch (*reg) {
 		case 0xd2:
 		case 0xd2:
-			pmac_tb_freeze = smp_core99_cypress_tb_freeze;
-			printk(KERN_INFO "Timebase clock is Cypress chip\n");
+			if (device_is_compatible(cc, "pulsar-legacy-slewing")) {
+				pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+				pmac_tb_pulsar_addr = 0xd2;
+				printk(KERN_INFO "Timebase clock is Pulsar chip\n");
+			} else if (device_is_compatible(cc, "cy28508")) {
+				pmac_tb_freeze = smp_core99_cypress_tb_freeze;
+				printk(KERN_INFO "Timebase clock is Cypress chip\n");
+			}
 			break;
 			break;
 		case 0xd4:
 		case 0xd4:
 			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
 			pmac_tb_freeze = smp_core99_pulsar_tb_freeze;
+			pmac_tb_pulsar_addr = 0xd4;
 			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
 			printk(KERN_INFO "Timebase clock is Pulsar chip\n");
 			break;
 			break;
 		}
 		}
@@ -210,12 +221,15 @@ static int __init smp_core99_probe(void)
 			pmac_tb_clock_chip_host = p;
 			pmac_tb_clock_chip_host = p;
 			smp_ops->give_timebase = smp_core99_give_timebase;
 			smp_ops->give_timebase = smp_core99_give_timebase;
 			smp_ops->take_timebase = smp_core99_take_timebase;
 			smp_ops->take_timebase = smp_core99_take_timebase;
+			of_node_put(cc);
+			of_node_put(p);
 			break;
 			break;
 		}
 		}
 	next:
 	next:
 		of_node_put(p);
 		of_node_put(p);
 	}
 	}
 
 
+ nohwsync:
 	mpic_request_ipis();
 	mpic_request_ipis();
 
 
 	return ncpus;
 	return ncpus;

+ 0 - 3
arch/ppc64/kernel/process.c

@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
 		childregs->gpr[1] = sp + sizeof(struct pt_regs);
 		p->thread.regs = NULL;	/* no user register state */
 		p->thread.regs = NULL;	/* no user register state */
 		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
 		clear_ti_thread_flag(p->thread_info, TIF_32BIT);
-#ifdef CONFIG_PPC_ISERIES
-		set_ti_thread_flag(p->thread_info, TIF_RUN_LIGHT);
-#endif
 	} else {
 	} else {
 		childregs->gpr[1] = usp;
 		childregs->gpr[1] = usp;
 		p->thread.regs = childregs;
 		p->thread.regs = childregs;

+ 115 - 39
arch/ppc64/kernel/prom_init.c

@@ -211,13 +211,23 @@ struct {
  */
  */
 #define ADDR(x)		(u32) ((unsigned long)(x) - offset)
 #define ADDR(x)		(u32) ((unsigned long)(x) - offset)
 
 
+/*
+ * Error results ... some OF calls will return "-1" on error, some
+ * will return 0, some will return either. To simplify, here are
+ * macros to use with any ihandle or phandle return value to check if
+ * it is valid
+ */
+
+#define PROM_ERROR		(-1u)
+#define PHANDLE_VALID(p)	((p) != 0 && (p) != PROM_ERROR)
+#define IHANDLE_VALID(i)	((i) != 0 && (i) != PROM_ERROR)
+
+
 /* This is the one and *ONLY* place where we actually call open
 /* This is the one and *ONLY* place where we actually call open
  * firmware from, since we need to make sure we're running in 32b
  * firmware from, since we need to make sure we're running in 32b
  * mode when we do.  We switch back to 64b mode upon return.
  * mode when we do.  We switch back to 64b mode upon return.
  */
  */
 
 
-#define PROM_ERROR	(-1)
-
 static int __init call_prom(const char *service, int nargs, int nret, ...)
 static int __init call_prom(const char *service, int nargs, int nret, ...)
 {
 {
 	int i;
 	int i;
@@ -587,14 +597,13 @@ static void __init prom_send_capabilities(void)
 {
 {
 	unsigned long offset = reloc_offset();
 	unsigned long offset = reloc_offset();
 	ihandle elfloader;
 	ihandle elfloader;
-	int ret;
 
 
 	elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
 	elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
 	if (elfloader == 0) {
 	if (elfloader == 0) {
 		prom_printf("couldn't open /packages/elf-loader\n");
 		prom_printf("couldn't open /packages/elf-loader\n");
 		return;
 		return;
 	}
 	}
-	ret = call_prom("call-method", 3, 1, ADDR("process-elf-header"),
+	call_prom("call-method", 3, 1, ADDR("process-elf-header"),
 			elfloader, ADDR(&fake_elf));
 			elfloader, ADDR(&fake_elf));
 	call_prom("close", 1, 0, elfloader);
 	call_prom("close", 1, 0, elfloader);
 }
 }
@@ -646,7 +655,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align)
 	    base = _ALIGN_UP(base + 0x100000, align)) {
 	    base = _ALIGN_UP(base + 0x100000, align)) {
 		prom_debug("    trying: 0x%x\n\r", base);
 		prom_debug("    trying: 0x%x\n\r", base);
 		addr = (unsigned long)prom_claim(base, size, 0);
 		addr = (unsigned long)prom_claim(base, size, 0);
-		if ((int)addr != PROM_ERROR)
+		if (addr != PROM_ERROR)
 			break;
 			break;
 		addr = 0;
 		addr = 0;
 		if (align == 0)
 		if (align == 0)
@@ -708,7 +717,7 @@ static unsigned long __init alloc_down(unsigned long size, unsigned long align,
 	for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
 	for(; base > RELOC(alloc_bottom); base = _ALIGN_DOWN(base - 0x100000, align))  {
 		prom_debug("    trying: 0x%x\n\r", base);
 		prom_debug("    trying: 0x%x\n\r", base);
 		addr = (unsigned long)prom_claim(base, size, 0);
 		addr = (unsigned long)prom_claim(base, size, 0);
-		if ((int)addr != PROM_ERROR)
+		if (addr != PROM_ERROR)
 			break;
 			break;
 		addr = 0;
 		addr = 0;
 	}
 	}
@@ -902,18 +911,19 @@ static void __init prom_instantiate_rtas(void)
 {
 {
 	unsigned long offset = reloc_offset();
 	unsigned long offset = reloc_offset();
 	struct prom_t *_prom = PTRRELOC(&prom);
 	struct prom_t *_prom = PTRRELOC(&prom);
-	phandle prom_rtas, rtas_node;
+	phandle rtas_node;
+	ihandle rtas_inst;
 	u32 base, entry = 0;
 	u32 base, entry = 0;
 	u32 size = 0;
 	u32 size = 0;
 
 
 	prom_debug("prom_instantiate_rtas: start...\n");
 	prom_debug("prom_instantiate_rtas: start...\n");
 
 
-	prom_rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	prom_debug("prom_rtas: %x\n", prom_rtas);
-	if (prom_rtas == (phandle) -1)
+	rtas_node = call_prom("finddevice", 1, 1, ADDR("/rtas"));
+	prom_debug("rtas_node: %x\n", rtas_node);
+	if (!PHANDLE_VALID(rtas_node))
 		return;
 		return;
 
 
-	prom_getprop(prom_rtas, "rtas-size", &size, sizeof(size));
+	prom_getprop(rtas_node, "rtas-size", &size, sizeof(size));
 	if (size == 0)
 	if (size == 0)
 		return;
 		return;
 
 
@@ -922,14 +932,18 @@ static void __init prom_instantiate_rtas(void)
 		prom_printf("RTAS allocation failed !\n");
 		prom_printf("RTAS allocation failed !\n");
 		return;
 		return;
 	}
 	}
-	prom_printf("instantiating rtas at 0x%x", base);
 
 
-	rtas_node = call_prom("open", 1, 1, ADDR("/rtas"));
-	prom_printf("...");
+	rtas_inst = call_prom("open", 1, 1, ADDR("/rtas"));
+	if (!IHANDLE_VALID(rtas_inst)) {
+		prom_printf("opening rtas package failed");
+		return;
+	}
+
+	prom_printf("instantiating rtas at 0x%x ...", base);
 
 
 	if (call_prom("call-method", 3, 2,
 	if (call_prom("call-method", 3, 2,
 		      ADDR("instantiate-rtas"),
 		      ADDR("instantiate-rtas"),
-		      rtas_node, base) != PROM_ERROR) {
+		      rtas_inst, base) != PROM_ERROR) {
 		entry = (long)_prom->args.rets[1];
 		entry = (long)_prom->args.rets[1];
 	}
 	}
 	if (entry == 0) {
 	if (entry == 0) {
@@ -940,8 +954,8 @@ static void __init prom_instantiate_rtas(void)
 
 
 	reserve_mem(base, size);
 	reserve_mem(base, size);
 
 
-	prom_setprop(prom_rtas, "linux,rtas-base", &base, sizeof(base));
-	prom_setprop(prom_rtas, "linux,rtas-entry", &entry, sizeof(entry));
+	prom_setprop(rtas_node, "linux,rtas-base", &base, sizeof(base));
+	prom_setprop(rtas_node, "linux,rtas-entry", &entry, sizeof(entry));
 
 
 	prom_debug("rtas base     = 0x%x\n", base);
 	prom_debug("rtas base     = 0x%x\n", base);
 	prom_debug("rtas entry    = 0x%x\n", entry);
 	prom_debug("rtas entry    = 0x%x\n", entry);
@@ -1062,7 +1076,7 @@ static void __init prom_initialize_tce_table(void)
 
 
 		prom_printf("opening PHB %s", path);
 		prom_printf("opening PHB %s", path);
 		phb_node = call_prom("open", 1, 1, path);
 		phb_node = call_prom("open", 1, 1, path);
-		if ( (long)phb_node <= 0)
+		if (phb_node == 0)
 			prom_printf("... failed\n");
 			prom_printf("... failed\n");
 		else
 		else
 			prom_printf("... done\n");
 			prom_printf("... done\n");
@@ -1279,12 +1293,12 @@ static void __init prom_init_client_services(unsigned long pp)
 
 
 	/* get a handle for the stdout device */
 	/* get a handle for the stdout device */
 	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
 	_prom->chosen = call_prom("finddevice", 1, 1, ADDR("/chosen"));
-	if ((long)_prom->chosen <= 0)
+	if (!PHANDLE_VALID(_prom->chosen))
 		prom_panic("cannot find chosen"); /* msg won't be printed :( */
 		prom_panic("cannot find chosen"); /* msg won't be printed :( */
 
 
 	/* get device tree root */
 	/* get device tree root */
 	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
 	_prom->root = call_prom("finddevice", 1, 1, ADDR("/"));
-	if ((long)_prom->root <= 0)
+	if (!PHANDLE_VALID(_prom->root))
 		prom_panic("cannot find device tree root"); /* msg won't be printed :( */
 		prom_panic("cannot find device tree root"); /* msg won't be printed :( */
 }
 }
 
 
@@ -1356,9 +1370,8 @@ static int __init prom_find_machine_type(void)
 	}
 	}
 	/* Default to pSeries. We need to know if we are running LPAR */
 	/* Default to pSeries. We need to know if we are running LPAR */
 	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
 	rtas = call_prom("finddevice", 1, 1, ADDR("/rtas"));
-	if (rtas != (phandle) -1) {
-		unsigned long x;
-		x = prom_getproplen(rtas, "ibm,hypertas-functions");
+	if (PHANDLE_VALID(rtas)) {
+		int x = prom_getproplen(rtas, "ibm,hypertas-functions");
 		if (x != PROM_ERROR) {
 		if (x != PROM_ERROR) {
 			prom_printf("Hypertas detected, assuming LPAR !\n");
 			prom_printf("Hypertas detected, assuming LPAR !\n");
 			return PLATFORM_PSERIES_LPAR;
 			return PLATFORM_PSERIES_LPAR;
@@ -1426,12 +1439,13 @@ static void __init prom_check_displays(void)
 		 * leave some room at the end of the path for appending extra
 		 * leave some room at the end of the path for appending extra
 		 * arguments
 		 * arguments
 		 */
 		 */
-		if (call_prom("package-to-path", 3, 1, node, path, PROM_SCRATCH_SIZE-10) < 0)
+		if (call_prom("package-to-path", 3, 1, node, path,
+			      PROM_SCRATCH_SIZE-10) == PROM_ERROR)
 			continue;
 			continue;
 		prom_printf("found display   : %s, opening ... ", path);
 		prom_printf("found display   : %s, opening ... ", path);
 		
 		
 		ih = call_prom("open", 1, 1, path);
 		ih = call_prom("open", 1, 1, path);
-		if (ih == (ihandle)0 || ih == (ihandle)-1) {
+		if (ih == 0) {
 			prom_printf("failed\n");
 			prom_printf("failed\n");
 			continue;
 			continue;
 		}
 		}
@@ -1514,6 +1528,12 @@ static unsigned long __init dt_find_string(char *str)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * The Open Firmware 1275 specification states properties must be 31 bytes or
+ * less, however not all firmwares obey this. Make it 64 bytes to be safe.
+ */
+#define MAX_PROPERTY_NAME 64
+
 static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 					 unsigned long *mem_end)
 					 unsigned long *mem_end)
 {
 {
@@ -1527,10 +1547,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 	/* get and store all property names */
 	/* get and store all property names */
 	prev_name = RELOC("");
 	prev_name = RELOC("");
 	for (;;) {
 	for (;;) {
-		
-		/* 32 is max len of name including nul. */
-		namep = make_room(mem_start, mem_end, 32, 1);
-		if (call_prom("nextprop", 3, 1, node, prev_name, namep) <= 0) {
+		int rc;
+
+		/* 64 is max len of name including nul. */
+		namep = make_room(mem_start, mem_end, MAX_PROPERTY_NAME, 1);
+		rc = call_prom("nextprop", 3, 1, node, prev_name, namep);
+		if (rc != 1) {
 			/* No more nodes: unwind alloc */
 			/* No more nodes: unwind alloc */
 			*mem_start = (unsigned long)namep;
 			*mem_start = (unsigned long)namep;
 			break;
 			break;
@@ -1555,18 +1577,12 @@ static void __init scan_dt_build_strings(phandle node, unsigned long *mem_start,
 	}
 	}
 }
 }
 
 
-/*
- * The Open Firmware 1275 specification states properties must be 31 bytes or
- * less, however not all firmwares obey this. Make it 64 bytes to be safe.
- */
-#define MAX_PROPERTY_NAME 64
-
 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 					unsigned long *mem_end)
 					unsigned long *mem_end)
 {
 {
 	int l, align;
 	int l, align;
 	phandle child;
 	phandle child;
-	char *namep, *prev_name, *sstart;
+	char *namep, *prev_name, *sstart, *p, *ep;
 	unsigned long soff;
 	unsigned long soff;
 	unsigned char *valp;
 	unsigned char *valp;
 	unsigned long offset = reloc_offset();
 	unsigned long offset = reloc_offset();
@@ -1588,6 +1604,14 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 			call_prom("package-to-path", 3, 1, node, namep, l);
 			call_prom("package-to-path", 3, 1, node, namep, l);
 		}
 		}
 		namep[l] = '\0';
 		namep[l] = '\0';
+		/* Fixup an Apple bug where they have bogus \0 chars in the
+		 * middle of the path in some properties
+		 */
+		for (p = namep, ep = namep + l; p < ep; p++)
+			if (*p == '\0') {
+				memmove(p, p+1, ep - p);
+				ep--; l--;
+			}
 		*mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
 		*mem_start = _ALIGN(((unsigned long) namep) + strlen(namep) + 1, 4);
 	}
 	}
 
 
@@ -1599,7 +1623,10 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 	prev_name = RELOC("");
 	prev_name = RELOC("");
 	sstart = (char *)RELOC(dt_string_start);
 	sstart = (char *)RELOC(dt_string_start);
 	for (;;) {
 	for (;;) {
-		if (call_prom("nextprop", 3, 1, node, prev_name, pname) <= 0)
+		int rc;
+
+		rc = call_prom("nextprop", 3, 1, node, prev_name, pname);
+		if (rc != 1)
 			break;
 			break;
 
 
 		/* find string offset */
 		/* find string offset */
@@ -1615,7 +1642,7 @@ static void __init scan_dt_build_struct(phandle node, unsigned long *mem_start,
 		l = call_prom("getproplen", 2, 1, node, pname);
 		l = call_prom("getproplen", 2, 1, node, pname);
 
 
 		/* sanity checks */
 		/* sanity checks */
-		if (l < 0)
+		if (l == PROM_ERROR)
 			continue;
 			continue;
 		if (l > MAX_PROPERTY_LENGTH) {
 		if (l > MAX_PROPERTY_LENGTH) {
 			prom_printf("WARNING: ignoring large property ");
 			prom_printf("WARNING: ignoring large property ");
@@ -1750,7 +1777,45 @@ static void __init flatten_device_tree(void)
 	prom_printf("Device tree struct  0x%x -> 0x%x\n",
 	prom_printf("Device tree struct  0x%x -> 0x%x\n",
 		    RELOC(dt_struct_start), RELOC(dt_struct_end));
 		    RELOC(dt_struct_start), RELOC(dt_struct_end));
 
 
- }
+}
+
+
+static void __init fixup_device_tree(void)
+{
+	unsigned long offset = reloc_offset();
+	phandle u3, i2c, mpic;
+	u32 u3_rev;
+	u32 interrupts[2];
+	u32 parent;
+
+	/* Some G5s have a missing interrupt definition, fix it up here */
+	u3 = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000"));
+	if (!PHANDLE_VALID(u3))
+		return;
+	i2c = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/i2c@f8001000"));
+	if (!PHANDLE_VALID(i2c))
+		return;
+	mpic = call_prom("finddevice", 1, 1, ADDR("/u3@0,f8000000/mpic@f8040000"));
+	if (!PHANDLE_VALID(mpic))
+		return;
+
+	/* check if proper rev of u3 */
+	if (prom_getprop(u3, "device-rev", &u3_rev, sizeof(u3_rev))
+	    == PROM_ERROR)
+		return;
+	if (u3_rev != 0x35)
+		return;
+	/* does it need fixup ? */
+	if (prom_getproplen(i2c, "interrupts") > 0)
+		return;
+	/* interrupt on this revision of u3 is number 0 and level */
+	interrupts[0] = 0;
+	interrupts[1] = 1;
+	prom_setprop(i2c, "interrupts", &interrupts, sizeof(interrupts));
+	parent = (u32)mpic;
+	prom_setprop(i2c, "interrupt-parent", &parent, sizeof(parent));
+}
+
 
 
 static void __init prom_find_boot_cpu(void)
 static void __init prom_find_boot_cpu(void)
 {
 {
@@ -1843,6 +1908,12 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
 	prom_setprop(_prom->chosen, "linux,platform",
 	prom_setprop(_prom->chosen, "linux,platform",
 		     &getprop_rval, sizeof(getprop_rval));
 		     &getprop_rval, sizeof(getprop_rval));
 
 
+	/*
+	 * On pSeries, inform the firmware about our capabilities
+	 */
+	if (RELOC(of_platform) & PLATFORM_PSERIES)
+		prom_send_capabilities();
+
 	/*
 	/*
 	 * On pSeries, copy the CPU hold code
 	 * On pSeries, copy the CPU hold code
 	 */
 	 */
@@ -1919,6 +1990,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4, unsigned long
 			PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
 			PTRRELOC(&prom_tce_alloc_end), sizeof(RELOC(prom_tce_alloc_end)));
 	}
 	}
 
 
+	/*
+	 * Fixup any known bugs in the device-tree
+	 */
+	fixup_device_tree();
+
 	/*
 	/*
 	 * Now finally create the flattened device-tree
 	 * Now finally create the flattened device-tree
 	 */
 	 */

+ 1 - 38
arch/ppc64/kernel/rtc.c

@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
 
 
 void iSeries_get_boot_time(struct rtc_time *tm)
 void iSeries_get_boot_time(struct rtc_time *tm)
 {
 {
-	unsigned long time;
-	static unsigned long lastsec = 1;
-
-	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
-	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
-	int year = 1970;
-	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
-	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
-	int sec = ( dataWord1 >> 8 ) & 0x000000FF;
-	int min = dataWord1 & 0x000000FF;
-	int hour = ( dataWord2 >> 24 ) & 0x000000FF;
-	int day = ( dataWord2 >> 8 ) & 0x000000FF;
-	int mon = dataWord2 & 0x000000FF;
-
 	if ( piranha_simulator )
 	if ( piranha_simulator )
 		return;
 		return;
 
 
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(year1);
-	BCD_TO_BIN(year2);
-	year = year1 * 100 + year2;
-
-	time = mktime(year, mon, day, hour, min, sec);
-	time += ( jiffies / HZ );
-
-	/* Now THIS is a nasty hack!
-	* It ensures that the first two calls get different answers.  
-	* That way the loop in init_time (time.c) will not think
-	* the clock is stuck.
-	*/
-	if ( lastsec ) {
-		time -= lastsec;
-		--lastsec;
-	}
-
-	to_tm(time, tm); 
-	tm->tm_year -= 1900;
+	mf_get_boot_rtc(tm);
 	tm->tm_mon  -= 1;
 	tm->tm_mon  -= 1;
 }
 }
 #endif
 #endif

Some files were not shown because too many files changed in this diff