summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/sound/alsa/Audiophile-Usb.txt81
-rw-r--r--Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl4
-rw-r--r--arch/powerpc/configs/cell_defconfig40
-rw-r--r--arch/powerpc/kernel/cputable.c16
-rw-r--r--arch/powerpc/kernel/module_64.c16
-rw-r--r--arch/powerpc/kernel/prom_init.c112
-rw-r--r--arch/powerpc/kernel/setup-common.c8
-rw-r--r--arch/powerpc/kernel/setup_64.c8
-rw-r--r--arch/powerpc/kernel/systbl.S13
-rw-r--r--arch/powerpc/mm/hugetlbpage.c295
-rw-r--r--arch/powerpc/mm/init_64.c7
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c10
-rw-r--r--arch/powerpc/platforms/cell/spu_callbacks.c13
-rw-r--r--arch/ppc/platforms/4xx/ocotea.c2
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c114
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c140
-rw-r--r--arch/ppc/platforms/mpc885ads_setup.c131
-rw-r--r--arch/ppc/platforms/pq2ads.c31
-rw-r--r--arch/ppc/syslib/ibm440gx_common.c13
-rw-r--r--arch/ppc/syslib/ibm440gx_common.h4
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c25
-rw-r--r--arch/ppc/syslib/ppc_sys.c4
-rw-r--r--arch/ppc/syslib/pq2_sys.c8
-rw-r--r--drivers/block/floppy.c2
-rw-r--r--drivers/input/serio/i8042-io.h4
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c2
-rw-r--r--drivers/scsi/Kconfig4
-rw-r--r--drivers/scsi/advansys.c2
-rw-r--r--drivers/serial/cpm_uart/cpm_uart.h49
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c280
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm1.c54
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c14
-rw-r--r--drivers/video/au1200fb.c1922
-rw-r--r--fs/stat.c2
-rw-r--r--include/asm-i386/i387.h4
-rw-r--r--include/asm-powerpc/cputable.h14
-rw-r--r--include/asm-powerpc/io.h6
-rw-r--r--include/asm-powerpc/page_64.h1
-rw-r--r--include/asm-powerpc/pgalloc.h2
-rw-r--r--include/asm-powerpc/unistd.h20
-rw-r--r--include/asm-ppc/ppc_sys.h2
-rw-r--r--include/asm-ppc/reg_booke.h1
-rw-r--r--include/sound/pcm.h6
-rw-r--r--include/sound/pcm_oss.h2
-rw-r--r--sound/core/Kconfig12
-rw-r--r--sound/core/oss/pcm_oss.c8
-rw-r--r--sound/core/pcm.c12
-rw-r--r--sound/core/pcm_lib.c6
-rw-r--r--sound/core/pcm_memory.c8
-rw-r--r--sound/drivers/dummy.c14
-rw-r--r--sound/drivers/mpu401/mpu401.c14
-rw-r--r--sound/drivers/serial-u16550.c14
-rw-r--r--sound/drivers/virmidi.c14
-rw-r--r--sound/isa/opti9xx/miro.c3
-rw-r--r--sound/pci/ad1889.c3
-rw-r--r--sound/pci/ali5451/ali5451.c2
-rw-r--r--sound/pci/als300.c2
-rw-r--r--sound/pci/als4000.c2
-rw-r--r--sound/pci/atiixp.c2
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/au88x0/au8810.c2
-rw-r--r--sound/pci/au88x0/au8820.c2
-rw-r--r--sound/pci/au88x0/au8830.c2
-rw-r--r--sound/pci/azt3328.c2
-rw-r--r--sound/pci/bt87x.c4
-rw-r--r--sound/pci/ca0106/ca0106_main.c2
-rw-r--r--sound/pci/cmipci.c2
-rw-r--r--sound/pci/cs4281.c2
-rw-r--r--sound/pci/cs46xx/cs46xx.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c2
-rw-r--r--sound/pci/emu10k1/emu10k1.c2
-rw-r--r--sound/pci/emu10k1/emu10k1x.c3
-rw-r--r--sound/pci/ens1370.c2
-rw-r--r--sound/pci/es1938.c2
-rw-r--r--sound/pci/es1968.c3
-rw-r--r--sound/pci/fm801.c2
-rw-r--r--sound/pci/hda/hda_intel.c2
-rw-r--r--sound/pci/hda/patch_analog.c13
-rw-r--r--sound/pci/hda/patch_realtek.c1
-rw-r--r--sound/pci/hda/patch_sigmatel.c4
-rw-r--r--sound/pci/ice1712/ice1712.c3
-rw-r--r--sound/pci/ice1712/ice1724.c2
-rw-r--r--sound/pci/intel8x0.c8
-rw-r--r--sound/pci/intel8x0m.c2
-rw-r--r--sound/pci/korg1212/korg1212.c2
-rw-r--r--sound/pci/maestro3.c3
-rw-r--r--sound/pci/mixart/mixart.c3
-rw-r--r--sound/pci/nm256/nm256.c2
-rw-r--r--sound/pci/pcxhr/pcxhr.c3
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c4
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme32.c2
-rw-r--r--sound/pci/rme96.c2
-rw-r--r--sound/pci/rme9652/hdsp.c2
-rw-r--r--sound/pci/rme9652/hdspm.c2
-rw-r--r--sound/pci/rme9652/rme9652.c2
-rw-r--r--sound/pci/sonicvibes.c2
-rw-r--r--sound/pci/trident/trident.c2
-rw-r--r--sound/pci/via82xx.c18
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/vx222/vx222.c2
-rw-r--r--sound/pci/ymfpci/ymfpci.c2
-rw-r--r--sound/pcmcia/Kconfig4
-rw-r--r--sound/ppc/toonie.c2
-rw-r--r--sound/usb/usbquirks.h9
105 files changed, 1436 insertions, 2315 deletions
diff --git a/Documentation/sound/alsa/Audiophile-Usb.txt b/Documentation/sound/alsa/Audiophile-Usb.txt
index 4692c8e..b535c2a 100644
--- a/Documentation/sound/alsa/Audiophile-Usb.txt
+++ b/Documentation/sound/alsa/Audiophile-Usb.txt
@@ -1,4 +1,4 @@
- Guide to using M-Audio Audiophile USB with ALSA and Jack v1.2
+ Guide to using M-Audio Audiophile USB with ALSA and Jack v1.3
========================================================
Thibault Le Meur <Thibault.LeMeur@supelec.fr>
@@ -22,16 +22,16 @@ The device has 4 audio interfaces, and 2 MIDI ports:
* Midi In (Mi)
* Midi Out (Mo)
-The internal DAC/ADC has the following caracteristics:
+The internal DAC/ADC has the following characteristics:
* sample depth of 16 or 24 bits
* sample rate from 8kHz to 96kHz
-* Two ports can't use different sample depths at the same time.Moreover, the
+* Two ports can't use different sample depths at the same time. Moreover, the
Audiophile USB documentation gives the following Warning: "Please exit any
audio application running before switching between bit depths"
Due to the USB 1.1 bandwidth limitation, a limited number of interfaces can be
activated at the same time depending on the audio mode selected:
- * 16-bit/48kHz ==> 4 channels in/ 4 channels out
+ * 16-bit/48kHz ==> 4 channels in/4 channels out
- Ai+Ao+Di+Do
* 24-bit/48kHz ==> 4 channels in/2 channels out,
or 2 channels in/4 channels out
@@ -41,8 +41,8 @@ activated at the same time depending on the audio mode selected:
Important facts about the Digital interface:
--------------------------------------------
- * The Do port additionnaly supports surround-encoded AC-3 and DTS passthrough,
-though I haven't tested it under linux
+ * The Do port additionally supports surround-encoded AC-3 and DTS passthrough,
+though I haven't tested it under Linux
- Note that in this setup only the Do interface can be enabled
* Apart from recording an audio digital stream, enabling the Di port is a way
to synchronize the device to an external sample clock
@@ -60,24 +60,23 @@ synchronization error (for instance sound played at an odd sample rate)
The Audiophile USB MIDI ports will be automatically supported once the
following modules have been loaded:
* snd-usb-audio
- * snd-seq
* snd-seq-midi
-No additionnal setting is required.
+No additional setting is required.
2.2 - Audio ports
-----------------
Audio functions of the Audiophile USB device are handled by the snd-usb-audio
module. This module can work in a default mode (without any device-specific
-parameter), or in an advanced mode with the device-specific parameter called
+parameter), or in an "advanced" mode with the device-specific parameter called
"device_setup".
2.2.1 - Default Alsa driver mode
-The default behaviour of the snd-usb-audio driver is to parse the device
+The default behavior of the snd-usb-audio driver is to parse the device
capabilities at startup and enable all functions inside the device (including
-all ports at any sample rates and any sample depths supported). This approach
+all ports at any supported sample rates and sample depths). This approach
has the advantage to let the driver easily switch from sample rates/depths
automatically according to the need of the application claiming the device.
@@ -114,9 +113,9 @@ gain).
For people having this problem, the snd-usb-audio module has a new module
parameter called "device_setup".
-2.2.2.1 - Initializing the working mode of the Audiohile USB
+2.2.2.1 - Initializing the working mode of the Audiophile USB
-As far as the Audiohile USB device is concerned, this value let the user
+As far as the Audiophile USB device is concerned, this value let the user
specify:
* the sample depth
* the sample rate
@@ -174,20 +173,20 @@ The parameter can be given:
IMPORTANT NOTE WHEN SWITCHING CONFIGURATION:
-------------------------------------------
- * You may need to _first_ intialize the module with the correct device_setup
+ * You may need to _first_ initialize the module with the correct device_setup
parameter and _only_after_ turn on the Audiophile USB device
* This is especially true when switching the sample depth:
- - first trun off the device
- - de-register the snd-usb-audio module
- - change the device_setup parameter (by either manually reprobing the module
- or changing modprobe.conf)
+ - first turn off the device
+ - de-register the snd-usb-audio module (modprobe -r)
+ - change the device_setup parameter by changing the device_setup
+ option in /etc/modprobe.conf
- turn on the device
2.2.2.3 - Audiophile USB's device_setup structure
If you want to understand the device_setup magic numbers for the Audiophile
USB, you need some very basic understanding of binary computation. However,
-this is not required to use the parameter and you may skip thi section.
+this is not required to use the parameter and you may skip this section.
The device_setup is one byte long and its structure is the following:
@@ -231,11 +230,11 @@ Caution:
2.2.3 - USB implementation details for this device
-You may safely skip this section if you're not interrested in driver
+You may safely skip this section if you're not interested in driver
development.
-This section describes some internals aspect of the device and summarize the
-data I got by usb-snooping the windows and linux drivers.
+This section describes some internal aspects of the device and summarize the
+data I got by usb-snooping the windows and Linux drivers.
The M-Audio Audiophile USB has 7 USB Interfaces:
a "USB interface":
@@ -277,9 +276,9 @@ Here is a short description of the AltSettings capabilities:
- 16-bit depth, 8-48kHz sample mode
- Synch playback (Do), audio format type III IEC1937_AC-3
-In order to ensure a correct intialization of the device, the driver
+In order to ensure a correct initialization of the device, the driver
_must_know_ how the device will be used:
- * if DTS is choosen, only Interface 2 with AltSet nb.6 must be
+ * if DTS is chosen, only Interface 2 with AltSet nb.6 must be
registered
* if 96KHz only AltSets nb.1 of each interface must be selected
* if samples are using 24bits/48KHz then AltSet 2 must me used if
@@ -290,7 +289,7 @@ _must_know_ how the device will be used:
is not connected
When device_setup is given as a parameter to the snd-usb-audio module, the
-parse_audio_enpoint function uses a quirk called
+parse_audio_endpoints function uses a quirk called
"audiophile_skip_setting_quirk" in order to prevent AltSettings not
corresponding to device_setup from being registered in the driver.
@@ -317,9 +316,8 @@ However you may see the following warning message:
using the "default" ALSA device. This is less efficient than it could be.
Consider using a hardware device instead rather than using the plug layer."
-
3.2 - Patching alsa to use direct pcm device
--------------------------------------------
+--------------------------------------------
A patch for Jack by Andreas Steinmetz adds support for Big Endian devices.
However it has not been included in the CVS tree.
@@ -331,3 +329,32 @@ After having applied the patch you can run jackd with the following command
line:
% jackd -R -dalsa -Phw:1,0 -r48000 -p128 -n2 -D -Chw:1,1
+3.2 - Getting 2 input and/or output interfaces in Jack
+------------------------------------------------------
+
+As you can see, starting the Jack server this way will only enable 1 stereo
+input (Di or Ai) and 1 stereo output (Ao or Do).
+
+This is due to the following restrictions:
+* Jack can only open one capture device and one playback device at a time
+* The Audiophile USB is seen as 2 (or three) Alsa devices: hw:1,0, hw:1,1
+ (and optionally hw:1,2)
+If you want to get Ai+Di and/or Ao+Do support with Jack, you would need to
+combine the Alsa devices into one logical "complex" device.
+
+If you want to give it a try, I recommend reading the information from
+this page: http://www.sound-man.co.uk/linuxaudio/ice1712multi.html
+It is related to another device (ice1712) but can be adapted to suit
+the Audiophile USB.
+
+Enabling multiple Audiophile USB interfaces for Jackd will certainly require:
+* patching Jack with the previously mentioned "Big Endian" patch
+* patching Jackd with the MMAP_COMPLEX patch (see the ice1712 page)
+* patching the alsa-lib/src/pcm/pcm_multi.c file (see the ice1712 page)
+* define a multi device (combination of hw:1,0 and hw:1,1) in your .asoundrc
+ file
+* start jackd with this device
+
+I had no success in testing this for now, but this may be due to my OS
+configuration. If you have any success with this kind of setup, please
+drop me an email.
diff --git a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
index 68eeebc..1faf763 100644
--- a/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
+++ b/Documentation/sound/alsa/DocBook/writing-an-alsa-driver.tmpl
@@ -1172,7 +1172,7 @@
}
/* PCI IDs */
- static struct pci_device_id snd_mychip_ids[] = {
+ static struct pci_device_id snd_mychip_ids[] __devinitdata = {
{ PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
....
@@ -1565,7 +1565,7 @@
<informalexample>
<programlisting>
<![CDATA[
- static struct pci_device_id snd_mychip_ids[] = {
+ static struct pci_device_id snd_mychip_ids[] __devinitdata = {
{ PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
....
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index fe22e54..dbe421d 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
CONFIG_MMU=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_PPC=y
CONFIG_EARLY_PRINTK=y
@@ -55,6 +56,7 @@ CONFIG_SYSCTL=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
# CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
# CONFIG_EMBEDDED is not set
@@ -69,10 +71,6 @@ CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
CONFIG_SLAB=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
@@ -84,7 +82,6 @@ CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
@@ -93,6 +90,7 @@ CONFIG_STOP_MACHINE=y
#
# Block layer
#
+# CONFIG_BLK_DEV_IO_TRACE is not set
#
# IO Schedulers
@@ -126,6 +124,7 @@ CONFIG_RTAS_FLASH=y
CONFIG_MMIO_NVRAM=y
CONFIG_CELL_IIC=y
# CONFIG_PPC_MPC106 is not set
+# CONFIG_PPC_970_NAP is not set
# CONFIG_CPU_FREQ is not set
# CONFIG_WANT_EARLY_SERIAL is not set
@@ -167,7 +166,6 @@ CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_EXTREME=y
# CONFIG_MEMORY_HOTPLUG is not set
CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_MIGRATION=y
# CONFIG_PPC_64K_PAGES is not set
CONFIG_SCHED_SMT=y
CONFIG_PROC_DEVICETREE=y
@@ -184,7 +182,6 @@ CONFIG_GENERIC_ISA_DMA=y
# CONFIG_PPC_INDIRECT_PCI is not set
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
# CONFIG_PCI_DEBUG is not set
#
@@ -226,6 +223,7 @@ CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
CONFIG_INET_TUNNEL=y
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
@@ -242,6 +240,7 @@ CONFIG_IPV6=y
CONFIG_INET6_AH=m
CONFIG_INET6_ESP=m
CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_TUNNEL=m
CONFIG_INET6_TUNNEL=m
CONFIG_IPV6_TUNNEL=m
CONFIG_NETFILTER=y
@@ -632,6 +631,7 @@ CONFIG_SERIAL_NONSTANDARD=y
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
CONFIG_SERIAL_8250_NR_UARTS=4
CONFIG_SERIAL_8250_RUNTIME_UARTS=4
# CONFIG_SERIAL_8250_EXTENDED is not set
@@ -717,7 +717,6 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_I2C_PARPORT_LIGHT is not set
# CONFIG_I2C_PROSAVAGE is not set
# CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
# CONFIG_I2C_SIS5595 is not set
# CONFIG_I2C_SIS630 is not set
# CONFIG_I2C_SIS96X is not set
@@ -736,9 +735,7 @@ CONFIG_I2C_ALGOBIT=y
# CONFIG_SENSORS_PCF8574 is not set
# CONFIG_SENSORS_PCA9539 is not set
# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
# CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
# CONFIG_I2C_DEBUG_CORE is not set
# CONFIG_I2C_DEBUG_ALGO is not set
# CONFIG_I2C_DEBUG_BUS is not set
@@ -766,10 +763,6 @@ CONFIG_I2C_ALGOBIT=y
#
#
-# Multimedia Capabilities Port drivers
-#
-
-#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
@@ -818,6 +811,19 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_MMC is not set
#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
+#
+
+#
# InfiniBand support
#
CONFIG_INFINIBAND=y
@@ -834,6 +840,11 @@ CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y
#
#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
+#
# File systems
#
CONFIG_EXT2_FS=y
@@ -889,7 +900,6 @@ CONFIG_TMPFS=y
CONFIG_HUGETLBFS=y
CONFIG_HUGETLB_PAGE=y
CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
# CONFIG_CONFIGFS_FS is not set
#
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 39e348a..3f7182d 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -57,6 +57,8 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
#define COMMON_USER_POWER5_PLUS (COMMON_USER_PPC64 | PPC_FEATURE_POWER5_PLUS|\
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
+#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
+ PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP)
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
PPC_FEATURE_BOOKE)
@@ -263,6 +265,20 @@ struct cpu_spec cpu_specs[] = {
.oprofile_type = PPC_OPROFILE_POWER4,
.platform = "power5+",
},
+ { /* Power6 */
+ .pvr_mask = 0xffff0000,
+ .pvr_value = 0x003e0000,
+ .cpu_name = "POWER6",
+ .cpu_features = CPU_FTRS_POWER6,
+ .cpu_user_features = COMMON_USER_POWER6,
+ .icache_bsize = 128,
+ .dcache_bsize = 128,
+ .num_pmcs = 6,
+ .cpu_setup = __setup_cpu_power4,
+ .oprofile_cpu_type = "ppc64/power6",
+ .oprofile_type = PPC_OPROFILE_POWER4,
+ .platform = "power6",
+ },
{ /* Cell Broadband Engine */
.pvr_mask = 0xffff0000,
.pvr_value = 0x00700000,
diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c
index 928b858..ba34001 100644
--- a/arch/powerpc/kernel/module_64.c
+++ b/arch/powerpc/kernel/module_64.c
@@ -191,11 +191,19 @@ int module_frob_arch_sections(Elf64_Ehdr *hdr,
(void *)hdr
+ sechdrs[sechdrs[i].sh_link].sh_offset);
}
- if (!me->arch.stubs_section || !me->arch.toc_section) {
- printk("%s: doesn't contain .toc or .stubs.\n", me->name);
+
+ if (!me->arch.stubs_section) {
+ printk("%s: doesn't contain .stubs.\n", me->name);
return -ENOEXEC;
}
+ /* If we don't have a .toc, just use .stubs. We need to set r2
+ to some reasonable value in case the module calls out to
+ other functions via a stub, or if a function pointer escapes
+ the module by some means. */
+ if (!me->arch.toc_section)
+ me->arch.toc_section = me->arch.stubs_section;
+
/* Override the stubs size */
sechdrs[me->arch.stubs_section].sh_size = get_stubs_size(hdr, sechdrs);
return 0;
@@ -342,7 +350,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break;
case R_PPC64_TOC16:
- /* Subtact TOC pointer */
+ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me);
if (value + 0x8000 > 0xffff) {
printk("%s: bad TOC16 relocation (%lu)\n",
@@ -355,7 +363,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
break;
case R_PPC64_TOC16_DS:
- /* Subtact TOC pointer */
+ /* Subtract TOC pointer */
value -= my_r2(sechdrs, me);
if ((value & 3) != 0 || value + 0x8000 > 0xffff) {
printk("%s: bad TOC16_DS relocation (%lu)\n",
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index 7e4d548..078fb55 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -636,10 +636,96 @@ static void __init early_cmdline_parse(void)
#ifdef CONFIG_PPC_PSERIES
/*
- * To tell the firmware what our capabilities are, we have to pass
- * it a fake 32-bit ELF header containing a couple of PT_NOTE sections
- * that contain structures that contain the actual values.
+ * There are two methods for telling firmware what our capabilities are.
+ * Newer machines have an "ibm,client-architecture-support" method on the
+ * root node. For older machines, we have to call the "process-elf-header"
+ * method in the /packages/elf-loader node, passing it a fake 32-bit
+ * ELF header containing a couple of PT_NOTE sections that contain
+ * structures that contain various information.
*/
+
+/*
+ * New method - extensible architecture description vector.
+ *
+ * Because the description vector contains a mix of byte and word
+ * values, we declare it as an unsigned char array, and use this
+ * macro to put word values in.
+ */
+#define W(x) ((x) >> 24) & 0xff, ((x) >> 16) & 0xff, \
+ ((x) >> 8) & 0xff, (x) & 0xff
+
+/* Option vector bits - generic bits in byte 1 */
+#define OV_IGNORE 0x80 /* ignore this vector */
+#define OV_CESSATION_POLICY 0x40 /* halt if unsupported option present*/
+
+/* Option vector 1: processor architectures supported */
+#define OV1_PPC_2_00 0x80 /* set if we support PowerPC 2.00 */
+#define OV1_PPC_2_01 0x40 /* set if we support PowerPC 2.01 */
+#define OV1_PPC_2_02 0x20 /* set if we support PowerPC 2.02 */
+#define OV1_PPC_2_03 0x10 /* set if we support PowerPC 2.03 */
+#define OV1_PPC_2_04 0x08 /* set if we support PowerPC 2.04 */
+#define OV1_PPC_2_05 0x04 /* set if we support PowerPC 2.05 */
+
+/* Option vector 2: Open Firmware options supported */
+#define OV2_REAL_MODE 0x20 /* set if we want OF in real mode */
+
+/* Option vector 3: processor options supported */
+#define OV3_FP 0x80 /* floating point */
+#define OV3_VMX 0x40 /* VMX/Altivec */
+
+/* Option vector 5: PAPR/OF options supported */
+#define OV5_LPAR 0x80 /* logical partitioning supported */
+#define OV5_SPLPAR 0x40 /* shared-processor LPAR supported */
+/* ibm,dynamic-reconfiguration-memory property supported */
+#define OV5_DRCONF_MEMORY 0x20
+#define OV5_LARGE_PAGES 0x10 /* large pages supported */
+
+/*
+ * The architecture vector has an array of PVR mask/value pairs,
+ * followed by # option vectors - 1, followed by the option vectors.
+ */
+static unsigned char ibm_architecture_vec[] = {
+ W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
+ W(0xffff0000), W(0x003e0000), /* POWER6 */
+ W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
+ 5 - 1, /* 5 option vectors */
+
+ /* option vector 1: processor architectures supported */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV1_PPC_2_00 | OV1_PPC_2_01 | OV1_PPC_2_02 | OV1_PPC_2_03 |
+ OV1_PPC_2_04 | OV1_PPC_2_05,
+
+ /* option vector 2: Open Firmware options supported */
+ 34 - 1, /* length */
+ OV2_REAL_MODE,
+ 0, 0,
+ W(0xffffffff), /* real_base */
+ W(0xffffffff), /* real_size */
+ W(0xffffffff), /* virt_base */
+ W(0xffffffff), /* virt_size */
+ W(0xffffffff), /* load_base */
+ W(64), /* 128MB min RMA */
+ W(0xffffffff), /* full client load */
+ 0, /* min RMA percentage of total RAM */
+ 48, /* max log_2(hash table size) */
+
+ /* option vector 3: processor options supported */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV3_FP | OV3_VMX,
+
+ /* option vector 4: IBM PAPR implementation */
+ 2 - 1, /* length */
+ 0, /* don't halt */
+
+ /* option vector 5: PAPR/OF options */
+ 3 - 1, /* length */
+ 0, /* don't ignore, don't halt */
+ OV5_LPAR | OV5_SPLPAR | OV5_LARGE_PAGES,
+};
+
+/* Old method - ELF header with PT_NOTE sections */
static struct fake_elf {
Elf32_Ehdr elfhdr;
Elf32_Phdr phdr[2];
@@ -728,8 +814,26 @@ static struct fake_elf {
static void __init prom_send_capabilities(void)
{
- ihandle elfloader;
+ ihandle elfloader, root;
+ prom_arg_t ret;
+
+ root = call_prom("open", 1, 1, ADDR("/"));
+ if (root != 0) {
+ /* try calling the ibm,client-architecture-support method */
+ if (call_prom_ret("call-method", 3, 2, &ret,
+ ADDR("ibm,client-architecture-support"),
+ ADDR(ibm_architecture_vec)) == 0) {
+ /* the call exists... */
+ if (ret)
+ prom_printf("WARNING: ibm,client-architecture"
+ "-support call FAILED!\n");
+ call_prom("close", 1, 0, root);
+ return;
+ }
+ call_prom("close", 1, 0, root);
+ }
+ /* no ibm,client-architecture-support call, try the old way */
elfloader = call_prom("open", 1, 1, ADDR("/packages/elf-loader"));
if (elfloader == 0) {
prom_printf("couldn't open /packages/elf-loader\n");
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 1d93e73..684ab1d 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -516,3 +516,11 @@ void probe_machine(void)
printk(KERN_INFO "Using %s machine description\n", ppc_md.name);
}
+
+int check_legacy_ioport(unsigned long base_port)
+{
+ if (ppc_md.check_legacy_ioport == NULL)
+ return 0;
+ return ppc_md.check_legacy_ioport(base_port);
+}
+EXPORT_SYMBOL(check_legacy_ioport);
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 13e91c4..4467c49 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -594,14 +594,6 @@ void ppc64_terminate_msg(unsigned int src, const char *msg)
printk("[terminate]%04x %s\n", src, msg);
}
-int check_legacy_ioport(unsigned long base_port)
-{
- if (ppc_md.check_legacy_ioport == NULL)
- return 0;
- return ppc_md.check_legacy_ioport(base_port);
-}
-EXPORT_SYMBOL(check_legacy_ioport);
-
void cpu_die(void)
{
if (ppc_md.cpu_die)
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S
index 0b98eea..cf56a1d 100644
--- a/arch/powerpc/kernel/systbl.S
+++ b/arch/powerpc/kernel/systbl.S
@@ -325,6 +325,19 @@ SYSCALL(unshare)
SYSCALL(splice)
SYSCALL(tee)
SYSCALL(vmsplice)
+COMPAT_SYS(openat)
+SYSCALL(mkdirat)
+SYSCALL(mknodat)
+SYSCALL(fchownat)
+COMPAT_SYS(futimesat)
+SYSX(sys_newfstatat, sys_fstatat64, sys_fstatat64)
+SYSCALL(unlinkat)
+SYSCALL(renameat)
+SYSCALL(linkat)
+SYSCALL(symlinkat)
+SYSCALL(readlinkat)
+SYSCALL(fchmodat)
+SYSCALL(faccessat)
/*
* please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c
diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
index 7370f9f..266b8b2 100644
--- a/arch/powerpc/mm/hugetlbpage.c
+++ b/arch/powerpc/mm/hugetlbpage.c
@@ -30,13 +30,66 @@
#define NUM_LOW_AREAS (0x100000000UL >> SID_SHIFT)
#define NUM_HIGH_AREAS (PGTABLE_RANGE >> HTLB_AREA_SHIFT)
+#ifdef CONFIG_PPC_64K_PAGES
+#define HUGEPTE_INDEX_SIZE (PMD_SHIFT-HPAGE_SHIFT)
+#else
+#define HUGEPTE_INDEX_SIZE (PUD_SHIFT-HPAGE_SHIFT)
+#endif
+#define PTRS_PER_HUGEPTE (1 << HUGEPTE_INDEX_SIZE)
+#define HUGEPTE_TABLE_SIZE (sizeof(pte_t) << HUGEPTE_INDEX_SIZE)
+
+#define HUGEPD_SHIFT (HPAGE_SHIFT + HUGEPTE_INDEX_SIZE)
+#define HUGEPD_SIZE (1UL << HUGEPD_SHIFT)
+#define HUGEPD_MASK (~(HUGEPD_SIZE-1))
+
+#define huge_pgtable_cache (pgtable_cache[HUGEPTE_CACHE_NUM])
+
+/* Flag to mark huge PD pointers. This means pmd_bad() and pud_bad()
+ * will choke on pointers to hugepte tables, which is handy for
+ * catching screwups early. */
+#define HUGEPD_OK 0x1
+
+typedef struct { unsigned long pd; } hugepd_t;
+
+#define hugepd_none(hpd) ((hpd).pd == 0)
+
+static inline pte_t *hugepd_page(hugepd_t hpd)
+{
+ BUG_ON(!(hpd.pd & HUGEPD_OK));
+ return (pte_t *)(hpd.pd & ~HUGEPD_OK);
+}
+
+static inline pte_t *hugepte_offset(hugepd_t *hpdp, unsigned long addr)
+{
+ unsigned long idx = ((addr >> HPAGE_SHIFT) & (PTRS_PER_HUGEPTE-1));
+ pte_t *dir = hugepd_page(*hpdp);
+
+ return dir + idx;
+}
+
+static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp,
+ unsigned long address)
+{
+ pte_t *new = kmem_cache_alloc(huge_pgtable_cache,
+ GFP_KERNEL|__GFP_REPEAT);
+
+ if (! new)
+ return -ENOMEM;
+
+ spin_lock(&mm->page_table_lock);
+ if (!hugepd_none(*hpdp))
+ kmem_cache_free(huge_pgtable_cache, new);
+ else
+ hpdp->pd = (unsigned long)new | HUGEPD_OK;
+ spin_unlock(&mm->page_table_lock);
+ return 0;
+}
+
/* Modelled after find_linux_pte() */
pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pg;
pud_t *pu;
- pmd_t *pm;
- pte_t *pt;
BUG_ON(! in_hugepage_area(mm->context, addr));
@@ -46,26 +99,14 @@ pte_t *huge_pte_offset(struct mm_struct *mm, unsigned long addr)
if (!pgd_none(*pg)) {
pu = pud_offset(pg, addr);
if (!pud_none(*pu)) {
- pm = pmd_offset(pu, addr);
#ifdef CONFIG_PPC_64K_PAGES
- /* Currently, we use the normal PTE offset within full
- * size PTE pages, thus our huge PTEs are scattered in
- * the PTE page and we do waste some. We may change
- * that in the future, but the current mecanism keeps
- * things much simpler
- */
- if (!pmd_none(*pm)) {
- /* Note: pte_offset_* are all equivalent on
- * ppc64 as we don't have HIGHMEM
- */
- pt = pte_offset_kernel(pm, addr);
- return pt;
- }
-#else /* CONFIG_PPC_64K_PAGES */
- /* On 4k pages, we put huge PTEs in the PMD page */
- pt = (pte_t *)pm;
- return pt;
-#endif /* CONFIG_PPC_64K_PAGES */
+ pmd_t *pm;
+ pm = pmd_offset(pu, addr);
+ if (!pmd_none(*pm))
+ return hugepte_offset((hugepd_t *)pm, addr);
+#else
+ return hugepte_offset((hugepd_t *)pu, addr);
+#endif
}
}
@@ -76,8 +117,7 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pg;
pud_t *pu;
- pmd_t *pm;
- pte_t *pt;
+ hugepd_t *hpdp = NULL;
BUG_ON(! in_hugepage_area(mm->context, addr));
@@ -87,23 +127,182 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr)
pu = pud_alloc(mm, pg, addr);
if (pu) {
+#ifdef CONFIG_PPC_64K_PAGES
+ pmd_t *pm;
pm = pmd_alloc(mm, pu, addr);
- if (pm) {
+ if (pm)
+ hpdp = (hugepd_t *)pm;
+#else
+ hpdp = (hugepd_t *)pu;
+#endif
+ }
+
+ if (! hpdp)
+ return NULL;
+
+ if (hugepd_none(*hpdp) && __hugepte_alloc(mm, hpdp, addr))
+ return NULL;
+
+ return hugepte_offset(hpdp, addr);
+}
+
+static void free_hugepte_range(struct mmu_gather *tlb, hugepd_t *hpdp)
+{
+ pte_t *hugepte = hugepd_page(*hpdp);
+
+ hpdp->pd = 0;
+ tlb->need_flush = 1;
+ pgtable_free_tlb(tlb, pgtable_free_cache(hugepte, HUGEPTE_CACHE_NUM,
+ HUGEPTE_TABLE_SIZE-1));
+}
+
#ifdef CONFIG_PPC_64K_PAGES
- /* See comment in huge_pte_offset. Note that if we ever
- * want to put the page size in the PMD, we would have
- * to open code our own pte_alloc* function in order
- * to populate and set the size atomically
- */
- pt = pte_alloc_map(mm, pm, addr);
-#else /* CONFIG_PPC_64K_PAGES */
- pt = (pte_t *)pm;
-#endif /* CONFIG_PPC_64K_PAGES */
- return pt;
- }
+static void hugetlb_free_pmd_range(struct mmu_gather *tlb, pud_t *pud,
+ unsigned long addr, unsigned long end,
+ unsigned long floor, unsigned long ceiling)
+{
+ pmd_t *pmd;
+ unsigned long next;
+ unsigned long start;
+
+ start = addr;
+ pmd = pmd_offset(pud, addr);
+ do {
+ next = pmd_addr_end(addr, end);
+ if (pmd_none(*pmd))
+ continue;
+ free_hugepte_range(tlb, (hugepd_t *)pmd);
+ } while (pmd++, addr = next, addr != end);
+
+ start &= PUD_MASK;
+ if (start < floor)
+ return;
+ if (ceiling) {
+ ceiling &= PUD_MASK;
+ if (!ceiling)
+ return;
}
+ if (end - 1 > ceiling - 1)
+ return;
- return NULL;
+ pmd = pmd_offset(pud, start);
+ pud_clear(pud);
+ pmd_free_tlb(tlb, pmd);
+}
+#endif
+
+static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
+ unsigned long addr, unsigned long end,
+ unsigned long floor, unsigned long ceiling)
+{
+ pud_t *pud;
+ unsigned long next;
+ unsigned long start;
+
+ start = addr;
+ pud = pud_offset(pgd, addr);
+ do {
+ next = pud_addr_end(addr, end);
+#ifdef CONFIG_PPC_64K_PAGES
+ if (pud_none_or_clear_bad(pud))
+ continue;
+ hugetlb_free_pmd_range(tlb, pud, addr, next, floor, ceiling);
+#else
+ if (pud_none(*pud))
+ continue;
+ free_hugepte_range(tlb, (hugepd_t *)pud);
+#endif
+ } while (pud++, addr = next, addr != end);
+
+ start &= PGDIR_MASK;
+ if (start < floor)
+ return;
+ if (ceiling) {
+ ceiling &= PGDIR_MASK;
+ if (!ceiling)
+ return;
+ }
+ if (end - 1 > ceiling - 1)
+ return;
+
+ pud = pud_offset(pgd, start);
+ pgd_clear(pgd);
+ pud_free_tlb(tlb, pud);
+}
+
+/*
+ * This function frees user-level page tables of a process.
+ *
+ * Must be called with pagetable lock held.
+ */
+void hugetlb_free_pgd_range(struct mmu_gather **tlb,
+ unsigned long addr, unsigned long end,
+ unsigned long floor, unsigned long ceiling)
+{
+ pgd_t *pgd;
+ unsigned long next;
+ unsigned long start;
+
+ /*
+ * Comments below take from the normal free_pgd_range(). They
+ * apply here too. The tests against HUGEPD_MASK below are
+ * essential, because we *don't* test for this at the bottom
+ * level. Without them we'll attempt to free a hugepte table
+ * when we unmap just part of it, even if there are other
+ * active mappings using it.
+ *
+ * The next few lines have given us lots of grief...
+ *
+ * Why are we testing HUGEPD* at this top level? Because
+ * often there will be no work to do at all, and we'd prefer
+ * not to go all the way down to the bottom just to discover
+ * that.
+ *
+ * Why all these "- 1"s? Because 0 represents both the bottom
+ * of the address space and the top of it (using -1 for the
+ * top wouldn't help much: the masks would do the wrong thing).
+ * The rule is that addr 0 and floor 0 refer to the bottom of
+ * the address space, but end 0 and ceiling 0 refer to the top
+ * Comparisons need to use "end - 1" and "ceiling - 1" (though
+ * that end 0 case should be mythical).
+ *
+ * Wherever addr is brought up or ceiling brought down, we
+ * must be careful to reject "the opposite 0" before it
+ * confuses the subsequent tests. But what about where end is
+ * brought down by HUGEPD_SIZE below? no, end can't go down to
+ * 0 there.
+ *
+ * Whereas we round start (addr) and ceiling down, by different
+ * masks at different levels, in order to test whether a table
+ * now has no other vmas using it, so can be freed, we don't
+ * bother to round floor or end up - the tests don't need that.
+ */
+
+ addr &= HUGEPD_MASK;
+ if (addr < floor) {
+ addr += HUGEPD_SIZE;
+ if (!addr)
+ return;
+ }
+ if (ceiling) {
+ ceiling &= HUGEPD_MASK;
+ if (!ceiling)
+ return;
+ }
+ if (end - 1 > ceiling - 1)
+ end -= HUGEPD_SIZE;
+ if (addr > end - 1)
+ return;
+
+ start = addr;
+ pgd = pgd_offset((*tlb)->mm, addr);
+ do {
+ BUG_ON(! in_hugepage_area((*tlb)->mm->context, addr));
+ next = pgd_addr_end(addr, end);
+ if (pgd_none_or_clear_bad(pgd))
+ continue;
+ hugetlb_free_pud_range(*tlb, pgd, addr, next, floor, ceiling);
+ } while (pgd++, addr = next, addr != end);
}
void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
@@ -841,3 +1040,27 @@ repeat:
out:
return err;
}
+
+static void zero_ctor(void *addr, kmem_cache_t *cache, unsigned long flags)
+{
+ memset(addr, 0, kmem_cache_size(cache));
+}
+
+static int __init hugetlbpage_init(void)
+{
+ if (!cpu_has_feature(CPU_FTR_16M_PAGE))
+ return -ENODEV;
+
+ huge_pgtable_cache = kmem_cache_create("hugepte_cache",
+ HUGEPTE_TABLE_SIZE,
+ HUGEPTE_TABLE_SIZE,
+ SLAB_HWCACHE_ALIGN |
+ SLAB_MUST_HWCACHE_ALIGN,
+ zero_ctor, NULL);
+ if (! huge_pgtable_cache)
+ panic("hugetlbpage_init(): could not create hugepte cache\n");
+
+ return 0;
+}
+
+module_init(hugetlbpage_init);
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index babebd1..9e30f96 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -162,7 +162,14 @@ static const char *pgtable_cache_name[ARRAY_SIZE(pgtable_cache_size)] = {
};
#endif /* CONFIG_PPC_64K_PAGES */
+#ifdef CONFIG_HUGETLB_PAGE
+/* Hugepages need one extra cache, initialized in hugetlbpage.c. We
+ * can't put into the tables above, because HPAGE_SHIFT is not compile
+ * time constant. */
+kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)+1];
+#else
kmem_cache_t *pgtable_cache[ARRAY_SIZE(pgtable_cache_size)];
+#endif
void pgtable_cache_init(void)
{
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 269dda4..ef47a62 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -306,19 +306,19 @@ spu_request_irqs(struct spu *spu)
snprintf(spu->irq_c0, sizeof (spu->irq_c0), "spe%02d.0", spu->number);
ret = request_irq(irq_base + spu->isrc,
- spu_irq_class_0, 0, spu->irq_c0, spu);
+ spu_irq_class_0, SA_INTERRUPT, spu->irq_c0, spu);
if (ret)
goto out;
snprintf(spu->irq_c1, sizeof (spu->irq_c1), "spe%02d.1", spu->number);
ret = request_irq(irq_base + IIC_CLASS_STRIDE + spu->isrc,
- spu_irq_class_1, 0, spu->irq_c1, spu);
+ spu_irq_class_1, SA_INTERRUPT, spu->irq_c1, spu);
if (ret)
goto out1;
snprintf(spu->irq_c2, sizeof (spu->irq_c2), "spe%02d.2", spu->number);
ret = request_irq(irq_base + 2*IIC_CLASS_STRIDE + spu->isrc,
- spu_irq_class_2, 0, spu->irq_c2, spu);
+ spu_irq_class_2, SA_INTERRUPT, spu->irq_c2, spu);
if (ret)
goto out2;
goto out;
@@ -487,10 +487,14 @@ int spu_irq_class_1_bottom(struct spu *spu)
ea = spu->dar;
dsisr = spu->dsisr;
if (dsisr & (MFC_DSISR_PTE_NOT_FOUND | MFC_DSISR_ACCESS_DENIED)) {
+ u64 flags;
+
access = (_PAGE_PRESENT | _PAGE_USER);
access |= (dsisr & MFC_DSISR_ACCESS_PUT) ? _PAGE_RW : 0UL;
+ local_irq_save(flags);
if (hash_page(ea, access, 0x300) != 0)
error |= CLASS1_ENABLE_STORAGE_FAULT_INTR;
+ local_irq_restore(flags);
}
if (error & CLASS1_ENABLE_STORAGE_FAULT_INTR) {
if ((ret = spu_handle_mm_fault(spu)) != 0)
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c
index b283380..95b3643 100644
--- a/arch/powerpc/platforms/cell/spu_callbacks.c
+++ b/arch/powerpc/platforms/cell/spu_callbacks.c
@@ -319,6 +319,19 @@ void *spu_syscall_table[] = {
[__NR_splice] sys_splice,
[__NR_tee] sys_tee,
[__NR_vmsplice] sys_vmsplice,
+ [__NR_openat] sys_openat,
+ [__NR_mkdirat] sys_mkdirat,
+ [__NR_mknodat] sys_mknodat,
+ [__NR_fchownat] sys_fchownat,
+ [__NR_futimesat] sys_futimesat,
+ [__NR_newfstatat] sys_newfstatat,
+ [__NR_unlinkat] sys_unlinkat,
+ [__NR_renameat] sys_renameat,
+ [__NR_linkat] sys_linkat,
+ [__NR_symlinkat] sys_symlinkat,
+ [__NR_readlinkat] sys_readlinkat,
+ [__NR_fchmodat] sys_fchmodat,
+ [__NR_faccessat] sys_faccessat,
};
long spu_sys_callback(struct spu_syscall_block *s)
diff --git a/arch/ppc/platforms/4xx/ocotea.c b/arch/ppc/platforms/4xx/ocotea.c
index f841972..554776d 100644
--- a/arch/ppc/platforms/4xx/ocotea.c
+++ b/arch/ppc/platforms/4xx/ocotea.c
@@ -331,7 +331,7 @@ static void __init ocotea_init(void)
void __init platform_init(unsigned long r3, unsigned long r4,
unsigned long r5, unsigned long r6, unsigned long r7)
{
- ibm44x_platform_init(r3, r4, r5, r6, r7);
+ ibm440gx_platform_init(r3, r4, r5, r6, r7);
ppc_md.setup_arch = ocotea_setup_arch;
ppc_md.show_cpuinfo = ocotea_show_cpuinfo;
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index bc9b94f..e62b757 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -26,11 +26,35 @@
#include <asm/irq.h>
#include <asm/ppc_sys.h>
#include <asm/ppcboot.h>
+#include <linux/fs_uart_pd.h>
#include "pq2ads_pd.h"
static void init_fcc1_ioports(void);
static void init_fcc2_ioports(void);
+static void init_scc1_uart_ioports(void);
+static void init_scc4_uart_ioports(void);
+
+static struct fs_uart_platform_info mpc8272_uart_pdata[] = {
+ [fsid_scc1_uart] = {
+ .init_ioports = init_scc1_uart_ioports,
+ .fs_no = fsid_scc1_uart,
+ .brg = 1,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
+ [fsid_scc4_uart] = {
+ .init_ioports = init_scc4_uart_ioports,
+ .fs_no = fsid_scc4_uart,
+ .brg = 4,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
+};
static struct fs_mii_bus_info mii_bus_info = {
.method = fsmii_bitbang,
@@ -201,6 +225,55 @@ static void __init mpc8272ads_fixup_enet_pdata(struct platform_device *pdev,
}
}
+static void mpc8272ads_fixup_uart_pdata(struct platform_device *pdev,
+ int idx)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+ int num = ARRAY_SIZE(mpc8272_uart_pdata);
+ int id = fs_uart_id_scc2fsid(idx);
+
+ /* no need to alter anything if console */
+ if ((id <= num) && (!pdev->dev.platform_data)) {
+ pinfo = &mpc8272_uart_pdata[id];
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ }
+}
+
+static void init_scc1_uart_ioports(void)
+{
+ cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+
+ /* SCC1 is only on port D */
+ setbits32(&immap->im_ioport.iop_ppard,0x00000003);
+ clrbits32(&immap->im_ioport.iop_psord,0x00000001);
+ setbits32(&immap->im_ioport.iop_psord,0x00000002);
+ clrbits32(&immap->im_ioport.iop_pdird,0x00000001);
+ setbits32(&immap->im_ioport.iop_pdird,0x00000002);
+
+ /* Wire BRG1 to SCC1 */
+ clrbits32(&immap->im_cpmux.cmx_scr,0x00ffffff);
+
+ iounmap(immap);
+}
+
+static void init_scc4_uart_ioports(void)
+{
+ cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+
+ setbits32(&immap->im_ioport.iop_ppard,0x00000600);
+ clrbits32(&immap->im_ioport.iop_psord,0x00000600);
+ clrbits32(&immap->im_ioport.iop_pdird,0x00000200);
+ setbits32(&immap->im_ioport.iop_pdird,0x00000400);
+
+ /* Wire BRG4 to SCC4 */
+ clrbits32(&immap->im_cpmux.cmx_scr,0x000000ff);
+ setbits32(&immap->im_cpmux.cmx_scr,0x0000001b);
+
+ iounmap(immap);
+}
+
static int mpc8272ads_platform_notify(struct device *dev)
{
static const struct platform_notify_dev_map dev_map[] = {
@@ -209,6 +282,10 @@ static int mpc8272ads_platform_notify(struct device *dev)
.rtn = mpc8272ads_fixup_enet_pdata
},
{
+ .bus_id = "fsl-cpm-scc:uart",
+ .rtn = mpc
+ },
+ {
.bus_id = NULL
}
};
@@ -230,7 +307,44 @@ int __init mpc8272ads_init(void)
ppc_sys_device_enable(MPC82xx_CPM_FCC1);
ppc_sys_device_enable(MPC82xx_CPM_FCC2);
+ /* to be ready for console, let's attach pdata here */
+#ifdef CONFIG_SERIAL_CPM_SCC1
+ ppc_sys_device_setfunc(MPC82xx_CPM_SCC1, PPC_SYS_FUNC_UART);
+ ppc_sys_device_enable(MPC82xx_CPM_SCC1);
+
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+ ppc_sys_device_setfunc(MPC82xx_CPM_SCC4, PPC_SYS_FUNC_UART);
+ ppc_sys_device_enable(MPC82xx_CPM_SCC4);
+#endif
+
+
return 0;
}
+/*
+ To prevent confusion, console selection is gross:
+ by 0 assumed SCC1 and by 1 assumed SCC4
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+
+ struct platform_device* pdev = NULL;
+ if(index) { /*assume SCC4 here*/
+ pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC4];
+ pinfo = &mpc8272<F12>_uart_pdata[1];
+ } else { /*over SCC1*/
+ pdev = &ppc_sys_platform_devices[MPC82xx_CPM_SCC1];
+ pinfo = &mpc8272_uart_pdata[0];
+ }
+
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+ return NULL;
+}
+
arch_initcall(mpc8272ads_init);
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index ac8fcc6..6ce3b84 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
#include <linux/mii.h>
#include <asm/delay.h>
@@ -37,6 +38,11 @@
extern unsigned char __res[];
+static void setup_fec1_ioports(void);
+static void setup_scc1_ioports(void);
+static void setup_smc1_ioports(void);
+static void setup_smc2_ioports(void);
+
static struct fs_mii_bus_info fec_mii_bus_info = {
.method = fsmii_fec,
.id = 0,
@@ -79,6 +85,28 @@ static struct fs_platform_info mpc8xx_scc_pdata = {
.phy_irq = -1,
.bus_info = &scc_mii_bus_info,
+
+};
+
+static struct fs_uart_platform_info mpc866_uart_pdata[] = {
+ [fsid_smc1_uart] = {
+ .brg = 1,
+ .fs_no = fsid_smc1_uart,
+ .init_ioports = setup_smc1_ioports,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
+ [fsid_smc2_uart] = {
+ .brg = 2,
+ .fs_no = fsid_smc2_uart,
+ .init_ioports = setup_smc2_ioports,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
};
void __init board_init(void)
@@ -92,9 +120,12 @@ void __init board_init(void)
printk(KERN_CRIT "Could not remap BCSR1\n");
return;
}
+
#ifdef CONFIG_SERIAL_CPM_SMC1
cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
clrbits32(bcsr_io,(0x80000000 >> 7));
+ cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
+ cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
#else
setbits32(bcsr_io,(0x80000000 >> 7));
@@ -108,6 +139,8 @@ void __init board_init(void)
cp->cp_simode &= ~(0xe0000000 >> 1);
cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
clrbits32(bcsr_io,(0x80000000 >> 13));
+ cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
+ cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
#else
clrbits32(bcsr_io,(0x80000000 >> 13));
cp->cp_pbpar &= ~(0x00000c00);
@@ -232,6 +265,74 @@ static void mpc866ads_fixup_scc_enet_pdata(struct platform_device *pdev,
mpc866ads_fixup_enet_pdata(pdev, fsid_scc1 + pdev->id - 1);
}
+static void setup_smc1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+ unsigned int iobits = 0x000000c0;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+
+ clrbits32(bcsr_io,BCSR1_RS232EN_1);
+ iounmap(bcsr_io);
+
+ setbits32(&immap->im_cpm.cp_pbpar, iobits);
+ clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+ clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+
+}
+
+static void setup_smc2_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+ unsigned int iobits = 0x00000c00;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+
+ clrbits32(bcsr_io,BCSR1_RS232EN_2);
+
+ iounmap(bcsr_io);
+
+#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
+ setbits32(&immap->im_cpm.cp_pbpar, iobits);
+ clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+ clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+#else
+ setbits16(&immap->im_ioport.iop_papar, iobits);
+ clrbits16(&immap->im_ioport.iop_padir, iobits);
+ clrbits16(&immap->im_ioport.iop_paodr, iobits);
+#endif
+
+}
+
+static void __init mpc866ads_fixup_uart_pdata(struct platform_device *pdev,
+ int idx)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+ int num = ARRAY_SIZE(mpc866_uart_pdata);
+
+ int id = fs_uart_id_smc2fsid(idx);
+
+ /* no need to alter anything if console */
+ if ((id <= num) && (!pdev->dev.platform_data)) {
+ pinfo = &mpc866_uart_pdata[id];
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ }
+}
+
static int mpc866ads_platform_notify(struct device *dev)
{
static const struct platform_notify_dev_map dev_map[] = {
@@ -244,6 +345,10 @@ static int mpc866ads_platform_notify(struct device *dev)
.rtn = mpc866ads_fixup_scc_enet_pdata,
},
{
+ .bus_id = "fsl-cpm-smc:uart",
+ .rtn = mpc866ads_fixup_uart_pdata
+ },
+ {
.bus_id = NULL
}
};
@@ -267,7 +372,42 @@ int __init mpc866ads_init(void)
#endif
ppc_sys_device_enable(MPC8xx_CPM_FEC1);
+/* Since either of the uarts could be used as console, they need to ready */
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ ppc_sys_device_enable(MPC8xx_CPM_SMC1);
+ ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMCer
+ ppc_sys_device_enable(MPC8xx_CPM_SMC2);
+ ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
+#endif
+
return 0;
}
+/*
+ To prevent confusion, console selection is gross:
+ by 0 assumed SMC1 and by 1 assumed SMC2
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+
+ struct platform_device* pdev = NULL;
+ if(index) { /*assume SMC2 here*/
+ pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
+ pinfo = &mpc866_uart_pdata[1];
+ } else { /*over SMC1*/
+ pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
+ pinfo = &mpc866_uart_pdata[0];
+ }
+
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+ return NULL;
+}
+
arch_initcall(mpc866ads_init);
diff --git a/arch/ppc/platforms/mpc885ads_setup.c b/arch/ppc/platforms/mpc885ads_setup.c
index 50a99e5..4b88679 100644
--- a/arch/ppc/platforms/mpc885ads_setup.c
+++ b/arch/ppc/platforms/mpc885ads_setup.c
@@ -20,6 +20,7 @@
#include <linux/device.h>
#include <linux/fs_enet_pd.h>
+#include <linux/fs_uart_pd.h>
#include <linux/mii.h>
#include <asm/delay.h>
@@ -35,9 +36,32 @@
#include <asm/ppc_sys.h>
extern unsigned char __res[];
+static void setup_smc1_ioports(void);
+static void setup_smc2_ioports(void);
static void __init mpc885ads_scc_phy_init(char);
+static struct fs_uart_platform_info mpc885_uart_pdata[] = {
+ [fsid_smc1_uart] = {
+ .brg = 1,
+ .fs_no = fsid_smc1_uart,
+ .init_ioports = setup_smc1_ioports,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
+ [fsid_smc2_uart] = {
+ .brg = 2,
+ .fs_no = fsid_smc2_uart,
+ .init_ioports = setup_smc2_ioports,
+ .tx_num_fifo = 4,
+ .tx_buf_size = 32,
+ .rx_num_fifo = 4,
+ .rx_buf_size = 32,
+ },
+};
+
static struct fs_mii_bus_info fec_mii_bus_info = {
.method = fsmii_fec,
.id = 0,
@@ -116,6 +140,8 @@ void __init board_init(void)
#ifdef CONFIG_SERIAL_CPM_SMC1
cp->cp_simode &= ~(0xe0000000 >> 17); /* brg1 */
clrbits32(bcsr_io, BCSR1_RS232EN_1);
+ cp->cp_smc[0].smc_smcm |= (SMCM_RX | SMCM_TX);
+ cp->cp_smc[0].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
#else
setbits32(bcsr_io,BCSR1_RS232EN_1);
cp->cp_smc[0].smc_smcmr = 0;
@@ -126,6 +152,8 @@ void __init board_init(void)
cp->cp_simode &= ~(0xe0000000 >> 1);
cp->cp_simode |= (0x20000000 >> 1); /* brg2 */
clrbits32(bcsr_io,BCSR1_RS232EN_2);
+ cp->cp_smc[1].smc_smcm |= (SMCM_RX | SMCM_TX);
+ cp->cp_smc[1].smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
#else
setbits32(bcsr_io,BCSR1_RS232EN_2);
cp->cp_smc[1].smc_smcmr = 0;
@@ -343,6 +371,70 @@ static void mpc885ads_scc_phy_init(char phy_addr)
out_be32(&fecp->fec_mii_speed, 0);
}
+static void setup_smc1_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+ unsigned int iobits = 0x000000c0;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+ clrbits32(bcsr_io,BCSR1_RS232EN_1);
+ iounmap(bcsr_io);
+
+ setbits32(&immap->im_cpm.cp_pbpar, iobits);
+ clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+ clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+}
+
+static void setup_smc2_ioports(void)
+{
+ immap_t *immap = (immap_t *) IMAP_ADDR;
+ unsigned *bcsr_io;
+ unsigned int iobits = 0x00000c00;
+
+ bcsr_io = ioremap(BCSR1, sizeof(unsigned long));
+
+ if (bcsr_io == NULL) {
+ printk(KERN_CRIT "Could not remap BCSR1\n");
+ return;
+ }
+ clrbits32(bcsr_io,BCSR1_RS232EN_2);
+ iounmap(bcsr_io);
+
+#ifndef CONFIG_SERIAL_CPM_ALT_SMC2
+ setbits32(&immap->im_cpm.cp_pbpar, iobits);
+ clrbits32(&immap->im_cpm.cp_pbdir, iobits);
+ clrbits16(&immap->im_cpm.cp_pbodr, iobits);
+#else
+ setbits16(&immap->im_ioport.iop_papar, iobits);
+ clrbits16(&immap->im_ioport.iop_padir, iobits);
+ clrbits16(&immap->im_ioport.iop_paodr, iobits);
+#endif
+}
+
+static void __init mpc885ads_fixup_uart_pdata(struct platform_device *pdev,
+ int idx)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+ int num = ARRAY_SIZE(mpc885_uart_pdata);
+
+ int id = fs_uart_id_smc2fsid(idx);
+
+ /* no need to alter anything if console */
+ if ((id <= num) && (!pdev->dev.platform_data)) {
+ pinfo = &mpc885_uart_pdata[id];
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ }
+}
+
+
static int mpc885ads_platform_notify(struct device *dev)
{
@@ -356,12 +448,17 @@ static int mpc885ads_platform_notify(struct device *dev)
.rtn = mpc885ads_fixup_scc_enet_pdata,
},
{
+ .bus_id = "fsl-cpm-smc:uart",
+ .rtn = mpc885ads_fixup_uart_pdata
+ },
+ {
.bus_id = NULL
}
};
platform_notify_map(dev_map,dev);
+ return 0;
}
int __init mpc885ads_init(void)
@@ -383,7 +480,41 @@ int __init mpc885ads_init(void)
ppc_sys_device_enable(MPC8xx_CPM_FEC2);
#endif
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ ppc_sys_device_enable(MPC8xx_CPM_SMC1);
+ ppc_sys_device_setfunc(MPC8xx_CPM_SMC1, PPC_SYS_FUNC_UART);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ ppc_sys_device_enable(MPC8xx_CPM_SMC2);
+ ppc_sys_device_setfunc(MPC8xx_CPM_SMC2, PPC_SYS_FUNC_UART);
+#endif
return 0;
}
arch_initcall(mpc885ads_init);
+
+/*
+ To prevent confusion, console selection is gross:
+ by 0 assumed SMC1 and by 1 assumed SMC2
+ */
+struct platform_device* early_uart_get_pdev(int index)
+{
+ bd_t *bd = (bd_t *) __res;
+ struct fs_uart_platform_info *pinfo;
+
+ struct platform_device* pdev = NULL;
+ if(index) { /*assume SMC2 here*/
+ pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC2];
+ pinfo = &mpc885_uart_pdata[1];
+ } else { /*over SMC1*/
+ pdev = &ppc_sys_platform_devices[MPC8xx_CPM_SMC1];
+ pinfo = &mpc885_uart_pdata[0];
+ }
+
+ pinfo->uart_clk = bd->bi_intfreq;
+ pdev->dev.platform_data = pinfo;
+ ppc_sys_fixup_mem_resource(pdev, IMAP_ADDR);
+ return NULL;
+}
+
diff --git a/arch/ppc/platforms/pq2ads.c b/arch/ppc/platforms/pq2ads.c
index 3365fd7..7fc2e02 100644
--- a/arch/ppc/platforms/pq2ads.c
+++ b/arch/ppc/platforms/pq2ads.c
@@ -14,11 +14,40 @@
#include <linux/init.h>
+#include <asm/io.h>
#include <asm/mpc8260.h>
+#include <asm/cpm2.h>
+#include <asm/immap_cpm2.h>
void __init
m82xx_board_setup(void)
{
+ cpm2_map_t* immap = ioremap(CPM_MAP_ADDR, sizeof(cpm2_map_t));
+ u32 *bcsr = ioremap(BCSR_ADDR+4, sizeof(u32));
+
/* Enable the 2nd UART port */
- *(volatile uint *)(BCSR_ADDR + 4) &= ~BCSR1_RS232_EN2;
+ clrbits32(bcsr, BCSR1_RS232_EN2);
+
+#ifdef CONFIG_SERIAL_CPM_SCC1
+ clrbits32((u32*)&immap->im_scc[0].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32((u32*)&immap->im_scc[0].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC2
+ clrbits32((u32*)&immap->im_scc[1].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32((u32*)&immap->im_scc[1].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC3
+ clrbits32((u32*)&immap->im_scc[2].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32((u32*)&immap->im_scc[2].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+#ifdef CONFIG_SERIAL_CPM_SCC4
+ clrbits32((u32*)&immap->im_scc[3].scc_sccm, UART_SCCM_TX | UART_SCCM_RX);
+ clrbits32((u32*)&immap->im_scc[3].scc_gsmrl, SCC_GSMRL_ENR | SCC_GSMRL_ENT);
+#endif
+
+ iounmap(bcsr);
+ iounmap(immap);
}
diff --git a/arch/ppc/syslib/ibm440gx_common.c b/arch/ppc/syslib/ibm440gx_common.c
index a7dd55f..f6cc168 100644
--- a/arch/ppc/syslib/ibm440gx_common.c
+++ b/arch/ppc/syslib/ibm440gx_common.c
@@ -2,7 +2,7 @@
* PPC440GX system library
*
* Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
- * Copyright (c) 2003, 2004 Zultys Technologies
+ * Copyright (c) 2003 - 2006 Zultys Technologies
*
* 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
@@ -282,3 +282,14 @@ int ibm440gx_show_cpuinfo(struct seq_file *m){
return 0;
}
+void __init ibm440gx_platform_init(unsigned long r3, unsigned long r4,
+ unsigned long r5, unsigned long r6,
+ unsigned long r7)
+{
+ /* Erratum 440_43 workaround, disable L1 cache parity checking */
+ if (!strcmp(cur_cpu_spec->cpu_name, "440GX Rev. C") ||
+ !strcmp(cur_cpu_spec->cpu_name, "440GX Rev. F"))
+ mtspr(SPRN_CCR1, mfspr(SPRN_CCR1) | CCR1_DPC);
+
+ ibm44x_platform_init(r3, r4, r5, r6, r7);
+}
diff --git a/arch/ppc/syslib/ibm440gx_common.h b/arch/ppc/syslib/ibm440gx_common.h
index a2ab9fa..a03ec60 100644
--- a/arch/ppc/syslib/ibm440gx_common.h
+++ b/arch/ppc/syslib/ibm440gx_common.h
@@ -29,6 +29,10 @@
void ibm440gx_get_clocks(struct ibm44x_clocks*, unsigned int sys_clk,
unsigned int ser_clk) __init;
+/* common 440GX platform init */
+void ibm440gx_platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7) __init;
+
/* Enable L2 cache */
void ibm440gx_l2c_enable(void) __init;
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index bd41ed8..6f53638 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -170,12 +170,18 @@ struct platform_device ppc_sys_platform_devices[] = {
[MPC8xx_CPM_SMC1] = {
.name = "fsl-cpm-smc",
.id = 1,
- .num_resources = 2,
+ .num_resources = 3,
.resource = (struct resource[]) {
{
.name = "regs",
- .start = 0xa82,
- .end = 0xa91,
+ .start = 0xa80,
+ .end = 0xa8f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "pram",
+ .start = 0x3e80,
+ .end = 0x3ebf,
.flags = IORESOURCE_MEM,
},
{
@@ -189,15 +195,22 @@ struct platform_device ppc_sys_platform_devices[] = {
[MPC8xx_CPM_SMC2] = {
.name = "fsl-cpm-smc",
.id = 2,
- .num_resources = 2,
+ .num_resources = 3,
.resource = (struct resource[]) {
{
.name = "regs",
- .start = 0xa92,
- .end = 0xaa1,
+ .start = 0xa90,
+ .end = 0xa9f,
.flags = IORESOURCE_MEM,
},
{
+ .name = "pram",
+ .start = 0x3f80,
+ .end = 0x3fbf,
+ .flags = IORESOURCE_MEM,
+
+ },
+ {
.name = "interrupt",
.start = MPC8xx_INT_SMC2,
.end = MPC8xx_INT_SMC2,
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index 7662c4e..2d48018 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -109,9 +109,11 @@ ppc_sys_fixup_mem_resource(struct platform_device *pdev, phys_addr_t paddr)
int i;
for (i = 0; i < pdev->num_resources; i++) {
struct resource *r = &pdev->resource[i];
- if ((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) {
+ if (((r->flags & IORESOURCE_MEM) == IORESOURCE_MEM) &&
+ ((r->flags & PPC_SYS_IORESOURCE_FIXUPPED) != PPC_SYS_IORESOURCE_FIXUPPED)) {
r->start += paddr;
r->end += paddr;
+ r->flags |= PPC_SYS_IORESOURCE_FIXUPPED;
}
}
}
diff --git a/arch/ppc/syslib/pq2_sys.c b/arch/ppc/syslib/pq2_sys.c
index 75e64f1..433b0fa 100644
--- a/arch/ppc/syslib/pq2_sys.c
+++ b/arch/ppc/syslib/pq2_sys.c
@@ -113,13 +113,13 @@ struct ppc_sys_spec ppc_sys_specs[] = {
.ppc_sys_name = "8248",
.mask = 0x0000ff00,
.value = 0x00000c00,
- .num_devices = 11,
+ .num_devices = 12,
.device_list = (enum ppc_sys_devices[])
{
MPC82xx_CPM_FCC1, MPC82xx_CPM_FCC2, MPC82xx_CPM_SCC1,
- MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SMC1,
- MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI, MPC82xx_CPM_I2C,
- MPC82xx_CPM_USB, MPC82xx_SEC1,
+ MPC82xx_CPM_SCC2, MPC82xx_CPM_SCC3, MPC82xx_CPM_SCC4,
+ MPC82xx_CPM_SMC1, MPC82xx_CPM_SMC2, MPC82xx_CPM_SPI,
+ MPC82xx_CPM_I2C, MPC82xx_CPM_USB, MPC82xx_SEC1,
},
},
{
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index bedb689..dff1e67 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -4301,7 +4301,7 @@ static int __init floppy_init(void)
}
use_virtual_dma = can_use_virtual_dma & 1;
-#if defined(CONFIG_PPC64)
+#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(FDC1)) {
del_timer(&fd_timeout);
err = -ENODEV;
diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
index 9a92216..cc21914 100644
--- a/drivers/input/serio/i8042-io.h
+++ b/drivers/input/serio/i8042-io.h
@@ -67,14 +67,14 @@ static inline int i8042_platform_init(void)
* On some platforms touching the i8042 data register region can do really
* bad things. Because of this the region is always reserved on such boxes.
*/
-#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC64)
+#if !defined(__sh__) && !defined(__alpha__) && !defined(__mips__) && !defined(CONFIG_PPC_MERGE)
if (!request_region(I8042_DATA_REG, 16, "i8042"))
return -EBUSY;
#endif
i8042_reset = 1;
-#if defined(CONFIG_PPC64)
+#if defined(CONFIG_PPC_MERGE)
if (check_legacy_ioport(I8042_DATA_REG))
return -EBUSY;
if (!request_region(I8042_DATA_REG, 16, "i8042"))
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index f9d87b8..320b3d9 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -616,7 +616,7 @@ static struct snd_kcontrol_new snd_cx88_capture_volume = {
* Only boards with eeprom and byte 1 at eeprom=1 have it
*/
-static struct pci_device_id cx88_audio_pci_tbl[] = {
+static struct pci_device_id cx88_audio_pci_tbl[] __devinitdata = {
{0x14f1,0x8801,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0x14f1,0x8811,PCI_ANY_ID,PCI_ANY_ID,0,0,0},
{0, }
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index 3e73026..a480a37 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -446,7 +446,9 @@ config SCSI_DPT_I2O
config SCSI_ADVANSYS
tristate "AdvanSys SCSI support"
- depends on (ISA || EISA || PCI) && SCSI && BROKEN
+ depends on SCSI
+ depends on ISA || EISA || PCI
+ depends on BROKEN || X86_32
help
This is a driver for all SCSI host adapters manufactured by
AdvanSys. It is documented in the kernel source in
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 28b9305..2a41963 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -2051,7 +2051,7 @@ STATIC ASC_DCNT AscGetMaxDmaCount(ushort);
#define ADV_VADDR_TO_U32 virt_to_bus
#define ADV_U32_TO_VADDR bus_to_virt
-#define AdvPortAddr ulong /* Virtual memory address size */
+#define AdvPortAddr void __iomem * /* Virtual memory address size */
/*
* Define Adv Library required memory access macros.
diff --git a/drivers/serial/cpm_uart/cpm_uart.h b/drivers/serial/cpm_uart/cpm_uart.h
index 73c8a08..aa5eb7d 100644
--- a/drivers/serial/cpm_uart/cpm_uart.h
+++ b/drivers/serial/cpm_uart/cpm_uart.h
@@ -10,6 +10,8 @@
#define CPM_UART_H
#include <linux/config.h>
+#include <linux/platform_device.h>
+#include <linux/fs_uart_pd.h>
#if defined(CONFIG_CPM2)
#include "cpm_uart_cpm2.h"
@@ -26,14 +28,14 @@
#define FLAG_SMC 0x00000002
#define FLAG_CONSOLE 0x00000001
-#define UART_SMC1 0
-#define UART_SMC2 1
-#define UART_SCC1 2
-#define UART_SCC2 3
-#define UART_SCC3 4
-#define UART_SCC4 5
+#define UART_SMC1 fsid_smc1_uart
+#define UART_SMC2 fsid_smc2_uart
+#define UART_SCC1 fsid_scc1_uart
+#define UART_SCC2 fsid_scc2_uart
+#define UART_SCC3 fsid_scc3_uart
+#define UART_SCC4 fsid_scc4_uart
-#define UART_NR 6
+#define UART_NR fs_uart_nr
#define RX_NUM_FIFO 4
#define RX_BUF_SIZE 32
@@ -64,6 +66,7 @@ struct uart_cpm_port {
uint dp_addr;
void *mem_addr;
dma_addr_t dma_addr;
+ u32 mem_size;
/* helpers */
int baud;
int bits;
@@ -90,4 +93,36 @@ void scc2_lineif(struct uart_cpm_port *pinfo);
void scc3_lineif(struct uart_cpm_port *pinfo);
void scc4_lineif(struct uart_cpm_port *pinfo);
+/*
+ virtual to phys transtalion
+*/
+static inline unsigned long cpu2cpm_addr(void* addr, struct uart_cpm_port *pinfo)
+{
+ int offset;
+ u32 val = (u32)addr;
+ /* sane check */
+ if ((val >= (u32)pinfo->mem_addr) &&
+ (val<((u32)pinfo->mem_addr + pinfo->mem_size))) {
+ offset = val - (u32)pinfo->mem_addr;
+ return pinfo->dma_addr+offset;
+ }
+ printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+ return 0;
+}
+
+static inline void *cpm2cpu_addr(unsigned long addr, struct uart_cpm_port *pinfo)
+{
+ int offset;
+ u32 val = addr;
+ /* sane check */
+ if ((val >= pinfo->dma_addr) &&
+ (val<(pinfo->dma_addr + pinfo->mem_size))) {
+ offset = val - (u32)pinfo->dma_addr;
+ return (void*)(pinfo->mem_addr+offset);
+ }
+ printk("%s(): address %x to translate out of range!\n", __FUNCTION__, val);
+ return 0;
+}
+
+
#endif /* CPM_UART_H */
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index b7bf4c6..ced193b 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -41,6 +41,7 @@
#include <linux/device.h>
#include <linux/bootmem.h>
#include <linux/dma-mapping.h>
+#include <linux/fs_uart_pd.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -60,7 +61,7 @@
/* Track which ports are configured as uarts */
int cpm_uart_port_map[UART_NR];
/* How many ports did we config as uarts */
-int cpm_uart_nr;
+int cpm_uart_nr = 0;
/**************************************************************/
@@ -71,18 +72,36 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo);
/**************************************************************/
-static inline unsigned long cpu2cpm_addr(void *addr)
+
+/* Place-holder for board-specific stuff */
+struct platform_device* __attribute__ ((weak)) __init
+early_uart_get_pdev(int index)
{
- if ((unsigned long)addr >= CPM_ADDR)
- return (unsigned long)addr;
- return virt_to_bus(addr);
+ return NULL;
}
-static inline void *cpm2cpu_addr(unsigned long addr)
+
+void cpm_uart_count(void)
{
- if (addr >= CPM_ADDR)
- return (void *)addr;
- return bus_to_virt(addr);
+ cpm_uart_nr = 0;
+#ifdef CONFIG_SERIAL_CPM_SMC1
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SMC2
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC1
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC2
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC3
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
+#endif
+#ifdef CONFIG_SERIAL_CPM_SCC4
+ cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
+#endif
}
/*
@@ -258,7 +277,7 @@ static void cpm_uart_int_rx(struct uart_port *port, struct pt_regs *regs)
}
/* get pointer */
- cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+ cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
/* loop through the buffer */
while (i-- > 0) {
@@ -601,7 +620,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
/* Pick next descriptor and fill from buffer */
bdp = pinfo->tx_cur;
- p = cpm2cpu_addr(bdp->cbd_bufaddr);
+ p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
*p++ = port->x_char;
bdp->cbd_datlen = 1;
@@ -628,7 +647,7 @@ static int cpm_uart_tx_pump(struct uart_port *port)
while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
count = 0;
- p = cpm2cpu_addr(bdp->cbd_bufaddr);
+ p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
while (count < pinfo->tx_fifosize) {
*p++ = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -677,12 +696,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
mem_addr = pinfo->mem_addr;
bdp = pinfo->rx_cur = pinfo->rx_bd_base;
for (i = 0; i < (pinfo->rx_nrfifos - 1); i++, bdp++) {
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+ bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
bdp->cbd_sc = BD_SC_EMPTY | BD_SC_INTRPT;
mem_addr += pinfo->rx_fifosize;
}
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+ bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
bdp->cbd_sc = BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT;
/* Set the physical address of the host memory
@@ -692,12 +711,12 @@ static void cpm_uart_initbd(struct uart_cpm_port *pinfo)
mem_addr = pinfo->mem_addr + L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize);
bdp = pinfo->tx_cur = pinfo->tx_bd_base;
for (i = 0; i < (pinfo->tx_nrfifos - 1); i++, bdp++) {
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+ bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
bdp->cbd_sc = BD_SC_INTRPT;
mem_addr += pinfo->tx_fifosize;
}
- bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr);
+ bdp->cbd_bufaddr = cpu2cpm_addr(mem_addr, pinfo);
bdp->cbd_sc = BD_SC_WRAP | BD_SC_INTRPT;
}
@@ -829,14 +848,6 @@ static int cpm_uart_request_port(struct uart_port *port)
if (pinfo->flags & FLAG_CONSOLE)
return 0;
- /*
- * Setup any port IO, connect any baud rate generators,
- * etc. This is expected to be handled by board
- * dependant code
- */
- if (pinfo->set_lineif)
- pinfo->set_lineif(pinfo);
-
if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -988,6 +999,54 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
},
};
+int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
+{
+ struct resource *r;
+ struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
+ int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
+ struct uart_cpm_port *pinfo;
+ int line;
+ u32 mem, pram;
+
+ for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);
+
+ pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];
+
+ pinfo->brg = pdata->brg;
+
+ if (!is_con) {
+ pinfo->port.line = line;
+ pinfo->port.flags = UPF_BOOT_AUTOCONF;
+ }
+
+ if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
+ return -EINVAL;
+ mem = r->start;
+
+ if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
+ return -EINVAL;
+ pram = r->start;
+
+ if(idx > fsid_smc2_uart) {
+ pinfo->sccp = (scc_t *)mem;
+ pinfo->sccup = (scc_uart_t *)pram;
+ } else {
+ pinfo->smcp = (smc_t *)mem;
+ pinfo->smcup = (smc_uart_t *)pram;
+ }
+ pinfo->tx_nrfifos = pdata->tx_num_fifo;
+ pinfo->tx_fifosize = pdata->tx_buf_size;
+
+ pinfo->rx_nrfifos = pdata->rx_num_fifo;
+ pinfo->rx_fifosize = pdata->rx_buf_size;
+
+ pinfo->port.uartclk = pdata->uart_clk;
+ pinfo->port.mapbase = (unsigned long)mem;
+ pinfo->port.irq = platform_get_irq(pdev, 0);
+
+ return 0;
+}
+
#ifdef CONFIG_SERIAL_CPM_CONSOLE
/*
* Print a string to the serial port trying not to disturb
@@ -1027,7 +1086,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
* If the buffer address is in the CPM DPRAM, don't
* convert it.
*/
- cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+ cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
*cp = *s;
@@ -1044,7 +1103,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
while ((bdp->cbd_sc & BD_SC_READY) != 0)
;
- cp = cpm2cpu_addr(bdp->cbd_bufaddr);
+ cp = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
*cp = 13;
bdp->cbd_datlen = 1;
@@ -1067,9 +1126,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
pinfo->tx_cur = (volatile cbd_t *) bdp;
}
-/*
- * Setup console. Be careful is called early !
- */
+
static int __init cpm_uart_console_setup(struct console *co, char *options)
{
struct uart_port *port;
@@ -1080,9 +1137,27 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
int flow = 'n';
int ret;
+ struct fs_uart_platform_info *pdata;
+ struct platform_device* pdev = early_uart_get_pdev(co->index);
+
port =
(struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
pinfo = (struct uart_cpm_port *)port;
+ if (!pdev) {
+ pr_info("cpm_uart: console: compat mode\n");
+ /* compatibility - will be cleaned up */
+ cpm_uart_init_portdesc();
+
+ if (pinfo->set_lineif)
+ pinfo->set_lineif(pinfo);
+ } else {
+ pdata = pdev->dev.platform_data;
+ if (pdata)
+ if (pdata->init_ioports)
+ pdata->init_ioports();
+
+ cpm_uart_drv_get_platform_data(pdev, 1);
+ }
pinfo->flags |= FLAG_CONSOLE;
@@ -1097,14 +1172,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
baud = 9600;
}
- /*
- * Setup any port IO, connect any baud rate generators,
- * etc. This is expected to be handled by board
- * dependant code
- */
- if (pinfo->set_lineif)
- pinfo->set_lineif(pinfo);
-
if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
@@ -1143,11 +1210,8 @@ static struct console cpm_scc_uart_console = {
int __init cpm_uart_console_init(void)
{
- int ret = cpm_uart_init_portdesc();
-
- if (!ret)
- register_console(&cpm_scc_uart_console);
- return ret;
+ register_console(&cpm_scc_uart_console);
+ return 0;
}
console_initcall(cpm_uart_console_init);
@@ -1165,44 +1229,130 @@ static struct uart_driver cpm_reg = {
.minor = SERIAL_CPM_MINOR,
.cons = CPM_UART_CONSOLE,
};
-
-static int __init cpm_uart_init(void)
+static int cpm_uart_drv_probe(struct device *dev)
{
- int ret, i;
-
- printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n");
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fs_uart_platform_info *pdata;
+ int ret = -ENODEV;
-#ifndef CONFIG_SERIAL_CPM_CONSOLE
- ret = cpm_uart_init_portdesc();
- if (ret)
+ if(!pdev) {
+ printk(KERN_ERR"CPM UART: platform data missing!\n");
return ret;
-#endif
+ }
- cpm_reg.nr = cpm_uart_nr;
- ret = uart_register_driver(&cpm_reg);
+ pdata = pdev->dev.platform_data;
+ pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
+ cpm_uart_port_map[pdata->fs_no]);
- if (ret)
+ if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
return ret;
- for (i = 0; i < cpm_uart_nr; i++) {
- int con = cpm_uart_port_map[i];
- cpm_uart_ports[con].port.line = i;
- cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
- uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
- }
+ if (pdata->init_ioports)
+ pdata->init_ioports();
- return ret;
+ ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
+
+ return ret;
}
-static void __exit cpm_uart_exit(void)
+static int cpm_uart_drv_remove(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
+
+ pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
+ cpm_uart_port_map[pdata->fs_no]);
+
+ uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
+ return 0;
+}
+
+static struct device_driver cpm_smc_uart_driver = {
+ .name = "fsl-cpm-smc:uart",
+ .bus = &platform_bus_type,
+ .probe = cpm_uart_drv_probe,
+ .remove = cpm_uart_drv_remove,
+};
+
+static struct device_driver cpm_scc_uart_driver = {
+ .name = "fsl-cpm-scc:uart",
+ .bus = &platform_bus_type,
+ .probe = cpm_uart_drv_probe,
+ .remove = cpm_uart_drv_remove,
+};
+
+/*
+ This is supposed to match uart devices on platform bus,
+ */
+static int match_is_uart (struct device* dev, void* data)
{
+ struct platform_device* pdev = container_of(dev, struct platform_device, dev);
+ int ret = 0;
+ /* this was setfunc as uart */
+ if(strstr(pdev->name,":uart")) {
+ ret = 1;
+ }
+ return ret;
+}
+
+
+static int cpm_uart_init(void) {
+
+ int ret;
int i;
+ struct device *dev;
+ printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");
+
+ /* lookup the bus for uart devices */
+ dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);
+
+ /* There are devices on the bus - all should be OK */
+ if (dev) {
+ cpm_uart_count();
+ cpm_reg.nr = cpm_uart_nr;
+
+ if (!(ret = uart_register_driver(&cpm_reg))) {
+ if ((ret = driver_register(&cpm_smc_uart_driver))) {
+ uart_unregister_driver(&cpm_reg);
+ return ret;
+ }
+ if ((ret = driver_register(&cpm_scc_uart_driver))) {
+ driver_unregister(&cpm_scc_uart_driver);
+ uart_unregister_driver(&cpm_reg);
+ }
+ }
+ } else {
+ /* No capable platform devices found - falling back to legacy mode */
+ pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
+ pr_info(
+ "cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
+#ifndef CONFIG_SERIAL_CPM_CONSOLE
+ ret = cpm_uart_init_portdesc();
+ if (ret)
+ return ret;
+#endif
+
+ cpm_reg.nr = cpm_uart_nr;
+ ret = uart_register_driver(&cpm_reg);
+
+ if (ret)
+ return ret;
+
+ for (i = 0; i < cpm_uart_nr; i++) {
+ int con = cpm_uart_port_map[i];
+ cpm_uart_ports[con].port.line = i;
+ cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
+ uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
+ }
- for (i = 0; i < cpm_uart_nr; i++) {
- int con = cpm_uart_port_map[i];
- uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port);
}
+ return ret;
+}
+static void __exit cpm_uart_exit(void)
+{
+ driver_unregister(&cpm_scc_uart_driver);
+ driver_unregister(&cpm_smc_uart_driver);
uart_unregister_driver(&cpm_reg);
}
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
index d789ee5..a5a3062 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c
@@ -81,58 +81,11 @@ void cpm_line_cr_cmd(int line, int cmd)
void smc1_lineif(struct uart_cpm_port *pinfo)
{
- volatile cpm8xx_t *cp = cpmp;
-
- (void)cp; /* fix warning */
-#if defined (CONFIG_MPC885ADS)
- /* Enable SMC1 transceivers */
- {
- cp->cp_pepar |= 0x000000c0;
- cp->cp_pedir &= ~0x000000c0;
- cp->cp_peso &= ~0x00000040;
- cp->cp_peso |= 0x00000080;
- }
-#elif defined (CONFIG_MPC86XADS)
- unsigned int iobits = 0x000000c0;
-
- if (!pinfo->is_portb) {
- cp->cp_pbpar |= iobits;
- cp->cp_pbdir &= ~iobits;
- cp->cp_pbodr &= ~iobits;
- } else {
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
- }
-#endif
pinfo->brg = 1;
}
void smc2_lineif(struct uart_cpm_port *pinfo)
{
- volatile cpm8xx_t *cp = cpmp;
-
- (void)cp; /* fix warning */
-#if defined (CONFIG_MPC885ADS)
- cp->cp_pepar |= 0x00000c00;
- cp->cp_pedir &= ~0x00000c00;
- cp->cp_peso &= ~0x00000400;
- cp->cp_peso |= 0x00000800;
-#elif defined (CONFIG_MPC86XADS)
- unsigned int iobits = 0x00000c00;
-
- if (!pinfo->is_portb) {
- cp->cp_pbpar |= iobits;
- cp->cp_pbdir &= ~iobits;
- cp->cp_pbodr &= ~iobits;
- } else {
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_papar |= iobits;
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_padir &= ~iobits;
- ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits;
- }
-
-#endif
-
pinfo->brg = 2;
}
@@ -191,7 +144,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
/* was hostalloc but changed cause it blows away the */
/* large tlb mapping when pinning the kernel area */
mem_addr = (u8 *) cpm_dpram_addr(cpm_dpalloc(memsz, 8));
- dma_addr = 0;
+ dma_addr = (u32)mem_addr;
} else
mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
GFP_KERNEL);
@@ -204,8 +157,9 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
}
pinfo->dp_addr = dp_offset;
- pinfo->mem_addr = mem_addr;
- pinfo->dma_addr = dma_addr;
+ pinfo->mem_addr = mem_addr; /* virtual address*/
+ pinfo->dma_addr = dma_addr; /* physical address*/
+ pinfo->mem_size = memsz;
pinfo->rx_buf = mem_addr;
pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index fd9e53e..7c6b07a 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -142,14 +142,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
* be supported in a sane fashion.
*/
#ifndef CONFIG_STX_GP3
-#ifdef CONFIG_MPC8560_ADS
- volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
- io->iop_ppard |= 0x00000018;
- io->iop_psord &= ~0x00000008; /* Rx */
- io->iop_psord &= ~0x00000010; /* Tx */
- io->iop_pdird &= ~0x00000008; /* Rx */
- io->iop_pdird |= 0x00000010; /* Tx */
-#else
volatile iop_cpm2_t *io = &cpm2_immr->im_ioport;
io->iop_pparb |= 0x008b0000;
io->iop_pdirb |= 0x00880000;
@@ -157,7 +149,6 @@ void scc2_lineif(struct uart_cpm_port *pinfo)
io->iop_pdirb &= ~0x00030000;
io->iop_psorb &= ~0x00030000;
#endif
-#endif
cpm2_immr->im_cpmux.cmx_scr &= 0xff00ffff;
cpm2_immr->im_cpmux.cmx_scr |= 0x00090000;
pinfo->brg = 2;
@@ -218,8 +209,10 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
memsz = L1_CACHE_ALIGN(pinfo->rx_nrfifos * pinfo->rx_fifosize) +
L1_CACHE_ALIGN(pinfo->tx_nrfifos * pinfo->tx_fifosize);
- if (is_con)
+ if (is_con) {
mem_addr = alloc_bootmem(memsz);
+ dma_addr = mem_addr;
+ }
else
mem_addr = dma_alloc_coherent(NULL, memsz, &dma_addr,
GFP_KERNEL);
@@ -234,6 +227,7 @@ int cpm_uart_allocbuf(struct uart_cpm_port *pinfo, unsigned int is_con)
pinfo->dp_addr = dp_offset;
pinfo->mem_addr = mem_addr;
pinfo->dma_addr = dma_addr;
+ pinfo->mem_size = memsz;
pinfo->rx_buf = mem_addr;
pinfo->tx_buf = pinfo->rx_buf + L1_CACHE_ALIGN(pinfo->rx_nrfifos
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index b367de3..600d3e0 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -1920,1925 +1920,3 @@ module_exit(au1200fb_cleanup);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1200 LCD Driver.
- *
- * Copyright 2004-2005 AMD
- * Author: AMD
- *
- * Based on:
- * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device
- * Created 28 Dec 1997 by Geert Uytterhoeven
- *
- * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ctype.h>
-#include <linux/dma-mapping.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include "au1200fb.h"
-
-#ifdef CONFIG_PM
-#include <asm/mach-au1x00/au1xxx_pm.h>
-#endif
-
-#ifndef CONFIG_FB_AU1200_DEVS
-#define CONFIG_FB_AU1200_DEVS 4
-#endif
-
-#define DRIVER_NAME "au1200fb"
-#define DRIVER_DESC "LCD controller driver for AU1200 processors"
-
-#define DEBUG 1
-
-#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)
-#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)
-#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)
-
-#if DEBUG
-#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)
-#else
-#define print_dbg(f, arg...) do {} while (0)
-#endif
-
-
-#define AU1200_LCD_FB_IOCTL 0x46FF
-
-#define AU1200_LCD_SET_SCREEN 1
-#define AU1200_LCD_GET_SCREEN 2
-#define AU1200_LCD_SET_WINDOW 3
-#define AU1200_LCD_GET_WINDOW 4
-#define AU1200_LCD_SET_PANEL 5
-#define AU1200_LCD_GET_PANEL 6
-
-#define SCREEN_SIZE (1<< 1)
-#define SCREEN_BACKCOLOR (1<< 2)
-#define SCREEN_BRIGHTNESS (1<< 3)
-#define SCREEN_COLORKEY (1<< 4)
-#define SCREEN_MASK (1<< 5)
-
-struct au1200_lcd_global_regs_t {
- unsigned int flags;
- unsigned int xsize;
- unsigned int ysize;
- unsigned int backcolor;
- unsigned int brightness;
- unsigned int colorkey;
- unsigned int mask;
- unsigned int panel_choice;
- char panel_desc[80];
-
-};
-
-#define WIN_POSITION (1<< 0)
-#define WIN_ALPHA_COLOR (1<< 1)
-#define WIN_ALPHA_MODE (1<< 2)
-#define WIN_PRIORITY (1<< 3)
-#define WIN_CHANNEL (1<< 4)
-#define WIN_BUFFER_FORMAT (1<< 5)
-#define WIN_COLOR_ORDER (1<< 6)
-#define WIN_PIXEL_ORDER (1<< 7)
-#define WIN_SIZE (1<< 8)
-#define WIN_COLORKEY_MODE (1<< 9)
-#define WIN_DOUBLE_BUFFER_MODE (1<< 10)
-#define WIN_RAM_ARRAY_MODE (1<< 11)
-#define WIN_BUFFER_SCALE (1<< 12)
-#define WIN_ENABLE (1<< 13)
-
-struct au1200_lcd_window_regs_t {
- unsigned int flags;
- unsigned int xpos;
- unsigned int ypos;
- unsigned int alpha_color;
- unsigned int alpha_mode;
- unsigned int priority;
- unsigned int channel;
- unsigned int buffer_format;
- unsigned int color_order;
- unsigned int pixel_order;
- unsigned int xsize;
- unsigned int ysize;
- unsigned int colorkey_mode;
- unsigned int double_buffer_mode;
- unsigned int ram_array_mode;
- unsigned int xscale;
- unsigned int yscale;
- unsigned int enable;
-};
-
-
-struct au1200_lcd_iodata_t {
- unsigned int subcmd;
- struct au1200_lcd_global_regs_t global;
- struct au1200_lcd_window_regs_t window;
-};
-
-#if defined(__BIG_ENDIAN)
-#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11
-#else
-#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00
-#endif
-#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565
-
-/* Private, per-framebuffer management information (independent of the panel itself) */
-struct au1200fb_device {
- struct fb_info fb_info; /* FB driver info record */
-
- int plane;
- unsigned char* fb_mem; /* FrameBuffer memory map */
- unsigned int fb_len;
- dma_addr_t fb_phys;
-};
-
-static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];
-/********************************************************************/
-
-/* LCD controller restrictions */
-#define AU1200_LCD_MAX_XRES 1280
-#define AU1200_LCD_MAX_YRES 1024
-#define AU1200_LCD_MAX_BPP 32
-#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */
-#define AU1200_LCD_NBR_PALETTE_ENTRIES 256
-
-/* Default number of visible screen buffer to allocate */
-#define AU1200FB_NBR_VIDEO_BUFFERS 1
-
-/********************************************************************/
-
-static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;
-static int window_index = 2; /* default is zero */
-static int panel_index = 2; /* default is zero */
-static struct window_settings *win;
-static struct panel_settings *panel;
-static int noblanking = 1;
-static int nohwcursor = 0;
-
-struct window_settings {
- unsigned char name[64];
- uint32 mode_backcolor;
- uint32 mode_colorkey;
- uint32 mode_colorkeymsk;
- struct {
- int xres;
- int yres;
- int xpos;
- int ypos;
- uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */
- uint32 mode_winenable;
- } w[4];
-};
-
-#if defined(__BIG_ENDIAN)
-#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00
-#else
-#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
-#endif
-
-extern int board_au1200fb_panel_init (void);
-extern int board_au1200fb_panel_shutdown (void);
-
-#ifdef CONFIG_PM
-int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
- au1xxx_request_t request, void *data);
-au1xxx_power_dev_t *LCD_pm_dev;
-#endif
-
-/*
- * Default window configurations
- */
-static struct window_settings windows[] = {
- { /* Index 0 */
- "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
- /* mode_backcolor */ 0x006600ff,
- /* mode_colorkey,msk*/ 0, 0,
- {
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP,
- /* mode_winenable*/ LCD_WINENABLE_WEN0,
- },
- {
- /* xres, yres, xpos, ypos */ 100, 100, 100, 100,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP |
- LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ LCD_WINENABLE_WEN1,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP,
- /* mode_winenable*/ 0,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP |
- LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ 0,
- },
- },
- },
-
- { /* Index 1 */
- "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
- /* mode_backcolor */ 0x006600ff,
- /* mode_colorkey,msk*/ 0, 0,
- {
- {
- /* xres, yres, xpos, ypos */ 320, 240, 5, 5,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP |
- LCD_WINCTRL1_PO_00,
- /* mode_winenable*/ LCD_WINENABLE_WEN0,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565
- | LCD_WINCTRL1_PO_16BPP,
- /* mode_winenable*/ 0,
- },
- {
- /* xres, yres, xpos, ypos */ 100, 100, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP |
- LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
- },
- {
- /* xres, yres, xpos, ypos */ 200, 25, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP |
- LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ 0,
- },
- },
- },
- { /* Index 2 */
- "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx",
- /* mode_backcolor */ 0x006600ff,
- /* mode_colorkey,msk*/ 0, 0,
- {
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP,
- /* mode_winenable*/ LCD_WINENABLE_WEN0,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP,
- /* mode_winenable*/ 0,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP |
- LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/,
- },
- {
- /* xres, yres, xpos, ypos */ 0, 0, 0, 0,
- /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 |
- LCD_WINCTRL1_PO_16BPP |
- LCD_WINCTRL1_PIPE,
- /* mode_winenable*/ 0,
- },
- },
- },
- /* Need VGA 640 @ 24bpp, @ 32bpp */
- /* Need VGA 800 @ 24bpp, @ 32bpp */
- /* Need VGA 1024 @ 24bpp, @ 32bpp */
-};
-
-/*
- * Controller configurations for various panels.
- */
-
-struct panel_settings
-{
- const char name[25]; /* Full name <vendor>_<model> */
-
- struct fb_monspecs monspecs; /* FB monitor specs */
-
- /* panel timings */
- uint32 mode_screen;
- uint32 mode_horztiming;
- uint32 mode_verttiming;
- uint32 mode_clkcontrol;
- uint32 mode_pwmdiv;
- uint32 mode_pwmhi;
- uint32 mode_outmask;
- uint32 mode_fifoctrl;
- uint32 mode_toyclksrc;
- uint32 mode_backlight;
- uint32 mode_auxpll;
- int (*device_init)(void);
- int (*device_shutdown)(void);
-#define Xres min_xres
-#define Yres min_yres
- u32 min_xres; /* Minimum horizontal resolution */
- u32 max_xres; /* Maximum horizontal resolution */
- u32 min_yres; /* Minimum vertical resolution */
- u32 max_yres; /* Maximum vertical resolution */
-};
-
-/********************************************************************/
-/* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is */
-
-/* List of panels known to work with the AU1200 LCD controller.
- * To add a new panel, enter the same specifications as the
- * Generic_TFT one, and MAKE SURE that it doesn't conflicts
- * with the controller restrictions. Restrictions are:
- *
- * STN color panels: max_bpp <= 12
- * STN mono panels: max_bpp <= 4
- * TFT panels: max_bpp <= 16
- * max_xres <= 800
- * max_yres <= 600
- */
-static struct panel_settings known_lcd_panels[] =
-{
- [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */
- .name = "QVGA_320x240",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = LCD_SCREEN_SX_N(320) |
- LCD_SCREEN_SY_N(240),
- .mode_horztiming = 0x00c4623b,
- .mode_verttiming = 0x00502814,
- .mode_clkcontrol = 0x00020002, /* /4=24Mhz */
- .mode_pwmdiv = 0x00000000,
- .mode_pwmhi = 0x00000000,
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
- 320, 320,
- 240, 240,
- },
-
- [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */
- .name = "VGA_640x480",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = 0x13f9df80,
- .mode_horztiming = 0x003c5859,
- .mode_verttiming = 0x00741201,
- .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
- .mode_pwmdiv = 0x00000000,
- .mode_pwmhi = 0x00000000,
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
- 640, 480,
- 640, 480,
- },
-
- [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */
- .name = "SVGA_800x600",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = 0x18fa5780,
- .mode_horztiming = 0x00dc7e77,
- .mode_verttiming = 0x00584805,
- .mode_clkcontrol = 0x00020000, /* /2=48Mhz */
- .mode_pwmdiv = 0x00000000,
- .mode_pwmhi = 0x00000000,
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
- 800, 800,
- 600, 600,
- },
-
- [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */
- .name = "XVGA_1024x768",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = 0x1ffaff80,
- .mode_horztiming = 0x007d0e57,
- .mode_verttiming = 0x00740a01,
- .mode_clkcontrol = 0x000A0000, /* /1 */
- .mode_pwmdiv = 0x00000000,
- .mode_pwmhi = 0x00000000,
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 6, /* 72MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
- 1024, 1024,
- 768, 768,
- },
-
- [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */
- .name = "XVGA_1280x1024",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = 0x27fbff80,
- .mode_horztiming = 0x00cdb2c7,
- .mode_verttiming = 0x00600002,
- .mode_clkcontrol = 0x000A0000, /* /1 */
- .mode_pwmdiv = 0x00000000,
- .mode_pwmhi = 0x00000000,
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 10, /* 120MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
- 1280, 1280,
- 1024, 1024,
- },
-
- [5] = { /* Samsung 1024x768 TFT */
- .name = "Samsung_1024x768_TFT",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = 0x1ffaff80,
- .mode_horztiming = 0x018cc677,
- .mode_verttiming = 0x00241217,
- .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */
- .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */
- .mode_pwmhi = 0x03400000, /* SCB 0x0 */
- .mode_outmask = 0x00FFFFFF,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
- 1024, 1024,
- 768, 768,
- },
-
- [6] = { /* Toshiba 640x480 TFT */
- .name = "Toshiba_640x480_TFT",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = LCD_SCREEN_SX_N(640) |
- LCD_SCREEN_SY_N(480),
- .mode_horztiming = LCD_HORZTIMING_HPW_N(96) |
- LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51),
- .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
- LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32),
- .mode_clkcontrol = 0x00000000, /* /4=24Mhz */
- .mode_pwmdiv = 0x8000063f,
- .mode_pwmhi = 0x03400000,
- .mode_outmask = 0x00fcfcfc,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
- 640, 480,
- 640, 480,
- },
-
- [7] = { /* Sharp 320x240 TFT */
- .name = "Sharp_320x240_TFT",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 12500,
- .hfmax = 20000,
- .vfmin = 38,
- .vfmax = 81,
- .dclkmin = 4500000,
- .dclkmax = 6800000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = LCD_SCREEN_SX_N(320) |
- LCD_SCREEN_SY_N(240),
- .mode_horztiming = LCD_HORZTIMING_HPW_N(60) |
- LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2),
- .mode_verttiming = LCD_VERTTIMING_VPW_N(2) |
- LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5),
- .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/
- .mode_pwmdiv = 0x8000063f,
- .mode_pwmhi = 0x03400000,
- .mode_outmask = 0x00fcfcfc,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
- 320, 320,
- 240, 240,
- },
-
- [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */
- .name = "Toppoly_TD070WGCB2",
- .monspecs = {
- .modedb = NULL,
- .modedb_len = 0,
- .hfmin = 30000,
- .hfmax = 70000,
- .vfmin = 60,
- .vfmax = 60,
- .dclkmin = 6000000,
- .dclkmax = 28000000,
- .input = FB_DISP_RGB,
- },
- .mode_screen = LCD_SCREEN_SX_N(856) |
- LCD_SCREEN_SY_N(480),
- .mode_horztiming = LCD_HORZTIMING_HND2_N(43) |
- LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114),
- .mode_verttiming = LCD_VERTTIMING_VND2_N(20) |
- LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4),
- .mode_clkcontrol = 0x00020001, /* /4=24Mhz */
- .mode_pwmdiv = 0x8000063f,
- .mode_pwmhi = 0x03400000,
- .mode_outmask = 0x00fcfcfc,
- .mode_fifoctrl = 0x2f2f2f2f,
- .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
- .mode_backlight = 0x00000000,
- .mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
- 856, 856,
- 480, 480,
- },
-};
-
-#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
-
-/********************************************************************/
-
-#ifdef CONFIG_PM
-static int set_brightness(unsigned int brightness)
-{
- unsigned int hi1, divider;
-
- /* limit brightness pwm duty to >= 30/1600 */
- if (brightness < 30) {
- brightness = 30;
- }
- divider = (lcd->pwmdiv & 0x3FFFF) + 1;
- hi1 = (lcd->pwmhi >> 16) + 1;
- hi1 = (((brightness & 0xFF) + 1) * divider >> 8);
- lcd->pwmhi &= 0xFFFF;
- lcd->pwmhi |= (hi1 << 16);
-
- return brightness;
-}
-#endif /* CONFIG_PM */
-
-static int winbpp (unsigned int winctrl1)
-{
- int bits = 0;
-
- /* how many bits are needed for each pixel format */
- switch (winctrl1 & LCD_WINCTRL1_FRM) {
- case LCD_WINCTRL1_FRM_1BPP:
- bits = 1;
- break;
- case LCD_WINCTRL1_FRM_2BPP:
- bits = 2;
- break;
- case LCD_WINCTRL1_FRM_4BPP:
- bits = 4;
- break;
- case LCD_WINCTRL1_FRM_8BPP:
- bits = 8;
- break;
- case LCD_WINCTRL1_FRM_12BPP:
- case LCD_WINCTRL1_FRM_16BPP655:
- case LCD_WINCTRL1_FRM_16BPP565:
- case LCD_WINCTRL1_FRM_16BPP556:
- case LCD_WINCTRL1_FRM_16BPPI1555:
- case LCD_WINCTRL1_FRM_16BPPI5551:
- case LCD_WINCTRL1_FRM_16BPPA1555:
- case LCD_WINCTRL1_FRM_16BPPA5551:
- bits = 16;
- break;
- case LCD_WINCTRL1_FRM_24BPP:
- case LCD_WINCTRL1_FRM_32BPP:
- bits = 32;
- break;
- }
-
- return bits;
-}
-
-static int fbinfo2index (struct fb_info *fb_info)
-{
- int i;
-
- for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) {
- if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info))
- return i;
- }
- printk("au1200fb: ERROR: fbinfo2index failed!\n");
- return -1;
-}
-
-static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
- int xpos, int ypos)
-{
- uint32 winctrl0, winctrl1, winenable, fb_offset = 0;
- int xsz, ysz;
-
- /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */
-
- winctrl0 = lcd->window[plane].winctrl0;
- winctrl1 = lcd->window[plane].winctrl1;
- winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN);
- winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY);
-
- /* Check for off-screen adjustments */
- xsz = win->w[plane].xres;
- ysz = win->w[plane].yres;
- if ((xpos + win->w[plane].xres) > panel->Xres) {
- /* Off-screen to the right */
- xsz = panel->Xres - xpos; /* off by 1 ??? */
- /*printk("off screen right\n");*/
- }
-
- if ((ypos + win->w[plane].yres) > panel->Yres) {
- /* Off-screen to the bottom */
- ysz = panel->Yres - ypos; /* off by 1 ??? */
- /*printk("off screen bottom\n");*/
- }
-
- if (xpos < 0) {
- /* Off-screen to the left */
- xsz = win->w[plane].xres + xpos;
- fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8);
- xpos = 0;
- /*printk("off screen left\n");*/
- }
-
- if (ypos < 0) {
- /* Off-screen to the top */
- ysz = win->w[plane].yres + ypos;
- /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */
- ypos = 0;
- /*printk("off screen top\n");*/
- }
-
- /* record settings */
- win->w[plane].xpos = xpos;
- win->w[plane].ypos = ypos;
-
- xsz -= 1;
- ysz -= 1;
- winctrl0 |= (xpos << 21);
- winctrl0 |= (ypos << 10);
- winctrl1 |= (xsz << 11);
- winctrl1 |= (ysz << 0);
-
- /* Disable the window while making changes, then restore WINEN */
- winenable = lcd->winenable & (1 << plane);
- au_sync();
- lcd->winenable &= ~(1 << plane);
- lcd->window[plane].winctrl0 = winctrl0;
- lcd->window[plane].winctrl1 = winctrl1;
- lcd->window[plane].winbuf0 =
- lcd->window[plane].winbuf1 = fbdev->fb_phys;
- lcd->window[plane].winbufctrl = 0; /* select winbuf0 */
- lcd->winenable |= winenable;
- au_sync();
-
- return 0;
-}
-
-static void au1200_setpanel (struct panel_settings *newpanel)
-{
- /*
- * Perform global setup/init of LCD controller
- */
- uint32 winenable;
-
- /* Make sure all windows disabled */
- winenable = lcd->winenable;
- lcd->winenable = 0;
- au_sync();
- /*
- * Ensure everything is disabled before reconfiguring
- */
- if (lcd->screen & LCD_SCREEN_SEN) {
- /* Wait for vertical sync period */
- lcd->intstatus = LCD_INT_SS;
- while ((lcd->intstatus & LCD_INT_SS) == 0) {
- au_sync();
- }
-
- lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/
-
- do {
- lcd->intstatus = lcd->intstatus; /*clear interrupts*/
- au_sync();
- /*wait for controller to shut down*/
- } while ((lcd->intstatus & LCD_INT_SD) == 0);
-
- /* Call shutdown of current panel (if up) */
- /* this must occur last, because if an external clock is driving
- the controller, the clock cannot be turned off before first
- shutting down the controller.
- */
- if (panel->device_shutdown != NULL)
- panel->device_shutdown();
- }
-
- /* Newpanel == NULL indicates a shutdown operation only */
- if (newpanel == NULL)
- return;
-
- panel = newpanel;
-
- printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres);
-
- /*
- * Setup clocking if internal LCD clock source (assumes sys_auxpll valid)
- */
- if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT))
- {
- uint32 sys_clksrc;
- au_writel(panel->mode_auxpll, SYS_AUXPLL);
- sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f;
- sys_clksrc |= panel->mode_toyclksrc;
- au_writel(sys_clksrc, SYS_CLKSRC);
- }
-
- /*
- * Configure panel timings
- */
- lcd->screen = panel->mode_screen;
- lcd->horztiming = panel->mode_horztiming;
- lcd->verttiming = panel->mode_verttiming;
- lcd->clkcontrol = panel->mode_clkcontrol;
- lcd->pwmdiv = panel->mode_pwmdiv;
- lcd->pwmhi = panel->mode_pwmhi;
- lcd->outmask = panel->mode_outmask;
- lcd->fifoctrl = panel->mode_fifoctrl;
- au_sync();
-
- /* fixme: Check window settings to make sure still valid
- * for new geometry */
-#if 0
- au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos);
- au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos);
- au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos);
- au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);
-#endif
- lcd->winenable = winenable;
-
- /*
- * Re-enable screen now that it is configured
- */
- lcd->screen |= LCD_SCREEN_SEN;
- au_sync();
-
- /* Call init of panel */
- if (panel->device_init != NULL) panel->device_init();
-
- /* FIX!!!! not appropriate on panel change!!! Global setup/init */
- lcd->intenable = 0;
- lcd->intstatus = ~0;
- lcd->backcolor = win->mode_backcolor;
-
- /* Setup Color Key - FIX!!! */
- lcd->colorkey = win->mode_colorkey;
- lcd->colorkeymsk = win->mode_colorkeymsk;
-
- /* Setup HWCursor - FIX!!! Need to support this eventually */
- lcd->hwc.cursorctrl = 0;
- lcd->hwc.cursorpos = 0;
- lcd->hwc.cursorcolor0 = 0;
- lcd->hwc.cursorcolor1 = 0;
- lcd->hwc.cursorcolor2 = 0;
- lcd->hwc.cursorcolor3 = 0;
-
-
-#if 0
-#define D(X) printk("%25s: %08X\n", #X, X)
- D(lcd->screen);
- D(lcd->horztiming);
- D(lcd->verttiming);
- D(lcd->clkcontrol);
- D(lcd->pwmdiv);
- D(lcd->pwmhi);
- D(lcd->outmask);
- D(lcd->fifoctrl);
- D(lcd->window[0].winctrl0);
- D(lcd->window[0].winctrl1);
- D(lcd->window[0].winctrl2);
- D(lcd->window[0].winbuf0);
- D(lcd->window[0].winbuf1);
- D(lcd->window[0].winbufctrl);
- D(lcd->window[1].winctrl0);
- D(lcd->window[1].winctrl1);
- D(lcd->window[1].winctrl2);
- D(lcd->window[1].winbuf0);
- D(lcd->window[1].winbuf1);
- D(lcd->window[1].winbufctrl);
- D(lcd->window[2].winctrl0);
- D(lcd->window[2].winctrl1);
- D(lcd->window[2].winctrl2);
- D(lcd->window[2].winbuf0);
- D(lcd->window[2].winbuf1);
- D(lcd->window[2].winbufctrl);
- D(lcd->window[3].winctrl0);
- D(lcd->window[3].winctrl1);
- D(lcd->window[3].winctrl2);
- D(lcd->window[3].winbuf0);
- D(lcd->window[3].winbuf1);
- D(lcd->window[3].winbufctrl);
- D(lcd->winenable);
- D(lcd->intenable);
- D(lcd->intstatus);
- D(lcd->backcolor);
- D(lcd->winenable);
- D(lcd->colorkey);
- D(lcd->colorkeymsk);
- D(lcd->hwc.cursorctrl);
- D(lcd->hwc.cursorpos);
- D(lcd->hwc.cursorcolor0);
- D(lcd->hwc.cursorcolor1);
- D(lcd->hwc.cursorcolor2);
- D(lcd->hwc.cursorcolor3);
-#endif
-}
-
-static void au1200_setmode(struct au1200fb_device *fbdev)
-{
- int plane = fbdev->plane;
- /* Window/plane setup */
- lcd->window[plane].winctrl1 = ( 0
- | LCD_WINCTRL1_PRI_N(plane)
- | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */
- ) ;
-
- au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos);
-
- lcd->window[plane].winctrl2 = ( 0
- | LCD_WINCTRL2_CKMODE_00
- | LCD_WINCTRL2_DBM
- | LCD_WINCTRL2_BX_N( fbdev->fb_info.fix.line_length)
- | LCD_WINCTRL2_SCX_1
- | LCD_WINCTRL2_SCY_1
- ) ;
- lcd->winenable |= win->w[plane].mode_winenable;
- au_sync();
-}
-
-
-/* Inline helpers */
-
-/*#define panel_is_dual(panel) ((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
-/*#define panel_is_active(panel)((panel->mode_screen & LCD_SCREEN_PT) == LCD_SCREEN_PT_010)*/
-
-#define panel_is_color(panel) ((panel->mode_screen & LCD_SCREEN_PT) <= LCD_SCREEN_PT_CDSTN)
-
-/* Bitfields format supported by the controller. */
-static struct fb_bitfield rgb_bitfields[][4] = {
- /* Red, Green, Blue, Transp */
- [LCD_WINCTRL1_FRM_16BPP655 >> 25] =
- { { 10, 6, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPP565 >> 25] =
- { { 11, 5, 0 }, { 5, 6, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPP556 >> 25] =
- { { 11, 5, 0 }, { 6, 5, 0 }, { 0, 6, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPPI1555 >> 25] =
- { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPPI5551 >> 25] =
- { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPPA1555 >> 25] =
- { { 10, 5, 0 }, { 5, 5, 0 }, { 0, 5, 0 }, { 15, 1, 0 } },
-
- [LCD_WINCTRL1_FRM_16BPPA5551 >> 25] =
- { { 11, 5, 0 }, { 6, 5, 0 }, { 1, 5, 0 }, { 0, 1, 0 } },
-
- [LCD_WINCTRL1_FRM_24BPP >> 25] =
- { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 0, 0, 0 } },
-
- [LCD_WINCTRL1_FRM_32BPP >> 25] =
- { { 16, 8, 0 }, { 8, 8, 0 }, { 0, 8, 0 }, { 24, 0, 0 } },
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* Helpers */
-
-static void au1200fb_update_fbinfo(struct fb_info *fbi)
-{
- /* FIX!!!! This also needs to take the window pixel format into account!!! */
-
- /* Update var-dependent FB info */
- if (panel_is_color(panel)) {
- if (fbi->var.bits_per_pixel <= 8) {
- /* palettized */
- fbi->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- fbi->fix.line_length = fbi->var.xres_virtual /
- (8/fbi->var.bits_per_pixel);
- } else {
- /* non-palettized */
- fbi->fix.visual = FB_VISUAL_TRUECOLOR;
- fbi->fix.line_length = fbi->var.xres_virtual * (fbi->var.bits_per_pixel / 8);
- }
- } else {
- /* mono FIX!!! mono 8 and 4 bits */
- fbi->fix.visual = FB_VISUAL_MONO10;
- fbi->fix.line_length = fbi->var.xres_virtual / 8;
- }
-
- fbi->screen_size = fbi->fix.line_length * fbi->var.yres_virtual;
- print_dbg("line length: %d\n", fbi->fix.line_length);
- print_dbg("bits_per_pixel: %d\n", fbi->var.bits_per_pixel);
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* AU1200 framebuffer driver */
-
-/* fb_check_var
- * Validate var settings with hardware restrictions and modify it if necessary
- */
-static int au1200fb_fb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *fbi)
-{
- struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
- u32 pixclock;
- int screen_size, plane;
-
- plane = fbdev->plane;
-
- /* Make sure that the mode respect all LCD controller and
- * panel restrictions. */
- var->xres = win->w[plane].xres;
- var->yres = win->w[plane].yres;
-
- /* No need for virtual resolution support */
- var->xres_virtual = var->xres;
- var->yres_virtual = var->yres;
-
- var->bits_per_pixel = winbpp(win->w[plane].mode_winctrl1);
-
- screen_size = var->xres_virtual * var->yres_virtual;
- if (var->bits_per_pixel > 8) screen_size *= (var->bits_per_pixel / 8);
- else screen_size /= (8/var->bits_per_pixel);
-
- if (fbdev->fb_len < screen_size)
- return -EINVAL; /* Virtual screen is to big, abort */
-
- /* FIX!!!! what are the implicaitons of ignoring this for windows ??? */
- /* The max LCD clock is fixed to 48MHz (value of AUX_CLK). The pixel
- * clock can only be obtain by dividing this value by an even integer.
- * Fallback to a slower pixel clock if necessary. */
- pixclock = max((u32)(PICOS2KHZ(var->pixclock) * 1000), fbi->monspecs.dclkmin);
- pixclock = min(pixclock, min(fbi->monspecs.dclkmax, (u32)AU1200_LCD_MAX_CLK/2));
-
- if (AU1200_LCD_MAX_CLK % pixclock) {
- int diff = AU1200_LCD_MAX_CLK % pixclock;
- pixclock -= diff;
- }
-
- var->pixclock = KHZ2PICOS(pixclock/1000);
-#if 0
- if (!panel_is_active(panel)) {
- int pcd = AU1200_LCD_MAX_CLK / (pixclock * 2) - 1;
-
- if (!panel_is_color(panel)
- && (panel->control_base & LCD_CONTROL_MPI) && (pcd < 3)) {
- /* STN 8bit mono panel support is up to 6MHz pixclock */
- var->pixclock = KHZ2PICOS(6000);
- } else if (!pcd) {
- /* Other STN panel support is up to 12MHz */
- var->pixclock = KHZ2PICOS(12000);
- }
- }
-#endif
- /* Set bitfield accordingly */
- switch (var->bits_per_pixel) {
- case 16:
- {
- /* 16bpp True color.
- * These must be set to MATCH WINCTRL[FORM] */
- int idx;
- idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
- var->red = rgb_bitfields[idx][0];
- var->green = rgb_bitfields[idx][1];
- var->blue = rgb_bitfields[idx][2];
- var->transp = rgb_bitfields[idx][3];
- break;
- }
-
- case 32:
- {
- /* 32bpp True color.
- * These must be set to MATCH WINCTRL[FORM] */
- int idx;
- idx = (win->w[0].mode_winctrl1 & LCD_WINCTRL1_FRM) >> 25;
- var->red = rgb_bitfields[idx][0];
- var->green = rgb_bitfields[idx][1];
- var->blue = rgb_bitfields[idx][2];
- var->transp = rgb_bitfields[idx][3];
- break;
- }
- default:
- print_dbg("Unsupported depth %dbpp", var->bits_per_pixel);
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* fb_set_par
- * Set hardware with var settings. This will enable the controller with a
- * specific mode, normally validated with the fb_check_var method
- */
-static int au1200fb_fb_set_par(struct fb_info *fbi)
-{
- struct au1200fb_device *fbdev = (struct au1200fb_device *)fbi;
-
- au1200fb_update_fbinfo(fbi);
- au1200_setmode(fbdev);
-
- return 0;
-}
-
-/* fb_setcolreg
- * Set color in LCD palette.
- */
-static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp, struct fb_info *fbi)
-{
- volatile u32 *palette = lcd->palette;
- u32 value;
-
- if (regno > (AU1200_LCD_NBR_PALETTE_ENTRIES - 1))
- return -EINVAL;
-
- if (fbi->var.grayscale) {
- /* Convert color to grayscale */
- red = green = blue =
- (19595 * red + 38470 * green + 7471 * blue) >> 16;
- }
-
- if (fbi->fix.visual == FB_VISUAL_TRUECOLOR) {
- /* Place color in the pseudopalette */
- if (regno > 16)
- return -EINVAL;
-
- palette = (u32*) fbi->pseudo_palette;
-
- red >>= (16 - fbi->var.red.length);
- green >>= (16 - fbi->var.green.length);
- blue >>= (16 - fbi->var.blue.length);
-
- value = (red << fbi->var.red.offset) |
- (green << fbi->var.green.offset)|
- (blue << fbi->var.blue.offset);
- value &= 0xFFFF;
-
- } else if (1 /*FIX!!! panel_is_active(fbdev->panel)*/) {
- /* COLOR TFT PALLETTIZED (use RGB 565) */
- value = (red & 0xF800)|((green >> 5) &
- 0x07E0)|((blue >> 11) & 0x001F);
- value &= 0xFFFF;
-
- } else if (0 /*panel_is_color(fbdev->panel)*/) {
- /* COLOR STN MODE */
- value = 0x1234;
- value &= 0xFFF;
- } else {
- /* MONOCHROME MODE */
- value = (green >> 12) & 0x000F;
- value &= 0xF;
- }
-
- palette[regno] = value;
-
- return 0;
-}
-
-/* fb_blank
- * Blank the screen. Depending on the mode, the screen will be
- * activated with the backlight color, or desactivated
- */
-static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
-{
- /* Short-circuit screen blanking */
- if (noblanking)
- return 0;
-
- switch (blank_mode) {
-
- case FB_BLANK_UNBLANK:
- case FB_BLANK_NORMAL:
- /* printk("turn on panel\n"); */
- au1200_setpanel(panel);
- break;
- case FB_BLANK_VSYNC_SUSPEND:
- case FB_BLANK_HSYNC_SUSPEND:
- case FB_BLANK_POWERDOWN:
- /* printk("turn off panel\n"); */
- au1200_setpanel(NULL);
- break;
- default:
- break;
-
- }
-
- /* FB_BLANK_NORMAL is a soft blank */
- return (blank_mode == FB_BLANK_NORMAL) ? -EINVAL : 0;
-}
-
-/* fb_mmap
- * Map video memory in user space. We don't use the generic fb_mmap
- * method mainly to allow the use of the TLB streaming flag (CCA=6)
- */
-static int au1200fb_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
-
-{
- unsigned int len;
- unsigned long start=0, off;
- struct au1200fb_device *fbdev = (struct au1200fb_device *) info;
-
-#ifdef CONFIG_PM
- au1xxx_pm_access(LCD_pm_dev);
-#endif
-
- if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {
- return -EINVAL;
- }
-
- start = fbdev->fb_phys & PAGE_MASK;
- len = PAGE_ALIGN((start & ~PAGE_MASK) + fbdev->fb_len);
-
- off = vma->vm_pgoff << PAGE_SHIFT;
-
- if ((vma->vm_end - vma->vm_start + off) > len) {
- return -EINVAL;
- }
-
- off += start;
- vma->vm_pgoff = off >> PAGE_SHIFT;
-
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- pgprot_val(vma->vm_page_prot) |= _CACHE_MASK; /* CCA=7 */
-
- vma->vm_flags |= VM_IO;
-
- return io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-
- return 0;
-}
-
-static void set_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
-{
-
- unsigned int hi1, divider;
-
- /* SCREEN_SIZE: user cannot reset size, must switch panel choice */
-
- if (pdata->flags & SCREEN_BACKCOLOR)
- lcd->backcolor = pdata->backcolor;
-
- if (pdata->flags & SCREEN_BRIGHTNESS) {
-
- // limit brightness pwm duty to >= 30/1600
- if (pdata->brightness < 30) {
- pdata->brightness = 30;
- }
- divider = (lcd->pwmdiv & 0x3FFFF) + 1;
- hi1 = (lcd->pwmhi >> 16) + 1;
- hi1 = (((pdata->brightness & 0xFF)+1) * divider >> 8);
- lcd->pwmhi &= 0xFFFF;
- lcd->pwmhi |= (hi1 << 16);
- }
-
- if (pdata->flags & SCREEN_COLORKEY)
- lcd->colorkey = pdata->colorkey;
-
- if (pdata->flags & SCREEN_MASK)
- lcd->colorkeymsk = pdata->mask;
- au_sync();
-}
-
-static void get_global(u_int cmd, struct au1200_lcd_global_regs_t *pdata)
-{
- unsigned int hi1, divider;
-
- pdata->xsize = ((lcd->screen & LCD_SCREEN_SX) >> 19) + 1;
- pdata->ysize = ((lcd->screen & LCD_SCREEN_SY) >> 8) + 1;
-
- pdata->backcolor = lcd->backcolor;
- pdata->colorkey = lcd->colorkey;
- pdata->mask = lcd->colorkeymsk;
-
- // brightness
- hi1 = (lcd->pwmhi >> 16) + 1;
- divider = (lcd->pwmdiv & 0x3FFFF) + 1;
- pdata->brightness = ((hi1 << 8) / divider) - 1;
- au_sync();
-}
-
-static void set_window(unsigned int plane,
- struct au1200_lcd_window_regs_t *pdata)
-{
- unsigned int val, bpp;
-
- /* Window control register 0 */
- if (pdata->flags & WIN_POSITION) {
- val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_OX |
- LCD_WINCTRL0_OY);
- val |= ((pdata->xpos << 21) & LCD_WINCTRL0_OX);
- val |= ((pdata->ypos << 10) & LCD_WINCTRL0_OY);
- lcd->window[plane].winctrl0 = val;
- }
- if (pdata->flags & WIN_ALPHA_COLOR) {
- val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_A);
- val |= ((pdata->alpha_color << 2) & LCD_WINCTRL0_A);
- lcd->window[plane].winctrl0 = val;
- }
- if (pdata->flags & WIN_ALPHA_MODE) {
- val = lcd->window[plane].winctrl0 & ~(LCD_WINCTRL0_AEN);
- val |= ((pdata->alpha_mode << 1) & LCD_WINCTRL0_AEN);
- lcd->window[plane].winctrl0 = val;
- }
-
- /* Window control register 1 */
- if (pdata->flags & WIN_PRIORITY) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PRI);
- val |= ((pdata->priority << 30) & LCD_WINCTRL1_PRI);
- lcd->window[plane].winctrl1 = val;
- }
- if (pdata->flags & WIN_CHANNEL) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PIPE);
- val |= ((pdata->channel << 29) & LCD_WINCTRL1_PIPE);
- lcd->window[plane].winctrl1 = val;
- }
- if (pdata->flags & WIN_BUFFER_FORMAT) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_FRM);
- val |= ((pdata->buffer_format << 25) & LCD_WINCTRL1_FRM);
- lcd->window[plane].winctrl1 = val;
- }
- if (pdata->flags & WIN_COLOR_ORDER) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_CCO);
- val |= ((pdata->color_order << 24) & LCD_WINCTRL1_CCO);
- lcd->window[plane].winctrl1 = val;
- }
- if (pdata->flags & WIN_PIXEL_ORDER) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_PO);
- val |= ((pdata->pixel_order << 22) & LCD_WINCTRL1_PO);
- lcd->window[plane].winctrl1 = val;
- }
- if (pdata->flags & WIN_SIZE) {
- val = lcd->window[plane].winctrl1 & ~(LCD_WINCTRL1_SZX |
- LCD_WINCTRL1_SZY);
- val |= (((pdata->xsize << 11) - 1) & LCD_WINCTRL1_SZX);
- val |= (((pdata->ysize) - 1) & LCD_WINCTRL1_SZY);
- lcd->window[plane].winctrl1 = val;
- /* program buffer line width */
- bpp = winbpp(val) / 8;
- val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_BX);
- val |= (((pdata->xsize * bpp) << 8) & LCD_WINCTRL2_BX);
- lcd->window[plane].winctrl2 = val;
- }
-
- /* Window control register 2 */
- if (pdata->flags & WIN_COLORKEY_MODE) {
- val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_CKMODE);
- val |= ((pdata->colorkey_mode << 24) & LCD_WINCTRL2_CKMODE);
- lcd->window[plane].winctrl2 = val;
- }
- if (pdata->flags & WIN_DOUBLE_BUFFER_MODE) {
- val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_DBM);
- val |= ((pdata->double_buffer_mode << 23) & LCD_WINCTRL2_DBM);
- lcd->window[plane].winctrl2 = val;
- }
- if (pdata->flags & WIN_RAM_ARRAY_MODE) {
- val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_RAM);
- val |= ((pdata->ram_array_mode << 21) & LCD_WINCTRL2_RAM);
- lcd->window[plane].winctrl2 = val;
- }
-
- /* Buffer line width programmed with WIN_SIZE */
-
- if (pdata->flags & WIN_BUFFER_SCALE) {
- val = lcd->window[plane].winctrl2 & ~(LCD_WINCTRL2_SCX |
- LCD_WINCTRL2_SCY);
- val |= ((pdata->xsize << 11) & LCD_WINCTRL2_SCX);
- val |= ((pdata->ysize) & LCD_WINCTRL2_SCY);
- lcd->window[plane].winctrl2 = val;
- }
-
- if (pdata->flags & WIN_ENABLE) {
- val = lcd->winenable;
- val &= ~(1<<plane);
- val |= (pdata->enable & 1) << plane;
- lcd->winenable = val;
- }
- au_sync();
-}
-
-static void get_window(unsigned int plane,
- struct au1200_lcd_window_regs_t *pdata)
-{
- /* Window control register 0 */
- pdata->xpos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OX) >> 21;
- pdata->ypos = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_OY) >> 10;
- pdata->alpha_color = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_A) >> 2;
- pdata->alpha_mode = (lcd->window[plane].winctrl0 & LCD_WINCTRL0_AEN) >> 1;
-
- /* Window control register 1 */
- pdata->priority = (lcd->window[plane].winctrl1& LCD_WINCTRL1_PRI) >> 30;
- pdata->channel = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PIPE) >> 29;
- pdata->buffer_format = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_FRM) >> 25;
- pdata->color_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_CCO) >> 24;
- pdata->pixel_order = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_PO) >> 22;
- pdata->xsize = ((lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZX) >> 11) + 1;
- pdata->ysize = (lcd->window[plane].winctrl1 & LCD_WINCTRL1_SZY) + 1;
-
- /* Window control register 2 */
- pdata->colorkey_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_CKMODE) >> 24;
- pdata->double_buffer_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_DBM) >> 23;
- pdata->ram_array_mode = (lcd->window[plane].winctrl2 & LCD_WINCTRL2_RAM) >> 21;
-
- pdata->enable = (lcd->winenable >> plane) & 1;
- au_sync();
-}
-
-static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
- unsigned long arg)
-{
- int plane;
- int val;
-
-#ifdef CONFIG_PM
- au1xxx_pm_access(LCD_pm_dev);
-#endif
-
- plane = fbinfo2index(info);
- print_dbg("au1200fb: ioctl %d on plane %d\n", cmd, plane);
-
- if (cmd == AU1200_LCD_FB_IOCTL) {
- struct au1200_lcd_iodata_t iodata;
-
- if (copy_from_user(&iodata, (void __user *) arg, sizeof(iodata)))
- return -EFAULT;
-
- print_dbg("FB IOCTL called\n");
-
- switch (iodata.subcmd) {
- case AU1200_LCD_SET_SCREEN:
- print_dbg("AU1200_LCD_SET_SCREEN\n");
- set_global(cmd, &iodata.global);
- break;
-
- case AU1200_LCD_GET_SCREEN:
- print_dbg("AU1200_LCD_GET_SCREEN\n");
- get_global(cmd, &iodata.global);
- break;
-
- case AU1200_LCD_SET_WINDOW:
- print_dbg("AU1200_LCD_SET_WINDOW\n");
- set_window(plane, &iodata.window);
- break;
-
- case AU1200_LCD_GET_WINDOW:
- print_dbg("AU1200_LCD_GET_WINDOW\n");
- get_window(plane, &iodata.window);
- break;
-
- case AU1200_LCD_SET_PANEL:
- print_dbg("AU1200_LCD_SET_PANEL\n");
- if ((iodata.global.panel_choice >= 0) &&
- (iodata.global.panel_choice <
- NUM_PANELS))
- {
- struct panel_settings *newpanel;
- panel_index = iodata.global.panel_choice;
- newpanel = &known_lcd_panels[panel_index];
- au1200_setpanel(newpanel);
- }
- break;
-
- case AU1200_LCD_GET_PANEL:
- print_dbg("AU1200_LCD_GET_PANEL\n");
- iodata.global.panel_choice = panel_index;
- break;
-
- default:
- return -EINVAL;
- }
-
- val = copy_to_user((void __user *) arg, &iodata, sizeof(iodata));
- if (val) {
- print_dbg("error: could not copy %d bytes\n", val);
- return -EFAULT;
- }
- }
-
- return 0;
-}
-
-
-static struct fb_ops au1200fb_fb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = au1200fb_fb_check_var,
- .fb_set_par = au1200fb_fb_set_par,
- .fb_setcolreg = au1200fb_fb_setcolreg,
- .fb_blank = au1200fb_fb_blank,
- .fb_fillrect = cfb_fillrect,
- .fb_copyarea = cfb_copyarea,
- .fb_imageblit = cfb_imageblit,
- .fb_sync = NULL,
- .fb_ioctl = au1200fb_ioctl,
- .fb_mmap = au1200fb_fb_mmap,
-};
-
-/*-------------------------------------------------------------------------*/
-
-static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id, struct pt_regs *regs)
-{
- /* Nothing to do for now, just clear any pending interrupt */
- lcd->intstatus = lcd->intstatus;
- au_sync();
-
- return IRQ_HANDLED;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* AU1200 LCD device probe helpers */
-
-static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
-{
- struct fb_info *fbi = &fbdev->fb_info;
- int bpp;
-
- memset(fbi, 0, sizeof(struct fb_info));
- fbi->fbops = &au1200fb_fb_ops;
-
- bpp = winbpp(win->w[fbdev->plane].mode_winctrl1);
-
- /* Copy monitor specs from panel data */
- /* fixme: we're setting up LCD controller windows, so these dont give a
- damn as to what the monitor specs are (the panel itself does, but that
- isnt done here...so maybe need a generic catchall monitor setting??? */
- memcpy(&fbi->monspecs, &panel->monspecs, sizeof(struct fb_monspecs));
-
- /* We first try the user mode passed in argument. If that failed,
- * or if no one has been specified, we default to the first mode of the
- * panel list. Note that after this call, var data will be set */
- if (!fb_find_mode(&fbi->var,
- fbi,
- NULL, /* drv_info.opt_mode, */
- fbi->monspecs.modedb,
- fbi->monspecs.modedb_len,
- fbi->monspecs.modedb,
- bpp)) {
-
- print_err("Cannot find valid mode for panel %s", panel->name);
- return -EFAULT;
- }
-
- fbi->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
- if (!fbi->pseudo_palette) {
- return -ENOMEM;
- }
- memset(fbi->pseudo_palette, 0, sizeof(u32) * 16);
-
- if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
- print_err("Fail to allocate colormap (%d entries)",
- AU1200_LCD_NBR_PALETTE_ENTRIES);
- kfree(fbi->pseudo_palette);
- return -EFAULT;
- }
-
- strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
- fbi->fix.smem_start = fbdev->fb_phys;
- fbi->fix.smem_len = fbdev->fb_len;
- fbi->fix.type = FB_TYPE_PACKED_PIXELS;
- fbi->fix.xpanstep = 0;
- fbi->fix.ypanstep = 0;
- fbi->fix.mmio_start = 0;
- fbi->fix.mmio_len = 0;
- fbi->fix.accel = FB_ACCEL_NONE;
-
- fbi->screen_base = (char __iomem *) fbdev->fb_mem;
-
- au1200fb_update_fbinfo(fbi);
-
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* AU1200 LCD controller device driver */
-
-static int au1200fb_drv_probe(struct device *dev)
-{
- struct au1200fb_device *fbdev;
- unsigned long page;
- int bpp, plane, ret;
-
- if (!dev)
- return -EINVAL;
-
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
- bpp = winbpp(win->w[plane].mode_winctrl1);
- if (win->w[plane].xres == 0)
- win->w[plane].xres = panel->Xres;
- if (win->w[plane].yres == 0)
- win->w[plane].yres = panel->Yres;
-
- fbdev = &_au1200fb_devices[plane];
- memset(fbdev, 0, sizeof(struct au1200fb_device));
- fbdev->plane = plane;
-
- /* Allocate the framebuffer to the maximum screen size */
- fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8;
-
- fbdev->fb_mem = dma_alloc_noncoherent(dev,
- PAGE_ALIGN(fbdev->fb_len),
- &fbdev->fb_phys, GFP_KERNEL);
- if (!fbdev->fb_mem) {
- print_err("fail to allocate frambuffer (size: %dK))",
- fbdev->fb_len / 1024);
- return -ENOMEM;
- }
-
- /*
- * Set page reserved so that mmap will work. This is necessary
- * since we'll be remapping normal memory.
- */
- for (page = (unsigned long)fbdev->fb_phys;
- page < PAGE_ALIGN((unsigned long)fbdev->fb_phys +
- fbdev->fb_len);
- page += PAGE_SIZE) {
- SetPageReserved(pfn_to_page(page >> PAGE_SHIFT)); /* LCD DMA is NOT coherent on Au1200 */
- }
- print_dbg("Framebuffer memory map at %p", fbdev->fb_mem);
- print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
-
- /* Init FB data */
- if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
- goto failed;
-
- /* Register new framebuffer */
- if ((ret = register_framebuffer(&fbdev->fb_info)) < 0) {
- print_err("cannot register new framebuffer");
- goto failed;
- }
-
- au1200fb_fb_set_par(&fbdev->fb_info);
-
-#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO)
- if (plane == 0)
- if (fb_prepare_logo(&fbdev->fb_info, FB_ROTATE_UR)) {
- /* Start display and show logo on boot */
- fb_set_cmap(&fbdev->fb_info.cmap,
- &fbdev->fb_info);
-
- fb_show_logo(&fbdev->fb_info, FB_ROTATE_UR);
- }
-#endif
- }
-
- /* Now hook interrupt too */
- if ((ret = request_irq(AU1200_LCD_INT, au1200fb_handle_irq,
- SA_INTERRUPT | SA_SHIRQ, "lcd", (void *)dev)) < 0) {
- print_err("fail to request interrupt line %d (err: %d)",
- AU1200_LCD_INT, ret);
- goto failed;
- }
-
- return 0;
-
-failed:
- /* NOTE: This only does the current plane/window that failed; others are still active */
- if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
- fbdev->fb_mem, fbdev->fb_phys);
- if (fbdev->fb_info.cmap.len != 0)
- fb_dealloc_cmap(&fbdev->fb_info.cmap);
- if (fbdev->fb_info.pseudo_palette)
- kfree(fbdev->fb_info.pseudo_palette);
- if (plane == 0)
- free_irq(AU1200_LCD_INT, (void*)dev);
- return ret;
-}
-
-static int au1200fb_drv_remove(struct device *dev)
-{
- struct au1200fb_device *fbdev;
- int plane;
-
- if (!dev)
- return -ENODEV;
-
- /* Turn off the panel */
- au1200_setpanel(NULL);
-
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane)
- {
- fbdev = &_au1200fb_devices[plane];
-
- /* Clean up all probe data */
- unregister_framebuffer(&fbdev->fb_info);
- if (fbdev->fb_mem)
- dma_free_noncoherent(dev, PAGE_ALIGN(fbdev->fb_len),
- fbdev->fb_mem, fbdev->fb_phys);
- if (fbdev->fb_info.cmap.len != 0)
- fb_dealloc_cmap(&fbdev->fb_info.cmap);
- if (fbdev->fb_info.pseudo_palette)
- kfree(fbdev->fb_info.pseudo_palette);
- }
-
- free_irq(AU1200_LCD_INT, (void *)dev);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int au1200fb_drv_suspend(struct device *dev, u32 state, u32 level)
-{
- /* TODO */
- return 0;
-}
-
-static int au1200fb_drv_resume(struct device *dev, u32 level)
-{
- /* TODO */
- return 0;
-}
-#endif /* CONFIG_PM */
-
-static struct device_driver au1200fb_driver = {
- .name = "au1200-lcd",
- .bus = &platform_bus_type,
- .probe = au1200fb_drv_probe,
- .remove = au1200fb_drv_remove,
-#ifdef CONFIG_PM
- .suspend = au1200fb_drv_suspend,
- .resume = au1200fb_drv_resume,
-#endif
-};
-
-/*-------------------------------------------------------------------------*/
-
-/* Kernel driver */
-
-static void au1200fb_setup(void)
-{
- char* options = NULL;
- char* this_opt;
- int num_panels = ARRAY_SIZE(known_lcd_panels);
- int panel_idx = -1;
-
- fb_get_options(DRIVER_NAME, &options);
-
- if (options) {
- while ((this_opt = strsep(&options,",")) != NULL) {
- /* Panel option - can be panel name,
- * "bs" for board-switch, or number/index */
- if (!strncmp(this_opt, "panel:", 6)) {
- int i;
- long int li;
- char *endptr;
- this_opt += 6;
- /* First check for index, which allows
- * to short circuit this mess */
- li = simple_strtol(this_opt, &endptr, 0);
- if (*endptr == '\0') {
- panel_idx = (int)li;
- }
- else if (strcmp(this_opt, "bs") == 0) {
- extern int board_au1200fb_panel(void);
- panel_idx = board_au1200fb_panel();
- }
-
- else
- for (i = 0; i < num_panels; i++) {
- if (!strcmp(this_opt, known_lcd_panels[i].name)) {
- panel_idx = i;
- break;
- }
- }
-
- if ((panel_idx < 0) || (panel_idx >= num_panels)) {
- print_warn("Panel %s not supported!", this_opt);
- }
- else
- panel_index = panel_idx;
- }
-
- else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
- nohwcursor = 1;
- }
-
- /* Unsupported option */
- else {
- print_warn("Unsupported option \"%s\"", this_opt);
- }
- }
- }
-}
-
-#ifdef CONFIG_PM
-static int au1200fb_pm_callback(au1xxx_power_dev_t *dev,
- au1xxx_request_t request, void *data) {
- int retval = -1;
- unsigned int d = 0;
- unsigned int brightness = 0;
-
- if (request == AU1XXX_PM_SLEEP) {
- board_au1200fb_panel_shutdown();
- }
- else if (request == AU1XXX_PM_WAKEUP) {
- if(dev->prev_state == SLEEP_STATE)
- {
- int plane;
- au1200_setpanel(panel);
- for (plane = 0; plane < CONFIG_FB_AU1200_DEVS; ++plane) {
- struct au1200fb_device *fbdev;
- fbdev = &_au1200fb_devices[plane];
- au1200fb_fb_set_par(&fbdev->fb_info);
- }
- }
-
- d = *((unsigned int*)data);
- if(d <=10) brightness = 26;
- else if(d<=20) brightness = 51;
- else if(d<=30) brightness = 77;
- else if(d<=40) brightness = 102;
- else if(d<=50) brightness = 128;
- else if(d<=60) brightness = 153;
- else if(d<=70) brightness = 179;
- else if(d<=80) brightness = 204;
- else if(d<=90) brightness = 230;
- else brightness = 255;
- set_brightness(brightness);
- } else if (request == AU1XXX_PM_GETSTATUS) {
- return dev->cur_state;
- } else if (request == AU1XXX_PM_ACCESS) {
- if (dev->cur_state != SLEEP_STATE)
- return retval;
- else {
- au1200_setpanel(panel);
- }
- } else if (request == AU1XXX_PM_IDLE) {
- } else if (request == AU1XXX_PM_CLEANUP) {
- }
-
- return retval;
-}
-#endif
-
-static int __init au1200fb_init(void)
-{
- print_info("" DRIVER_DESC "");
-
- /* Setup driver with options */
- au1200fb_setup();
-
- /* Point to the panel selected */
- panel = &known_lcd_panels[panel_index];
- win = &windows[window_index];
-
- printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
- printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
-
- /* Kickstart the panel, the framebuffers/windows come soon enough */
- au1200_setpanel(panel);
-
- #ifdef CONFIG_PM
- LCD_pm_dev = new_au1xxx_power_device("LCD", &au1200fb_pm_callback, NULL);
- if ( LCD_pm_dev == NULL)
- printk(KERN_INFO "Unable to create a power management device entry for the au1200fb.\n");
- else
- printk(KERN_INFO "Power management device entry for the au1200fb loaded.\n");
- #endif
-
- return driver_register(&au1200fb_driver);
-}
-
-static void __exit au1200fb_cleanup(void)
-{
- driver_unregister(&au1200fb_driver);
-}
-
-module_init(au1200fb_init);
-module_exit(au1200fb_cleanup);
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_LICENSE("GPL");
diff --git a/fs/stat.c b/fs/stat.c
index 9948cc1..0f282fa 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -261,7 +261,7 @@ asmlinkage long sys_newlstat(char __user *filename, struct stat __user *statbuf)
return error;
}
-#ifndef __ARCH_WANT_STAT64
+#if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
asmlinkage long sys_newfstatat(int dfd, char __user *filename,
struct stat __user *statbuf, int flag)
{
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h
index 7b1f011..bc1d6ed 100644
--- a/include/asm-i386/i387.h
+++ b/include/asm-i386/i387.h
@@ -58,13 +58,13 @@ static inline void __save_init_fpu( struct task_struct *tsk )
alternative_input(
"fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
"fxsave %[fx]\n"
- "bt $7,%[fsw] ; jc 1f ; fnclex\n1:",
+ "bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
X86_FEATURE_FXSR,
[fx] "m" (tsk->thread.i387.fxsave),
[fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
is pending. Clear the x87 state here by setting it to fixed
- values. __per_cpu_offset[0] is a random variable that should be in L1 */
+ values. safe_address is a random variable that should be in L1 */
alternative_input(
GENERIC_NOP8 GENERIC_NOP2,
"emms\n\t" /* clear stack tags */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index 4321483..9fcf016 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -22,6 +22,7 @@
#define PPC_FEATURE_BOOKE 0x00008000
#define PPC_FEATURE_SMT 0x00004000
#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
+#define PPC_FEATURE_ARCH_2_05 0x00001000
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
@@ -320,6 +321,11 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_MMCRA_SIHV | CPU_FTR_PURR)
+#define CPU_FTRS_POWER6 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
+ CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
+ CPU_FTR_MMCRA | CPU_FTR_SMT | \
+ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
+ CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE)
#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -331,8 +337,8 @@ extern void do_cpu_ftr_fixups(unsigned long offset);
#ifdef __powerpc64__
#define CPU_FTRS_POSSIBLE \
(CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 | \
- CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_CELL | \
- CPU_FTR_CI_LARGE_PAGE)
+ CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 | \
+ CPU_FTRS_CELL | CPU_FTR_CI_LARGE_PAGE)
#else
enum {
CPU_FTRS_POSSIBLE =
@@ -376,8 +382,8 @@ enum {
#ifdef __powerpc64__
#define CPU_FTRS_ALWAYS \
(CPU_FTRS_POWER3 & CPU_FTRS_RS64 & CPU_FTRS_POWER4 & \
- CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_CELL & \
- CPU_FTRS_POSSIBLE)
+ CPU_FTRS_PPC970 & CPU_FTRS_POWER5 & CPU_FTRS_POWER6 & \
+ CPU_FTRS_CELL & CPU_FTRS_POSSIBLE)
#else
enum {
CPU_FTRS_ALWAYS =
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index 68efbea..f1c2469 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -9,6 +9,9 @@
* 2 of the License, or (at your option) any later version.
*/
+/* Check of existence of legacy devices */
+extern int check_legacy_ioport(unsigned long base_port);
+
#ifndef CONFIG_PPC64
#include <asm-ppc/io.h>
#else
@@ -437,9 +440,6 @@ out:
#define dma_cache_wback(_start,_size) do { } while (0)
#define dma_cache_wback_inv(_start,_size) do { } while (0)
-/* Check of existence of legacy devices */
-extern int check_legacy_ioport(unsigned long base_port);
-
/*
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
diff --git a/include/asm-powerpc/page_64.h b/include/asm-powerpc/page_64.h
index 3fb061b..eab779c 100644
--- a/include/asm-powerpc/page_64.h
+++ b/include/asm-powerpc/page_64.h
@@ -101,6 +101,7 @@ extern unsigned int HPAGE_SHIFT;
- (1U << GET_HTLB_AREA(addr))) & 0xffff)
#define ARCH_HAS_HUGEPAGE_ONLY_RANGE
+#define ARCH_HAS_HUGETLB_FREE_PGD_RANGE
#define ARCH_HAS_PREPARE_HUGEPAGE_RANGE
#define ARCH_HAS_SETCLEAR_HUGE_PTE
diff --git a/include/asm-powerpc/pgalloc.h b/include/asm-powerpc/pgalloc.h
index a00ee00..9f0917c 100644
--- a/include/asm-powerpc/pgalloc.h
+++ b/include/asm-powerpc/pgalloc.h
@@ -17,11 +17,13 @@ extern kmem_cache_t *pgtable_cache[];
#define PTE_CACHE_NUM 0
#define PMD_CACHE_NUM 1
#define PGD_CACHE_NUM 2
+#define HUGEPTE_CACHE_NUM 3
#else
#define PTE_CACHE_NUM 0
#define PMD_CACHE_NUM 1
#define PUD_CACHE_NUM 1
#define PGD_CACHE_NUM 0
+#define HUGEPTE_CACHE_NUM 2
#endif
/*
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 34325e2..908acb4 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -304,8 +304,25 @@
#define __NR_splice 283
#define __NR_tee 284
#define __NR_vmsplice 285
+#define __NR_openat 286
+#define __NR_mkdirat 287
+#define __NR_mknodat 288
+#define __NR_fchownat 289
+#define __NR_futimesat 290
+#ifdef __powerpc64__
+#define __NR_newfstatat 291
+#else
+#define __NR_fstatat64 291
+#endif
+#define __NR_unlinkat 292
+#define __NR_renameat 293
+#define __NR_linkat 294
+#define __NR_symlinkat 295
+#define __NR_readlinkat 296
+#define __NR_fchmodat 297
+#define __NR_faccessat 298
-#define __NR_syscalls 286
+#define __NR_syscalls 299
#ifdef __KERNEL__
#define __NR__exit __NR_exit
@@ -458,6 +475,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
#ifdef CONFIG_PPC64
#define __ARCH_WANT_COMPAT_SYS_TIME
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
+#define __ARCH_WANT_SYS_NEWFSTATAT
#endif
/*
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 4b94f70..40f197a 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -39,6 +39,8 @@
#error "need definition of ppc_sys_devices"
#endif
+#define PPC_SYS_IORESOURCE_FIXUPPED 0x00000001
+
struct ppc_sys_spec {
/* PPC sys is matched via (ID & mask) == value, id could be
* PVR, SVR, IMMR, * etc. */
diff --git a/include/asm-ppc/reg_booke.h b/include/asm-ppc/reg_booke.h
index 00ad9c7..4944c0f 100644
--- a/include/asm-ppc/reg_booke.h
+++ b/include/asm-ppc/reg_booke.h
@@ -237,6 +237,7 @@ do { \
#endif
/* Bit definitions for CCR1. */
+#define CCR1_DPC 0x00000100 /* Disable L1 I-Cache/D-Cache parity checking */
#define CCR1_TCS 0x00000080 /* Timer Clock Select */
/* Bit definitions for the MCSR. */
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index df70e75..3734258 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -374,12 +374,14 @@ struct snd_pcm_substream {
/* -- OSS things -- */
struct snd_pcm_oss_substream oss;
#endif
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_root;
struct snd_info_entry *proc_info_entry;
struct snd_info_entry *proc_hw_params_entry;
struct snd_info_entry *proc_sw_params_entry;
struct snd_info_entry *proc_status_entry;
struct snd_info_entry *proc_prealloc_entry;
+#endif
/* misc flags */
unsigned int no_mmap_ctrl: 1;
unsigned int hw_opened: 1;
@@ -400,12 +402,14 @@ struct snd_pcm_str {
struct snd_pcm_oss_stream oss;
#endif
struct snd_pcm_file *files;
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_root;
struct snd_info_entry *proc_info_entry;
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
unsigned int xrun_debug; /* 0 = disabled, 1 = verbose, 2 = stacktrace */
struct snd_info_entry *proc_xrun_debug_entry;
#endif
+#endif
};
struct snd_pcm {
diff --git a/include/sound/pcm_oss.h b/include/sound/pcm_oss.h
index 39df2ba..c854647 100644
--- a/include/sound/pcm_oss.h
+++ b/include/sound/pcm_oss.h
@@ -75,7 +75,9 @@ struct snd_pcm_oss_substream {
struct snd_pcm_oss_stream {
struct snd_pcm_oss_setup *setup_list; /* setup list */
struct mutex setup_mutex;
+#ifdef CONFIG_SND_VERBOSE_PROCFS
struct snd_info_entry *proc_entry;
+#endif
};
struct snd_pcm_oss {
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 8efc1b1..4262a1c 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -142,7 +142,7 @@ config SND_SUPPORT_OLD_API
config SND_VERBOSE_PROCFS
bool "Verbose procfs contents"
- depends on SND
+ depends on SND && PROC_FS
default y
help
Say Y here to include code for verbose procfs contents (provides
@@ -171,3 +171,13 @@ config SND_DEBUG_DETECT
help
Say Y here to enable extra-verbose log messages printed when
detecting devices.
+
+config SND_PCM_XRUN_DEBUG
+ bool "Enable PCM ring buffer overrun/underrun debugging"
+ default n
+ depends on SND_DEBUG && SND_VERBOSE_PROCFS
+ help
+ Say Y to enable the PCM ring buffer overrun/underrun debugging.
+ It is usually not required, but if you have trouble with
+ sound clicking when system is loaded, it may help to determine
+ the process or driver which causes the scheduling gaps.
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index c5978d6..ac990bf 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -1242,6 +1242,8 @@ static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int for
if (format != AFMT_QUERY) {
formats = snd_pcm_oss_get_formats(pcm_oss_file);
+ if (formats < 0)
+ return formats;
if (!(formats & format))
format = AFMT_U8;
for (idx = 1; idx >= 0; --idx) {
@@ -2212,7 +2214,7 @@ static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
return 0;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SND_VERBOSE_PROCFS
/*
* /proc interface
*/
@@ -2366,10 +2368,10 @@ static void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
}
}
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
#define snd_pcm_oss_proc_init(pcm)
#define snd_pcm_oss_proc_done(pcm)
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/*
* ENTRY functions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index 122e10a..84b0003 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -142,7 +142,7 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
return -ENOIOCTLCMD;
}
-#if defined(CONFIG_PROC_FS) && defined(CONFIG_SND_VERBOSE_PROCFS)
+#ifdef CONFIG_SND_VERBOSE_PROCFS
#define STATE(v) [SNDRV_PCM_STATE_##v] = #v
#define STREAM(v) [SNDRV_PCM_STREAM_##v] = #v
@@ -436,7 +436,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
snd_iprintf(buffer, "appl_ptr : %ld\n", runtime->control->appl_ptr);
}
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
static void snd_pcm_xrun_debug_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
@@ -480,7 +480,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
}
pstr->proc_info_entry = entry;
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if ((entry = snd_info_create_card_entry(pcm->card, "xrun_debug",
pstr->proc_root)) != NULL) {
entry->c.text.read_size = 64;
@@ -501,7 +501,7 @@ static int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr)
static int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr)
{
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (pstr->proc_xrun_debug_entry) {
snd_info_unregister(pstr->proc_xrun_debug_entry);
pstr->proc_xrun_debug_entry = NULL;
@@ -599,12 +599,12 @@ static int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream)
}
return 0;
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
static inline int snd_pcm_stream_proc_init(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_stream_proc_done(struct snd_pcm_str *pstr) { return 0; }
static inline int snd_pcm_substream_proc_init(struct snd_pcm_substream *substream) { return 0; }
static inline int snd_pcm_substream_proc_done(struct snd_pcm_substream *substream) { return 0; }
-#endif /* CONFIG_PROC_FS */
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/**
* snd_pcm_new_stream - create a new PCM stream
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 230a940..eedc6cb 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -130,7 +130,7 @@ void snd_pcm_playback_silence(struct snd_pcm_substream *substream, snd_pcm_ufram
static void xrun(struct snd_pcm_substream *substream)
{
snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN);
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (substream->pstr->xrun_debug) {
snd_printd(KERN_DEBUG "XRUN: pcmC%dD%d%c\n",
substream->pcm->card->number,
@@ -204,7 +204,7 @@ static inline int snd_pcm_update_hw_ptr_interrupt(struct snd_pcm_substream *subs
delta = hw_ptr_interrupt - new_hw_ptr;
if (delta > 0) {
if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (runtime->periods > 1 && substream->pstr->xrun_debug) {
snd_printd(KERN_ERR "Unexpected hw_pointer value [1] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
if (substream->pstr->xrun_debug > 1)
@@ -249,7 +249,7 @@ int snd_pcm_update_hw_ptr(struct snd_pcm_substream *substream)
delta = old_hw_ptr - new_hw_ptr;
if (delta > 0) {
if ((snd_pcm_uframes_t)delta < runtime->buffer_size / 2) {
-#ifdef CONFIG_SND_DEBUG
+#ifdef CONFIG_SND_PCM_XRUN_DEBUG
if (runtime->periods > 2 && substream->pstr->xrun_debug) {
snd_printd(KERN_ERR "Unexpected hw_pointer value [2] (stream = %i, delta: -%ld, max jitter = %ld): wrong interrupt acknowledge?\n", substream->stream, (long) delta, runtime->buffer_size / 2);
if (substream->pstr->xrun_debug > 1)
diff --git a/sound/core/pcm_memory.c b/sound/core/pcm_memory.c
index a0119ae..428f8c1 100644
--- a/sound/core/pcm_memory.c
+++ b/sound/core/pcm_memory.c
@@ -100,8 +100,10 @@ static void snd_pcm_lib_preallocate_dma_free(struct snd_pcm_substream *substream
int snd_pcm_lib_preallocate_free(struct snd_pcm_substream *substream)
{
snd_pcm_lib_preallocate_dma_free(substream);
+#ifdef CONFIG_SND_VERBOSE_PROCFS
snd_info_unregister(substream->proc_prealloc_entry);
substream->proc_prealloc_entry = NULL;
+#endif
return 0;
}
@@ -124,7 +126,7 @@ int snd_pcm_lib_preallocate_free_for_all(struct snd_pcm *pcm)
return 0;
}
-#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_SND_VERBOSE_PROCFS
/*
* read callback for prealloc proc file
*
@@ -203,9 +205,9 @@ static inline void preallocate_info_init(struct snd_pcm_substream *substream)
substream->proc_prealloc_entry = entry;
}
-#else /* !CONFIG_PROC_FS */
+#else /* !CONFIG_SND_VERBOSE_PROCFS */
#define preallocate_info_init(s)
-#endif
+#endif /* CONFIG_SND_VERBOSE_PROCFS */
/*
* pre-allocate the buffer and create a proc file for the substream
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index e35fd57..ae0df54 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -675,10 +675,8 @@ static int __init alsa_card_dummy_init(void)
continue;
device = platform_device_register_simple(SND_DUMMY_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -686,14 +684,10 @@ static int __init alsa_card_dummy_init(void)
#ifdef MODULE
printk(KERN_ERR "Dummy soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_dummy_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_dummy_unregister_all();
- return err;
}
static void __exit alsa_card_dummy_exit(void)
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 9ea3059..da7ef26 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -251,10 +251,8 @@ static int __init alsa_card_mpu401_init(void)
#endif
device = platform_device_register_simple(SND_MPU401_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
platform_devices[i] = device;
snd_mpu401_devices++;
}
@@ -266,14 +264,10 @@ static int __init alsa_card_mpu401_init(void)
#ifdef MODULE
printk(KERN_ERR "MPU-401 device not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_mpu401_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_mpu401_unregister_all();
- return err;
}
static void __exit alsa_card_mpu401_exit(void)
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index 1a7fbef..c01b4c5 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -996,10 +996,8 @@ static int __init alsa_card_serial_init(void)
continue;
device = platform_device_register_simple(SND_SERIAL_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -1007,14 +1005,10 @@ static int __init alsa_card_serial_init(void)
#ifdef MODULE
printk(KERN_ERR "serial midi soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_serial_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_serial_unregister_all();
- return err;
}
static void __exit alsa_card_serial_exit(void)
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index a3ee306..26eb249 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -169,10 +169,8 @@ static int __init alsa_card_virmidi_init(void)
continue;
device = platform_device_register_simple(SND_VIRMIDI_DRIVER,
i, NULL, 0);
- if (IS_ERR(device)) {
- err = PTR_ERR(device);
- goto errout;
- }
+ if (IS_ERR(device))
+ continue;
devices[i] = device;
cards++;
}
@@ -180,14 +178,10 @@ static int __init alsa_card_virmidi_init(void)
#ifdef MODULE
printk(KERN_ERR "Card-VirMIDI soundcard not found or device busy\n");
#endif
- err = -ENODEV;
- goto errout;
+ snd_virmidi_unregister_all();
+ return -ENODEV;
}
return 0;
-
- errout:
- snd_virmidi_unregister_all();
- return err;
}
static void __exit alsa_card_virmidi_exit(void)
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 83d64bc..e6bfcf7 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -1179,20 +1179,17 @@ static int __init snd_card_miro_aci_detect(struct snd_card *card, struct snd_mir
/* force ACI into a known state */
for (i = 0; i < 3; i++)
if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't force aci into known state.\n");
return -ENXIO;
}
if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 ||
(miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port);
return -ENXIO;
}
if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) {
- snd_card_free(card);
snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
miro->aci_port);
return -ENXIO;
diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c
index c6c8333..eece1c7 100644
--- a/sound/pci/ad1889.c
+++ b/sound/pci/ad1889.c
@@ -39,7 +39,6 @@
#include <linux/interrupt.h>
#include <linux/compiler.h>
#include <linux/delay.h>
-#include <linux/dma-mapping.h>
#include <sound/driver.h>
#include <sound/core.h>
@@ -1052,7 +1051,7 @@ snd_ad1889_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
-static struct pci_device_id snd_ad1889_ids[] = {
+static struct pci_device_id snd_ad1889_ids[] __devinitdata = {
{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
{ 0, },
};
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index fc92b68..e2dbc21 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -279,7 +279,7 @@ struct snd_ali {
#endif
};
-static struct pci_device_id snd_ali_ids[] = {
+static struct pci_device_id snd_ali_ids[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
{0, }
};
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 91899f8..901b08a 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -146,7 +146,7 @@ struct snd_als300_substream_data {
int block_counter_register;
};
-static struct pci_device_id snd_als300_ids[] = {
+static struct pci_device_id snd_als300_ids[] __devinitdata = {
{ 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
{ 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
{ 0, }
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 100d812..60423b1 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -116,7 +116,7 @@ struct snd_card_als4000 {
#endif
};
-static struct pci_device_id snd_als4000_ids[] = {
+static struct pci_device_id snd_als4000_ids[] __devinitdata = {
{ 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
{ 0, }
};
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 12e6188..d0f759d 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -284,7 +284,7 @@ struct atiixp {
/*
*/
-static struct pci_device_id snd_atiixp_ids[] = {
+static struct pci_device_id snd_atiixp_ids[] __devinitdata = {
{ 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
{ 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */
{ 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 1d37660..12a34c3 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -262,7 +262,7 @@ struct atiixp_modem {
/*
*/
-static struct pci_device_id snd_atiixp_ids[] = {
+static struct pci_device_id snd_atiixp_ids[] __devinitdata = {
{ 0x1002, 0x434d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */
{ 0x1002, 0x4378, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */
{ 0, }
diff --git a/sound/pci/au88x0/au8810.c b/sound/pci/au88x0/au8810.c
index fce22c7..bd33529 100644
--- a/sound/pci/au88x0/au8810.c
+++ b/sound/pci/au88x0/au8810.c
@@ -1,6 +1,6 @@
#include "au8810.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1,},
{0,}
diff --git a/sound/pci/au88x0/au8820.c b/sound/pci/au88x0/au8820.c
index d1fbcce..7e3fd83 100644
--- a/sound/pci/au88x0/au8820.c
+++ b/sound/pci/au88x0/au8820.c
@@ -1,6 +1,6 @@
#include "au8820.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{0,}
diff --git a/sound/pci/au88x0/au8830.c b/sound/pci/au88x0/au8830.c
index d4f2717..b840f66 100644
--- a/sound/pci/au88x0/au8830.c
+++ b/sound/pci/au88x0/au8830.c
@@ -1,6 +1,6 @@
#include "au8830.h"
#include "au88x0.h"
-static struct pci_device_id snd_vortex_ids[] = {
+static struct pci_device_id snd_vortex_ids[] __devinitdata = {
{PCI_VENDOR_ID_AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{0,}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 680077e..52a3645 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -216,7 +216,7 @@ struct snd_azf3328 {
int irq;
};
-static const struct pci_device_id snd_azf3328_ids[] = {
+static const struct pci_device_id snd_azf3328_ids[] __devinitdata = {
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
{ 0, }
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 7b44a8d..9ee07d4 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -774,7 +774,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
.driver_data = rate }
/* driver_data is the default digital_rate value for that device */
-static struct pci_device_id snd_bt87x_ids[] = {
+static struct pci_device_id snd_bt87x_ids[] __devinitdata = {
/* Hauppauge WinTV series */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, 32000),
/* Hauppauge WinTV series */
@@ -911,7 +911,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
/* default entries for all Bt87x cards - it's not exported */
/* driver_data is set to 0 to call detection */
-static struct pci_device_id snd_bt87x_default_ids[] = {
+static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, 0),
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, 0),
{ }
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 9477838..fd8bfeb 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1561,7 +1561,7 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
}
// PCI IDs
-static struct pci_device_id snd_ca0106_ids[] = {
+static struct pci_device_id snd_ca0106_ids[] __devinitdata = {
{ 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
{ 0, }
};
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 2ecbddb..e5ce2da 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2609,7 +2609,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
#endif
-static struct pci_device_id snd_cmipci_ids[] = {
+static struct pci_device_id snd_cmipci_ids[] __devinitdata = {
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index ac4e73f..b3c94d8 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -494,7 +494,7 @@ struct cs4281 {
static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_cs4281_ids[] = {
+static struct pci_device_id snd_cs4281_ids[] __devinitdata = {
{ 0x1013, 0x6005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4281 */
{ 0, }
};
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index c590602..848d772 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -65,7 +65,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
module_param_array(mmap_valid, bool, NULL, 0444);
MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
-static struct pci_device_id snd_cs46xx_ids[] = {
+static struct pci_device_id snd_cs46xx_ids[] __devinitdata = {
{ 0x1013, 0x6001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4280 */
{ 0x1013, 0x6003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4612 */
{ 0x1013, 0x6004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CS4615 */
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 9fc7f38..2c1213a 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -45,7 +45,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
-static struct pci_device_id snd_cs5535audio_ids[] = {
+static struct pci_device_id snd_cs5535audio_ids[] __devinitdata = {
{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO,
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 2dfa932..42b11ba 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -77,7 +77,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
/*
* Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
*/
-static struct pci_device_id snd_emu10k1_ids[] = {
+static struct pci_device_id snd_emu10k1_ids[] __devinitdata = {
{ 0x1102, 0x0002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* EMU10K1 */
{ 0x1102, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy */
{ 0x1102, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, /* Audigy 2 Value SB0400 */
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 3e332f3..d51290c 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -36,7 +36,6 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
@@ -1596,7 +1595,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
}
// PCI IDs
-static struct pci_device_id snd_emu10k1x_ids[] = {
+static struct pci_device_id snd_emu10k1x_ids[] __devinitdata = {
{ 0x1102, 0x0006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Dell OEM version (EMU10K1) */
{ 0, }
};
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index a5533c8..ca9e34e 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -446,7 +446,7 @@ struct ensoniq {
static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_audiopci_ids[] = {
+static struct pci_device_id snd_audiopci_ids[] __devinitdata = {
#ifdef CHIP1370
{ 0x1274, 0x5000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ES1370 */
#endif
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 4d62fe4..6f9094c 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -242,7 +242,7 @@ struct es1938 {
static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_es1938_ids[] = {
+static struct pci_device_id snd_es1938_ids[] __devinitdata = {
{ 0x125d, 0x1969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Solo-1 */
{ 0, }
};
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index e3ad17f..5ff4175 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -104,7 +104,6 @@
#include <linux/slab.h>
#include <linux/gameport.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <sound/core.h>
@@ -593,7 +592,7 @@ struct es1968 {
static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static struct pci_device_id snd_es1968_ids[] = {
+static struct pci_device_id snd_es1968_ids[] __devinitdata = {
/* Maestro 1 */
{ 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
/* Maestro 2 */
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 6ab4aef..d72fc28 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -199,7 +199,7 @@ struct fm801 {
#endif
};
-static struct pci_device_id snd_fm801_ids[] = {
+static struct pci_device_id snd_fm801_ids[] __devinitdata = {
{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
{ 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
{ 0, }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 0ad60ae..e821d65 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1614,7 +1614,7 @@ static void __devexit azx_remove(struct pci_dev *pci)
}
/* PCI IDs */
-static struct pci_device_id azx_ids[] = {
+static struct pci_device_id azx_ids[] __devinitdata = {
{ 0x8086, 0x2668, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH6 */
{ 0x8086, 0x27d8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ICH7 */
{ 0x8086, 0x269a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ICH }, /* ESB2 */
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index bcfca15..40f000b 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -799,10 +799,14 @@ static struct hda_board_config ad1986a_cfg_tbl[] = {
{ .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD },
{ .pci_subvendor = 0x144d, .pci_subdevice = 0xc024,
.config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1213,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7,
.config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */
+ { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297,
+ .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */
{ .pci_subvendor = 0x103c, .pci_subdevice = 0x30af,
.config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */
{}
@@ -1330,12 +1334,8 @@ enum { AD1981_BASIC, AD1981_HP };
static struct hda_board_config ad1981_cfg_tbl[] = {
{ .modelname = "hp", .config = AD1981_HP },
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x30aa,
- .config = AD1981_HP }, /* HP nx6320 */
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x309f,
- .config = AD1981_HP }, /* HP nx9420 AngelFire */
- { .pci_subvendor = 0x103c, .pci_subdevice = 0x30a2,
- .config = AD1981_HP }, /* HP nx9420 AngelFire */
+ /* All HP models */
+ { .pci_subvendor = 0x103c, .config = AD1981_HP },
{ .modelname = "basic", .config = AD1981_BASIC },
{}
};
@@ -2623,5 +2623,6 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
{ .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
{ .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
{ .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
+ { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
{} /* terminator */
};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 66bbdb6..f0e9a9c 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -2148,6 +2148,7 @@ static struct hda_board_config alc880_cfg_tbl[] = {
{ .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
{ .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
{ .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
+ { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
{ .modelname = "asus", .config = ALC880_ASUS },
{ .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7152607..8c440fb 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1212,8 +1212,8 @@ static hda_nid_t vaio_mux_nids[] = { 0x15 };
static struct hda_input_mux vaio_mux = {
.num_items = 2,
.items = {
- /* { "HP", 0x0 },
- { "Unknown", 0x1 }, */
+ /* { "HP", 0x0 }, */
+ { "Line", 0x1 },
{ "Mic", 0x2 },
{ "PCM", 0x3 },
}
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 32f8415..c56793b 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -56,7 +56,6 @@
#include <linux/dma-mapping.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <linux/mutex.h>
#include <sound/core.h>
@@ -108,7 +107,7 @@ module_param_array(dxr_enable, int, NULL, 0444);
MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
-static struct pci_device_id snd_ice1712_ids[] = {
+static struct pci_device_id snd_ice1712_ids[] __devinitdata = {
{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
{ 0, }
};
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index fce616c..b1c007e 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -86,7 +86,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
/* Both VT1720 and VT1724 have the same PCI IDs */
-static struct pci_device_id snd_vt1724_ids[] = {
+static struct pci_device_id snd_vt1724_ids[] __devinitdata = {
{ PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, }
};
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index ebbf2cf..0df7602 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -413,7 +413,7 @@ struct intel8x0 {
u32 int_sta_mask; /* interrupt status mask */
};
-static struct pci_device_id snd_intel8x0_ids[] = {
+static struct pci_device_id snd_intel8x0_ids[] __devinitdata = {
{ 0x8086, 0x2415, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
{ 0x8086, 0x2425, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
{ 0x8086, 0x2445, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
@@ -1293,6 +1293,7 @@ static int snd_intel8x0_ali_ac97spdifout_close(struct snd_pcm_substream *substre
return 0;
}
+#if 0 // NYI
static int snd_intel8x0_ali_spdifin_open(struct snd_pcm_substream *substream)
{
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
@@ -1308,7 +1309,6 @@ static int snd_intel8x0_ali_spdifin_close(struct snd_pcm_substream *substream)
return 0;
}
-#if 0 // NYI
static int snd_intel8x0_ali_spdifout_open(struct snd_pcm_substream *substream)
{
struct intel8x0 *chip = snd_pcm_substream_chip(substream);
@@ -1435,6 +1435,7 @@ static struct snd_pcm_ops snd_intel8x0_ali_ac97spdifout_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
+#if 0 // NYI
static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = {
.open = snd_intel8x0_ali_spdifin_open,
.close = snd_intel8x0_ali_spdifin_close,
@@ -1446,7 +1447,6 @@ static struct snd_pcm_ops snd_intel8x0_ali_spdifin_ops = {
.pointer = snd_intel8x0_pcm_pointer,
};
-#if 0 // NYI
static struct snd_pcm_ops snd_intel8x0_ali_spdifout_ops = {
.open = snd_intel8x0_ali_spdifout_open,
.close = snd_intel8x0_ali_spdifout_close,
@@ -1582,7 +1582,7 @@ static struct ich_pcm_table ali_pcms[] __devinitdata = {
{
.suffix = "IEC958",
.playback_ops = &snd_intel8x0_ali_ac97spdifout_ops,
- .capture_ops = &snd_intel8x0_ali_spdifin_ops,
+ /* .capture_ops = &snd_intel8x0_ali_spdifin_ops, */
.prealloc_size = 64 * 1024,
.prealloc_max_size = 128 * 1024,
.ac97_idx = ALID_AC97SPDIFOUT,
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 47e26aa..720635f 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -224,7 +224,7 @@ struct intel8x0m {
unsigned int pcm_pos_shift;
};
-static struct pci_device_id snd_intel8x0m_ids[] = {
+static struct pci_device_id snd_intel8x0m_ids[] __devinitdata = {
{ 0x8086, 0x2416, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801AA */
{ 0x8086, 0x2426, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82901AB */
{ 0x8086, 0x2446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 82801BA */
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 4721c09..e39fad1 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -424,7 +424,7 @@ module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
-static struct pci_device_id snd_korg1212_ids[] = {
+static struct pci_device_id snd_korg1212_ids[] __devinitdata = {
{
.vendor = 0x10b5,
.device = 0x906d,
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 9c90d90..1928e06 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,7 +41,6 @@
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/moduleparam.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/info.h>
#include <sound/control.h>
@@ -870,7 +869,7 @@ struct snd_m3 {
/*
* pci ids
*/
-static struct pci_device_id snd_m3_ids[] = {
+static struct pci_device_id snd_m3_ids[] __devinitdata = {
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index b5a0950..09cc078 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -28,7 +28,6 @@
#include <linux/dma-mapping.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -62,7 +61,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
/*
*/
-static struct pci_device_id snd_mixart_ids[] = {
+static struct pci_device_id snd_mixart_ids[] __devinitdata = {
{ 0x1057, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* MC8240 */
{ 0, }
};
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index cc297ab..b92d660 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -263,7 +263,7 @@ struct nm256 {
/*
* PCI ids
*/
-static struct pci_device_id snd_nm256_ids[] = {
+static struct pci_device_id snd_nm256_ids[] __devinitdata = {
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{PCI_VENDOR_ID_NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 35875c8..dafa223 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -30,7 +30,6 @@
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/mutex.h>
-#include <linux/dma-mapping.h>
#include <sound/core.h>
#include <sound/initval.h>
@@ -74,7 +73,7 @@ enum {
PCI_ID_LAST
};
-static struct pci_device_id pcxhr_ids[] = {
+static struct pci_device_id pcxhr_ids[] __devinitdata = {
{ 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */
{ 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */
{ 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 03517c1..369c19f 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -385,8 +385,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
fw.size = dsp->length;
fw.data = vmalloc(fw.size);
if (! fw.data) {
- snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%d bytes)\n",
- fw.size);
+ snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n",
+ (unsigned long)fw.size);
return -ENOMEM;
}
if (copy_from_user(fw.data, dsp->image, dsp->length)) {
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index f148ee4..d8cc985 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -506,7 +506,7 @@ static int riptide_reset(struct cmdif *cif, struct snd_riptide *chip);
/*
*/
-static struct pci_device_id snd_riptide_ids[] = {
+static struct pci_device_id snd_riptide_ids[] __devinitdata = {
{
.vendor = 0x127a,.device = 0x4310,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
@@ -527,7 +527,7 @@ static struct pci_device_id snd_riptide_ids[] = {
};
#ifdef SUPPORT_JOYSTICK
-static struct pci_device_id snd_riptide_joystick_ids[] = {
+static struct pci_device_id snd_riptide_joystick_ids[] __devinitdata = {
{
.vendor = 0x127a,.device = 0x4312,
.subvendor = PCI_ANY_ID,.subdevice = PCI_ANY_ID,
diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c
index ab78544..55b1d48 100644
--- a/sound/pci/rme32.c
+++ b/sound/pci/rme32.c
@@ -227,7 +227,7 @@ struct rme32 {
struct snd_kcontrol *spdif_ctl;
};
-static struct pci_device_id snd_rme32_ids[] = {
+static struct pci_device_id snd_rme32_ids[] __devinitdata = {
{PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0,},
{PCI_VENDOR_ID_XILINX_RME, PCI_DEVICE_ID_RME_DIGI32_8,
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 6c2a9f4..3c1bc53 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -232,7 +232,7 @@ struct rme96 {
struct snd_kcontrol *spdif_ctl;
};
-static struct pci_device_id snd_rme96_ids[] = {
+static struct pci_device_id snd_rme96_ids[] __devinitdata = {
{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_RME_DIGI96_8,
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index ebf7a2b..61f82f0 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -568,7 +568,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
}
-static struct pci_device_id snd_hdsp_ids[] = {
+static struct pci_device_id snd_hdsp_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_XILINX,
.device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP,
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index b5538ef..722b9e6 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -426,7 +426,7 @@ static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = {
};
-static struct pci_device_id snd_hdspm_ids[] = {
+static struct pci_device_id snd_hdspm_ids[] __devinitdata = {
{
.vendor = PCI_VENDOR_ID_XILINX,
.device = PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI,
diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c
index a687eb6..75d6406 100644
--- a/sound/pci/rme9652/rme9652.c
+++ b/sound/pci/rme9652/rme9652.c
@@ -315,7 +315,7 @@ static void snd_hammerfall_free_buffer(struct snd_dma_buffer *dmab, struct pci_d
}
-static struct pci_device_id snd_rme9652_ids[] = {
+static struct pci_device_id snd_rme9652_ids[] __devinitdata = {
{
.vendor = 0x10ee,
.device = 0x3fc4,
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c
index 2d66a09..91f8bf3 100644
--- a/sound/pci/sonicvibes.c
+++ b/sound/pci/sonicvibes.c
@@ -243,7 +243,7 @@ struct sonicvibes {
#endif
};
-static struct pci_device_id snd_sonic_ids[] = {
+static struct pci_device_id snd_sonic_ids[] __devinitdata = {
{ 0x5333, 0xca00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
{ 0, }
};
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index b453804..9624a5f 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -63,7 +63,7 @@ MODULE_PARM_DESC(pcm_channels, "Number of hardware channels assigned for PCM.");
module_param_array(wavetable_size, int, NULL, 0444);
MODULE_PARM_DESC(wavetable_size, "Maximum memory size in kB for wavetable synth.");
-static struct pci_device_id snd_trident_ids[] = {
+static struct pci_device_id snd_trident_ids[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_DX),
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
{PCI_DEVICE(PCI_VENDOR_ID_TRIDENT, PCI_DEVICE_ID_TRIDENT_4DWAVE_NX),
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index 0f171dd..39daf62 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -123,6 +123,7 @@ module_param(enable, bool, 0444);
#define VIA_REV_8233A 0x40 /* 1 rec, 1 multi-pb, spdf */
#define VIA_REV_8235 0x50 /* 2 rec, 4 pb, 1 multi-pb, spdif */
#define VIA_REV_8237 0x60
+#define VIA_REV_8251 0x70
/*
* Direct registers
@@ -395,7 +396,7 @@ struct via82xx {
#endif
};
-static struct pci_device_id snd_via82xx_ids[] = {
+static struct pci_device_id snd_via82xx_ids[] __devinitdata = {
/* 0x1106, 0x3058 */
{ PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, }, /* 686A */
/* 0x1106, 0x3059 */
@@ -862,6 +863,11 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst
if (!status)
status = inb(VIADEV_REG(viadev, OFFSET_STATUS));
+ /* An apparent bug in the 8251 is worked around by sending a
+ * REG_CTRL_START. */
+ if (chip->revision == VIA_REV_8251 && (status & VIA_REG_STAT_EOL))
+ snd_via82xx_pcm_trigger(substream, SNDRV_PCM_TRIGGER_START);
+
if (!(status & VIA_REG_STAT_ACTIVE)) {
res = 0;
goto unlock;
@@ -2313,6 +2319,7 @@ static struct via823x_info via823x_cards[] __devinitdata = {
{ VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
{ VIA_REV_8235, "VIA 8235", TYPE_VIA8233 },
{ VIA_REV_8237, "VIA 8237", TYPE_VIA8233 },
+ { VIA_REV_8251, "VIA 8251", TYPE_VIA8233 },
};
/*
@@ -2325,7 +2332,7 @@ struct dxs_whitelist {
short action; /* new dxs_support value */
};
-static int __devinit check_dxs_list(struct pci_dev *pci)
+static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
{
static struct dxs_whitelist whitelist[] = {
{ .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
@@ -2342,6 +2349,7 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
{ .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */
{ .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */
{ .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */
+ { .subvendor = 0x1043, .subdevice = 0x81b9, .action = VIA_DXS_SRC }, /* ASUS A8V-MX */
{ .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
{ .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
{ .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
@@ -2405,6 +2413,10 @@ static int __devinit check_dxs_list(struct pci_dev *pci)
}
}
+ /* for newer revision, default to DXS_SRC */
+ if (revision >= VIA_REV_8235)
+ return VIA_DXS_SRC;
+
/*
* not detected, try 48k rate only to be sure.
*/
@@ -2449,7 +2461,7 @@ static int __devinit snd_via82xx_probe(struct pci_dev *pci,
}
if (chip_type != TYPE_VIA8233A) {
if (dxs_support == VIA_DXS_AUTO)
- dxs_support = check_dxs_list(pci);
+ dxs_support = check_dxs_list(pci, revision);
/* force to use VIA8233 or 8233A model according to
* dxs_support module option
*/
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 22ce4d3..ef97e50 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -261,7 +261,7 @@ struct via82xx_modem {
struct snd_info_entry *proc_entry;
};
-static struct pci_device_id snd_via82xx_modem_ids[] = {
+static struct pci_device_id snd_via82xx_modem_ids[] __devinitdata = {
{ 0x1106, 0x3068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA82XX_MODEM, },
{ 0, }
};
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index c816ddf..0f1ebb0 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -60,7 +60,7 @@ enum {
VX_PCI_VX222_NEW
};
-static struct pci_device_id snd_vx222_ids[] = {
+static struct pci_device_id snd_vx222_ids[] __devinitdata = {
{ 0x10b5, 0x9050, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_OLD, }, /* PLX */
{ 0x10b5, 0x9030, 0x1369, PCI_ANY_ID, 0, 0, VX_PCI_VX222_NEW, }, /* PLX */
{ 0, }
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index db57ce9..65ebf5f 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -70,7 +70,7 @@ MODULE_PARM_DESC(rear_switch, "Enable shared rear/line-in switch");
module_param_array(rear_swap, bool, NULL, 0444);
MODULE_PARM_DESC(rear_swap, "Swap rear channels (must be enabled for correct IEC958 (S/PDIF)) output");
-static struct pci_device_id snd_ymfpci_ids[] = {
+static struct pci_device_id snd_ymfpci_ids[] __devinitdata = {
{ 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
{ 0x1073, 0x000d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724F */
{ 0x1073, 0x000a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF740 */
diff --git a/sound/pcmcia/Kconfig b/sound/pcmcia/Kconfig
index 5d1b0b7..c9fa1a2 100644
--- a/sound/pcmcia/Kconfig
+++ b/sound/pcmcia/Kconfig
@@ -5,7 +5,7 @@ menu "PCMCIA devices"
config SND_VXPOCKET
tristate "Digigram VXpocket"
- depends on SND && PCMCIA && ISA
+ depends on SND && PCMCIA
select SND_VX_LIB
help
Say Y here to include support for Digigram VXpocket and
@@ -16,7 +16,7 @@ config SND_VXPOCKET
config SND_PDAUDIOCF
tristate "Sound Core PDAudioCF"
- depends on SND && PCMCIA && ISA
+ depends on SND && PCMCIA
select SND_PCM
help
Say Y here to include support for Sound Core PDAudioCF
diff --git a/sound/ppc/toonie.c b/sound/ppc/toonie.c
index 4e59517..1ac7c85 100644
--- a/sound/ppc/toonie.c
+++ b/sound/ppc/toonie.c
@@ -335,7 +335,7 @@ static void toonie_cleanup(struct snd_pmac *chip)
chip->mixer_data = NULL;
}
-int snd_pmac_toonie_init(struct snd_pmac *chip)
+int __init snd_pmac_toonie_init(struct snd_pmac *chip)
{
struct pmac_toonie *mix;
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index 0992a09..9351846 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1531,6 +1531,15 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
},
{
+ USB_DEVICE_VENDOR_SPEC(0x0ccd, 0x0014),
+ .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
+ .vendor_name = "TerraTec",
+ .product_name = "PHASE 26",
+ .ifnum = 3,
+ .type = QUIRK_MIDI_STANDARD_INTERFACE
+ }
+},
+{
USB_DEVICE(0x0ccd, 0x0035),
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
.vendor_name = "Miditech",