diff --git a/[refs] b/[refs] index dc37e02919ea..638983515a4e 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 06e727d2a5d9d889fabad35223ad77205a9bebb9 +refs/heads/master: bf0c0259c79b325fd4ea139f363366d319786ea2 diff --git a/trunk/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/trunk/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index ff53183c3848..807fca2ae2a4 100644 --- a/trunk/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/trunk/Documentation/ABI/testing/sysfs-platform-ideapad-laptop @@ -4,20 +4,3 @@ KernelVersion: 2.6.37 Contact: "Ike Panhc " Description: Control the power of camera module. 1 means on, 0 means off. - -What: /sys/devices/platform/ideapad/cfg -Date: Jun 2011 -KernelVersion: 3.1 -Contact: "Ike Panhc " -Description: - Ideapad capability bits. - Bit 8-10: 1 - Intel graphic only - 2 - ATI graphic only - 3 - Nvidia graphic only - 4 - Intel and ATI graphic - 5 - Intel and Nvidia graphic - Bit 16: Bluetooth exist (1 for exist) - Bit 17: 3G exist (1 for exist) - Bit 18: Wifi exist (1 for exist) - Bit 19: Camera exist (1 for exist) - diff --git a/trunk/Documentation/CodingStyle b/trunk/Documentation/CodingStyle index c940239d9678..fa6e25b94a54 100644 --- a/trunk/Documentation/CodingStyle +++ b/trunk/Documentation/CodingStyle @@ -80,13 +80,22 @@ available tools. The limit on the length of lines is 80 columns and this is a strongly preferred limit. -Statements longer than 80 columns will be broken into sensible chunks, unless -exceeding 80 columns significantly increases readability and does not hide -information. Descendants are always substantially shorter than the parent and -are placed substantially to the right. The same applies to function headers -with a long argument list. However, never break user-visible strings such as -printk messages, because that breaks the ability to grep for them. - +Statements longer than 80 columns will be broken into sensible chunks. +Descendants are always substantially shorter than the parent and are placed +substantially to the right. The same applies to function headers with a long +argument list. Long strings are as well broken into shorter strings. The +only exception to this is where exceeding 80 columns significantly increases +readability and does not hide information. + +void fun(int a, int b, int c) +{ + if (condition) + printk(KERN_WARNING "Warning this is a long printk with " + "3 parameters a: %u b: %u " + "c: %u \n", a, b, c); + else + next_statement; +} Chapter 3: Placing Braces and Spaces diff --git a/trunk/Documentation/acpi/apei/einj.txt b/trunk/Documentation/acpi/apei/einj.txt index 5cc699ba5453..dfab71848dc8 100644 --- a/trunk/Documentation/acpi/apei/einj.txt +++ b/trunk/Documentation/acpi/apei/einj.txt @@ -48,19 +48,12 @@ directory apei/einj. The following files are provided. - param1 This file is used to set the first error parameter value. Effect of parameter depends on error_type specified. For memory error, this is - physical memory address. Only available if param_extension module - parameter is specified. + physical memory address. - param2 This file is used to set the second error parameter value. Effect of parameter depends on error_type specified. For memory error, this is - physical memory address mask. Only available if param_extension - module parameter is specified. - -Injecting parameter support is a BIOS version specific extension, that -is, it only works on some BIOS version. If you want to use it, please -make sure your BIOS version has the proper support and specify -"param_extension=y" in module parameter. + physical memory address mask. For more information about EINJ, please refer to ACPI specification version 4.0, section 17.5. diff --git a/trunk/Documentation/device-mapper/dm-crypt.txt b/trunk/Documentation/device-mapper/dm-crypt.txt index 2c656ae43ba7..6b5c42dbbe84 100644 --- a/trunk/Documentation/device-mapper/dm-crypt.txt +++ b/trunk/Documentation/device-mapper/dm-crypt.txt @@ -4,8 +4,7 @@ dm-crypt Device-Mapper's "crypt" target provides transparent encryption of block devices using the kernel crypto API. -Parameters: \ - [<#opt_params> ] +Parameters: Encryption cipher and an optional IV generation mode. @@ -38,24 +37,6 @@ Parameters: \ Starting sector within the device where the encrypted data begins. -<#opt_params> - Number of optional parameters. If there are no optional parameters, - the optional paramaters section can be skipped or #opt_params can be zero. - Otherwise #opt_params is the number of following arguments. - - Example of optional parameters section: - 1 allow_discards - -allow_discards - Block discard requests (a.k.a. TRIM) are passed through the crypt device. - The default is to ignore discard requests. - - WARNING: Assess the specific security risks carefully before enabling this - option. For example, allowing discards on encrypted devices may lead to - the leak of information about the ciphertext device (filesystem type, - used space etc.) if the discarded blocks can be located easily on the - device later. - Example scripts =============== LUKS (Linux Unified Key Setup) is now the preferred way to set up disk diff --git a/trunk/Documentation/device-mapper/dm-flakey.txt b/trunk/Documentation/device-mapper/dm-flakey.txt index 6ff5c2327227..c8efdfd19a65 100644 --- a/trunk/Documentation/device-mapper/dm-flakey.txt +++ b/trunk/Documentation/device-mapper/dm-flakey.txt @@ -1,53 +1,17 @@ dm-flakey ========= -This target is the same as the linear target except that it exhibits -unreliable behaviour periodically. It's been found useful in simulating -failing devices for testing purposes. +This target is the same as the linear target except that it returns I/O +errors periodically. It's been found useful in simulating failing +devices for testing purposes. Starting from the time the table is loaded, the device is available for - seconds, then exhibits unreliable behaviour for seconds, and then this cycle repeats. + seconds, then returns errors for seconds, +and then this cycle repeats. -Also, consider using this in combination with the dm-delay target too, -which can delay reads and writes and/or send them to different -underlying devices. - -Table parameters ----------------- - \ - [ []] - -Mandatory parameters: +Parameters: : Full pathname to the underlying block-device, or a "major:minor" device-number. : Starting sector within the device. : Number of seconds device is available. : Number of seconds device returns errors. - -Optional feature parameters: - If no feature parameters are present, during the periods of - unreliability, all I/O returns errors. - - drop_writes: - All write I/O is silently ignored. - Read I/O is handled correctly. - - corrupt_bio_byte : - During , replace of the data of - each matching bio with . - - : The offset of the byte to replace. - Counting starts at 1, to replace the first byte. - : Either 'r' to corrupt reads or 'w' to corrupt writes. - 'w' is incompatible with drop_writes. - : The value (from 0-255) to write. - : Perform the replacement only if bio->bi_rw has all the - selected flags set. - -Examples: - corrupt_bio_byte 32 r 1 0 - - replaces the 32nd byte of READ bios with the value 1 - - corrupt_bio_byte 224 w 0 32 - - replaces the 224th byte of REQ_META (=32) bios with the value 0 diff --git a/trunk/Documentation/device-mapper/dm-raid.txt b/trunk/Documentation/device-mapper/dm-raid.txt index 2a8c11331d2d..33b6b7071ac8 100644 --- a/trunk/Documentation/device-mapper/dm-raid.txt +++ b/trunk/Documentation/device-mapper/dm-raid.txt @@ -1,108 +1,70 @@ -dm-raid -------- +Device-mapper RAID (dm-raid) is a bridge from DM to MD. It +provides a way to use device-mapper interfaces to access the MD RAID +drivers. -The device-mapper RAID (dm-raid) target provides a bridge from DM to MD. -It allows the MD RAID drivers to be accessed using a device-mapper -interface. +As with all device-mapper targets, the nominal public interfaces are the +constructor (CTR) tables and the status outputs (both STATUSTYPE_INFO +and STATUSTYPE_TABLE). The CTR table looks like the following: -The target is named "raid" and it accepts the following parameters: - - <#raid_params> \ - <#raid_devs> [.. ] - -: - raid1 RAID1 mirroring - raid4 RAID4 dedicated parity disk - raid5_la RAID5 left asymmetric - - rotating parity 0 with data continuation - raid5_ra RAID5 right asymmetric - - rotating parity N with data continuation - raid5_ls RAID5 left symmetric - - rotating parity 0 with data restart - raid5_rs RAID5 right symmetric - - rotating parity N with data restart - raid6_zr RAID6 zero restart - - rotating parity zero (left-to-right) with data restart - raid6_nr RAID6 N restart - - rotating parity N (right-to-left) with data restart - raid6_nc RAID6 N continue - - rotating parity N (right-to-left) with data continuation - - Refererence: Chapter 4 of - http://www.snia.org/sites/default/files/SNIA_DDF_Technical_Position_v2.0.pdf - -<#raid_params>: The number of parameters that follow. - - consists of - Mandatory parameters: - : Chunk size in sectors. This parameter is often known as - "stripe size". It is the only mandatory parameter and - is placed first. - - followed by optional parameters (in any order): - [sync|nosync] Force or prevent RAID initialization. - - [rebuild ] Rebuild drive number idx (first drive is 0). - - [daemon_sleep ] - Interval between runs of the bitmap daemon that - clear bits. A longer interval means less bitmap I/O but - resyncing after a failure is likely to take longer. - - [min_recovery_rate ] Throttle RAID initialization - [max_recovery_rate ] Throttle RAID initialization - [write_mostly ] Drive index is write-mostly - [max_write_behind ] See '-write-behind=' (man mdadm) - [stripe_cache ] Stripe cache size (higher RAIDs only) - [region_size ] - The region_size multiplied by the number of regions is the - logical size of the array. The bitmap records the device - synchronisation state for each region. - -<#raid_devs>: The number of devices composing the array. - Each device consists of two entries. The first is the device - containing the metadata (if any); the second is the one containing the - data. - - If a drive has failed or is missing at creation time, a '-' can be - given for both the metadata and data drives for a given position. - - -Example tables --------------- -# RAID4 - 4 data drives, 1 parity (no metadata devices) +1: raid \ +2: <#raid_params> \ +3: <#raid_devs> .. + +Line 1 contains the standard first three arguments to any device-mapper +target - the start, length, and target type fields. The target type in +this case is "raid". + +Line 2 contains the arguments that define the particular raid +type/personality/level, the required arguments for that raid type, and +any optional arguments. Possible raid types include: raid4, raid5_la, +raid5_ls, raid5_rs, raid6_zr, raid6_nr, and raid6_nc. (raid1 is +planned for the future.) The list of required and optional parameters +is the same for all the current raid types. The required parameters are +positional, while the optional parameters are given as key/value pairs. +The possible parameters are as follows: + Chunk size in sectors. + [[no]sync] Force/Prevent RAID initialization + [rebuild ] Rebuild the drive indicated by the index + [daemon_sleep ] Time between bitmap daemon work to clear bits + [min_recovery_rate ] Throttle RAID initialization + [max_recovery_rate ] Throttle RAID initialization + [max_write_behind ] See '-write-behind=' (man mdadm) + [stripe_cache ] Stripe cache size for higher RAIDs + +Line 3 contains the list of devices that compose the array in +metadata/data device pairs. If the metadata is stored separately, a '-' +is given for the metadata device position. If a drive has failed or is +missing at creation time, a '-' can be given for both the metadata and +data drives for a given position. + +NB. Currently all metadata devices must be specified as '-'. + +Examples: +# RAID4 - 4 data drives, 1 parity # No metadata devices specified to hold superblock/bitmap info # Chunk size of 1MiB # (Lines separated for easy reading) - 0 1960893648 raid \ raid4 1 2048 \ 5 - 8:17 - 8:33 - 8:49 - 8:65 - 8:81 -# RAID4 - 4 data drives, 1 parity (with metadata devices) +# RAID4 - 4 data drives, 1 parity (no metadata devices) # Chunk size of 1MiB, force RAID initialization, # min recovery rate at 20 kiB/sec/disk - 0 1960893648 raid \ - raid4 4 2048 sync min_recovery_rate 20 \ - 5 8:17 8:18 8:33 8:34 8:49 8:50 8:65 8:66 8:81 8:82 + raid4 4 2048 min_recovery_rate 20 sync\ + 5 - 8:17 - 8:33 - 8:49 - 8:65 - 8:81 -'dmsetup table' displays the table used to construct the mapping. -The optional parameters are always printed in the order listed -above with "sync" or "nosync" always output ahead of the other -arguments, regardless of the order used when originally loading the table. -Arguments that can be repeated are ordered by value. +Performing a 'dmsetup table' should display the CTR table used to +construct the mapping (with possible reordering of optional +parameters). -'dmsetup status' yields information on the state and health of the -array. -The output is as follows: +Performing a 'dmsetup status' will yield information on the state and +health of the array. The output is as follows: 1: raid \ 2: <#devices> <1 health char for each dev> -Line 1 is the standard output produced by device-mapper. -Line 2 is produced by the raid target, and best explained by example: +Line 1 is standard DM output. Line 2 is best shown by example: 0 1960893648 raid raid4 5 AAAAA 2/490221568 Here we can see the RAID type is raid4, there are 5 devices - all of which are 'A'live, and the array is 2/490221568 complete with recovery. -Faulty or missing devices are marked 'D'. Devices that are out-of-sync -are marked 'a'. diff --git a/trunk/Documentation/devicetree/bindings/gpio/gpio_keys.txt b/trunk/Documentation/devicetree/bindings/gpio/gpio_keys.txt index 5c2c02140a62..7190c99d7611 100644 --- a/trunk/Documentation/devicetree/bindings/gpio/gpio_keys.txt +++ b/trunk/Documentation/devicetree/bindings/gpio/gpio_keys.txt @@ -10,7 +10,7 @@ Optional properties: Each button (key) is represented as a sub-node of "gpio-keys": Subnode properties: - - gpios: OF device-tree gpio specification. + - gpios: OF devcie-tree gpio specificatin. - label: Descriptive name of the key. - linux,code: Keycode to emit. diff --git a/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt b/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt deleted file mode 100644 index a00c94ccbdee..000000000000 --- a/trunk/Documentation/devicetree/bindings/input/fsl-mma8450.txt +++ /dev/null @@ -1,11 +0,0 @@ -* Freescale MMA8450 3-Axis Accelerometer - -Required properties: -- compatible : "fsl,mma8450". - -Example: - -accelerometer: mma8450@1c { - compatible = "fsl,mma8450"; - reg = <0x1c>; -}; diff --git a/trunk/Documentation/fault-injection/fault-injection.txt b/trunk/Documentation/fault-injection/fault-injection.txt index 82a5d250d75e..7be15e44d481 100644 --- a/trunk/Documentation/fault-injection/fault-injection.txt +++ b/trunk/Documentation/fault-injection/fault-injection.txt @@ -143,7 +143,8 @@ o provide a way to configure fault attributes failslab, fail_page_alloc, and fail_make_request use this way. Helper functions: - fault_create_debugfs_attr(name, parent, attr); + init_fault_attr_dentries(entries, attr, name); + void cleanup_fault_attr_dentries(entries); - module parameters diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index c4a6e148732a..ea0bace0124a 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -296,6 +296,15 @@ Who: Ravikiran Thirumalai --------------------------- +What: CONFIG_THERMAL_HWMON +When: January 2009 +Why: This option was introduced just to allow older lm-sensors userspace + to keep working over the upgrade to 2.6.26. At the scheduled time of + removal fixed lm-sensors (2.x or 3.x) should be readily available. +Who: Rene Herman + +--------------------------- + What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS (in net/core/net-sysfs.c) When: After the only user (hal) has seen a release with the patches @@ -581,14 +590,3 @@ Why: This driver has been superseded by g_mass_storage. Who: Alan Stern ---------------------------- - -What: threeg and interface sysfs files in /sys/devices/platform/acer-wmi -When: 2012 -Why: In 3.0, we can now autodetect internal 3G device and already have - the threeg rfkill device. So, we plan to remove threeg sysfs support - for it's no longer necessary. - - We also plan to remove interface sysfs file that exposed which ACPI-WMI - interface that was used by acer-wmi driver. It will replaced by - information log when acer-wmi initial. -Who: Lee, Chun-Yi diff --git a/trunk/Documentation/frv/booting.txt b/trunk/Documentation/frv/booting.txt index 37c4d84a0e57..ace200b7c214 100644 --- a/trunk/Documentation/frv/booting.txt +++ b/trunk/Documentation/frv/booting.txt @@ -106,20 +106,13 @@ separated by spaces: To use the first on-chip serial port at baud rate 115200, no parity, 8 bits, and no flow control. - (*) root= + (*) root=/dev/ - This specifies the device upon which the root filesystem resides. It - may be specified by major and minor number, device path, or even - partition uuid, if supported. For example: + This specifies the device upon which the root filesystem resides. For + example: /dev/nfs NFS root filesystem /dev/mtdblock3 Fourth RedBoot partition on the System Flash - PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=1 - first partition after the partition with the given UUID - 253:0 Device with major 253 and minor 0 - - Authoritative information can be found in - "Documentation/kernel-parameters.txt". (*) rw diff --git a/trunk/Documentation/ioctl/ioctl-number.txt b/trunk/Documentation/ioctl/ioctl-number.txt index 845a191004b1..72ba8d51dbc1 100644 --- a/trunk/Documentation/ioctl/ioctl-number.txt +++ b/trunk/Documentation/ioctl/ioctl-number.txt @@ -292,7 +292,6 @@ Code Seq#(hex) Include File Comments 0xA0 all linux/sdp/sdp.h Industrial Device Project -0xA2 00-0F arch/tile/include/asm/hardwall.h 0xA3 80-8F Port ACL in development: 0xA3 90-9F linux/dtlk.h diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 78926aa2531c..26a83743af19 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -163,11 +163,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. See also Documentation/power/pm.txt, pci=noacpi - acpi_rsdp= [ACPI,EFI,KEXEC] - Pass the RSDP address to the kernel, mostly used - on machines running EFI runtime service to boot the - second kernel for kdump. - acpi_apic_instance= [ACPI, IOAPIC] Format: 2: use 2nd APIC table, if available @@ -551,9 +546,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. /proc//coredump_filter. See also Documentation/filesystems/proc.txt. - cpuidle.off=1 [CPU_IDLE] - disable the cpuidle sub-system - cpcihp_generic= [HW,PCI] Generic port I/O CompactPCI driver Format: ,,,[,] @@ -2248,7 +2240,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. ro [KNL] Mount root device read-only on boot root= [KNL] Root filesystem - See name_to_dev_t comment in init/do_mounts.c. rootdelay= [KNL] Delay (in seconds) to pause before attempting to mount the root filesystem @@ -2680,27 +2671,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted. vmpoff= [KNL,S390] Perform z/VM CP command after power off. Format: - vsyscall= [X86-64] - Controls the behavior of vsyscalls (i.e. calls to - fixed addresses of 0xffffffffff600x00 from legacy - code). Most statically-linked binaries and older - versions of glibc use these calls. Because these - functions are at fixed addresses, they make nice - targets for exploits that can control RIP. - - emulate [default] Vsyscalls turn into traps and are - emulated reasonably safely. - - native Vsyscalls are native syscall instructions. - This is a little bit faster than trapping - and makes a few dynamic recompilers work - better than they would in emulation mode. - It also makes exploits much easier to write. - - none Vsyscalls don't work at all. This makes - them quite hard to use for exploits but - might break your system. - vt.cur_default= [VT] Default cursor shape. Format: 0xCCBBAA, where AA, BB, and CC are the same as the parameters of the [?A;B;Cc escape sequence; diff --git a/trunk/Documentation/m68k/kernel-options.txt b/trunk/Documentation/m68k/kernel-options.txt index 97d45f276fe6..c93bed66e25d 100644 --- a/trunk/Documentation/m68k/kernel-options.txt +++ b/trunk/Documentation/m68k/kernel-options.txt @@ -129,20 +129,6 @@ decimal 11 is the major of SCSI CD-ROMs, and the minor 0 stands for the first of these. You can find out all valid major numbers by looking into include/linux/major.h. -In addition to major and minor numbers, if the device containing your -root partition uses a partition table format with unique partition -identifiers, then you may use them. For instance, -"root=PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF". It is also -possible to reference another partition on the same device using a -known partition UUID as the starting point. For example, -if partition 5 of the device has the UUID of -00112233-4455-6677-8899-AABBCCDDEEFF then partition 3 may be found as -follows: - PARTUUID=00112233-4455-6677-8899-AABBCCDDEEFF/PARTNROFF=-2 - -Authoritative information can be found in -"Documentation/kernel-parameters.txt". - 2.2) ro, rw ----------- diff --git a/trunk/Documentation/networking/bonding.txt b/trunk/Documentation/networking/bonding.txt index 91df678fb7f8..675612ff41ae 100644 --- a/trunk/Documentation/networking/bonding.txt +++ b/trunk/Documentation/networking/bonding.txt @@ -238,18 +238,6 @@ ad_select This option was added in bonding version 3.4.0. -all_slaves_active - - Specifies that duplicate frames (received on inactive ports) should be - dropped (0) or delivered (1). - - Normally, bonding will drop duplicate frames (received on inactive - ports), which is desirable for most users. But there are some times - it is nice to allow duplicate frames to be delivered. - - The default value is 0 (drop duplicate frames received on inactive - ports). - arp_interval Specifies the ARP link monitoring frequency in milliseconds. @@ -445,23 +433,6 @@ miimon determined. See the High Availability section for additional information. The default value is 0. -min_links - - Specifies the minimum number of links that must be active before - asserting carrier. It is similar to the Cisco EtherChannel min-links - feature. This allows setting the minimum number of member ports that - must be up (link-up state) before marking the bond device as up - (carrier on). This is useful for situations where higher level services - such as clustering want to ensure a minimum number of low bandwidth - links are active before switchover. This option only affect 802.3ad - mode. - - The default value is 0. This will cause carrier to be asserted (for - 802.3ad mode) whenever there is an active aggregator, regardless of the - number of available links in that aggregator. Note that, because an - aggregator cannot be active without at least one available link, - setting this option to 0 or to 1 has the exact same effect. - mode Specifies one of the bonding policies. The default is @@ -628,7 +599,7 @@ num_unsol_na affect only the active-backup mode. These options were added for bonding versions 3.3.0 and 3.4.0 respectively. - From Linux 3.0 and bonding version 3.7.1, these notifications + From Linux 2.6.40 and bonding version 3.7.1, these notifications are generated by the ipv4 and ipv6 code and the numbers of repetitions cannot be set independently. diff --git a/trunk/Documentation/networking/scaling.txt b/trunk/Documentation/networking/scaling.txt deleted file mode 100644 index 7254b4b5910e..000000000000 --- a/trunk/Documentation/networking/scaling.txt +++ /dev/null @@ -1,371 +0,0 @@ -Scaling in the Linux Networking Stack - - -Introduction -============ - -This document describes a set of complementary techniques in the Linux -networking stack to increase parallelism and improve performance for -multi-processor systems. - -The following technologies are described: - - RSS: Receive Side Scaling - RPS: Receive Packet Steering - RFS: Receive Flow Steering - Accelerated Receive Flow Steering - XPS: Transmit Packet Steering - - -RSS: Receive Side Scaling -========================= - -Contemporary NICs support multiple receive and transmit descriptor queues -(multi-queue). On reception, a NIC can send different packets to different -queues to distribute processing among CPUs. The NIC distributes packets by -applying a filter to each packet that assigns it to one of a small number -of logical flows. Packets for each flow are steered to a separate receive -queue, which in turn can be processed by separate CPUs. This mechanism is -generally known as “Receive-side Scaling” (RSS). The goal of RSS and -the other scaling techniques to increase performance uniformly. -Multi-queue distribution can also be used for traffic prioritization, but -that is not the focus of these techniques. - -The filter used in RSS is typically a hash function over the network -and/or transport layer headers-- for example, a 4-tuple hash over -IP addresses and TCP ports of a packet. The most common hardware -implementation of RSS uses a 128-entry indirection table where each entry -stores a queue number. The receive queue for a packet is determined -by masking out the low order seven bits of the computed hash for the -packet (usually a Toeplitz hash), taking this number as a key into the -indirection table and reading the corresponding value. - -Some advanced NICs allow steering packets to queues based on -programmable filters. For example, webserver bound TCP port 80 packets -can be directed to their own receive queue. Such “n-tuple” filters can -be configured from ethtool (--config-ntuple). - -==== RSS Configuration - -The driver for a multi-queue capable NIC typically provides a kernel -module parameter for specifying the number of hardware queues to -configure. In the bnx2x driver, for instance, this parameter is called -num_queues. A typical RSS configuration would be to have one receive queue -for each CPU if the device supports enough queues, or otherwise at least -one for each cache domain at a particular cache level (L1, L2, etc.). - -The indirection table of an RSS device, which resolves a queue by masked -hash, is usually programmed by the driver at initialization. The -default mapping is to distribute the queues evenly in the table, but the -indirection table can be retrieved and modified at runtime using ethtool -commands (--show-rxfh-indir and --set-rxfh-indir). Modifying the -indirection table could be done to give different queues different -relative weights. - -== RSS IRQ Configuration - -Each receive queue has a separate IRQ associated with it. The NIC triggers -this to notify a CPU when new packets arrive on the given queue. The -signaling path for PCIe devices uses message signaled interrupts (MSI-X), -that can route each interrupt to a particular CPU. The active mapping -of queues to IRQs can be determined from /proc/interrupts. By default, -an IRQ may be handled on any CPU. Because a non-negligible part of packet -processing takes place in receive interrupt handling, it is advantageous -to spread receive interrupts between CPUs. To manually adjust the IRQ -affinity of each interrupt see Documentation/IRQ-affinity. Some systems -will be running irqbalance, a daemon that dynamically optimizes IRQ -assignments and as a result may override any manual settings. - -== Suggested Configuration - -RSS should be enabled when latency is a concern or whenever receive -interrupt processing forms a bottleneck. Spreading load between CPUs -decreases queue length. For low latency networking, the optimal setting -is to allocate as many queues as there are CPUs in the system (or the -NIC maximum, if lower). Because the aggregate number of interrupts grows -with each additional queue, the most efficient high-rate configuration -is likely the one with the smallest number of receive queues where no -CPU that processes receive interrupts reaches 100% utilization. Per-cpu -load can be observed using the mpstat utility. - - -RPS: Receive Packet Steering -============================ - -Receive Packet Steering (RPS) is logically a software implementation of -RSS. Being in software, it is necessarily called later in the datapath. -Whereas RSS selects the queue and hence CPU that will run the hardware -interrupt handler, RPS selects the CPU to perform protocol processing -above the interrupt handler. This is accomplished by placing the packet -on the desired CPU’s backlog queue and waking up the CPU for processing. -RPS has some advantages over RSS: 1) it can be used with any NIC, -2) software filters can easily be added to hash over new protocols, -3) it does not increase hardware device interrupt rate (although it does -introduce inter-processor interrupts (IPIs)). - -RPS is called during bottom half of the receive interrupt handler, when -a driver sends a packet up the network stack with netif_rx() or -netif_receive_skb(). These call the get_rps_cpu() function, which -selects the queue that should process a packet. - -The first step in determining the target CPU for RPS is to calculate a -flow hash over the packet’s addresses or ports (2-tuple or 4-tuple hash -depending on the protocol). This serves as a consistent hash of the -associated flow of the packet. The hash is either provided by hardware -or will be computed in the stack. Capable hardware can pass the hash in -the receive descriptor for the packet; this would usually be the same -hash used for RSS (e.g. computed Toeplitz hash). The hash is saved in -skb->rx_hash and can be used elsewhere in the stack as a hash of the -packet’s flow. - -Each receive hardware queue has an associated list of CPUs to which -RPS may enqueue packets for processing. For each received packet, -an index into the list is computed from the flow hash modulo the size -of the list. The indexed CPU is the target for processing the packet, -and the packet is queued to the tail of that CPU’s backlog queue. At -the end of the bottom half routine, IPIs are sent to any CPUs for which -packets have been queued to their backlog queue. The IPI wakes backlog -processing on the remote CPU, and any queued packets are then processed -up the networking stack. - -==== RPS Configuration - -RPS requires a kernel compiled with the CONFIG_RPS kconfig symbol (on -by default for SMP). Even when compiled in, RPS remains disabled until -explicitly configured. The list of CPUs to which RPS may forward traffic -can be configured for each receive queue using a sysfs file entry: - - /sys/class/net//queues/rx-/rps_cpus - -This file implements a bitmap of CPUs. RPS is disabled when it is zero -(the default), in which case packets are processed on the interrupting -CPU. Documentation/IRQ-affinity.txt explains how CPUs are assigned to -the bitmap. - -== Suggested Configuration - -For a single queue device, a typical RPS configuration would be to set -the rps_cpus to the CPUs in the same cache domain of the interrupting -CPU. If NUMA locality is not an issue, this could also be all CPUs in -the system. At high interrupt rate, it might be wise to exclude the -interrupting CPU from the map since that already performs much work. - -For a multi-queue system, if RSS is configured so that a hardware -receive queue is mapped to each CPU, then RPS is probably redundant -and unnecessary. If there are fewer hardware queues than CPUs, then -RPS might be beneficial if the rps_cpus for each queue are the ones that -share the same cache domain as the interrupting CPU for that queue. - - -RFS: Receive Flow Steering -========================== - -While RPS steers packets solely based on hash, and thus generally -provides good load distribution, it does not take into account -application locality. This is accomplished by Receive Flow Steering -(RFS). The goal of RFS is to increase datacache hitrate by steering -kernel processing of packets to the CPU where the application thread -consuming the packet is running. RFS relies on the same RPS mechanisms -to enqueue packets onto the backlog of another CPU and to wake up that -CPU. - -In RFS, packets are not forwarded directly by the value of their hash, -but the hash is used as index into a flow lookup table. This table maps -flows to the CPUs where those flows are being processed. The flow hash -(see RPS section above) is used to calculate the index into this table. -The CPU recorded in each entry is the one which last processed the flow. -If an entry does not hold a valid CPU, then packets mapped to that entry -are steered using plain RPS. Multiple table entries may point to the -same CPU. Indeed, with many flows and few CPUs, it is very likely that -a single application thread handles flows with many different flow hashes. - -rps_sock_table is a global flow table that contains the *desired* CPU for -flows: the CPU that is currently processing the flow in userspace. Each -table value is a CPU index that is updated during calls to recvmsg and -sendmsg (specifically, inet_recvmsg(), inet_sendmsg(), inet_sendpage() -and tcp_splice_read()). - -When the scheduler moves a thread to a new CPU while it has outstanding -receive packets on the old CPU, packets may arrive out of order. To -avoid this, RFS uses a second flow table to track outstanding packets -for each flow: rps_dev_flow_table is a table specific to each hardware -receive queue of each device. Each table value stores a CPU index and a -counter. The CPU index represents the *current* CPU onto which packets -for this flow are enqueued for further kernel processing. Ideally, kernel -and userspace processing occur on the same CPU, and hence the CPU index -in both tables is identical. This is likely false if the scheduler has -recently migrated a userspace thread while the kernel still has packets -enqueued for kernel processing on the old CPU. - -The counter in rps_dev_flow_table values records the length of the current -CPU's backlog when a packet in this flow was last enqueued. Each backlog -queue has a head counter that is incremented on dequeue. A tail counter -is computed as head counter + queue length. In other words, the counter -in rps_dev_flow_table[i] records the last element in flow i that has -been enqueued onto the currently designated CPU for flow i (of course, -entry i is actually selected by hash and multiple flows may hash to the -same entry i). - -And now the trick for avoiding out of order packets: when selecting the -CPU for packet processing (from get_rps_cpu()) the rps_sock_flow table -and the rps_dev_flow table of the queue that the packet was received on -are compared. If the desired CPU for the flow (found in the -rps_sock_flow table) matches the current CPU (found in the rps_dev_flow -table), the packet is enqueued onto that CPU’s backlog. If they differ, -the current CPU is updated to match the desired CPU if one of the -following is true: - -- The current CPU's queue head counter >= the recorded tail counter - value in rps_dev_flow[i] -- The current CPU is unset (equal to NR_CPUS) -- The current CPU is offline - -After this check, the packet is sent to the (possibly updated) current -CPU. These rules aim to ensure that a flow only moves to a new CPU when -there are no packets outstanding on the old CPU, as the outstanding -packets could arrive later than those about to be processed on the new -CPU. - -==== RFS Configuration - -RFS is only available if the kconfig symbol CONFIG_RFS is enabled (on -by default for SMP). The functionality remains disabled until explicitly -configured. The number of entries in the global flow table is set through: - - /proc/sys/net/core/rps_sock_flow_entries - -The number of entries in the per-queue flow table are set through: - - /sys/class/net//queues/tx-/rps_flow_cnt - -== Suggested Configuration - -Both of these need to be set before RFS is enabled for a receive queue. -Values for both are rounded up to the nearest power of two. The -suggested flow count depends on the expected number of active connections -at any given time, which may be significantly less than the number of open -connections. We have found that a value of 32768 for rps_sock_flow_entries -works fairly well on a moderately loaded server. - -For a single queue device, the rps_flow_cnt value for the single queue -would normally be configured to the same value as rps_sock_flow_entries. -For a multi-queue device, the rps_flow_cnt for each queue might be -configured as rps_sock_flow_entries / N, where N is the number of -queues. So for instance, if rps_flow_entries is set to 32768 and there -are 16 configured receive queues, rps_flow_cnt for each queue might be -configured as 2048. - - -Accelerated RFS -=============== - -Accelerated RFS is to RFS what RSS is to RPS: a hardware-accelerated load -balancing mechanism that uses soft state to steer flows based on where -the application thread consuming the packets of each flow is running. -Accelerated RFS should perform better than RFS since packets are sent -directly to a CPU local to the thread consuming the data. The target CPU -will either be the same CPU where the application runs, or at least a CPU -which is local to the application thread’s CPU in the cache hierarchy. - -To enable accelerated RFS, the networking stack calls the -ndo_rx_flow_steer driver function to communicate the desired hardware -queue for packets matching a particular flow. The network stack -automatically calls this function every time a flow entry in -rps_dev_flow_table is updated. The driver in turn uses a device specific -method to program the NIC to steer the packets. - -The hardware queue for a flow is derived from the CPU recorded in -rps_dev_flow_table. The stack consults a CPU to hardware queue map which -is maintained by the NIC driver. This is an auto-generated reverse map of -the IRQ affinity table shown by /proc/interrupts. Drivers can use -functions in the cpu_rmap (“CPU affinity reverse map”) kernel library -to populate the map. For each CPU, the corresponding queue in the map is -set to be one whose processing CPU is closest in cache locality. - -==== Accelerated RFS Configuration - -Accelerated RFS is only available if the kernel is compiled with -CONFIG_RFS_ACCEL and support is provided by the NIC device and driver. -It also requires that ntuple filtering is enabled via ethtool. The map -of CPU to queues is automatically deduced from the IRQ affinities -configured for each receive queue by the driver, so no additional -configuration should be necessary. - -== Suggested Configuration - -This technique should be enabled whenever one wants to use RFS and the -NIC supports hardware acceleration. - -XPS: Transmit Packet Steering -============================= - -Transmit Packet Steering is a mechanism for intelligently selecting -which transmit queue to use when transmitting a packet on a multi-queue -device. To accomplish this, a mapping from CPU to hardware queue(s) is -recorded. The goal of this mapping is usually to assign queues -exclusively to a subset of CPUs, where the transmit completions for -these queues are processed on a CPU within this set. This choice -provides two benefits. First, contention on the device queue lock is -significantly reduced since fewer CPUs contend for the same queue -(contention can be eliminated completely if each CPU has its own -transmit queue). Secondly, cache miss rate on transmit completion is -reduced, in particular for data cache lines that hold the sk_buff -structures. - -XPS is configured per transmit queue by setting a bitmap of CPUs that -may use that queue to transmit. The reverse mapping, from CPUs to -transmit queues, is computed and maintained for each network device. -When transmitting the first packet in a flow, the function -get_xps_queue() is called to select a queue. This function uses the ID -of the running CPU as a key into the CPU-to-queue lookup table. If the -ID matches a single queue, that is used for transmission. If multiple -queues match, one is selected by using the flow hash to compute an index -into the set. - -The queue chosen for transmitting a particular flow is saved in the -corresponding socket structure for the flow (e.g. a TCP connection). -This transmit queue is used for subsequent packets sent on the flow to -prevent out of order (ooo) packets. The choice also amortizes the cost -of calling get_xps_queues() over all packets in the connection. To avoid -ooo packets, the queue for a flow can subsequently only be changed if -skb->ooo_okay is set for a packet in the flow. This flag indicates that -there are no outstanding packets in the flow, so the transmit queue can -change without the risk of generating out of order packets. The -transport layer is responsible for setting ooo_okay appropriately. TCP, -for instance, sets the flag when all data for a connection has been -acknowledged. - -==== XPS Configuration - -XPS is only available if the kconfig symbol CONFIG_XPS is enabled (on by -default for SMP). The functionality remains disabled until explicitly -configured. To enable XPS, the bitmap of CPUs that may use a transmit -queue is configured using the sysfs file entry: - -/sys/class/net//queues/tx-/xps_cpus - -== Suggested Configuration - -For a network device with a single transmission queue, XPS configuration -has no effect, since there is no choice in this case. In a multi-queue -system, XPS is preferably configured so that each CPU maps onto one queue. -If there are as many queues as there are CPUs in the system, then each -queue can also map onto one CPU, resulting in exclusive pairings that -experience no contention. If there are fewer queues than CPUs, then the -best CPUs to share a given queue are probably those that share the cache -with the CPU that processes transmit completions for that queue -(transmit interrupts). - - -Further Information -=================== -RPS and RFS were introduced in kernel 2.6.35. XPS was incorporated into -2.6.38. Original patches were submitted by Tom Herbert -(therbert@google.com) - -Accelerated RFS was introduced in 2.6.35. Original patches were -submitted by Ben Hutchings (bhutchings@solarflare.com) - -Authors: -Tom Herbert (therbert@google.com) -Willem de Bruijn (willemb@google.com) diff --git a/trunk/Documentation/power/runtime_pm.txt b/trunk/Documentation/power/runtime_pm.txt index 4ce5450ab6e8..14dd3c6ad97e 100644 --- a/trunk/Documentation/power/runtime_pm.txt +++ b/trunk/Documentation/power/runtime_pm.txt @@ -54,10 +54,11 @@ referred to as subsystem-level callbacks in what follows. By default, the callbacks are always invoked in process context with interrupts enabled. However, subsystems can use the pm_runtime_irq_safe() helper function to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume() -callbacks should be invoked in atomic context with interrupts disabled. -This implies that these callback routines must not block or sleep, but it also -means that the synchronous helper functions listed at the end of Section 4 can -be used within an interrupt handler or in an atomic context. +callbacks should be invoked in atomic context with interrupts disabled +(->runtime_idle() is still invoked the default way). This implies that these +callback routines must not block or sleep, but it also means that the +synchronous helper functions listed at the end of Section 4 can be used within +an interrupt handler or in an atomic context. The subsystem-level suspend callback is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include @@ -482,7 +483,6 @@ pm_runtime_suspend() pm_runtime_autosuspend() pm_runtime_resume() pm_runtime_get_sync() -pm_runtime_put_sync() pm_runtime_put_sync_suspend() 5. Runtime PM Initialization, Device Probing and Removal diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index 1e55e1eeb811..c9c6324a7a9f 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -2643,8 +2643,9 @@ S: Maintained F: arch/x86/math-emu/ FRAME RELAY DLCI/FRAD (Sangoma drivers too) +M: Mike McLagan L: netdev@vger.kernel.org -S: Orphan +S: Maintained F: drivers/net/wan/dlci.c F: drivers/net/wan/sdla.c @@ -3366,12 +3367,6 @@ F: drivers/net/ixgb/ F: drivers/net/ixgbe/ F: drivers/net/ixgbevf/ -INTEL MRST PMU DRIVER -M: Len Brown -L: linux-pm@lists.linux-foundation.org -S: Supported -F: arch/x86/platform/mrst/pmu.* - INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT L: linux-wireless@vger.kernel.org S: Orphan @@ -3905,9 +3900,9 @@ F: arch/powerpc/platforms/powermac/ F: drivers/macintosh/ LINUX FOR POWERPC EMBEDDED MPC5XXX -M: Anatolij Gustschin +M: Grant Likely L: linuxppc-dev@lists.ozlabs.org -T: git git://git.denx.de/linux-2.6-agust.git +T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: arch/powerpc/platforms/512x/ F: arch/powerpc/platforms/52xx/ @@ -4414,10 +4409,10 @@ F: net/*/netfilter/ F: net/netfilter/ NETLABEL -M: Paul Moore +M: Paul Moore W: http://netlabel.sf.net L: netdev@vger.kernel.org -S: Maintained +S: Supported F: Documentation/netlabel/ F: include/net/netlabel.h F: net/netlabel/ @@ -4462,6 +4457,7 @@ F: include/linux/netdevice.h NETWORKING [IPv4/IPv6] M: "David S. Miller" M: Alexey Kuznetsov +M: "Pekka Savola (ipv6)" M: James Morris M: Hideaki YOSHIFUJI M: Patrick McHardy @@ -4474,7 +4470,7 @@ F: include/net/ip* F: arch/x86/net/* NETWORKING [LABELED] (NetLabel, CIPSO, Labeled IPsec, SECMARK) -M: Paul Moore +M: Paul Moore L: netdev@vger.kernel.org S: Maintained @@ -4726,7 +4722,6 @@ S: Maintained F: drivers/of F: include/linux/of*.h K: of_get_property -K: of_match_table OPENRISC ARCHITECTURE M: Jonas Bonn @@ -6323,7 +6318,6 @@ F: include/linux/sysv_fs.h TARGET SUBSYSTEM M: Nicholas A. Bellinger L: linux-scsi@vger.kernel.org -L: target-devel@vger.kernel.org L: http://groups.google.com/group/linux-iscsi-target-dev W: http://www.linux-iscsi.org T: git git://git.kernel.org/pub/scm/linux/kernel/git/nab/lio-core-2.6.git master @@ -7357,7 +7351,7 @@ THE REST M: Linus Torvalds L: linux-kernel@vger.kernel.org Q: http://patchwork.kernel.org/project/LKML/list/ -T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git +T: git git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git S: Buried alive in reporters F: * F: */ diff --git a/trunk/Makefile b/trunk/Makefile index b4ca4e111c9a..f676d15cd348 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 3 -PATCHLEVEL = 1 +PATCHLEVEL = 0 SUBLEVEL = 0 -EXTRAVERSION = -rc1 +EXTRAVERSION = NAME = Sneaky Weasel # *DOCUMENTATION* diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 4b0669cbb3b0..26b0e2397a57 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -178,7 +178,4 @@ config HAVE_ARCH_MUTEX_CPU_RELAX config HAVE_RCU_TABLE_FREE bool -config ARCH_HAVE_NMI_SAFE_CMPXCHG - bool - source "kernel/gcov/Kconfig" diff --git a/trunk/arch/alpha/Kconfig b/trunk/arch/alpha/Kconfig index 60cde53d266c..ca2da8da6e9c 100644 --- a/trunk/arch/alpha/Kconfig +++ b/trunk/arch/alpha/Kconfig @@ -14,7 +14,6 @@ config ALPHA select AUTO_IRQ_AFFINITY if SMP select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_HAVE_NMI_SAFE_CMPXCHG help The Alpha is a 64-bit general-purpose processor designed and marketed by the Digital Equipment Corporation of blessed memory, diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 5ebc5d922ea1..2c71a8f3535a 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -195,7 +195,8 @@ config VECTORS_BASE The base address of exception vectors. config ARM_PATCH_PHYS_VIRT - bool "Patch physical to virtual translations at runtime" + bool "Patch physical to virtual translations at runtime (EXPERIMENTAL)" + depends on EXPERIMENTAL depends on !XIP_KERNEL && MMU depends on !ARCH_REALVIEW || !SPARSEMEM help diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c index aeef960ff795..acca35aebe28 100644 --- a/trunk/arch/arm/kernel/armksyms.c +++ b/trunk/arch/arm/kernel/armksyms.c @@ -112,6 +112,9 @@ EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); #endif + /* crypto hash */ +EXPORT_SYMBOL(sha_transform); + /* gcc lib functions */ EXPORT_SYMBOL(__ashldi3); EXPORT_SYMBOL(__ashrdi3); diff --git a/trunk/arch/arm/kernel/iwmmxt.S b/trunk/arch/arm/kernel/iwmmxt.S index a08783823b32..7fa3bb0d2397 100644 --- a/trunk/arch/arm/kernel/iwmmxt.S +++ b/trunk/arch/arm/kernel/iwmmxt.S @@ -195,10 +195,10 @@ ENTRY(iwmmxt_task_disable) @ enable access to CP0 and CP1 XSC(mrc p15, 0, r4, c15, c1, 0) - XSC(orr r4, r4, #0x3) + XSC(orr r4, r4, #0xf) XSC(mcr p15, 0, r4, c15, c1, 0) PJ4(mrc p15, 0, r4, c1, c0, 2) - PJ4(orr r4, r4, #0xf) + PJ4(orr r4, r4, #0x3) PJ4(mcr p15, 0, r4, c1, c0, 2) mov r0, #0 @ nothing to load @@ -313,7 +313,7 @@ ENTRY(iwmmxt_task_switch) teq r2, r3 @ next task owns it? movne pc, lr @ no: leave Concan disabled -1: @ flip Concan access +1: @ flip Conan access XSC(eor r1, r1, #0x3) XSC(mcr p15, 0, r1, c15, c1, 0) PJ4(eor r1, r1, #0xf) diff --git a/trunk/arch/arm/kernel/module.c b/trunk/arch/arm/kernel/module.c index cc2020c2c709..05b377616fd5 100644 --- a/trunk/arch/arm/kernel/module.c +++ b/trunk/arch/arm/kernel/module.c @@ -323,11 +323,7 @@ int module_finalize(const Elf32_Ehdr *hdr, const Elf_Shdr *sechdrs, #endif s = find_mod_section(hdr, sechdrs, ".alt.smp.init"); if (s && !is_smp()) -#ifdef CONFIG_SMP_ON_UP fixup_smp((void *)s->sh_addr, s->sh_size); -#else - return -EINVAL; -#endif return 0; } diff --git a/trunk/arch/arm/kernel/process.c b/trunk/arch/arm/kernel/process.c index 1a347f481e5e..5e1e54197227 100644 --- a/trunk/arch/arm/kernel/process.c +++ b/trunk/arch/arm/kernel/process.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include @@ -197,8 +196,7 @@ void cpu_idle(void) cpu_relax(); } else { stop_critical_timings(); - if (cpuidle_idle_call()) - pm_idle(); + pm_idle(); start_critical_timings(); /* * This will eventually be removed - pm_idle diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile index cf73a7f742dd..59ff42ddf0ae 100644 --- a/trunk/arch/arm/lib/Makefile +++ b/trunk/arch/arm/lib/Makefile @@ -12,7 +12,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o sha1.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o mmu-y := clear_user.o copy_page.o getuser.o putuser.o diff --git a/trunk/arch/arm/lib/sha1.S b/trunk/arch/arm/lib/sha1.S new file mode 100644 index 000000000000..eb0edb80d7b8 --- /dev/null +++ b/trunk/arch/arm/lib/sha1.S @@ -0,0 +1,211 @@ +/* + * linux/arch/arm/lib/sha1.S + * + * SHA transform optimized for ARM + * + * Copyright: (C) 2005 by Nicolas Pitre + * Created: September 17, 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * The reference implementation for this code is linux/lib/sha1.c + */ + +#include + + .text + + +/* + * void sha_transform(__u32 *digest, const char *in, __u32 *W) + * + * Note: the "in" ptr may be unaligned. + */ + +ENTRY(sha_transform) + + stmfd sp!, {r4 - r8, lr} + + @ for (i = 0; i < 16; i++) + @ W[i] = be32_to_cpu(in[i]); + +#ifdef __ARMEB__ + mov r4, r0 + mov r0, r2 + mov r2, #64 + bl memcpy + mov r2, r0 + mov r0, r4 +#else + mov r3, r2 + mov lr, #16 +1: ldrb r4, [r1], #1 + ldrb r5, [r1], #1 + ldrb r6, [r1], #1 + ldrb r7, [r1], #1 + subs lr, lr, #1 + orr r5, r5, r4, lsl #8 + orr r6, r6, r5, lsl #8 + orr r7, r7, r6, lsl #8 + str r7, [r3], #4 + bne 1b +#endif + + @ for (i = 0; i < 64; i++) + @ W[i+16] = ror(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 31); + + sub r3, r2, #4 + mov lr, #64 +2: ldr r4, [r3, #4]! + subs lr, lr, #1 + ldr r5, [r3, #8] + ldr r6, [r3, #32] + ldr r7, [r3, #52] + eor r4, r4, r5 + eor r4, r4, r6 + eor r4, r4, r7 + mov r4, r4, ror #31 + str r4, [r3, #64] + bne 2b + + /* + * The SHA functions are: + * + * f1(B,C,D) = (D ^ (B & (C ^ D))) + * f2(B,C,D) = (B ^ C ^ D) + * f3(B,C,D) = ((B & C) | (D & (B | C))) + * + * Then the sub-blocks are processed as follows: + * + * A' = ror(A, 27) + f(B,C,D) + E + K + *W++ + * B' = A + * C' = ror(B, 2) + * D' = C + * E' = D + * + * We therefore unroll each loop 5 times to avoid register shuffling. + * Also the ror for C (and also D and E which are successivelyderived + * from it) is applied in place to cut on an additional mov insn for + * each round. + */ + + .macro sha_f1, A, B, C, D, E + ldr r3, [r2], #4 + eor ip, \C, \D + add \E, r1, \E, ror #2 + and ip, \B, ip, ror #2 + add \E, \E, \A, ror #27 + eor ip, ip, \D, ror #2 + add \E, \E, r3 + add \E, \E, ip + .endm + + .macro sha_f2, A, B, C, D, E + ldr r3, [r2], #4 + add \E, r1, \E, ror #2 + eor ip, \B, \C, ror #2 + add \E, \E, \A, ror #27 + eor ip, ip, \D, ror #2 + add \E, \E, r3 + add \E, \E, ip + .endm + + .macro sha_f3, A, B, C, D, E + ldr r3, [r2], #4 + add \E, r1, \E, ror #2 + orr ip, \B, \C, ror #2 + add \E, \E, \A, ror #27 + and ip, ip, \D, ror #2 + add \E, \E, r3 + and r3, \B, \C, ror #2 + orr ip, ip, r3 + add \E, \E, ip + .endm + + ldmia r0, {r4 - r8} + + mov lr, #4 + ldr r1, .L_sha_K + 0 + + /* adjust initial values */ + mov r6, r6, ror #30 + mov r7, r7, ror #30 + mov r8, r8, ror #30 + +3: subs lr, lr, #1 + sha_f1 r4, r5, r6, r7, r8 + sha_f1 r8, r4, r5, r6, r7 + sha_f1 r7, r8, r4, r5, r6 + sha_f1 r6, r7, r8, r4, r5 + sha_f1 r5, r6, r7, r8, r4 + bne 3b + + ldr r1, .L_sha_K + 4 + mov lr, #4 + +4: subs lr, lr, #1 + sha_f2 r4, r5, r6, r7, r8 + sha_f2 r8, r4, r5, r6, r7 + sha_f2 r7, r8, r4, r5, r6 + sha_f2 r6, r7, r8, r4, r5 + sha_f2 r5, r6, r7, r8, r4 + bne 4b + + ldr r1, .L_sha_K + 8 + mov lr, #4 + +5: subs lr, lr, #1 + sha_f3 r4, r5, r6, r7, r8 + sha_f3 r8, r4, r5, r6, r7 + sha_f3 r7, r8, r4, r5, r6 + sha_f3 r6, r7, r8, r4, r5 + sha_f3 r5, r6, r7, r8, r4 + bne 5b + + ldr r1, .L_sha_K + 12 + mov lr, #4 + +6: subs lr, lr, #1 + sha_f2 r4, r5, r6, r7, r8 + sha_f2 r8, r4, r5, r6, r7 + sha_f2 r7, r8, r4, r5, r6 + sha_f2 r6, r7, r8, r4, r5 + sha_f2 r5, r6, r7, r8, r4 + bne 6b + + ldmia r0, {r1, r2, r3, ip, lr} + add r4, r1, r4 + add r5, r2, r5 + add r6, r3, r6, ror #2 + add r7, ip, r7, ror #2 + add r8, lr, r8, ror #2 + stmia r0, {r4 - r8} + + ldmfd sp!, {r4 - r8, pc} + +ENDPROC(sha_transform) + + .align 2 +.L_sha_K: + .word 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 + + +/* + * void sha_init(__u32 *buf) + */ + + .align 2 +.L_sha_initial_digest: + .word 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 + +ENTRY(sha_init) + + str lr, [sp, #-4]! + adr r1, .L_sha_initial_digest + ldmia r1, {r1, r2, r3, ip, lr} + stmia r0, {r1, r2, r3, ip, lr} + ldr pc, [sp], #4 + +ENDPROC(sha_init) diff --git a/trunk/arch/arm/mach-imx/clock-imx25.c b/trunk/arch/arm/mach-imx/clock-imx25.c index e63e23504fe5..0fc7ba56d616 100644 --- a/trunk/arch/arm/mach-imx/clock-imx25.c +++ b/trunk/arch/arm/mach-imx/clock-imx25.c @@ -331,9 +331,6 @@ int __init mx25_clocks_init(void) __raw_writel(__raw_readl(CRM_BASE+0x64) | (1 << 7) | (1 << 0), CRM_BASE + 0x64); - /* Clock source for gpt is ahb_div */ - __raw_writel(__raw_readl(CRM_BASE+0x64) & ~(1 << 5), CRM_BASE + 0x64); - mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); return 0; diff --git a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index 6778f8193bc6..6707de0ab716 100644 --- a/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/trunk/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -197,17 +196,6 @@ static struct pca953x_platform_data visstrim_m10_pca9555_pdata = { .invert = 0, }; -static struct aic32x4_pdata visstrim_m10_aic32x4_pdata = { - .power_cfg = AIC32X4_PWR_MICBIAS_2075_LDOIN | - AIC32X4_PWR_AVDD_DVDD_WEAK_DISABLE | - AIC32X4_PWR_AIC32X4_LDO_ENABLE | - AIC32X4_PWR_CMMODE_LDOIN_RANGE_18_36 | - AIC32X4_PWR_CMMODE_HP_LDOIN_POWERED, - .micpga_routing = AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K | - AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K, - .swapdacs = false, -}; - static struct i2c_board_info visstrim_m10_i2c_devices[] = { { I2C_BOARD_INFO("pca9555", 0x20), @@ -215,7 +203,6 @@ static struct i2c_board_info visstrim_m10_i2c_devices[] = { }, { I2C_BOARD_INFO("tlv320aic32x4", 0x18), - .platform_data = &visstrim_m10_aic32x4_pdata, } }; diff --git a/trunk/arch/arm/mach-imx/mach-mx31ads.c b/trunk/arch/arm/mach-imx/mach-mx31ads.c index 29ca8907a780..0ce49478a479 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31ads.c +++ b/trunk/arch/arm/mach-imx/mach-mx31ads.c @@ -468,7 +468,7 @@ static struct i2c_board_info __initdata mx31ads_i2c1_devices[] = { #endif }; -static void __init mxc_init_i2c(void) +static void mxc_init_i2c(void) { i2c_register_board_info(1, mx31ads_i2c1_devices, ARRAY_SIZE(mx31ads_i2c1_devices)); @@ -486,7 +486,7 @@ static unsigned int ssi_pins[] = { MX31_PIN_STXD5__STXD5, }; -static void __init mxc_init_audio(void) +static void mxc_init_audio(void) { imx31_add_imx_ssi(0, NULL); mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); diff --git a/trunk/arch/arm/mach-imx/mach-mx31lilly.c b/trunk/arch/arm/mach-imx/mach-mx31lilly.c index 126913ad106a..750368ddf0f9 100644 --- a/trunk/arch/arm/mach-imx/mach-mx31lilly.c +++ b/trunk/arch/arm/mach-imx/mach-mx31lilly.c @@ -192,7 +192,7 @@ static struct mxc_usbh_platform_data usbh2_pdata __initdata = { .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT, }; -static void __init lilly1131_usb_init(void) +static void lilly1131_usb_init(void) { imx31_add_mxc_ehci_hs(1, &usbh1_pdata); diff --git a/trunk/arch/arm/mach-mmp/gplugd.c b/trunk/arch/arm/mach-mmp/gplugd.c index 98e25d9aaab6..c070c24255f4 100644 --- a/trunk/arch/arm/mach-mmp/gplugd.c +++ b/trunk/arch/arm/mach-mmp/gplugd.c @@ -16,18 +16,16 @@ #include #include #include +#include #include "common.h" static unsigned long gplugd_pin_config[] __initdata = { /* UART3 */ - GPIO8_UART3_TXD, - GPIO9_UART3_RXD, - GPIO1O_UART3_CTS, - GPIO11_UART3_RTS, - - /* USB OTG PEN */ - GPIO18_GPIO, + GPIO8_UART3_SOUT, + GPIO9_UART3_SIN, + GPI1O_UART3_CTS, + GPI11_UART3_RTS, /* MMC2 */ GPIO28_MMC2_CMD, @@ -111,12 +109,6 @@ static unsigned long gplugd_pin_config[] __initdata = { GPIO105_CI2C_SDA, GPIO106_CI2C_SCL, - /* SPI NOR Flash on SSP2 */ - GPIO107_SSP2_RXD, - GPIO108_SSP2_TXD, - GPIO110_GPIO, /* SPI_CSn */ - GPIO111_SSP2_CLK, - /* Select JTAG */ GPIO109_GPIO, @@ -162,7 +154,7 @@ static void __init select_disp_freq(void) "frequency\n"); } else { gpio_direction_output(35, 1); - gpio_free(35); + gpio_free(104); } if (unlikely(gpio_request(85, "DISP_FREQ_SEL_2"))) { @@ -170,7 +162,7 @@ static void __init select_disp_freq(void) "frequency\n"); } else { gpio_direction_output(85, 0); - gpio_free(85); + gpio_free(104); } } diff --git a/trunk/arch/arm/mach-mmp/include/mach/mfp-gplugd.h b/trunk/arch/arm/mach-mmp/include/mach/mfp-gplugd.h new file mode 100644 index 000000000000..b8cf38d85600 --- /dev/null +++ b/trunk/arch/arm/mach-mmp/include/mach/mfp-gplugd.h @@ -0,0 +1,52 @@ +/* + * linux/arch/arm/mach-mmp/include/mach/mfp-gplugd.h + * + * MFP definitions used in gplugD + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __MACH_MFP_GPLUGD_H +#define __MACH_MFP_GPLUGD_H + +#include +#include + +/* UART3 */ +#define GPIO8_UART3_SOUT MFP_CFG(GPIO8, AF2) +#define GPIO9_UART3_SIN MFP_CFG(GPIO9, AF2) +#define GPI1O_UART3_CTS MFP_CFG(GPIO10, AF2) +#define GPI11_UART3_RTS MFP_CFG(GPIO11, AF2) + +/* MMC2 */ +#define GPIO28_MMC2_CMD MFP_CFG_DRV(GPIO28, AF6, FAST) +#define GPIO29_MMC2_CLK MFP_CFG_DRV(GPIO29, AF6, FAST) +#define GPIO30_MMC2_DAT0 MFP_CFG_DRV(GPIO30, AF6, FAST) +#define GPIO31_MMC2_DAT1 MFP_CFG_DRV(GPIO31, AF6, FAST) +#define GPIO32_MMC2_DAT2 MFP_CFG_DRV(GPIO32, AF6, FAST) +#define GPIO33_MMC2_DAT3 MFP_CFG_DRV(GPIO33, AF6, FAST) + +/* I2S */ +#undef GPIO114_I2S_FRM +#undef GPIO115_I2S_BCLK + +#define GPIO114_I2S_FRM MFP_CFG_DRV(GPIO114, AF1, FAST) +#define GPIO115_I2S_BCLK MFP_CFG_DRV(GPIO115, AF1, FAST) +#define GPIO116_I2S_TXD MFP_CFG_DRV(GPIO116, AF1, FAST) + +/* MMC4 */ +#define GPIO125_MMC4_DAT3 MFP_CFG_DRV(GPIO125, AF7, FAST) +#define GPIO126_MMC4_DAT2 MFP_CFG_DRV(GPIO126, AF7, FAST) +#define GPIO127_MMC4_DAT1 MFP_CFG_DRV(GPIO127, AF7, FAST) +#define GPIO0_2_MMC4_DAT0 MFP_CFG_DRV(GPIO0_2, AF7, FAST) +#define GPIO1_2_MMC4_CMD MFP_CFG_DRV(GPIO1_2, AF7, FAST) +#define GPIO2_2_MMC4_CLK MFP_CFG_DRV(GPIO2_2, AF7, FAST) + +/* OTG GPIO */ +#define GPIO_USB_OTG_PEN 18 +#define GPIO_USB_OIDIR 20 + +/* Other GPIOs are 35, 84, 85 */ +#endif /* __MACH_MFP_GPLUGD_H */ diff --git a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h index 92aaa3c19d61..8c782328b21c 100644 --- a/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h +++ b/trunk/arch/arm/mach-mmp/include/mach/mfp-pxa168.h @@ -203,10 +203,6 @@ #define GPIO33_CF_nCD2 MFP_CFG(GPIO33, AF3) /* UART */ -#define GPIO8_UART3_TXD MFP_CFG(GPIO8, AF2) -#define GPIO9_UART3_RXD MFP_CFG(GPIO9, AF2) -#define GPIO1O_UART3_CTS MFP_CFG(GPIO10, AF2) -#define GPIO11_UART3_RTS MFP_CFG(GPIO11, AF2) #define GPIO88_UART2_TXD MFP_CFG(GPIO88, AF2) #define GPIO89_UART2_RXD MFP_CFG(GPIO89, AF2) #define GPIO107_UART1_TXD MFP_CFG_DRV(GPIO107, AF1, FAST) @@ -236,22 +232,6 @@ #define GPIO53_MMC1_CD MFP_CFG(GPIO53, AF1) #define GPIO46_MMC1_WP MFP_CFG(GPIO46, AF1) -/* MMC2 */ -#define GPIO28_MMC2_CMD MFP_CFG_DRV(GPIO28, AF6, FAST) -#define GPIO29_MMC2_CLK MFP_CFG_DRV(GPIO29, AF6, FAST) -#define GPIO30_MMC2_DAT0 MFP_CFG_DRV(GPIO30, AF6, FAST) -#define GPIO31_MMC2_DAT1 MFP_CFG_DRV(GPIO31, AF6, FAST) -#define GPIO32_MMC2_DAT2 MFP_CFG_DRV(GPIO32, AF6, FAST) -#define GPIO33_MMC2_DAT3 MFP_CFG_DRV(GPIO33, AF6, FAST) - -/* MMC4 */ -#define GPIO125_MMC4_DAT3 MFP_CFG_DRV(GPIO125, AF7, FAST) -#define GPIO126_MMC4_DAT2 MFP_CFG_DRV(GPIO126, AF7, FAST) -#define GPIO127_MMC4_DAT1 MFP_CFG_DRV(GPIO127, AF7, FAST) -#define GPIO0_2_MMC4_DAT0 MFP_CFG_DRV(GPIO0_2, AF7, FAST) -#define GPIO1_2_MMC4_CMD MFP_CFG_DRV(GPIO1_2, AF7, FAST) -#define GPIO2_2_MMC4_CLK MFP_CFG_DRV(GPIO2_2, AF7, FAST) - /* LCD */ #define GPIO84_LCD_CS MFP_CFG(GPIO84, AF1) #define GPIO60_LCD_DD0 MFP_CFG(GPIO60, AF1) @@ -289,12 +269,11 @@ #define GPIO106_CI2C_SCL MFP_CFG(GPIO106, AF1) /* I2S */ -#define GPIO113_I2S_MCLK MFP_CFG(GPIO113, AF6) -#define GPIO114_I2S_FRM MFP_CFG(GPIO114, AF1) -#define GPIO115_I2S_BCLK MFP_CFG(GPIO115, AF1) -#define GPIO116_I2S_RXD MFP_CFG(GPIO116, AF2) -#define GPIO116_I2S_TXD MFP_CFG(GPIO116, AF1) -#define GPIO117_I2S_TXD MFP_CFG(GPIO117, AF2) +#define GPIO113_I2S_MCLK MFP_CFG(GPIO113,AF6) +#define GPIO114_I2S_FRM MFP_CFG(GPIO114,AF1) +#define GPIO115_I2S_BCLK MFP_CFG(GPIO115,AF1) +#define GPIO116_I2S_RXD MFP_CFG(GPIO116,AF2) +#define GPIO117_I2S_TXD MFP_CFG(GPIO117,AF2) /* PWM */ #define GPIO96_PWM3_OUT MFP_CFG(GPIO96, AF1) @@ -345,10 +324,4 @@ #define GPIO101_MII_MDIO MFP_CFG(GPIO101, AF5) #define GPIO103_RX_DV MFP_CFG(GPIO103, AF5) -/* SSP2 */ -#define GPIO107_SSP2_RXD MFP_CFG(GPIO107, AF4) -#define GPIO108_SSP2_TXD MFP_CFG(GPIO108, AF4) -#define GPIO111_SSP2_CLK MFP_CFG(GPIO111, AF4) -#define GPIO112_SSP2_FRM MFP_CFG(GPIO112, AF4) - #endif /* __ASM_MACH_MFP_PXA168_H */ diff --git a/trunk/arch/arm/mach-mmp/time.c b/trunk/arch/arm/mach-mmp/time.c index 4e91ee6e27c8..99833b9485cf 100644 --- a/trunk/arch/arm/mach-mmp/time.c +++ b/trunk/arch/arm/mach-mmp/time.c @@ -51,12 +51,12 @@ static inline uint32_t timer_read(void) { int delay = 100; - __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(1)); + __raw_writel(1, TIMERS_VIRT_BASE + TMR_CVWR(0)); while (delay--) cpu_relax(); - return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(1)); + return __raw_readl(TIMERS_VIRT_BASE + TMR_CVWR(0)); } unsigned long long notrace sched_clock(void) @@ -75,51 +75,28 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id) { struct clock_event_device *c = dev_id; - /* - * Clear pending interrupt status. - */ - __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); - - /* - * Disable timer 0. - */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); - + /* disable and clear pending interrupt status */ + __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); + __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_ICR(0)); c->event_handler(c); - return IRQ_HANDLED; } static int timer_set_next_event(unsigned long delta, struct clock_event_device *dev) { - unsigned long flags; + unsigned long flags, next; local_irq_save(flags); - /* - * Disable timer 0. - */ - __raw_writel(0x02, TIMERS_VIRT_BASE + TMR_CER); - - /* - * Clear and enable timer match 0 interrupt. - */ + /* clear pending interrupt status and enable */ __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_ICR(0)); __raw_writel(0x01, TIMERS_VIRT_BASE + TMR_IER(0)); - /* - * Setup new clockevent timer value. - */ - __raw_writel(delta - 1, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); - - /* - * Enable timer 0. - */ - __raw_writel(0x03, TIMERS_VIRT_BASE + TMR_CER); + next = timer_read() + delta; + __raw_writel(next, TIMERS_VIRT_BASE + TMR_TN_MM(0, 0)); local_irq_restore(flags); - return 0; } @@ -168,26 +145,23 @@ static struct clocksource cksrc = { static void __init timer_config(void) { uint32_t ccr = __raw_readl(TIMERS_VIRT_BASE + TMR_CCR); + uint32_t cer = __raw_readl(TIMERS_VIRT_BASE + TMR_CER); + uint32_t cmr = __raw_readl(TIMERS_VIRT_BASE + TMR_CMR); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_CER); /* disable */ + __raw_writel(cer & ~0x1, TIMERS_VIRT_BASE + TMR_CER); /* disable */ - ccr &= (cpu_is_mmp2()) ? (TMR_CCR_CS_0(0) | TMR_CCR_CS_1(0)) : - (TMR_CCR_CS_0(3) | TMR_CCR_CS_1(3)); + ccr &= (cpu_is_mmp2()) ? TMR_CCR_CS_0(0) : TMR_CCR_CS_0(3); __raw_writel(ccr, TIMERS_VIRT_BASE + TMR_CCR); - /* set timer 0 to periodic mode, and timer 1 to free-running mode */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CMR); + /* free-running mode */ + __raw_writel(cmr | 0x01, TIMERS_VIRT_BASE + TMR_CMR); - __raw_writel(0x1, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* periodic */ + __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(0)); /* free-running */ __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(0)); /* clear status */ __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(0)); - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_PLCR(1)); /* free-running */ - __raw_writel(0x7, TIMERS_VIRT_BASE + TMR_ICR(1)); /* clear status */ - __raw_writel(0x0, TIMERS_VIRT_BASE + TMR_IER(1)); - - /* enable timer 1 counter */ - __raw_writel(0x2, TIMERS_VIRT_BASE + TMR_CER); + /* enable timer counter */ + __raw_writel(cer | 0x01, TIMERS_VIRT_BASE + TMR_CER); } static struct irqaction timer_irq = { diff --git a/trunk/arch/arm/mach-mx5/board-cpuimx51.c b/trunk/arch/arm/mach-mx5/board-cpuimx51.c index 68934ea8725a..7c893fa70266 100644 --- a/trunk/arch/arm/mach-mx5/board-cpuimx51.c +++ b/trunk/arch/arm/mach-mx5/board-cpuimx51.c @@ -81,7 +81,7 @@ static struct plat_serial8250_port serial_platform_data[] = { .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP, }, { .mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000), - .irq = gpio_to_irq(CPUIMX51_QUARTD_GPIO), + .irq = irq_to_gpio(CPUIMX51_QUARTD_GPIO), .irqflags = IRQF_TRIGGER_HIGH, .uartclk = CPUIMX51_QUART_XTAL, .regshift = CPUIMX51_QUART_REGSHIFT, diff --git a/trunk/arch/arm/mach-mx5/board-mx51_babbage.c b/trunk/arch/arm/mach-mx5/board-mx51_babbage.c index 11b0ff67f89d..e400b09109ce 100644 --- a/trunk/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/trunk/arch/arm/mach-mx5/board-mx51_babbage.c @@ -369,7 +369,7 @@ static void __init mx51_babbage_init(void) ARRAY_SIZE(mx51babbage_pads)); imx51_add_imx_uart(0, &uart_pdata); - imx51_add_imx_uart(1, NULL); + imx51_add_imx_uart(1, &uart_pdata); imx51_add_imx_uart(2, &uart_pdata); babbage_fec_reset(); diff --git a/trunk/arch/arm/mach-mx5/board-mx51_efikamx.c b/trunk/arch/arm/mach-mx5/board-mx51_efikamx.c index 551daf85ff8c..f70700dc0ec1 100644 --- a/trunk/arch/arm/mach-mx5/board-mx51_efikamx.c +++ b/trunk/arch/arm/mach-mx5/board-mx51_efikamx.c @@ -108,9 +108,9 @@ static void __init mx51_efikamx_board_id(void) gpio_request(EFIKAMX_PCBID2, "pcbid2"); gpio_direction_input(EFIKAMX_PCBID2); - id = gpio_get_value(EFIKAMX_PCBID0) ? 1 : 0; - id |= (gpio_get_value(EFIKAMX_PCBID1) ? 1 : 0) << 1; - id |= (gpio_get_value(EFIKAMX_PCBID2) ? 1 : 0) << 2; + id = gpio_get_value(EFIKAMX_PCBID0); + id |= gpio_get_value(EFIKAMX_PCBID1) << 1; + id |= gpio_get_value(EFIKAMX_PCBID2) << 2; switch (id) { case 7: diff --git a/trunk/arch/arm/mach-mx5/board-mx51_efikasb.c b/trunk/arch/arm/mach-mx5/board-mx51_efikasb.c index 8a9bca22beb5..2e4d9d32a87c 100644 --- a/trunk/arch/arm/mach-mx5/board-mx51_efikasb.c +++ b/trunk/arch/arm/mach-mx5/board-mx51_efikasb.c @@ -156,24 +156,23 @@ static struct gpio_keys_button mx51_efikasb_keys[] = { { .code = KEY_POWER, .gpio = EFIKASB_PWRKEY, - .type = EV_KEY, + .type = EV_PWR, .desc = "Power Button", .wakeup = 1, - .active_low = 1, + .debounce_interval = 10, /* ms */ }, { .code = SW_LID, .gpio = EFIKASB_LID, .type = EV_SW, .desc = "Lid Switch", - .active_low = 1, }, { - .code = KEY_RFKILL, + /* SW_RFKILLALL vs KEY_RFKILL ? */ + .code = SW_RFKILL_ALL, .gpio = EFIKASB_RFKILL, - .type = EV_KEY, + .type = EV_SW, .desc = "rfkill", - .active_low = 1, }, }; @@ -225,8 +224,8 @@ static void __init mx51_efikasb_board_id(void) gpio_request(EFIKASB_PCBID1, "pcb id1"); gpio_direction_input(EFIKASB_PCBID1); - id = gpio_get_value(EFIKASB_PCBID0) ? 1 : 0; - id |= (gpio_get_value(EFIKASB_PCBID1) ? 1 : 0) << 1; + id = gpio_get_value(EFIKASB_PCBID0); + id |= gpio_get_value(EFIKASB_PCBID1) << 1; switch (id) { default: diff --git a/trunk/arch/arm/mach-mx5/clock-mx51-mx53.c b/trunk/arch/arm/mach-mx5/clock-mx51-mx53.c index f7bf996f463b..7f20308c4dbd 100644 --- a/trunk/arch/arm/mach-mx5/clock-mx51-mx53.c +++ b/trunk/arch/arm/mach-mx5/clock-mx51-mx53.c @@ -271,11 +271,7 @@ static int _clk_pll_enable(struct clk *clk) int i = 0; pllbase = _get_pll_base(clk); - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); - if (reg & MXC_PLL_DP_CTL_UPEN) - return 0; - - reg |= MXC_PLL_DP_CTL_UPEN; + reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); /* Wait for lock */ diff --git a/trunk/arch/arm/mach-mx5/mx51_efika.c b/trunk/arch/arm/mach-mx5/mx51_efika.c index c9209454807a..4435e03cea5d 100644 --- a/trunk/arch/arm/mach-mx5/mx51_efika.c +++ b/trunk/arch/arm/mach-mx5/mx51_efika.c @@ -186,7 +186,7 @@ static int initialize_usbh1_port(struct platform_device *pdev) mdelay(10); - return mx51_initialize_usb_hw(pdev->id, MXC_EHCI_ITC_NO_THRESHOLD); + return mx51_initialize_usb_hw(0, MXC_EHCI_ITC_NO_THRESHOLD); } static struct mxc_usbh_platform_data usbh1_config = { diff --git a/trunk/arch/arm/mach-omap2/Kconfig b/trunk/arch/arm/mach-omap2/Kconfig index 57b66d590c52..4ae6257b39a4 100644 --- a/trunk/arch/arm/mach-omap2/Kconfig +++ b/trunk/arch/arm/mach-omap2/Kconfig @@ -7,6 +7,7 @@ config ARCH_OMAP2PLUS_TYPICAL default y select AEABI select REGULATOR + select PM select PM_RUNTIME select VFP select NEON if ARCH_OMAP3 || ARCH_OMAP4 diff --git a/trunk/arch/arm/mach-omap2/board-am3517crane.c b/trunk/arch/arm/mach-omap2/board-am3517crane.c index 933e9353cb37..5f2b55ff04ff 100644 --- a/trunk/arch/arm/mach-omap2/board-am3517crane.c +++ b/trunk/arch/arm/mach-omap2/board-am3517crane.c @@ -45,6 +45,8 @@ static struct omap_board_config_kernel am3517_crane_config[] __initdata = { static struct omap_board_mux board_mux[] __initdata = { { .reg_offset = OMAP_MUX_TERMINATOR }, }; +#else +#define board_mux NULL #endif static void __init am3517_crane_init_early(void) diff --git a/trunk/arch/arm/mach-omap2/board-omap3beagle.c b/trunk/arch/arm/mach-omap2/board-omap3beagle.c index 3ae16b4e3f52..32f5f895568a 100644 --- a/trunk/arch/arm/mach-omap2/board-omap3beagle.c +++ b/trunk/arch/arm/mach-omap2/board-omap3beagle.c @@ -491,22 +491,23 @@ static void __init beagle_opp_init(void) /* Custom OPP enabled for all xM versions */ if (cpu_is_omap3630()) { - struct device *mpu_dev, *iva_dev; + struct omap_hwmod *mh = omap_hwmod_lookup("mpu"); + struct omap_hwmod *dh = omap_hwmod_lookup("iva"); + struct device *dev; - mpu_dev = omap2_get_mpuss_device(); - iva_dev = omap2_get_iva_device(); - - if (!mpu_dev || !iva_dev) { + if (!mh || !dh) { pr_err("%s: Aiee.. no mpu/dsp devices? %p %p\n", - __func__, mpu_dev, iva_dev); + __func__, mh, dh); return; } /* Enable MPU 1GHz and lower opps */ - r = opp_enable(mpu_dev, 800000000); + dev = &mh->od->pdev.dev; + r = opp_enable(dev, 800000000); /* TODO: MPU 1GHz needs SR and ABB */ /* Enable IVA 800MHz and lower opps */ - r |= opp_enable(iva_dev, 660000000); + dev = &dh->od->pdev.dev; + r |= opp_enable(dev, 660000000); /* TODO: DSP 800MHz needs SR and ABB */ if (r) { pr_err("%s: failed to enable higher opp %d\n", @@ -515,8 +516,10 @@ static void __init beagle_opp_init(void) * Cleanup - disable the higher freqs - we dont care * about the results */ - opp_disable(mpu_dev, 800000000); - opp_disable(iva_dev, 660000000); + dev = &mh->od->pdev.dev; + opp_disable(dev, 800000000); + dev = &dh->od->pdev.dev; + opp_disable(dev, 660000000); } } return; diff --git a/trunk/arch/arm/mach-omap2/cminst44xx.h b/trunk/arch/arm/mach-omap2/cminst44xx.h index a018a7327879..f2ea6453ade0 100644 --- a/trunk/arch/arm/mach-omap2/cminst44xx.h +++ b/trunk/arch/arm/mach-omap2/cminst44xx.h @@ -18,36 +18,13 @@ extern void omap4_cminst_clkdm_force_sleep(u8 part, s16 inst, u16 cdoffs); extern void omap4_cminst_clkdm_force_wakeup(u8 part, s16 inst, u16 cdoffs); extern int omap4_cminst_wait_module_ready(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); - -# ifdef CONFIG_ARCH_OMAP4 -extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs); +extern int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); extern void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); extern void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, u16 clkctrl_offs); -# else - -static inline int omap4_cminst_wait_module_idle(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ - return 0; -} - -static inline void omap4_cminst_module_enable(u8 mode, u8 part, u16 inst, - s16 cdoffs, u16 clkctrl_offs) -{ -} - -static inline void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs, - u16 clkctrl_offs) -{ -} - -# endif - /* * In an ideal world, we would not export these low-level functions, * but this will probably take some time to fix properly diff --git a/trunk/arch/arm/mach-omap2/mux.c b/trunk/arch/arm/mach-omap2/mux.c index 655e9480eb98..c7fb22abc219 100644 --- a/trunk/arch/arm/mach-omap2/mux.c +++ b/trunk/arch/arm/mach-omap2/mux.c @@ -821,10 +821,11 @@ static void __init omap_mux_set_cmdline_signals(void) if (!omap_mux_options) return; - options = kstrdup(omap_mux_options, GFP_KERNEL); + options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL); if (!options) return; + strcpy(options, omap_mux_options); next_opt = options; while ((token = strsep(&next_opt, ",")) != NULL) { @@ -854,19 +855,24 @@ static int __init omap_mux_copy_names(struct omap_mux *src, for (i = 0; i < OMAP_MUX_NR_MODES; i++) { if (src->muxnames[i]) { - dst->muxnames[i] = kstrdup(src->muxnames[i], - GFP_KERNEL); + dst->muxnames[i] = + kmalloc(strlen(src->muxnames[i]) + 1, + GFP_KERNEL); if (!dst->muxnames[i]) goto free; + strcpy(dst->muxnames[i], src->muxnames[i]); } } #ifdef CONFIG_DEBUG_FS for (i = 0; i < OMAP_MUX_NR_SIDES; i++) { if (src->balls[i]) { - dst->balls[i] = kstrdup(src->balls[i], GFP_KERNEL); + dst->balls[i] = + kmalloc(strlen(src->balls[i]) + 1, + GFP_KERNEL); if (!dst->balls[i]) goto free; + strcpy(dst->balls[i], src->balls[i]); } } #endif diff --git a/trunk/arch/arm/mach-omap2/smartreflex.c b/trunk/arch/arm/mach-omap2/smartreflex.c index 34c01a7de810..2ce2fb7664bc 100644 --- a/trunk/arch/arm/mach-omap2/smartreflex.c +++ b/trunk/arch/arm/mach-omap2/smartreflex.c @@ -621,7 +621,7 @@ void sr_disable(struct voltagedomain *voltdm) sr_v2_disable(sr); } - pm_runtime_put_sync_suspend(&sr->pdev->dev); + pm_runtime_put_sync(&sr->pdev->dev); } /** @@ -860,7 +860,6 @@ static int __init omap_sr_probe(struct platform_device *pdev) irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); pm_runtime_enable(&pdev->dev); - pm_runtime_irq_safe(&pdev->dev); sr_info->pdev = pdev; sr_info->srid = pdev->id; diff --git a/trunk/arch/arm/mach-omap2/timer.c b/trunk/arch/arm/mach-omap2/timer.c index cf1de7d2630d..e9640728239b 100644 --- a/trunk/arch/arm/mach-omap2/timer.c +++ b/trunk/arch/arm/mach-omap2/timer.c @@ -293,8 +293,7 @@ static void __init omap2_gp_clocksource_init(int gptimer_id, pr_info("OMAP clocksource: GPTIMER%d at %lu Hz\n", gptimer_id, clksrc.rate); - __omap_dm_timer_load_start(clksrc.io_base, - OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1); + __omap_dm_timer_load_start(clksrc.io_base, OMAP_TIMER_CTRL_ST, 0, 1); init_sched_clock(&cd, dmtimer_update_sched_clock, 32, clksrc.rate); if (clocksource_register_hz(&clocksource_gpt, clksrc.rate)) diff --git a/trunk/arch/arm/mach-omap2/twl-common.c b/trunk/arch/arm/mach-omap2/twl-common.c index daa056ed8738..2543342dbccb 100644 --- a/trunk/arch/arm/mach-omap2/twl-common.c +++ b/trunk/arch/arm/mach-omap2/twl-common.c @@ -48,7 +48,14 @@ void __init omap_pmic_init(int bus, u32 clkrate, omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1); } -#if defined(CONFIG_ARCH_OMAP3) +static struct twl4030_usb_data omap4_usb_pdata = { + .phy_init = omap4430_phy_init, + .phy_exit = omap4430_phy_exit, + .phy_power = omap4430_phy_power, + .phy_set_clock = omap4430_phy_set_clk, + .phy_suspend = omap4430_phy_suspend, +}; + static struct twl4030_usb_data omap3_usb_pdata = { .usb_mode = T2_USB_MODE_ULPI, }; @@ -115,45 +122,6 @@ static struct regulator_init_data omap3_vpll2_idata = { .consumer_supplies = omap3_vpll2_supplies, }; -void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, - u32 pdata_flags, u32 regulators_flags) -{ - if (!pmic_data->irq_base) - pmic_data->irq_base = TWL4030_IRQ_BASE; - if (!pmic_data->irq_end) - pmic_data->irq_end = TWL4030_IRQ_END; - - /* Common platform data configurations */ - if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) - pmic_data->usb = &omap3_usb_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci) - pmic_data->bci = &omap3_bci_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) - pmic_data->madc = &omap3_madc_pdata; - - if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio) - pmic_data->audio = &omap3_audio_pdata; - - /* Common regulator configurations */ - if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) - pmic_data->vdac = &omap3_vdac_idata; - - if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2) - pmic_data->vpll2 = &omap3_vpll2_idata; -} -#endif /* CONFIG_ARCH_OMAP3 */ - -#if defined(CONFIG_ARCH_OMAP4) -static struct twl4030_usb_data omap4_usb_pdata = { - .phy_init = omap4430_phy_init, - .phy_exit = omap4430_phy_exit, - .phy_power = omap4430_phy_power, - .phy_set_clock = omap4430_phy_set_clk, - .phy_suspend = omap4430_phy_suspend, -}; - static struct regulator_init_data omap4_vdac_idata = { .constraints = { .min_uV = 1800000, @@ -305,4 +273,32 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, !pmic_data->clk32kg) pmic_data->clk32kg = &omap4_clk32kg_idata; } -#endif /* CONFIG_ARCH_OMAP4 */ + +void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, + u32 pdata_flags, u32 regulators_flags) +{ + if (!pmic_data->irq_base) + pmic_data->irq_base = TWL4030_IRQ_BASE; + if (!pmic_data->irq_end) + pmic_data->irq_end = TWL4030_IRQ_END; + + /* Common platform data configurations */ + if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) + pmic_data->usb = &omap3_usb_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_BCI && !pmic_data->bci) + pmic_data->bci = &omap3_bci_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_MADC && !pmic_data->madc) + pmic_data->madc = &omap3_madc_pdata; + + if (pdata_flags & TWL_COMMON_PDATA_AUDIO && !pmic_data->audio) + pmic_data->audio = &omap3_audio_pdata; + + /* Common regulator configurations */ + if (regulators_flags & TWL_COMMON_REGULATOR_VDAC && !pmic_data->vdac) + pmic_data->vdac = &omap3_vdac_idata; + + if (regulators_flags & TWL_COMMON_REGULATOR_VPLL2 && !pmic_data->vpll2) + pmic_data->vpll2 = &omap3_vpll2_idata; +} diff --git a/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c b/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c index af0c2fe1ea37..9026249233ad 100644 --- a/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c +++ b/trunk/arch/arm/mach-s3c64xx/mach-crag6410.c @@ -65,7 +65,7 @@ #include #include -#include +#include #include #include @@ -614,7 +614,7 @@ static struct wm831x_pdata glenfarclas_pmic_pdata __initdata = { .disable_touch = true, }; -static struct wm8996_retune_mobile_config wm8996_retune[] = { +static struct wm8915_retune_mobile_config wm8915_retune[] = { { .name = "Sub LPF", .rate = 48000, @@ -635,12 +635,12 @@ static struct wm8996_retune_mobile_config wm8996_retune[] = { }, }; -static struct wm8996_pdata wm8996_pdata __initdata = { +static struct wm8915_pdata wm8915_pdata __initdata = { .ldo_ena = S3C64XX_GPN(7), .gpio_base = CODEC_GPIO_BASE, .micdet_def = 1, - .inl_mode = WM8996_DIFFERRENTIAL_1, - .inr_mode = WM8996_DIFFERRENTIAL_1, + .inl_mode = WM8915_DIFFERRENTIAL_1, + .inr_mode = WM8915_DIFFERRENTIAL_1, .irq_flags = IRQF_TRIGGER_RISING, @@ -652,8 +652,8 @@ static struct wm8996_pdata wm8996_pdata __initdata = { 0x020e, /* GPIO5 == CLKOUT */ }, - .retune_mobile_cfgs = wm8996_retune, - .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune), + .retune_mobile_cfgs = wm8915_retune, + .num_retune_mobile_cfgs = ARRAY_SIZE(wm8915_retune), }; static struct wm8962_pdata wm8962_pdata __initdata = { @@ -679,8 +679,8 @@ static struct i2c_board_info i2c_devs1[] __initdata = { .platform_data = &glenfarclas_pmic_pdata }, { I2C_BOARD_INFO("wm1250-ev1", 0x27) }, - { I2C_BOARD_INFO("wm8996", 0x1a), - .platform_data = &wm8996_pdata, + { I2C_BOARD_INFO("wm8915", 0x1a), + .platform_data = &wm8915_pdata, .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2, }, { I2C_BOARD_INFO("wm9081", 0x6c), diff --git a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c index dd39fee59549..964c6c3cd7a6 100644 --- a/trunk/arch/arm/mach-sa1100/pci-nanoengine.c +++ b/trunk/arch/arm/mach-sa1100/pci-nanoengine.c @@ -28,7 +28,6 @@ #include #include -#include static DEFINE_SPINLOCK(nano_lock); diff --git a/trunk/arch/arm/mm/alignment.c b/trunk/arch/arm/mm/alignment.c index cfbcf8b95599..be7c638b648b 100644 --- a/trunk/arch/arm/mm/alignment.c +++ b/trunk/arch/arm/mm/alignment.c @@ -22,7 +22,6 @@ #include #include -#include #include #include "fault.h" @@ -96,33 +95,6 @@ static const char *usermode_action[] = { "signal+warn" }; -/* Return true if and only if the ARMv6 unaligned access model is in use. */ -static bool cpu_is_v6_unaligned(void) -{ - return cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U); -} - -static int safe_usermode(int new_usermode, bool warn) -{ - /* - * ARMv6 and later CPUs can perform unaligned accesses for - * most single load and store instructions up to word size. - * LDM, STM, LDRD and STRD still need to be handled. - * - * Ignoring the alignment fault is not an option on these - * CPUs since we spin re-faulting the instruction without - * making any progress. - */ - if (cpu_is_v6_unaligned() && !(new_usermode & (UM_FIXUP | UM_SIGNAL))) { - new_usermode |= UM_FIXUP; - - if (warn) - printk(KERN_WARNING "alignment: ignoring faults is unsafe on this CPU. Defaulting to fixup mode.\n"); - } - - return new_usermode; -} - static int alignment_proc_show(struct seq_file *m, void *v) { seq_printf(m, "User:\t\t%lu\n", ai_user); @@ -153,7 +125,7 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer if (get_user(mode, buffer)) return -EFAULT; if (mode >= '0' && mode <= '5') - ai_usermode = safe_usermode(mode - '0', true); + ai_usermode = mode - '0'; } return count; } @@ -914,16 +886,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) if (ai_usermode & UM_FIXUP) goto fixup; - if (ai_usermode & UM_SIGNAL) { - siginfo_t si; - - si.si_signo = SIGBUS; - si.si_errno = 0; - si.si_code = BUS_ADRALN; - si.si_addr = (void __user *)addr; - - force_sig_info(si.si_signo, &si, current); - } else { + if (ai_usermode & UM_SIGNAL) + force_sig(SIGBUS, current); + else { /* * We're about to disable the alignment trap and return to * user space. But if an interrupt occurs before actually @@ -961,11 +926,20 @@ static int __init alignment_init(void) return -ENOMEM; #endif - if (cpu_is_v6_unaligned()) { + /* + * ARMv6 and later CPUs can perform unaligned accesses for + * most single load and store instructions up to word size. + * LDM, STM, LDRD and STRD still need to be handled. + * + * Ignoring the alignment fault is not an option on these + * CPUs since we spin re-faulting the instruction without + * making any progress. + */ + if (cpu_architecture() >= CPU_ARCH_ARMv6 && (cr_alignment & CR_U)) { cr_alignment &= ~CR_A; cr_no_alignment &= ~CR_A; set_cr(cr_alignment); - ai_usermode = safe_usermode(ai_usermode, false); + ai_usermode = UM_FIXUP; } hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN, diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 91bca355cd31..2fee782077c1 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -441,7 +441,7 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) static inline void poison_init_mem(void *s, size_t count) { u32 *p = (u32 *)s; - for (; count != 0; count -= 4) + while ((count = count - 4)) *p++ = 0xe7fddef0; } diff --git a/trunk/arch/arm/mm/proc-arm946.S b/trunk/arch/arm/mm/proc-arm946.S index 683af3a182b7..f8f7ea34bfc5 100644 --- a/trunk/arch/arm/mm/proc-arm946.S +++ b/trunk/arch/arm/mm/proc-arm946.S @@ -410,7 +410,6 @@ __arm946_proc_info: .long 0x41009460 .long 0xff00fff0 .long 0 - .long 0 b __arm946_setup .long cpu_arch_name .long cpu_elf_name @@ -419,6 +418,6 @@ __arm946_proc_info: .long arm946_processor_functions .long 0 .long 0 - .long arm946_cache_fns + .long arm940_cache_fns .size __arm946_proc_info, . - __arm946_proc_info diff --git a/trunk/arch/arm/plat-mxc/include/mach/debug-macro.S b/trunk/arch/arm/plat-mxc/include/mach/debug-macro.S index e4dde91f0231..91fc7cdb5dc9 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/trunk/arch/arm/plat-mxc/include/mach/debug-macro.S @@ -44,14 +44,6 @@ #define UART_PADDR MX51_UART1_BASE_ADDR #endif -/* iMX50/53 have same addresses, but not iMX51 */ -#if defined(CONFIG_SOC_IMX50) || defined(CONFIG_SOC_IMX53) -#ifdef UART_PADDR -#error "CONFIG_DEBUG_LL is incompatible with multiple archs" -#endif -#define UART_PADDR MX53_UART1_BASE_ADDR -#endif - #define UART_VADDR IMX_IO_ADDRESS(UART_PADDR) .macro addruart, rp, rv diff --git a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h index 5408fd1fc736..9440b9e00e89 100644 --- a/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h +++ b/trunk/arch/arm/plat-mxc/include/mach/iomux-mx53.h @@ -30,9 +30,6 @@ #define MX53_SDHC_PAD_CTRL (PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \ PAD_CTL_PUS_47K_UP | PAD_CTL_DSE_HIGH | \ PAD_CTL_SRE_FAST) -#define PAD_CTRL_I2C (PAD_CTL_SRE_FAST | PAD_CTL_ODE | PAD_CTL_PKE | \ - PAD_CTL_PUE | PAD_CTL_DSE_HIGH | PAD_CTL_PUS_100K_UP \ - | PAD_CTL_HYS) #define _MX53_PAD_GPIO_19__KPP_COL_5 IOMUX_PAD(0x348, 0x20, 0, 0x840, 0, 0) #define _MX53_PAD_GPIO_19__GPIO4_5 IOMUX_PAD(0x348, 0x20, 1, 0x0, 0, 0) @@ -1259,7 +1256,7 @@ #define MX53_PAD_KEY_COL3__GPIO4_12 (_MX53_PAD_KEY_COL3__GPIO4_12 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__USBOH3_H2_DP (_MX53_PAD_KEY_COL3__USBOH3_H2_DP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__SPDIF_IN1 (_MX53_PAD_KEY_COL3__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_KEY_COL3__I2C2_SCL (_MX53_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_KEY_COL3__I2C2_SCL (_MX53_PAD_KEY_COL3__I2C2_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__ECSPI1_SS3 (_MX53_PAD_KEY_COL3__ECSPI1_SS3 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__FEC_CRS (_MX53_PAD_KEY_COL3__FEC_CRS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK (_MX53_PAD_KEY_COL3__USBPHY1_SIECLOCK | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1267,7 +1264,7 @@ #define MX53_PAD_KEY_ROW3__GPIO4_13 (_MX53_PAD_KEY_ROW3__GPIO4_13 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__USBOH3_H2_DM (_MX53_PAD_KEY_ROW3__USBOH3_H2_DM | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK (_MX53_PAD_KEY_ROW3__CCM_ASRC_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_KEY_ROW3__I2C2_SDA (_MX53_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_KEY_ROW3__I2C2_SDA (_MX53_PAD_KEY_ROW3__I2C2_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__OSC32K_32K_OUT (_MX53_PAD_KEY_ROW3__OSC32K_32K_OUT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__CCM_PLL4_BYP (_MX53_PAD_KEY_ROW3__CCM_PLL4_BYP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 (_MX53_PAD_KEY_ROW3__USBPHY1_LINESTATE_0 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1539,7 +1536,7 @@ #define MX53_PAD_CSI0_DAT8__KPP_COL_7 (_MX53_PAD_CSI0_DAT8__KPP_COL_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__ECSPI2_SCLK (_MX53_PAD_CSI0_DAT8__ECSPI2_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC (_MX53_PAD_CSI0_DAT8__USBOH3_USBH3_OC | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_CSI0_DAT8__I2C1_SDA (_MX53_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_CSI0_DAT8__I2C1_SDA (_MX53_PAD_CSI0_DAT8__I2C1_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 (_MX53_PAD_CSI0_DAT8__EMI_EMI_DEBUG_37 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 (_MX53_PAD_CSI0_DAT8__TPIU_TRACE_5 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 (_MX53_PAD_CSI0_DAT9__IPU_CSI0_D_9 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1547,7 +1544,7 @@ #define MX53_PAD_CSI0_DAT9__KPP_ROW_7 (_MX53_PAD_CSI0_DAT9__KPP_ROW_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__ECSPI2_MOSI (_MX53_PAD_CSI0_DAT9__ECSPI2_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR (_MX53_PAD_CSI0_DAT9__USBOH3_USBH3_PWR | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_CSI0_DAT9__I2C1_SCL (_MX53_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_CSI0_DAT9__I2C1_SCL (_MX53_PAD_CSI0_DAT9__I2C1_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 (_MX53_PAD_CSI0_DAT9__EMI_EMI_DEBUG_38 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 (_MX53_PAD_CSI0_DAT9__TPIU_TRACE_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 (_MX53_PAD_CSI0_DAT10__IPU_CSI0_D_10 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1634,25 +1631,25 @@ #define MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK (_MX53_PAD_EIM_EB2__CCM_DI1_EXT_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS (_MX53_PAD_EIM_EB2__IPU_SER_DISP1_CS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_EB2__ECSPI1_SS0 (_MX53_PAD_EIM_EB2__ECSPI1_SS0 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_EB2__I2C2_SCL (_MX53_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_EB2__I2C2_SCL (_MX53_PAD_EIM_EB2__I2C2_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__EMI_WEIM_D_16 (_MX53_PAD_EIM_D16__EMI_WEIM_D_16 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__GPIO3_16 (_MX53_PAD_EIM_D16__GPIO3_16 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__IPU_DI0_PIN5 (_MX53_PAD_EIM_D16__IPU_DI0_PIN5 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK (_MX53_PAD_EIM_D16__IPU_DISPB1_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D16__ECSPI1_SCLK (_MX53_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D16__I2C2_SDA (_MX53_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_D16__I2C2_SDA (_MX53_PAD_EIM_D16__I2C2_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__EMI_WEIM_D_17 (_MX53_PAD_EIM_D17__EMI_WEIM_D_17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__GPIO3_17 (_MX53_PAD_EIM_D17__GPIO3_17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__IPU_DI0_PIN6 (_MX53_PAD_EIM_D17__IPU_DI0_PIN6 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN (_MX53_PAD_EIM_D17__IPU_DISPB1_SER_DIN | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D17__ECSPI1_MISO (_MX53_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D17__I2C3_SCL (_MX53_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_D17__I2C3_SCL (_MX53_PAD_EIM_D17__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__EMI_WEIM_D_18 (_MX53_PAD_EIM_D18__EMI_WEIM_D_18 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__GPIO3_18 (_MX53_PAD_EIM_D18__GPIO3_18 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__IPU_DI0_PIN7 (_MX53_PAD_EIM_D18__IPU_DI0_PIN7 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO (_MX53_PAD_EIM_D18__IPU_DISPB1_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__ECSPI1_MOSI (_MX53_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D18__I2C3_SDA (_MX53_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_D18__I2C3_SDA (_MX53_PAD_EIM_D18__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D18__IPU_DI1_D0_CS (_MX53_PAD_EIM_D18__IPU_DI1_D0_CS | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D19__EMI_WEIM_D_19 (_MX53_PAD_EIM_D19__EMI_WEIM_D_19 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D19__GPIO3_19 (_MX53_PAD_EIM_D19__GPIO3_19 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1675,7 +1672,7 @@ #define MX53_PAD_EIM_D21__IPU_DI0_PIN17 (_MX53_PAD_EIM_D21__IPU_DI0_PIN17 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK (_MX53_PAD_EIM_D21__IPU_DISPB0_SER_CLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D21__CSPI_SCLK (_MX53_PAD_EIM_D21__CSPI_SCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D21__I2C1_SCL (_MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_D21__I2C1_SCL (_MX53_PAD_EIM_D21__I2C1_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D21__USBOH3_USBOTG_OC (_MX53_PAD_EIM_D21__USBOH3_USBOTG_OC | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D22__EMI_WEIM_D_22 (_MX53_PAD_EIM_D22__EMI_WEIM_D_22 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D22__GPIO3_22 (_MX53_PAD_EIM_D22__GPIO3_22 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -1735,7 +1732,7 @@ #define MX53_PAD_EIM_D28__UART2_CTS (_MX53_PAD_EIM_D28__UART2_CTS | MUX_PAD_CTRL(MX53_UART_PAD_CTRL)) #define MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO (_MX53_PAD_EIM_D28__IPU_DISPB0_SER_DIO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D28__CSPI_MOSI (_MX53_PAD_EIM_D28__CSPI_MOSI | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_EIM_D28__I2C1_SDA (_MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_EIM_D28__I2C1_SDA (_MX53_PAD_EIM_D28__I2C1_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D28__IPU_EXT_TRIG (_MX53_PAD_EIM_D28__IPU_EXT_TRIG | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D28__IPU_DI0_PIN13 (_MX53_PAD_EIM_D28__IPU_DI0_PIN13 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_EIM_D29__EMI_WEIM_D_29 (_MX53_PAD_EIM_D29__EMI_WEIM_D_29 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2300,7 +2297,7 @@ #define MX53_PAD_GPIO_9__SCC_FAIL_STATE (_MX53_PAD_GPIO_9__SCC_FAIL_STATE | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__ESAI1_HCKR (_MX53_PAD_GPIO_3__ESAI1_HCKR | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__GPIO1_3 (_MX53_PAD_GPIO_3__GPIO1_3 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_3__I2C3_SCL (_MX53_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_GPIO_3__I2C3_SCL (_MX53_PAD_GPIO_3__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__DPLLIP1_TOG_EN (_MX53_PAD_GPIO_3__DPLLIP1_TOG_EN | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__CCM_CLKO2 (_MX53_PAD_GPIO_3__CCM_CLKO2 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 (_MX53_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2308,7 +2305,7 @@ #define MX53_PAD_GPIO_3__MLB_MLBCLK (_MX53_PAD_GPIO_3__MLB_MLBCLK | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__ESAI1_SCKT (_MX53_PAD_GPIO_6__ESAI1_SCKT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__GPIO1_6 (_MX53_PAD_GPIO_6__GPIO1_6 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_6__I2C3_SDA (_MX53_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_GPIO_6__I2C3_SDA (_MX53_PAD_GPIO_6__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__CCM_CCM_OUT_0 (_MX53_PAD_GPIO_6__CCM_CCM_OUT_0 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__CSU_CSU_INT_DEB (_MX53_PAD_GPIO_6__CSU_CSU_INT_DEB | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 (_MX53_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2336,7 +2333,7 @@ #define MX53_PAD_GPIO_5__CCM_CLKO (_MX53_PAD_GPIO_5__CCM_CLKO | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 (_MX53_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 (_MX53_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_5__I2C3_SCL (_MX53_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_GPIO_5__I2C3_SCL (_MX53_PAD_GPIO_5__I2C3_SCL | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_5__CCM_PLL1_BYP (_MX53_PAD_GPIO_5__CCM_PLL1_BYP | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_7__ESAI1_TX4_RX1 (_MX53_PAD_GPIO_7__ESAI1_TX4_RX1 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_7__GPIO1_7 (_MX53_PAD_GPIO_7__GPIO1_7 | MUX_PAD_CTRL(NO_PAD_CTRL)) @@ -2359,7 +2356,7 @@ #define MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT (_MX53_PAD_GPIO_16__TZIC_PWRFAIL_INT | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 (_MX53_PAD_GPIO_16__RTC_CE_RTC_EXT_TRIG1 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_16__SPDIF_IN1 (_MX53_PAD_GPIO_16__SPDIF_IN1 | MUX_PAD_CTRL(NO_PAD_CTRL)) -#define MX53_PAD_GPIO_16__I2C3_SDA (_MX53_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(PAD_CTRL_I2C)) +#define MX53_PAD_GPIO_16__I2C3_SDA (_MX53_PAD_GPIO_16__I2C3_SDA | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_16__SJC_DE_B (_MX53_PAD_GPIO_16__SJC_DE_B | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_17__ESAI1_TX0 (_MX53_PAD_GPIO_17__ESAI1_TX0 | MUX_PAD_CTRL(NO_PAD_CTRL)) #define MX53_PAD_GPIO_17__GPIO7_12 (_MX53_PAD_GPIO_17__GPIO7_12 | MUX_PAD_CTRL(NO_PAD_CTRL)) diff --git a/trunk/arch/arm/plat-omap/Kconfig b/trunk/arch/arm/plat-omap/Kconfig index bb8f4a6b3e37..6e6735f04ee3 100644 --- a/trunk/arch/arm/plat-omap/Kconfig +++ b/trunk/arch/arm/plat-omap/Kconfig @@ -13,7 +13,6 @@ config ARCH_OMAP1 bool "TI OMAP1" select CLKDEV_LOOKUP select CLKSRC_MMIO - select GENERIC_IRQ_CHIP help "Systems based on omap7xx, omap15xx or omap16xx" diff --git a/trunk/arch/arm/plat-omap/include/plat/dma.h b/trunk/arch/arm/plat-omap/include/plat/dma.h index dc562a5c0a8a..d1c916fcf770 100644 --- a/trunk/arch/arm/plat-omap/include/plat/dma.h +++ b/trunk/arch/arm/plat-omap/include/plat/dma.h @@ -195,11 +195,6 @@ #define OMAP36XX_DMA_UART4_TX 81 /* S_DMA_80 */ #define OMAP36XX_DMA_UART4_RX 82 /* S_DMA_81 */ - -/* Only for AM35xx */ -#define AM35XX_DMA_UART4_TX 54 -#define AM35XX_DMA_UART4_RX 55 - /*----------------------------------------------------------------------------*/ #define OMAP1_DMA_TOUT_IRQ (1 << 0) diff --git a/trunk/arch/arm/plat-omap/include/plat/irqs.h b/trunk/arch/arm/plat-omap/include/plat/irqs.h index 30e10719b774..926d25c780f3 100644 --- a/trunk/arch/arm/plat-omap/include/plat/irqs.h +++ b/trunk/arch/arm/plat-omap/include/plat/irqs.h @@ -357,7 +357,6 @@ #define INT_35XX_EMAC_C0_TX_PULSE_IRQ 69 #define INT_35XX_EMAC_C0_MISC_PULSE_IRQ 70 #define INT_35XX_USBOTG_IRQ 71 -#define INT_35XX_UART4 84 #define INT_35XX_CCDC_VD0_IRQ 88 #define INT_35XX_CCDC_VD1_IRQ 92 #define INT_35XX_CCDC_VD2_IRQ 93 diff --git a/trunk/arch/arm/plat-omap/include/plat/serial.h b/trunk/arch/arm/plat-omap/include/plat/serial.h index de3b10c18127..2723f9166ea2 100644 --- a/trunk/arch/arm/plat-omap/include/plat/serial.h +++ b/trunk/arch/arm/plat-omap/include/plat/serial.h @@ -56,9 +56,6 @@ #define TI816X_UART2_BASE 0x48022000 #define TI816X_UART3_BASE 0x48024000 -/* AM3505/3517 UART4 */ -#define AM35XX_UART4_BASE 0x4809E000 /* Only on AM3505/3517 */ - /* External port on Zoom2/3 */ #define ZOOM_UART_BASE 0x10000000 #define ZOOM_UART_VIRT 0xfa400000 diff --git a/trunk/arch/arm/plat-omap/iovmm.c b/trunk/arch/arm/plat-omap/iovmm.c index 79e7fedb8602..c60737c49a32 100644 --- a/trunk/arch/arm/plat-omap/iovmm.c +++ b/trunk/arch/arm/plat-omap/iovmm.c @@ -423,6 +423,9 @@ static void sgtable_fill_kmalloc(struct sg_table *sgt, u32 pa, u32 da, { unsigned int i; struct scatterlist *sg; + void *va; + + va = phys_to_virt(pa); for_each_sg(sgt->sgl, sg, sgt->nents, i) { unsigned bytes; diff --git a/trunk/arch/arm/tools/mach-types b/trunk/arch/arm/tools/mach-types index fff68d0d521b..3b3776d0a1a7 100644 --- a/trunk/arch/arm/tools/mach-types +++ b/trunk/arch/arm/tools/mach-types @@ -910,7 +910,7 @@ omapl138_case_a3 MACH_OMAPL138_CASE_A3 OMAPL138_CASE_A3 3280 uemd MACH_UEMD UEMD 3281 ccwmx51mut MACH_CCWMX51MUT CCWMX51MUT 3282 rockhopper MACH_ROCKHOPPER ROCKHOPPER 3283 -encore MACH_ENCORE ENCORE 3284 +nookcolor MACH_NOOKCOLOR NOOKCOLOR 3284 hkdkc100 MACH_HKDKC100 HKDKC100 3285 ts42xx MACH_TS42XX TS42XX 3286 aebl MACH_AEBL AEBL 3287 diff --git a/trunk/arch/avr32/Kconfig b/trunk/arch/avr32/Kconfig index 197e96f70405..e9d689b7c833 100644 --- a/trunk/arch/avr32/Kconfig +++ b/trunk/arch/avr32/Kconfig @@ -10,7 +10,6 @@ config AVR32 select GENERIC_IRQ_PROBE select HARDIRQS_SW_RESEND select GENERIC_IRQ_SHOW - select ARCH_HAVE_NMI_SAFE_CMPXCHG help AVR32 is a high-performance 32-bit RISC microprocessor core, designed for cost-sensitive embedded applications, with particular diff --git a/trunk/arch/cris/arch-v10/drivers/sync_serial.c b/trunk/arch/cris/arch-v10/drivers/sync_serial.c index 466af40c5822..850265373611 100644 --- a/trunk/arch/cris/arch-v10/drivers/sync_serial.c +++ b/trunk/arch/cris/arch-v10/drivers/sync_serial.c @@ -158,7 +158,7 @@ static int sync_serial_open(struct inode *inode, struct file *file); static int sync_serial_release(struct inode *inode, struct file *file); static unsigned int sync_serial_poll(struct file *filp, poll_table *wait); -static long sync_serial_ioctl(struct file *file, +static int sync_serial_ioctl(struct file *file, unsigned int cmd, unsigned long arg); static ssize_t sync_serial_write(struct file *file, const char *buf, size_t count, loff_t *ppos); @@ -625,11 +625,11 @@ static int sync_serial_open(struct inode *inode, struct file *file) *R_IRQ_MASK1_SET = 1 << port->data_avail_bit; DEBUG(printk(KERN_DEBUG "sser%d rec started\n", dev)); } - err = 0; + ret = 0; out: mutex_unlock(&sync_serial_mutex); - return err; + return ret; } static int sync_serial_release(struct inode *inode, struct file *file) diff --git a/trunk/arch/cris/arch-v10/kernel/irq.c b/trunk/arch/cris/arch-v10/kernel/irq.c index ba0e5965d6e3..907cfb5a873d 100644 --- a/trunk/arch/cris/arch-v10/kernel/irq.c +++ b/trunk/arch/cris/arch-v10/kernel/irq.c @@ -20,9 +20,6 @@ #define crisv10_mask_irq(irq_nr) (*R_VECT_MASK_CLR = 1 << (irq_nr)); #define crisv10_unmask_irq(irq_nr) (*R_VECT_MASK_SET = 1 << (irq_nr)); -extern void kgdb_init(void); -extern void breakpoint(void); - /* don't use set_int_vector, it bypasses the linux interrupt handlers. it is * global just so that the kernel gdb can use it. */ diff --git a/trunk/arch/cris/include/asm/thread_info.h b/trunk/arch/cris/include/asm/thread_info.h index 332f19c54557..29b74a105830 100644 --- a/trunk/arch/cris/include/asm/thread_info.h +++ b/trunk/arch/cris/include/asm/thread_info.h @@ -11,6 +11,8 @@ #ifdef __KERNEL__ +#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR + #ifndef __ASSEMBLY__ #include #include @@ -65,10 +67,8 @@ struct thread_info { #define init_thread_info (init_thread_union.thread_info) -#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR /* thread information allocation */ -#define alloc_thread_info_node(tsk, node) \ - ((struct thread_info *) __get_free_pages(GFP_KERNEL, 1)) +#define alloc_thread_info(tsk, node) ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) #define free_thread_info(ti) free_pages((unsigned long) (ti), 1) #endif /* !__ASSEMBLY__ */ diff --git a/trunk/arch/frv/Kconfig b/trunk/arch/frv/Kconfig index bad27a6ff407..cb884e489425 100644 --- a/trunk/arch/frv/Kconfig +++ b/trunk/arch/frv/Kconfig @@ -7,7 +7,6 @@ config FRV select HAVE_PERF_EVENTS select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_SHOW - select ARCH_HAVE_NMI_SAFE_CMPXCHG config ZONE_DMA bool diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index 124854714958..64c7ab7e7a81 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -28,7 +28,6 @@ config IA64 select IRQ_PER_CPU select GENERIC_IRQ_SHOW select ARCH_WANT_OPTIONAL_GPIOLIB - select ARCH_HAVE_NMI_SAFE_CMPXCHG default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/trunk/arch/ia64/kernel/efi.c b/trunk/arch/ia64/kernel/efi.c index c38d22e5e902..6fc03aff046c 100644 --- a/trunk/arch/ia64/kernel/efi.c +++ b/trunk/arch/ia64/kernel/efi.c @@ -156,7 +156,7 @@ prefix##_get_next_variable (unsigned long *name_size, efi_char16_t *name, \ #define STUB_SET_VARIABLE(prefix, adjust_arg) \ static efi_status_t \ prefix##_set_variable (efi_char16_t *name, efi_guid_t *vendor, \ - u32 attr, unsigned long data_size, \ + unsigned long attr, unsigned long data_size, \ void *data) \ { \ struct ia64_fpreg fr[6]; \ diff --git a/trunk/arch/m68k/Kconfig b/trunk/arch/m68k/Kconfig index 9e8ee9d2b8ca..284cd3771eaa 100644 --- a/trunk/arch/m68k/Kconfig +++ b/trunk/arch/m68k/Kconfig @@ -6,7 +6,6 @@ config M68K select GENERIC_ATOMIC64 if MMU select HAVE_GENERIC_HARDIRQS if !MMU select GENERIC_IRQ_SHOW if !MMU - select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS config RWSEM_GENERIC_SPINLOCK bool diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index e077b0bf56ca..65adc86a230e 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -15,7 +15,6 @@ config PARISC select HAVE_GENERIC_HARDIRQS select GENERIC_IRQ_PROBE select IRQ_PER_CPU - select ARCH_HAVE_NMI_SAFE_CMPXCHG help The PA-RISC microprocessor is designed by Hewlett-Packard and used diff --git a/trunk/arch/parisc/include/asm/atomic.h b/trunk/arch/parisc/include/asm/atomic.h index 4054b31e0fa9..b1dc71f5534e 100644 --- a/trunk/arch/parisc/include/asm/atomic.h +++ b/trunk/arch/parisc/include/asm/atomic.h @@ -258,10 +258,10 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) #define ATOMIC64_INIT(i) ((atomic64_t) { (i) }) -static __inline__ s64 +static __inline__ int __atomic64_add_return(s64 i, atomic64_t *v) { - s64 ret; + int ret; unsigned long flags; _atomic_spin_lock_irqsave(v, flags); diff --git a/trunk/arch/parisc/include/asm/futex.h b/trunk/arch/parisc/include/asm/futex.h index 2388bdb32832..67a33cc27ef2 100644 --- a/trunk/arch/parisc/include/asm/futex.h +++ b/trunk/arch/parisc/include/asm/futex.h @@ -5,14 +5,11 @@ #include #include -#include #include static inline int futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) { - unsigned long int flags; - u32 val; int op = (encoded_op >> 28) & 7; int cmp = (encoded_op >> 24) & 15; int oparg = (encoded_op << 8) >> 20; @@ -21,58 +18,21 @@ futex_atomic_op_inuser (int encoded_op, u32 __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - if (!access_ok(VERIFY_WRITE, uaddr, sizeof(*uaddr))) + if (! access_ok (VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; pagefault_disable(); - _atomic_spin_lock_irqsave(uaddr, flags); - switch (op) { case FUTEX_OP_SET: - /* *(int *)UADDR2 = OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) - ret = put_user(oparg, uaddr); - break; case FUTEX_OP_ADD: - /* *(int *)UADDR2 += OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval + oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_OR: - /* *(int *)UADDR2 |= OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval | oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_ANDN: - /* *(int *)UADDR2 &= ~OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval & ~oparg; - ret = put_user(val, uaddr); - } - break; case FUTEX_OP_XOR: - /* *(int *)UADDR2 ^= OPARG; */ - ret = get_user(oldval, uaddr); - if (!ret) { - val = oldval ^ oparg; - ret = put_user(val, uaddr); - } - break; default: ret = -ENOSYS; } - _atomic_spin_unlock_irqrestore(uaddr, flags); - pagefault_enable(); if (!ret) { @@ -94,9 +54,7 @@ static inline int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval) { - int ret; u32 val; - unsigned long flags; /* futex.c wants to do a cmpxchg_inatomic on kernel NULL, which is * our gateway page, and causes no end of trouble... @@ -107,24 +65,12 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) return -EFAULT; - /* HPPA has no cmpxchg in hardware and therefore the - * best we can do here is use an array of locks. The - * lock selected is based on a hash of the userspace - * address. This should scale to a couple of CPUs. - */ - - _atomic_spin_lock_irqsave(uaddr, flags); - - ret = get_user(val, uaddr); - - if (!ret && val == oldval) - ret = put_user(newval, uaddr); - + if (get_user(val, uaddr)) + return -EFAULT; + if (val == oldval && put_user(newval, uaddr)) + return -EFAULT; *uval = val; - - _atomic_spin_unlock_irqrestore(uaddr, flags); - - return ret; + return 0; } #endif /*__KERNEL__*/ diff --git a/trunk/arch/parisc/include/asm/unistd.h b/trunk/arch/parisc/include/asm/unistd.h index d61de64f990a..3392de3e7be0 100644 --- a/trunk/arch/parisc/include/asm/unistd.h +++ b/trunk/arch/parisc/include/asm/unistd.h @@ -821,9 +821,8 @@ #define __NR_open_by_handle_at (__NR_Linux + 326) #define __NR_syncfs (__NR_Linux + 327) #define __NR_setns (__NR_Linux + 328) -#define __NR_sendmmsg (__NR_Linux + 329) -#define __NR_Linux_syscalls (__NR_sendmmsg + 1) +#define __NR_Linux_syscalls (__NR_setns + 1) #define __IGNORE_select /* newselect */ diff --git a/trunk/arch/parisc/kernel/syscall_table.S b/trunk/arch/parisc/kernel/syscall_table.S index e66366fd2abc..34a4f5a2fffb 100644 --- a/trunk/arch/parisc/kernel/syscall_table.S +++ b/trunk/arch/parisc/kernel/syscall_table.S @@ -427,7 +427,6 @@ ENTRY_COMP(open_by_handle_at) ENTRY_SAME(syncfs) ENTRY_SAME(setns) - ENTRY_COMP(sendmmsg) /* Nothing yet */ diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index 6926b61acfea..374c475e56a3 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -136,7 +136,6 @@ config PPC select HAVE_SYSCALL_TRACEPOINTS select HAVE_BPF_JIT if (PPC64 && NET) select HAVE_ARCH_JUMP_LABEL - select ARCH_HAVE_NMI_SAFE_CMPXCHG config EARLY_PRINTK bool diff --git a/trunk/arch/powerpc/include/asm/jump_label.h b/trunk/arch/powerpc/include/asm/jump_label.h index 938986e412f1..1f780b95c0f0 100644 --- a/trunk/arch/powerpc/include/asm/jump_label.h +++ b/trunk/arch/powerpc/include/asm/jump_label.h @@ -22,6 +22,7 @@ static __always_inline bool arch_static_branch(struct jump_label_key *key) asm goto("1:\n\t" "nop\n\t" ".pushsection __jump_table, \"aw\"\n\t" + ".align 4\n\t" JUMP_ENTRY_TYPE "1b, %l[l_yes], %c0\n\t" ".popsection \n\t" : : "i" (key) : : l_yes); @@ -40,6 +41,7 @@ struct jump_entry { jump_label_t code; jump_label_t target; jump_label_t key; + jump_label_t pad; }; #endif /* _ASM_POWERPC_JUMP_LABEL_H */ diff --git a/trunk/arch/powerpc/include/asm/kdump.h b/trunk/arch/powerpc/include/asm/kdump.h index bffd062adf79..6857af58b02e 100644 --- a/trunk/arch/powerpc/include/asm/kdump.h +++ b/trunk/arch/powerpc/include/asm/kdump.h @@ -3,7 +3,17 @@ #include +/* + * If CONFIG_RELOCATABLE is enabled we can place the kdump kernel anywhere. + * To keep enough space in the RMO for the first stage kernel on 64bit, we + * place it at 64MB. If CONFIG_RELOCATABLE is not enabled we must place + * the second stage at 32MB. + */ +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC64) +#define KDUMP_KERNELBASE 0x4000000 +#else #define KDUMP_KERNELBASE 0x2000000 +#endif /* How many bytes to reserve at zero for kdump. The reserve limit should * be greater or equal to the trampoline's end address. diff --git a/trunk/arch/powerpc/include/asm/reg.h b/trunk/arch/powerpc/include/asm/reg.h index 559da199edb5..e8aaf6fce38b 100644 --- a/trunk/arch/powerpc/include/asm/reg.h +++ b/trunk/arch/powerpc/include/asm/reg.h @@ -1003,6 +1003,7 @@ #define PV_970 0x0039 #define PV_POWER5 0x003A #define PV_POWER5p 0x003B +#define PV_POWER7 0x003F #define PV_970FX 0x003C #define PV_POWER6 0x003E #define PV_POWER7 0x003F @@ -1023,16 +1024,13 @@ #define mtmsrd(v) __mtmsrd((v), 0) #define mtmsr(v) mtmsrd(v) #else -#define mtmsr(v) asm volatile("mtmsr %0" : \ - : "r" ((unsigned long)(v)) \ - : "memory") +#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v) : "memory") #endif #define mfspr(rn) ({unsigned long rval; \ asm volatile("mfspr %0," __stringify(rn) \ : "=r" (rval)); rval;}) -#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : \ - : "r" ((unsigned long)(v)) \ +#define mtspr(rn, v) asm volatile("mtspr " __stringify(rn) ",%0" : : "r" (v)\ : "memory") #ifdef __powerpc64__ diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index fa44ff538861..9fb933248ab6 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -2051,8 +2051,7 @@ static struct cpu_spec __initdata cpu_specs[] = { static struct cpu_spec the_cpu_spec; -static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, - struct cpu_spec *s) +static void __init setup_cpu_spec(unsigned long offset, struct cpu_spec *s) { struct cpu_spec *t = &the_cpu_spec; struct cpu_spec old; @@ -2115,8 +2114,6 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, t->cpu_setup(offset, t); } #endif /* CONFIG_PPC64 || CONFIG_BOOKE */ - - return t; } struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) @@ -2127,8 +2124,10 @@ struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr) s = PTRRELOC(s); for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) { - if ((pvr & s->pvr_mask) == s->pvr_value) - return setup_cpu_spec(offset, s); + if ((pvr & s->pvr_mask) == s->pvr_value) { + setup_cpu_spec(offset, s); + return s; + } } BUG(); diff --git a/trunk/arch/powerpc/kernel/iomap.c b/trunk/arch/powerpc/kernel/iomap.c index b25f6325fc70..1577434f4088 100644 --- a/trunk/arch/powerpc/kernel/iomap.c +++ b/trunk/arch/powerpc/kernel/iomap.c @@ -117,7 +117,6 @@ void ioport_unmap(void __iomem *addr) EXPORT_SYMBOL(ioport_map); EXPORT_SYMBOL(ioport_unmap); -#ifdef CONFIG_PCI void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max) { resource_size_t start = pci_resource_start(dev, bar); @@ -147,4 +146,3 @@ void pci_iounmap(struct pci_dev *dev, void __iomem *addr) EXPORT_SYMBOL(pci_iomap); EXPORT_SYMBOL(pci_iounmap); -#endif /* CONFIG_PCI */ diff --git a/trunk/arch/powerpc/kernel/machine_kexec.c b/trunk/arch/powerpc/kernel/machine_kexec.c index 9ce1672afb59..6658a1589955 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec.c +++ b/trunk/arch/powerpc/kernel/machine_kexec.c @@ -136,16 +136,12 @@ void __init reserve_crashkernel(void) crashk_res.start = KDUMP_KERNELBASE; #else if (!crashk_res.start) { -#ifdef CONFIG_PPC64 /* - * On 64bit we split the RMO in half but cap it at half of - * a small SLB (128MB) since the crash kernel needs to place - * itself and some stacks to be in the first segment. + * unspecified address, choose a region of specified size + * can overlap with initrd (ignoring corruption when retained) + * ppc64 requires kernel and some stacks to be in first segemnt */ - crashk_res.start = min(0x80000000ULL, (ppc64_rma_size / 2)); -#else crashk_res.start = KDUMP_KERNELBASE; -#endif } crash_base = PAGE_ALIGN(crashk_res.start); diff --git a/trunk/arch/powerpc/kernel/perf_callchain.c b/trunk/arch/powerpc/kernel/perf_callchain.c index 564c1d8bdb5c..d05ae4204bbf 100644 --- a/trunk/arch/powerpc/kernel/perf_callchain.c +++ b/trunk/arch/powerpc/kernel/perf_callchain.c @@ -154,12 +154,8 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret) ((unsigned long)ptr & 7)) return -EFAULT; - pagefault_disable(); - if (!__get_user_inatomic(*ret, ptr)) { - pagefault_enable(); + if (!__get_user_inatomic(*ret, ptr)) return 0; - } - pagefault_enable(); return read_user_stack_slow(ptr, ret, 8); } @@ -170,12 +166,8 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) ((unsigned long)ptr & 3)) return -EFAULT; - pagefault_disable(); - if (!__get_user_inatomic(*ret, ptr)) { - pagefault_enable(); + if (!__get_user_inatomic(*ret, ptr)) return 0; - } - pagefault_enable(); return read_user_stack_slow(ptr, ret, 4); } @@ -302,17 +294,11 @@ static inline int current_is_64bit(void) */ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret) { - int rc; - if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) || ((unsigned long)ptr & 3)) return -EFAULT; - pagefault_disable(); - rc = __get_user_inatomic(*ret, ptr); - pagefault_enable(); - - return rc; + return __get_user_inatomic(*ret, ptr); } static inline void perf_callchain_user_64(struct perf_callchain_entry *entry, diff --git a/trunk/arch/powerpc/kernel/prom_init.c b/trunk/arch/powerpc/kernel/prom_init.c index a909f4e9343b..c016033ba78d 100644 --- a/trunk/arch/powerpc/kernel/prom_init.c +++ b/trunk/arch/powerpc/kernel/prom_init.c @@ -1020,7 +1020,7 @@ static unsigned long __init alloc_up(unsigned long size, unsigned long align) } if (addr == 0) return 0; - RELOC(alloc_bottom) = addr + size; + RELOC(alloc_bottom) = addr; prom_debug(" -> %x\n", addr); prom_debug(" alloc_bottom : %x\n", RELOC(alloc_bottom)); @@ -1830,13 +1830,11 @@ static void __init *make_room(unsigned long *mem_start, unsigned long *mem_end, if (room > DEVTREE_CHUNK_SIZE) room = DEVTREE_CHUNK_SIZE; if (room < PAGE_SIZE) - prom_panic("No memory for flatten_device_tree " - "(no room)\n"); + prom_panic("No memory for flatten_device_tree (no room)"); chunk = alloc_up(room, 0); if (chunk == 0) - prom_panic("No memory for flatten_device_tree " - "(claim failed)\n"); - *mem_end = chunk + room; + prom_panic("No memory for flatten_device_tree (claim failed)"); + *mem_end = RELOC(alloc_top); } ret = (void *)*mem_start; @@ -2044,7 +2042,7 @@ static void __init flatten_device_tree(void) /* * Check how much room we have between alloc top & bottom (+/- a - * few pages), crop to 1MB, as this is our "chunk" size + * few pages), crop to 4Mb, as this is our "chuck" size */ room = RELOC(alloc_top) - RELOC(alloc_bottom) - 0x4000; if (room > DEVTREE_CHUNK_SIZE) @@ -2055,7 +2053,7 @@ static void __init flatten_device_tree(void) mem_start = (unsigned long)alloc_up(room, PAGE_SIZE); if (mem_start == 0) prom_panic("Can't allocate initial device-tree chunk\n"); - mem_end = mem_start + room; + mem_end = RELOC(alloc_top); /* Get root of tree */ root = call_prom("peer", 1, 1, (phandle)0); diff --git a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S index de2950135e6e..6dd33581a228 100644 --- a/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S +++ b/trunk/arch/powerpc/kvm/book3s_hv_rmhandlers.S @@ -1251,7 +1251,7 @@ BEGIN_FTR_SECTION reg = 0 .rept 32 li r6,reg*16+VCPU_VSRS - STXVD2X(reg,r6,r3) + stxvd2x reg,r6,r3 reg = reg + 1 .endr FTR_SECTION_ELSE @@ -1313,7 +1313,7 @@ BEGIN_FTR_SECTION reg = 0 .rept 32 li r7,reg*16+VCPU_VSRS - LXVD2X(reg,r7,r4) + lxvd2x reg,r7,r4 reg = reg + 1 .endr FTR_SECTION_ELSE diff --git a/trunk/arch/powerpc/platforms/Kconfig b/trunk/arch/powerpc/platforms/Kconfig index b9ba86191aed..d0af7fb2f344 100644 --- a/trunk/arch/powerpc/platforms/Kconfig +++ b/trunk/arch/powerpc/platforms/Kconfig @@ -24,7 +24,7 @@ source "arch/powerpc/platforms/wsp/Kconfig" config KVM_GUEST bool "KVM Guest support" - default n + default y ---help--- This option enables various optimizations for running under the KVM hypervisor. Overhead for the kernel when not running inside KVM should diff --git a/trunk/arch/powerpc/platforms/pseries/dtl.c b/trunk/arch/powerpc/platforms/pseries/dtl.c index 0e8656370063..e9190073bb97 100644 --- a/trunk/arch/powerpc/platforms/pseries/dtl.c +++ b/trunk/arch/powerpc/platforms/pseries/dtl.c @@ -181,7 +181,7 @@ static void dtl_stop(struct dtl *dtl) lppaca_of(dtl->cpu).dtl_enable_mask = 0x0; - unregister_dtl(hwcpu); + unregister_dtl(hwcpu, __pa(dtl->buf)); } static u64 dtl_current_index(struct dtl *dtl) diff --git a/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c b/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c index 83a3ca2fd282..bc0288501f17 100644 --- a/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c +++ b/trunk/arch/powerpc/platforms/pseries/hotplug-cpu.c @@ -135,7 +135,7 @@ static void pseries_mach_cpu_die(void) get_lppaca()->idle = 0; if (get_preferred_offline_state(cpu) == CPU_STATE_ONLINE) { - unregister_slb_shadow(hwcpu); + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); /* * Call to start_secondary_resume() will not return. @@ -150,7 +150,7 @@ static void pseries_mach_cpu_die(void) WARN_ON(get_preferred_offline_state(cpu) != CPU_STATE_OFFLINE); set_cpu_current_state(cpu, CPU_STATE_OFFLINE); - unregister_slb_shadow(hwcpu); + unregister_slb_shadow(hwcpu, __pa(get_slb_shadow())); rtas_stop_self(); /* Should never get here... */ diff --git a/trunk/arch/powerpc/platforms/pseries/io_event_irq.c b/trunk/arch/powerpc/platforms/pseries/io_event_irq.c index 2c4dd1fb8333..c829e6067d54 100644 --- a/trunk/arch/powerpc/platforms/pseries/io_event_irq.c +++ b/trunk/arch/powerpc/platforms/pseries/io_event_irq.c @@ -212,15 +212,17 @@ static int __init ioei_init(void) struct device_node *np; ioei_check_exception_token = rtas_token("check-exception"); - if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) + if (ioei_check_exception_token == RTAS_UNKNOWN_SERVICE) { + pr_warning("IO Event IRQ not supported on this system !\n"); return -ENODEV; - + } np = of_find_node_by_path("/event-sources/ibm,io-events"); if (np) { request_event_sources_irqs(np, ioei_interrupt, "IO_EVENT"); - pr_info("IBM I/O event interrupts enabled\n"); of_node_put(np); } else { + pr_err("io_event_irq: No ibm,io-events on system! " + "IO Event interrupt disabled.\n"); return -ENODEV; } return 0; diff --git a/trunk/arch/powerpc/platforms/pseries/kexec.c b/trunk/arch/powerpc/platforms/pseries/kexec.c index 7d94bdc63d50..54cf3a4aa16b 100644 --- a/trunk/arch/powerpc/platforms/pseries/kexec.c +++ b/trunk/arch/powerpc/platforms/pseries/kexec.c @@ -25,30 +25,20 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary) { /* Don't risk a hypervisor call if we're crashing */ if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) { - int ret; - int cpu = smp_processor_id(); - int hwcpu = hard_smp_processor_id(); + unsigned long addr; - if (get_lppaca()->dtl_enable_mask) { - ret = unregister_dtl(hwcpu); - if (ret) { - pr_err("WARNING: DTL deregistration for cpu " - "%d (hw %d) failed with %d\n", - cpu, hwcpu, ret); - } - } - - ret = unregister_slb_shadow(hwcpu); - if (ret) { - pr_err("WARNING: SLB shadow buffer deregistration " - "for cpu %d (hw %d) failed with %d\n", - cpu, hwcpu, ret); - } + addr = __pa(get_slb_shadow()); + if (unregister_slb_shadow(hard_smp_processor_id(), addr)) + printk("SLB shadow buffer deregistration of " + "cpu %u (hw_cpu_id %d) failed\n", + smp_processor_id(), + hard_smp_processor_id()); - ret = unregister_vpa(hwcpu); - if (ret) { - pr_err("WARNING: VPA deregistration for cpu %d " - "(hw %d) failed with %d\n", cpu, hwcpu, ret); + addr = __pa(get_lppaca()); + if (unregister_vpa(hard_smp_processor_id(), addr)) { + printk("VPA deregistration of cpu %u (hw_cpu_id %d) " + "failed\n", smp_processor_id(), + hard_smp_processor_id()); } } } diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index c9a29dae8c05..f7205d344efd 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -67,8 +67,9 @@ void vpa_init(int cpu) ret = register_vpa(hwcpu, addr); if (ret) { - pr_err("WARNING: VPA registration for cpu %d (hw %d) of area " - "%lx failed with %ld\n", cpu, hwcpu, addr, ret); + printk(KERN_ERR "WARNING: vpa_init: VPA registration for " + "cpu %d (hw %d) of area %lx returns %ld\n", + cpu, hwcpu, addr, ret); return; } /* @@ -79,9 +80,10 @@ void vpa_init(int cpu) if (firmware_has_feature(FW_FEATURE_SPLPAR)) { ret = register_slb_shadow(hwcpu, addr); if (ret) - pr_err("WARNING: SLB shadow buffer registration for " - "cpu %d (hw %d) of area %lx failed with %ld\n", - cpu, hwcpu, addr, ret); + printk(KERN_ERR + "WARNING: vpa_init: SLB shadow buffer " + "registration for cpu %d (hw %d) of area %lx " + "returns %ld\n", cpu, hwcpu, addr, ret); } /* @@ -98,9 +100,8 @@ void vpa_init(int cpu) dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; ret = register_dtl(hwcpu, __pa(dtl)); if (ret) - pr_err("WARNING: DTL registration of cpu %d (hw %d) " - "failed with %ld\n", smp_processor_id(), - hwcpu, ret); + pr_warn("DTL registration failed for cpu %d (%ld)\n", + cpu, ret); lppaca_of(cpu).dtl_enable_mask = 2; } } @@ -203,7 +204,7 @@ static void pSeries_lpar_hptab_clear(void) unsigned long ptel; } ptes[4]; long lpar_rc; - unsigned long i, j; + int i, j; /* Read in batches of 4, * invalidate only valid entries not in the VRMA diff --git a/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h b/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h index 41c24c146d6a..4bf21207d7d3 100644 --- a/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h +++ b/trunk/arch/powerpc/platforms/pseries/plpar_wrappers.h @@ -53,9 +53,9 @@ static inline long vpa_call(unsigned long flags, unsigned long cpu, return plpar_hcall_norets(H_REGISTER_VPA, flags, cpu, vpa); } -static inline long unregister_vpa(unsigned long cpu) +static inline long unregister_vpa(unsigned long cpu, unsigned long vpa) { - return vpa_call(0x5, cpu, 0); + return vpa_call(0x5, cpu, vpa); } static inline long register_vpa(unsigned long cpu, unsigned long vpa) @@ -63,9 +63,9 @@ static inline long register_vpa(unsigned long cpu, unsigned long vpa) return vpa_call(0x1, cpu, vpa); } -static inline long unregister_slb_shadow(unsigned long cpu) +static inline long unregister_slb_shadow(unsigned long cpu, unsigned long vpa) { - return vpa_call(0x7, cpu, 0); + return vpa_call(0x7, cpu, vpa); } static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) @@ -73,9 +73,9 @@ static inline long register_slb_shadow(unsigned long cpu, unsigned long vpa) return vpa_call(0x3, cpu, vpa); } -static inline long unregister_dtl(unsigned long cpu) +static inline long unregister_dtl(unsigned long cpu, unsigned long vpa) { - return vpa_call(0x6, cpu, 0); + return vpa_call(0x6, cpu, vpa); } static inline long register_dtl(unsigned long cpu, unsigned long vpa) diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 0969fd98c4fa..d00e52926b71 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -324,9 +324,8 @@ static int alloc_dispatch_logs(void) dtl->enqueue_to_dispatch_time = DISPATCH_LOG_BYTES; ret = register_dtl(hard_smp_processor_id(), __pa(dtl)); if (ret) - pr_err("WARNING: DTL registration of cpu %d (hw %d) failed " - "with %d\n", smp_processor_id(), - hard_smp_processor_id(), ret); + pr_warn("DTL registration failed for boot cpu %d (%d)\n", + smp_processor_id(), ret); get_paca()->lppaca_ptr->dtl_enable_mask = 2; return 0; diff --git a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c index dbfe96bc878a..a59ba96d2c21 100644 --- a/trunk/arch/powerpc/sysdev/ppc4xx_pci.c +++ b/trunk/arch/powerpc/sysdev/ppc4xx_pci.c @@ -655,6 +655,8 @@ struct ppc4xx_pciex_hwops static struct ppc4xx_pciex_hwops *ppc4xx_pciex_hwops; +#ifdef CONFIG_44x + static int __init ppc4xx_pciex_wait_on_sdr(struct ppc4xx_pciex_port *port, unsigned int sdr_offset, unsigned int mask, @@ -686,7 +688,6 @@ static int __init ppc4xx_pciex_port_reset_sdr(struct ppc4xx_pciex_port *port) return 0; } - static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) { printk(KERN_INFO "PCIE%d: Checking link...\n", port->index); @@ -717,8 +718,6 @@ static void __init ppc4xx_pciex_check_link_sdr(struct ppc4xx_pciex_port *port) printk(KERN_INFO "PCIE%d: No device detected.\n", port->index); } -#ifdef CONFIG_44x - /* Check various reset bits of the 440SPe PCIe core */ static int __init ppc440spe_pciex_check_reset(struct device_node *np) { diff --git a/trunk/arch/s390/Kconfig b/trunk/arch/s390/Kconfig index ed5cb5af5281..c03fef7a9c22 100644 --- a/trunk/arch/s390/Kconfig +++ b/trunk/arch/s390/Kconfig @@ -81,7 +81,6 @@ config S390 select INIT_ALL_POSSIBLE select HAVE_IRQ_WORK select HAVE_PERF_EVENTS - select ARCH_HAVE_NMI_SAFE_CMPXCHG select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 select HAVE_KERNEL_LZMA @@ -274,11 +273,11 @@ config MARCH_Z10 on older machines. config MARCH_Z196 - bool "IBM zEnterprise 114 and 196" + bool "IBM zEnterprise 196" help - Select this to enable optimizations for IBM zEnterprise 114 and 196 - (2818 and 2817 series). The kernel will be slightly faster but will - not work on older machines. + Select this to enable optimizations for IBM zEnterprise 196 + (2817 series). The kernel will be slightly faster but will not work + on older machines. endchoice diff --git a/trunk/arch/s390/include/asm/ipl.h b/trunk/arch/s390/include/asm/ipl.h index 97cc4403fabf..5e95d95450b3 100644 --- a/trunk/arch/s390/include/asm/ipl.h +++ b/trunk/arch/s390/include/asm/ipl.h @@ -167,6 +167,5 @@ enum diag308_rc { }; extern int diag308(unsigned long subcode, void *addr); -extern void diag308_reset(void); #endif /* _ASM_S390_IPL_H */ diff --git a/trunk/arch/s390/include/asm/lowcore.h b/trunk/arch/s390/include/asm/lowcore.h index e85c911aabf0..f26280d9e88d 100644 --- a/trunk/arch/s390/include/asm/lowcore.h +++ b/trunk/arch/s390/include/asm/lowcore.h @@ -18,7 +18,6 @@ void system_call(void); void pgm_check_handler(void); void mcck_int_handler(void); void io_int_handler(void); -void psw_restart_int_handler(void); #ifdef CONFIG_32BIT @@ -151,10 +150,7 @@ struct _lowcore { */ __u32 ipib; /* 0x0e00 */ __u32 ipib_checksum; /* 0x0e04 */ - - /* 64 bit save area */ - __u64 save_area_64; /* 0x0e08 */ - __u8 pad_0x0e10[0x0f00-0x0e10]; /* 0x0e10 */ + __u8 pad_0x0e08[0x0f00-0x0e08]; /* 0x0e08 */ /* Extended facility list */ __u64 stfle_fac_list[32]; /* 0x0f00 */ @@ -290,10 +286,7 @@ struct _lowcore { */ __u64 ipib; /* 0x0e00 */ __u32 ipib_checksum; /* 0x0e08 */ - - /* 64 bit save area */ - __u64 save_area_64; /* 0x0e0c */ - __u8 pad_0x0e14[0x0f00-0x0e14]; /* 0x0e14 */ + __u8 pad_0x0e0c[0x0f00-0x0e0c]; /* 0x0e0c */ /* Extended facility list */ __u64 stfle_fac_list[32]; /* 0x0f00 */ diff --git a/trunk/arch/s390/include/asm/processor.h b/trunk/arch/s390/include/asm/processor.h index a4b6229e5d4b..55dfcc8bdc0d 100644 --- a/trunk/arch/s390/include/asm/processor.h +++ b/trunk/arch/s390/include/asm/processor.h @@ -119,12 +119,14 @@ struct stack_frame { * Do necessary setup to start up a new thread. */ #define start_thread(regs, new_psw, new_stackp) do { \ + set_fs(USER_DS); \ regs->psw.mask = psw_user_bits; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ } while (0) #define start_thread31(regs, new_psw, new_stackp) do { \ + set_fs(USER_DS); \ regs->psw.mask = psw_user32_bits; \ regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ regs->gprs[15] = new_stackp; \ diff --git a/trunk/arch/s390/include/asm/system.h b/trunk/arch/s390/include/asm/system.h index 6582f69f2389..d382629a0172 100644 --- a/trunk/arch/s390/include/asm/system.h +++ b/trunk/arch/s390/include/asm/system.h @@ -113,7 +113,6 @@ extern void pfault_fini(void); extern void cmma_init(void); extern int memcpy_real(void *, void *, size_t); -extern void copy_to_absolute_zero(void *dest, void *src, size_t count); #define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ diff --git a/trunk/arch/s390/kernel/asm-offsets.c b/trunk/arch/s390/kernel/asm-offsets.c index 532fd4322156..05d8f38734ec 100644 --- a/trunk/arch/s390/kernel/asm-offsets.c +++ b/trunk/arch/s390/kernel/asm-offsets.c @@ -27,9 +27,12 @@ int main(void) BLANK(); DEFINE(__TASK_pid, offsetof(struct task_struct, pid)); BLANK(); - DEFINE(__THREAD_per_cause, offsetof(struct task_struct, thread.per_event.cause)); - DEFINE(__THREAD_per_address, offsetof(struct task_struct, thread.per_event.address)); - DEFINE(__THREAD_per_paid, offsetof(struct task_struct, thread.per_event.paid)); + DEFINE(__THREAD_per_cause, + offsetof(struct task_struct, thread.per_event.cause)); + DEFINE(__THREAD_per_address, + offsetof(struct task_struct, thread.per_event.address)); + DEFINE(__THREAD_per_paid, + offsetof(struct task_struct, thread.per_event.paid)); BLANK(); DEFINE(__TI_task, offsetof(struct thread_info, task)); DEFINE(__TI_domain, offsetof(struct thread_info, exec_domain)); @@ -139,7 +142,6 @@ int main(void) DEFINE(__LC_FPREGS_SAVE_AREA, offsetof(struct _lowcore, floating_pt_save_area)); DEFINE(__LC_GPREGS_SAVE_AREA, offsetof(struct _lowcore, gpregs_save_area)); DEFINE(__LC_CREGS_SAVE_AREA, offsetof(struct _lowcore, cregs_save_area)); - DEFINE(__LC_SAVE_AREA_64, offsetof(struct _lowcore, save_area_64)); #ifdef CONFIG_32BIT DEFINE(SAVE_AREA_BASE, offsetof(struct _lowcore, extended_save_area_addr)); #else /* CONFIG_32BIT */ diff --git a/trunk/arch/s390/kernel/base.S b/trunk/arch/s390/kernel/base.S index 255435663bf8..209938c1dfc8 100644 --- a/trunk/arch/s390/kernel/base.S +++ b/trunk/arch/s390/kernel/base.S @@ -76,42 +76,6 @@ s390_base_pgm_handler_fn: .quad 0 .previous -# -# Calls diag 308 subcode 1 and continues execution -# -# The following conditions must be ensured before calling this function: -# * Prefix register = 0 -# * Lowcore protection is disabled -# -ENTRY(diag308_reset) - larl %r4,.Lctlregs # Save control registers - stctg %c0,%c15,0(%r4) - larl %r4,.Lrestart_psw # Setup restart PSW at absolute 0 - lghi %r3,0 - lg %r4,0(%r4) # Save PSW - sturg %r4,%r3 # Use sturg, because of large pages - lghi %r1,1 - diag %r1,%r1,0x308 -.Lrestart_part2: - lhi %r0,0 # Load r0 with zero - lhi %r1,2 # Use mode 2 = ESAME (dump) - sigp %r1,%r0,0x12 # Switch to ESAME mode - sam64 # Switch to 64 bit addressing mode - larl %r4,.Lctlregs # Restore control registers - lctlg %c0,%c15,0(%r4) - br %r14 -.align 16 -.Lrestart_psw: - .long 0x00080000,0x80000000 + .Lrestart_part2 - - .section .bss -.align 8 -.Lctlregs: - .rept 16 - .quad 0 - .endr - .previous - #else /* CONFIG_64BIT */ ENTRY(s390_base_mcck_handler) diff --git a/trunk/arch/s390/kernel/compat_signal.c b/trunk/arch/s390/kernel/compat_signal.c index a9a285b8c4ad..eee999853a7c 100644 --- a/trunk/arch/s390/kernel/compat_signal.c +++ b/trunk/arch/s390/kernel/compat_signal.c @@ -380,13 +380,20 @@ asmlinkage long sys32_sigreturn(void) goto badframe; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32)) goto badframe; + sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (restore_sigregs32(regs, &frame->sregs)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; + return regs->gprs[2]; + badframe: force_sig(SIGSEGV, current); return 0; @@ -406,22 +413,31 @@ asmlinkage long sys32_rt_sigreturn(void) goto badframe; if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; + sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (restore_sigregs32(regs, &frame->uc.uc_mcontext)) goto badframe; if (restore_sigregs_gprs_high(regs, frame->gprs_high)) goto badframe; + err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); st.ss_sp = compat_ptr(ss_sp); err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); if (err) goto badframe; + set_fs (KERNEL_DS); do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]); set_fs (old_fs); + return regs->gprs[2]; + badframe: force_sig(SIGSEGV, current); return 0; @@ -589,10 +605,10 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info, * OK, we're invoking a handler */ -int handle_signal32(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) +int +handle_signal32(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { - sigset_t blocked; int ret; /* Set up the stack frame */ @@ -600,12 +616,15 @@ int handle_signal32(unsigned long sig, struct k_sigaction *ka, ret = setup_rt_frame32(sig, ka, info, oldset, regs); else ret = setup_frame32(sig, ka, oldset, regs); - if (ret) - return ret; - sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(&blocked, sig); - set_current_blocked(&blocked); - return 0; + + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + return ret; } diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index 02ec8fe7d03f..3eab7cfab07c 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -849,34 +849,6 @@ restart_crash: restart_go: #endif -# -# PSW restart interrupt handler -# -ENTRY(psw_restart_int_handler) - st %r15,__LC_SAVE_AREA_64(%r0) # save r15 - basr %r15,0 -0: l %r15,.Lrestart_stack-0b(%r15) # load restart stack - l %r15,0(%r15) - ahi %r15,-SP_SIZE # make room for pt_regs - stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack - mvc SP_R15(4,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack - mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw - xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 - basr %r14,0 -1: l %r14,.Ldo_restart-1b(%r14) - basr %r14,%r14 - - basr %r14,0 # load disabled wait PSW if -2: lpsw restart_psw_crash-2b(%r14) # do_restart returns - .align 4 -.Ldo_restart: - .long do_restart -.Lrestart_stack: - .long restart_stack - .align 8 -restart_psw_crash: - .long 0x000a0000,0x00000000 + restart_psw_crash - .section .kprobes.text, "ax" #ifdef CONFIG_CHECK_STACK diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 5f729d627cef..7a0fd426ca92 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -865,26 +865,6 @@ restart_crash: restart_go: #endif -# -# PSW restart interrupt handler -# -ENTRY(psw_restart_int_handler) - stg %r15,__LC_SAVE_AREA_64(%r0) # save r15 - larl %r15,restart_stack # load restart stack - lg %r15,0(%r15) - aghi %r15,-SP_SIZE # make room for pt_regs - stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack - mvc SP_R15(8,%r15),__LC_SAVE_AREA_64(%r0)# store saved %r15 to stack - mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw - xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 - brasl %r14,do_restart - - larl %r14,restart_psw_crash # load disabled wait PSW if - lpswe 0(%r14) # do_restart returns - .align 8 -restart_psw_crash: - .quad 0x0002000080000000,0x0000000000000000 + restart_psw_crash - .section .kprobes.text, "ax" #ifdef CONFIG_CHECK_STACK diff --git a/trunk/arch/s390/kernel/ipl.c b/trunk/arch/s390/kernel/ipl.c index 04361d5a4279..a689070be287 100644 --- a/trunk/arch/s390/kernel/ipl.c +++ b/trunk/arch/s390/kernel/ipl.c @@ -45,13 +45,11 @@ * - halt * - power off * - reipl - * - restart */ #define ON_PANIC_STR "on_panic" #define ON_HALT_STR "on_halt" #define ON_POFF_STR "on_poff" #define ON_REIPL_STR "on_reboot" -#define ON_RESTART_STR "on_restart" struct shutdown_action; struct shutdown_trigger { @@ -1546,20 +1544,17 @@ static char vmcmd_on_reboot[128]; static char vmcmd_on_panic[128]; static char vmcmd_on_halt[128]; static char vmcmd_on_poff[128]; -static char vmcmd_on_restart[128]; DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt); DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff); -DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart); static struct attribute *vmcmd_attrs[] = { &sys_vmcmd_on_reboot_attr.attr, &sys_vmcmd_on_panic_attr.attr, &sys_vmcmd_on_halt_attr.attr, &sys_vmcmd_on_poff_attr.attr, - &sys_vmcmd_on_restart_attr.attr, NULL, }; @@ -1581,8 +1576,6 @@ static void vmcmd_run(struct shutdown_trigger *trigger) cmd = vmcmd_on_halt; else if (strcmp(trigger->name, ON_POFF_STR) == 0) cmd = vmcmd_on_poff; - else if (strcmp(trigger->name, ON_RESTART_STR) == 0) - cmd = vmcmd_on_restart; else return; @@ -1714,34 +1707,6 @@ static void do_panic(void) stop_run(&on_panic_trigger); } -/* on restart */ - -static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR, - &reipl_action}; - -static ssize_t on_restart_show(struct kobject *kobj, - struct kobj_attribute *attr, char *page) -{ - return sprintf(page, "%s\n", on_restart_trigger.action->name); -} - -static ssize_t on_restart_store(struct kobject *kobj, - struct kobj_attribute *attr, - const char *buf, size_t len) -{ - return set_trigger(buf, &on_restart_trigger, len); -} - -static struct kobj_attribute on_restart_attr = - __ATTR(on_restart, 0644, on_restart_show, on_restart_store); - -void do_restart(void) -{ - smp_send_stop(); - on_restart_trigger.action->fn(&on_restart_trigger); - stop_run(&on_restart_trigger); -} - /* on halt */ static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action}; @@ -1818,9 +1783,7 @@ static void __init shutdown_triggers_init(void) if (sysfs_create_file(&shutdown_actions_kset->kobj, &on_poff_attr.attr)) goto fail; - if (sysfs_create_file(&shutdown_actions_kset->kobj, - &on_restart_attr.attr)) - goto fail; + return; fail: panic("shutdown_triggers_init failed\n"); @@ -1996,12 +1959,6 @@ static void do_reset_calls(void) { struct reset_call *reset; -#ifdef CONFIG_64BIT - if (diag308_set_works) { - diag308_reset(); - return; - } -#endif list_for_each_entry(reset, &rcall, list) reset->fn(); } diff --git a/trunk/arch/s390/kernel/reipl64.S b/trunk/arch/s390/kernel/reipl64.S index e690975403f4..78eb7cfbd3d1 100644 --- a/trunk/arch/s390/kernel/reipl64.S +++ b/trunk/arch/s390/kernel/reipl64.S @@ -1,5 +1,5 @@ /* - * Copyright IBM Corp 2000,2011 + * Copyright IBM Corp 2000,2009 * Author(s): Holger Smolinski , * Denis Joseph Barrow, */ @@ -7,64 +7,6 @@ #include #include -# -# store_status -# -# Prerequisites to run this function: -# - Prefix register is set to zero -# - Original prefix register is stored in "dump_prefix_page" -# - Lowcore protection is off -# -ENTRY(store_status) - /* Save register one and load save area base */ - stg %r1,__LC_SAVE_AREA_64(%r0) - lghi %r1,SAVE_AREA_BASE - /* General purpose registers */ - stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - lg %r2,__LC_SAVE_AREA_64(%r0) - stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) - /* Control registers */ - stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - /* Access registers */ - stam %a0,%a15,__LC_AREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - /* Floating point registers */ - std %f0, 0x00 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f1, 0x08 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f2, 0x10 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f3, 0x18 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f4, 0x20 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f5, 0x28 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f6, 0x30 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f7, 0x38 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f8, 0x40 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f9, 0x48 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f10,0x50 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f11,0x58 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f12,0x60 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f13,0x68 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f14,0x70 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - std %f15,0x78 + __LC_FPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) - /* Floating point control register */ - stfpc __LC_FP_CREG_SAVE_AREA-SAVE_AREA_BASE(%r1) - /* CPU timer */ - stpt __LC_CPU_TIMER_SAVE_AREA-SAVE_AREA_BASE(%r1) - /* Saved prefix register */ - larl %r2,dump_prefix_page - mvc __LC_PREFIX_SAVE_AREA-SAVE_AREA_BASE(4,%r1),0(%r2) - /* Clock comparator - seven bytes */ - larl %r2,.Lclkcmp - stckc 0(%r2) - mvc __LC_CLOCK_COMP_SAVE_AREA-SAVE_AREA_BASE + 1(7,%r1),1(%r2) - /* Program status word */ - epsw %r2,%r3 - st %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 0(%r1) - st %r3,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 4(%r1) - larl %r2,store_status - stg %r2,__LC_PSW_SAVE_AREA-SAVE_AREA_BASE + 8(%r1) - br %r14 -.align 8 -.Lclkcmp: .quad 0x0000000000000000 - # # do_reipl_asm # Parameter: r2 = schid of reipl device @@ -73,7 +15,22 @@ ENTRY(store_status) ENTRY(do_reipl_asm) basr %r13,0 .Lpg0: lpswe .Lnewpsw-.Lpg0(%r13) -.Lpg1: brasl %r14,store_status +.Lpg1: # do store status of all registers + + stg %r1,.Lregsave-.Lpg0(%r13) + lghi %r1,0x1000 + stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1) + lg %r0,.Lregsave-.Lpg0(%r13) + stg %r0,__LC_GPREGS_SAVE_AREA-0x1000+8(%r1) + stctg %c0,%c15,__LC_CREGS_SAVE_AREA-0x1000(%r1) + stam %a0,%a15,__LC_AREGS_SAVE_AREA-0x1000(%r1) + lg %r10,.Ldump_pfx-.Lpg0(%r13) + mvc __LC_PREFIX_SAVE_AREA-0x1000(4,%r1),0(%r10) + stfpc __LC_FP_CREG_SAVE_AREA-0x1000(%r1) + stckc .Lclkcmp-.Lpg0(%r13) + mvc __LC_CLOCK_COMP_SAVE_AREA-0x1000(7,%r1),.Lclkcmp-.Lpg0(%r13) + stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1) + stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1) lctlg %c6,%c6,.Lall-.Lpg0(%r13) lgr %r1,%r2 @@ -110,7 +67,10 @@ ENTRY(do_reipl_asm) st %r14,.Ldispsw+12-.Lpg0(%r13) lpswe .Ldispsw-.Lpg0(%r13) .align 8 +.Lclkcmp: .quad 0x0000000000000000 .Lall: .quad 0x00000000ff000000 +.Ldump_pfx: .quad dump_prefix_page +.Lregsave: .quad 0x0000000000000000 .align 16 /* * These addresses have to be 31 bit otherwise diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index 7b371c37061d..0c35dee10b00 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -346,7 +346,7 @@ setup_lowcore(void) lc = __alloc_bootmem_low(LC_PAGES * PAGE_SIZE, LC_PAGES * PAGE_SIZE, 0); lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; lc->restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; + PSW_ADDR_AMODE | (unsigned long) restart_int_handler; if (user_mode != HOME_SPACE_MODE) lc->restart_psw.mask |= PSW_ASC_HOME; lc->external_new_psw.mask = psw_kernel_bits; @@ -529,27 +529,6 @@ static void __init setup_memory_end(void) memory_end = memory_size; } -void *restart_stack __attribute__((__section__(".data"))); - -/* - * Setup new PSW and allocate stack for PSW restart interrupt - */ -static void __init setup_restart_psw(void) -{ - psw_t psw; - - restart_stack = __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0); - restart_stack += ASYNC_SIZE; - - /* - * Setup restart PSW for absolute zero lowcore. This is necesary - * if PSW restart is done on an offline CPU that has lowcore zero - */ - psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; - psw.addr = PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; - copy_to_absolute_zero(&S390_lowcore.restart_psw, &psw, sizeof(psw)); -} - static void __init setup_memory(void) { @@ -752,7 +731,6 @@ static void __init setup_hwcaps(void) strcpy(elf_platform, "z10"); break; case 0x2817: - case 0x2818: strcpy(elf_platform, "z196"); break; } @@ -814,7 +792,6 @@ setup_arch(char **cmdline_p) setup_addressing_mode(); setup_memory(); setup_resources(); - setup_restart_psw(); setup_lowcore(); cpu_init(); diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index 9a40e1cc5ec3..abbb3c3c7aab 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -57,15 +57,17 @@ typedef struct */ SYSCALL_DEFINE3(sigsuspend, int, history0, int, history1, old_sigset_t, mask) { - sigset_t blocked; - - current->saved_sigmask = current->blocked; mask &= _BLOCKABLE; - siginitset(&blocked, mask); - set_current_blocked(&blocked); + spin_lock_irq(¤t->sighand->siglock); + current->saved_sigmask = current->blocked; + siginitset(¤t->blocked, mask); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + set_current_state(TASK_INTERRUPTIBLE); schedule(); - set_restore_sigmask(); + set_thread_flag(TIF_RESTORE_SIGMASK); + return -ERESTARTNOHAND; } @@ -170,11 +172,18 @@ SYSCALL_DEFINE0(sigreturn) goto badframe; if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE)) goto badframe; + sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (restore_sigregs(regs, &frame->sregs)) goto badframe; + return regs->gprs[2]; + badframe: force_sig(SIGSEGV, current); return 0; @@ -190,14 +199,21 @@ SYSCALL_DEFINE0(rt_sigreturn) goto badframe; if (__copy_from_user(&set.sig, &frame->uc.uc_sigmask, sizeof(set))) goto badframe; + sigdelsetmask(&set, ~_BLOCKABLE); - set_current_blocked(&set); + spin_lock_irq(¤t->sighand->siglock); + current->blocked = set; + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + if (restore_sigregs(regs, &frame->uc.uc_mcontext)) goto badframe; + if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]) == -EFAULT) goto badframe; return regs->gprs[2]; + badframe: force_sig(SIGSEGV, current); return 0; @@ -369,11 +385,14 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return -EFAULT; } -static int handle_signal(unsigned long sig, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, - struct pt_regs *regs) +/* + * OK, we're invoking a handler + */ + +static int +handle_signal(unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) { - sigset_t blocked; int ret; /* Set up the stack frame */ @@ -381,13 +400,17 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, ret = setup_rt_frame(sig, ka, info, oldset, regs); else ret = setup_frame(sig, ka, oldset, regs); - if (ret) - return ret; - sigorsets(&blocked, ¤t->blocked, &ka->sa.sa_mask); - if (!(ka->sa.sa_flags & SA_NODEFER)) - sigaddset(&blocked, sig); - set_current_blocked(&blocked); - return 0; + + if (ret == 0) { + spin_lock_irq(¤t->sighand->siglock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + if (!(ka->sa.sa_flags & SA_NODEFER)) + sigaddset(¤t->blocked,sig); + recalc_sigpending(); + spin_unlock_irq(¤t->sighand->siglock); + } + + return ret; } /* diff --git a/trunk/arch/s390/kernel/smp.c b/trunk/arch/s390/kernel/smp.c index 6ab16ac64d29..a6d85c0a7f20 100644 --- a/trunk/arch/s390/kernel/smp.c +++ b/trunk/arch/s390/kernel/smp.c @@ -452,27 +452,23 @@ static void __init smp_detect_cpus(void) */ int __cpuinit start_secondary(void *cpuvoid) { + /* Setup the cpu */ cpu_init(); preempt_disable(); + /* Enable TOD clock interrupts on the secondary cpu. */ init_cpu_timer(); + /* Enable cpu timer interrupts on the secondary cpu. */ init_cpu_vtimer(); + /* Enable pfault pseudo page faults on this cpu. */ pfault_init(); + /* call cpu notifiers */ notify_cpu_starting(smp_processor_id()); + /* Mark this cpu as online */ ipi_call_lock(); set_cpu_online(smp_processor_id(), true); ipi_call_unlock(); - __ctl_clear_bit(0, 28); /* Disable lowcore protection */ - S390_lowcore.restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; - S390_lowcore.restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) psw_restart_int_handler; - __ctl_set_bit(0, 28); /* Enable lowcore protection */ - /* - * Wait until the cpu which brought this one up marked it - * active before enabling interrupts. - */ - while (!cpumask_test_cpu(smp_processor_id(), cpu_active_mask)) - cpu_relax(); + /* Switch on interrupts */ local_irq_enable(); /* cpu_idle will call schedule for us */ cpu_idle(); @@ -511,11 +507,7 @@ static int __cpuinit smp_alloc_lowcore(int cpu) memset((char *)lowcore + 512, 0, sizeof(*lowcore) - 512); lowcore->async_stack = async_stack + ASYNC_SIZE; lowcore->panic_stack = panic_stack + PAGE_SIZE; - lowcore->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; - lowcore->restart_psw.addr = - PSW_ADDR_AMODE | (unsigned long) restart_int_handler; - if (user_mode != HOME_SPACE_MODE) - lowcore->restart_psw.mask |= PSW_ASC_HOME; + #ifndef CONFIG_64BIT if (MACHINE_HAS_IEEE) { unsigned long save_area; diff --git a/trunk/arch/s390/mm/maccess.c b/trunk/arch/s390/mm/maccess.c index 5dbbaa6e594c..51e5cd9b906a 100644 --- a/trunk/arch/s390/mm/maccess.c +++ b/trunk/arch/s390/mm/maccess.c @@ -85,19 +85,3 @@ int memcpy_real(void *dest, void *src, size_t count) arch_local_irq_restore(flags); return rc; } - -/* - * Copy memory to absolute zero - */ -void copy_to_absolute_zero(void *dest, void *src, size_t count) -{ - unsigned long cr0; - - BUG_ON((unsigned long) dest + count >= sizeof(struct _lowcore)); - preempt_disable(); - __ctl_store(cr0, 0, 0); - __ctl_clear_bit(0, 28); /* disable lowcore protection */ - memcpy_real(dest + store_prefix(), src, count); - __ctl_load(cr0, 0, 0); - preempt_enable(); -} diff --git a/trunk/arch/s390/mm/pgtable.c b/trunk/arch/s390/mm/pgtable.c index 4d1f2bce87b3..2adb23938a7f 100644 --- a/trunk/arch/s390/mm/pgtable.c +++ b/trunk/arch/s390/mm/pgtable.c @@ -528,7 +528,6 @@ static inline void page_table_free_pgste(unsigned long *table) static inline unsigned long *page_table_alloc_pgste(struct mm_struct *mm, unsigned long vmaddr) { - return NULL; } static inline void page_table_free_pgste(unsigned long *table) diff --git a/trunk/arch/sh/Kconfig b/trunk/arch/sh/Kconfig index ff9177c8f643..748ff1920068 100644 --- a/trunk/arch/sh/Kconfig +++ b/trunk/arch/sh/Kconfig @@ -11,7 +11,6 @@ config SUPERH select HAVE_DMA_ATTRS select HAVE_IRQ_WORK select HAVE_PERF_EVENTS - select ARCH_HAVE_NMI_SAFE_CMPXCHG if (GUSA_RB || CPU_SH4A) select PERF_USE_VMALLOC select HAVE_KERNEL_GZIP select HAVE_KERNEL_BZIP2 diff --git a/trunk/arch/sh/kernel/idle.c b/trunk/arch/sh/kernel/idle.c index 32114e0941ae..84db0d6ccd0d 100644 --- a/trunk/arch/sh/kernel/idle.c +++ b/trunk/arch/sh/kernel/idle.c @@ -16,13 +16,12 @@ #include #include #include -#include #include #include #include #include -static void (*pm_idle)(void); +void (*pm_idle)(void) = NULL; static int hlt_counter; @@ -101,8 +100,7 @@ void cpu_idle(void) local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); - if (cpuidle_idle_call()) - pm_idle(); + pm_idle(); /* * Sanity check to ensure that pm_idle() returns * with IRQs enabled diff --git a/trunk/arch/sparc/Kconfig b/trunk/arch/sparc/Kconfig index 42c67beadcae..1074dddcb104 100644 --- a/trunk/arch/sparc/Kconfig +++ b/trunk/arch/sparc/Kconfig @@ -54,7 +54,6 @@ config SPARC64 select HAVE_PERF_EVENTS select PERF_USE_VMALLOC select IRQ_PREFLOW_FASTEOI - select ARCH_HAVE_NMI_SAFE_CMPXCHG config ARCH_DEFCONFIG string diff --git a/trunk/arch/sparc/include/asm/Kbuild b/trunk/arch/sparc/include/asm/Kbuild index 2c2e38821f60..3c93f08ce187 100644 --- a/trunk/arch/sparc/include/asm/Kbuild +++ b/trunk/arch/sparc/include/asm/Kbuild @@ -16,8 +16,3 @@ header-y += traps.h header-y += uctx.h header-y += utrap.h header-y += watchdog.h - -generic-y += div64.h -generic-y += local64.h -generic-y += irq_regs.h -generic-y += local.h diff --git a/trunk/arch/sparc/include/asm/bitops_64.h b/trunk/arch/sparc/include/asm/bitops_64.h index 29011cc0e4be..325e295d60de 100644 --- a/trunk/arch/sparc/include/asm/bitops_64.h +++ b/trunk/arch/sparc/include/asm/bitops_64.h @@ -26,28 +26,61 @@ extern void change_bit(unsigned long nr, volatile unsigned long *addr); #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() +#include +#include #include #include #include #ifdef __KERNEL__ -extern int ffs(int x); -extern unsigned long __ffs(unsigned long); - -#include #include +#include /* * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -extern unsigned long __arch_hweight64(__u64 w); -extern unsigned int __arch_hweight32(unsigned int w); -extern unsigned int __arch_hweight16(unsigned int w); -extern unsigned int __arch_hweight8(unsigned int w); +#ifdef ULTRA_HAS_POPULATION_COUNT + +static inline unsigned int __arch_hweight64(unsigned long w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w)); + return res; +} + +static inline unsigned int __arch_hweight32(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffffffff)); + return res; +} +static inline unsigned int __arch_hweight16(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xffff)); + return res; +} + +static inline unsigned int __arch_hweight8(unsigned int w) +{ + unsigned int res; + + __asm__ ("popc %1,%0" : "=r" (res) : "r" (w & 0xff)); + return res; +} + +#else + +#include + +#endif #include #include #endif /* __KERNEL__ */ diff --git a/trunk/arch/sparc/include/asm/div64.h b/trunk/arch/sparc/include/asm/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/trunk/arch/sparc/include/asm/div64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sparc/include/asm/elf_64.h b/trunk/arch/sparc/include/asm/elf_64.h index 7df8b7f544d4..64f7a00b3747 100644 --- a/trunk/arch/sparc/include/asm/elf_64.h +++ b/trunk/arch/sparc/include/asm/elf_64.h @@ -59,33 +59,15 @@ #define R_SPARC_6 45 /* Bits present in AT_HWCAP, primarily for Sparc32. */ -#define HWCAP_SPARC_FLUSH 0x00000001 -#define HWCAP_SPARC_STBAR 0x00000002 -#define HWCAP_SPARC_SWAP 0x00000004 -#define HWCAP_SPARC_MULDIV 0x00000008 -#define HWCAP_SPARC_V9 0x00000010 -#define HWCAP_SPARC_ULTRA3 0x00000020 -#define HWCAP_SPARC_BLKINIT 0x00000040 -#define HWCAP_SPARC_N2 0x00000080 - -/* Solaris compatible AT_HWCAP bits. */ -#define AV_SPARC_MUL32 0x00000100 /* 32x32 multiply is efficient */ -#define AV_SPARC_DIV32 0x00000200 /* 32x32 divide is efficient */ -#define AV_SPARC_FSMULD 0x00000400 /* 'fsmuld' is efficient */ -#define AV_SPARC_V8PLUS 0x00000800 /* v9 insn available to 32bit */ -#define AV_SPARC_POPC 0x00001000 /* 'popc' is efficient */ -#define AV_SPARC_VIS 0x00002000 /* VIS insns available */ -#define AV_SPARC_VIS2 0x00004000 /* VIS2 insns available */ -#define AV_SPARC_ASI_BLK_INIT 0x00008000 /* block init ASIs available */ -#define AV_SPARC_FMAF 0x00010000 /* fused multiply-add */ -#define AV_SPARC_VIS3 0x00020000 /* VIS3 insns available */ -#define AV_SPARC_HPC 0x00040000 /* HPC insns available */ -#define AV_SPARC_RANDOM 0x00080000 /* 'random' insn available */ -#define AV_SPARC_TRANS 0x00100000 /* transaction insns available */ -#define AV_SPARC_FJFMAU 0x00200000 /* unfused multiply-add */ -#define AV_SPARC_IMA 0x00400000 /* integer multiply-add */ -#define AV_SPARC_ASI_CACHE_SPARING \ - 0x00800000 /* cache sparing ASIs available */ + +#define HWCAP_SPARC_FLUSH 1 /* CPU supports flush instruction. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 +#define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 +#define HWCAP_SPARC_N2 128 #define CORE_DUMP_USE_REGSET @@ -180,8 +162,33 @@ typedef struct { #define ELF_ET_DYN_BASE 0x0000010000000000UL #define COMPAT_ELF_ET_DYN_BASE 0x0000000070000000UL -extern unsigned long sparc64_elf_hwcap; -#define ELF_HWCAP sparc64_elf_hwcap + +/* This yields a mask that user programs can use to figure out what + instruction set this cpu supports. */ + +/* On Ultra, we support all of the v8 capabilities. */ +static inline unsigned int sparc64_elf_hwcap(void) +{ + unsigned int cap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | + HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | + HWCAP_SPARC_V9); + + if (tlb_type == cheetah || tlb_type == cheetah_plus) + cap |= HWCAP_SPARC_ULTRA3; + else if (tlb_type == hypervisor) { + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= HWCAP_SPARC_BLKINIT; + if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || + sun4v_chip_type == SUN4V_CHIP_NIAGARA3) + cap |= HWCAP_SPARC_N2; + } + + return cap; +} + +#define ELF_HWCAP sparc64_elf_hwcap() /* This yields a string that ld.so will use to load implementation specific libraries for optimization. This is more specific in diff --git a/trunk/arch/sparc/include/asm/hypervisor.h b/trunk/arch/sparc/include/asm/hypervisor.h index 015a761eaa32..7a5f80df15d0 100644 --- a/trunk/arch/sparc/include/asm/hypervisor.h +++ b/trunk/arch/sparc/include/asm/hypervisor.h @@ -2927,13 +2927,6 @@ extern unsigned long sun4v_ncs_request(unsigned long request, #define HV_FAST_FIRE_GET_PERFREG 0x120 #define HV_FAST_FIRE_SET_PERFREG 0x121 -#define HV_FAST_REBOOT_DATA_SET 0x172 - -#ifndef __ASSEMBLY__ -extern unsigned long sun4v_reboot_data_set(unsigned long ra, - unsigned long len); -#endif - /* Function numbers for HV_CORE_TRAP. */ #define HV_CORE_SET_VER 0x00 #define HV_CORE_PUTCHAR 0x01 @@ -2947,17 +2940,11 @@ extern unsigned long sun4v_reboot_data_set(unsigned long ra, #define HV_GRP_CORE 0x0001 #define HV_GRP_INTR 0x0002 #define HV_GRP_SOFT_STATE 0x0003 -#define HV_GRP_TM 0x0080 #define HV_GRP_PCI 0x0100 #define HV_GRP_LDOM 0x0101 #define HV_GRP_SVC_CHAN 0x0102 #define HV_GRP_NCS 0x0103 #define HV_GRP_RNG 0x0104 -#define HV_GRP_PBOOT 0x0105 -#define HV_GRP_TPM 0x0107 -#define HV_GRP_SDIO 0x0108 -#define HV_GRP_SDIO_ERR 0x0109 -#define HV_GRP_REBOOT_DATA 0x0110 #define HV_GRP_NIAG_PERF 0x0200 #define HV_GRP_FIRE_PERF 0x0201 #define HV_GRP_N2_CPU 0x0202 diff --git a/trunk/arch/sparc/include/asm/irq_regs.h b/trunk/arch/sparc/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/trunk/arch/sparc/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sparc/include/asm/local.h b/trunk/arch/sparc/include/asm/local.h new file mode 100644 index 000000000000..bc80815a435c --- /dev/null +++ b/trunk/arch/sparc/include/asm/local.h @@ -0,0 +1,6 @@ +#ifndef _SPARC_LOCAL_H +#define _SPARC_LOCAL_H + +#include + +#endif diff --git a/trunk/arch/sparc/include/asm/local64.h b/trunk/arch/sparc/include/asm/local64.h new file mode 100644 index 000000000000..36c93b5cc239 --- /dev/null +++ b/trunk/arch/sparc/include/asm/local64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/sparc/include/asm/tsb.h b/trunk/arch/sparc/include/asm/tsb.h index 1a8afd1ad04f..83c571d8c8a7 100644 --- a/trunk/arch/sparc/include/asm/tsb.h +++ b/trunk/arch/sparc/include/asm/tsb.h @@ -133,6 +133,29 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; sub TSB, 0x8, TSB; \ TSB_STORE(TSB, TAG); +#define KTSB_LOAD_QUAD(TSB, REG) \ + ldda [TSB] ASI_NUCLEUS_QUAD_LDD, REG; + +#define KTSB_STORE(ADDR, VAL) \ + stxa VAL, [ADDR] ASI_N; + +#define KTSB_LOCK_TAG(TSB, REG1, REG2) \ +99: lduwa [TSB] ASI_N, REG1; \ + sethi %hi(TSB_TAG_LOCK_HIGH), REG2;\ + andcc REG1, REG2, %g0; \ + bne,pn %icc, 99b; \ + nop; \ + casa [TSB] ASI_N, REG1, REG2;\ + cmp REG1, REG2; \ + bne,pn %icc, 99b; \ + nop; \ + +#define KTSB_WRITE(TSB, TTE, TAG) \ + add TSB, 0x8, TSB; \ + stxa TTE, [TSB] ASI_N; \ + sub TSB, 0x8, TSB; \ + stxa TAG, [TSB] ASI_N; + /* Do a kernel page table walk. Leaves physical PTE pointer in * REG1. Jumps to FAIL_LABEL on early page table walk termination. * VADDR will not be clobbered, but REG2 will. @@ -216,8 +239,6 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; (KERNEL_TSB_SIZE_BYTES / 16) #define KERNEL_TSB4M_NENTRIES 4096 -#define KTSB_PHYS_SHIFT 15 - /* Do a kernel TSB lookup at tl>0 on VADDR+TAG, branch to OK_LABEL * on TSB hit. REG1, REG2, REG3, and REG4 are used as temporaries * and the found TTE will be left in REG1. REG3 and REG4 must @@ -226,22 +247,13 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * VADDR and TAG will be preserved and not clobbered by this macro. */ #define KERN_TSB_LOOKUP_TL1(VADDR, TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ -661: sethi %hi(swapper_tsb), REG1; \ + sethi %hi(swapper_tsb), REG1; \ or REG1, %lo(swapper_tsb), REG1; \ - .section .swapper_tsb_phys_patch, "ax"; \ - .word 661b; \ - .previous; \ -661: nop; \ - .section .tsb_ldquad_phys_patch, "ax"; \ - .word 661b; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - .previous; \ srlx VADDR, PAGE_SHIFT, REG2; \ and REG2, (KERNEL_TSB_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - TSB_LOAD_QUAD(REG2, REG3); \ + KTSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; @@ -251,21 +263,12 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; * we can make use of that for the index computation. */ #define KERN_TSB4M_LOOKUP_TL1(TAG, REG1, REG2, REG3, REG4, OK_LABEL) \ -661: sethi %hi(swapper_4m_tsb), REG1; \ + sethi %hi(swapper_4m_tsb), REG1; \ or REG1, %lo(swapper_4m_tsb), REG1; \ - .section .swapper_4m_tsb_phys_patch, "ax"; \ - .word 661b; \ - .previous; \ -661: nop; \ - .section .tsb_ldquad_phys_patch, "ax"; \ - .word 661b; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - sllx REG1, KTSB_PHYS_SHIFT, REG1; \ - .previous; \ and TAG, (KERNEL_TSB4M_NENTRIES - 1), REG2; \ sllx REG2, 4, REG2; \ add REG1, REG2, REG2; \ - TSB_LOAD_QUAD(REG2, REG3); \ + KTSB_LOAD_QUAD(REG2, REG3); \ cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; diff --git a/trunk/arch/sparc/kernel/cpu.c b/trunk/arch/sparc/kernel/cpu.c index 9810fd881058..17cf290dc2bc 100644 --- a/trunk/arch/sparc/kernel/cpu.c +++ b/trunk/arch/sparc/kernel/cpu.c @@ -396,7 +396,6 @@ static int show_cpuinfo(struct seq_file *m, void *__unused) , cpu_data(0).clock_tick #endif ); - cpucap_info(m); #ifdef CONFIG_SMP smp_bogo(m); #endif diff --git a/trunk/arch/sparc/kernel/ds.c b/trunk/arch/sparc/kernel/ds.c index 7429b47c3aca..dd1342c0a3be 100644 --- a/trunk/arch/sparc/kernel/ds.c +++ b/trunk/arch/sparc/kernel/ds.c @@ -15,15 +15,12 @@ #include #include -#include #include #include #include #include #include -#include "kernel.h" - #define DRV_MODULE_NAME "ds" #define PFX DRV_MODULE_NAME ": " #define DRV_MODULE_VERSION "1.0" @@ -831,32 +828,18 @@ void ldom_set_var(const char *var, const char *value) } } -static char full_boot_str[256] __attribute__((aligned(32))); -static int reboot_data_supported; - void ldom_reboot(const char *boot_command) { /* Don't bother with any of this if the boot_command * is empty. */ if (boot_command && strlen(boot_command)) { - unsigned long len; + char full_boot_str[256]; strcpy(full_boot_str, "boot "); strcpy(full_boot_str + strlen("boot "), boot_command); - len = strlen(full_boot_str); - if (reboot_data_supported) { - unsigned long ra = kimage_addr_to_ra(full_boot_str); - unsigned long hv_ret; - - hv_ret = sun4v_reboot_data_set(ra, len); - if (hv_ret != HV_EOK) - pr_err("SUN4V: Unable to set reboot data " - "hv_ret=%lu\n", hv_ret); - } else { - ldom_set_var("reboot-command", full_boot_str); - } + ldom_set_var("reboot-command", full_boot_str); } sun4v_mach_sir(); } @@ -1254,16 +1237,6 @@ static struct vio_driver ds_driver = { static int __init ds_init(void) { - unsigned long hv_ret, major, minor; - - if (tlb_type == hypervisor) { - hv_ret = sun4v_get_version(HV_GRP_REBOOT_DATA, &major, &minor); - if (hv_ret == HV_EOK) { - pr_info("SUN4V: Reboot data supported (maj=%lu,min=%lu).\n", - major, minor); - reboot_data_supported = 1; - } - } kthread_run(ds_thread, NULL, "kldomd"); return vio_register_driver(&ds_driver); diff --git a/trunk/arch/sparc/kernel/entry.h b/trunk/arch/sparc/kernel/entry.h index e27f8ea8656e..d1f1361c4167 100644 --- a/trunk/arch/sparc/kernel/entry.h +++ b/trunk/arch/sparc/kernel/entry.h @@ -42,20 +42,6 @@ extern void fpsave(unsigned long *fpregs, unsigned long *fsr, extern void fpload(unsigned long *fpregs, unsigned long *fsr); #else /* CONFIG_SPARC32 */ -struct popc_3insn_patch_entry { - unsigned int addr; - unsigned int insns[3]; -}; -extern struct popc_3insn_patch_entry __popc_3insn_patch, - __popc_3insn_patch_end; - -struct popc_6insn_patch_entry { - unsigned int addr; - unsigned int insns[6]; -}; -extern struct popc_6insn_patch_entry __popc_6insn_patch, - __popc_6insn_patch_end; - extern void __init per_cpu_patch(void); extern void __init sun4v_patch(void); extern void __init boot_cpu_id_too_large(int cpu); diff --git a/trunk/arch/sparc/kernel/head_64.S b/trunk/arch/sparc/kernel/head_64.S index 0eac1b2fc53d..c752603a7c0d 100644 --- a/trunk/arch/sparc/kernel/head_64.S +++ b/trunk/arch/sparc/kernel/head_64.S @@ -559,7 +559,7 @@ niagara2_patch: nop call niagara_patch_bzero nop - call niagara_patch_pageops + call niagara2_patch_pageops nop ba,a,pt %xcc, 80f diff --git a/trunk/arch/sparc/kernel/hvapi.c b/trunk/arch/sparc/kernel/hvapi.c index c2d055d8ba9e..d306e648c33c 100644 --- a/trunk/arch/sparc/kernel/hvapi.c +++ b/trunk/arch/sparc/kernel/hvapi.c @@ -28,17 +28,11 @@ static struct api_info api_table[] = { { .group = HV_GRP_CORE, .flags = FLAG_PRE_API }, { .group = HV_GRP_INTR, }, { .group = HV_GRP_SOFT_STATE, }, - { .group = HV_GRP_TM, }, { .group = HV_GRP_PCI, .flags = FLAG_PRE_API }, { .group = HV_GRP_LDOM, }, { .group = HV_GRP_SVC_CHAN, .flags = FLAG_PRE_API }, { .group = HV_GRP_NCS, .flags = FLAG_PRE_API }, { .group = HV_GRP_RNG, }, - { .group = HV_GRP_PBOOT, }, - { .group = HV_GRP_TPM, }, - { .group = HV_GRP_SDIO, }, - { .group = HV_GRP_SDIO_ERR, }, - { .group = HV_GRP_REBOOT_DATA, }, { .group = HV_GRP_NIAG_PERF, .flags = FLAG_PRE_API }, { .group = HV_GRP_FIRE_PERF, }, { .group = HV_GRP_N2_CPU, }, diff --git a/trunk/arch/sparc/kernel/hvcalls.S b/trunk/arch/sparc/kernel/hvcalls.S index 58d60de4d65b..8a5f35ffb15e 100644 --- a/trunk/arch/sparc/kernel/hvcalls.S +++ b/trunk/arch/sparc/kernel/hvcalls.S @@ -798,10 +798,3 @@ ENTRY(sun4v_niagara2_setperf) retl nop ENDPROC(sun4v_niagara2_setperf) - -ENTRY(sun4v_reboot_data_set) - mov HV_FAST_REBOOT_DATA_SET, %o5 - ta HV_FAST_TRAP - retl - nop -ENDPROC(sun4v_reboot_data_set) diff --git a/trunk/arch/sparc/kernel/kernel.h b/trunk/arch/sparc/kernel/kernel.h index fd6c36b1df74..6f6544cfa0ef 100644 --- a/trunk/arch/sparc/kernel/kernel.h +++ b/trunk/arch/sparc/kernel/kernel.h @@ -4,27 +4,12 @@ #include #include -#include -#include /* cpu.c */ extern const char *sparc_pmu_type; extern unsigned int fsr_storage; extern int ncpus_probed; -#ifdef CONFIG_SPARC64 -/* setup_64.c */ -struct seq_file; -extern void cpucap_info(struct seq_file *); - -static inline unsigned long kimage_addr_to_ra(const char *p) -{ - unsigned long val = (unsigned long) p; - - return kern_base + (val - KERNBASE); -} -#endif - #ifdef CONFIG_SPARC32 /* cpu.c */ extern void cpu_probe(void); diff --git a/trunk/arch/sparc/kernel/ktlb.S b/trunk/arch/sparc/kernel/ktlb.S index 79f310364849..1d361477d7d6 100644 --- a/trunk/arch/sparc/kernel/ktlb.S +++ b/trunk/arch/sparc/kernel/ktlb.S @@ -47,16 +47,16 @@ kvmap_itlb_tsb_miss: kvmap_itlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_itlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_itlb_longpath - TSB_STORE(%g1, %g7) + KTSB_STORE(%g1, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ @@ -102,9 +102,9 @@ kvmap_itlb_longpath: kvmap_itlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_itlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_itlb_load nop @@ -112,17 +112,17 @@ kvmap_itlb_obp: kvmap_dtlb_obp: OBP_TRANS_LOOKUP(%g4, %g5, %g2, %g3, kvmap_dtlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop .align 32 kvmap_dtlb_tsb4m_load: - TSB_LOCK_TAG(%g1, %g2, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_WRITE(%g1, %g5, %g6) ba,pt %xcc, kvmap_dtlb_load nop @@ -222,16 +222,16 @@ kvmap_linear_patch: kvmap_dtlb_vmalloc_addr: KERN_PGTABLE_WALK(%g4, %g5, %g2, kvmap_dtlb_longpath) - TSB_LOCK_TAG(%g1, %g2, %g7) + KTSB_LOCK_TAG(%g1, %g2, %g7) /* Load and check PTE. */ ldxa [%g5] ASI_PHYS_USE_EC, %g5 mov 1, %g7 sllx %g7, TSB_TAG_INVALID_BIT, %g7 brgez,a,pn %g5, kvmap_dtlb_longpath - TSB_STORE(%g1, %g7) + KTSB_STORE(%g1, %g7) - TSB_WRITE(%g1, %g5, %g6) + KTSB_WRITE(%g1, %g5, %g6) /* fallthrough to TLB load */ diff --git a/trunk/arch/sparc/kernel/mdesc.c b/trunk/arch/sparc/kernel/mdesc.c index acaebb63c4fd..42f28c7420e1 100644 --- a/trunk/arch/sparc/kernel/mdesc.c +++ b/trunk/arch/sparc/kernel/mdesc.c @@ -508,8 +508,6 @@ const char *mdesc_node_name(struct mdesc_handle *hp, u64 node) } EXPORT_SYMBOL(mdesc_node_name); -static u64 max_cpus = 64; - static void __init report_platform_properties(void) { struct mdesc_handle *hp = mdesc_grab(); @@ -545,10 +543,8 @@ static void __init report_platform_properties(void) if (v) printk("PLATFORM: watchdog-max-timeout [%llu ms]\n", *v); v = mdesc_get_property(hp, pn, "max-cpus", NULL); - if (v) { - max_cpus = *v; - printk("PLATFORM: max-cpus [%llu]\n", max_cpus); - } + if (v) + printk("PLATFORM: max-cpus [%llu]\n", *v); #ifdef CONFIG_SMP { @@ -719,7 +715,7 @@ static void __cpuinit set_proc_ids(struct mdesc_handle *hp) } static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, - unsigned long def, unsigned long max) + unsigned char def) { u64 val; @@ -730,9 +726,6 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, if (!val || val >= 64) goto use_default; - if (val > max) - val = max; - *mask = ((1U << val) * 64U) - 1U; return; @@ -743,28 +736,19 @@ static void __cpuinit get_one_mondo_bits(const u64 *p, unsigned int *mask, static void __cpuinit get_mondo_data(struct mdesc_handle *hp, u64 mp, struct trap_per_cpu *tb) { - static int printed; const u64 *val; val = mdesc_get_property(hp, mp, "q-cpu-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7, ilog2(max_cpus * 2)); + get_one_mondo_bits(val, &tb->cpu_mondo_qmask, 7); val = mdesc_get_property(hp, mp, "q-dev-mondo-#bits", NULL); - get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7, 8); + get_one_mondo_bits(val, &tb->dev_mondo_qmask, 7); val = mdesc_get_property(hp, mp, "q-resumable-#bits", NULL); - get_one_mondo_bits(val, &tb->resum_qmask, 6, 7); + get_one_mondo_bits(val, &tb->resum_qmask, 6); val = mdesc_get_property(hp, mp, "q-nonresumable-#bits", NULL); - get_one_mondo_bits(val, &tb->nonresum_qmask, 2, 2); - if (!printed++) { - pr_info("SUN4V: Mondo queue sizes " - "[cpu(%u) dev(%u) r(%u) nr(%u)]\n", - tb->cpu_mondo_qmask + 1, - tb->dev_mondo_qmask + 1, - tb->resum_qmask + 1, - tb->nonresum_qmask + 1); - } + get_one_mondo_bits(val, &tb->nonresum_qmask, 2); } static void * __cpuinit mdesc_iterate_over_cpus(void *(*func)(struct mdesc_handle *, u64, int, void *), void *arg, cpumask_t *mask) diff --git a/trunk/arch/sparc/kernel/setup_64.c b/trunk/arch/sparc/kernel/setup_64.c index 3e9daea1653d..c4dd0999da86 100644 --- a/trunk/arch/sparc/kernel/setup_64.c +++ b/trunk/arch/sparc/kernel/setup_64.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include @@ -47,8 +46,6 @@ #include #include #include -#include -#include #ifdef CONFIG_IP_PNP #include @@ -272,40 +269,6 @@ void __init sun4v_patch(void) sun4v_hvapi_init(); } -static void __init popc_patch(void) -{ - struct popc_3insn_patch_entry *p3; - struct popc_6insn_patch_entry *p6; - - p3 = &__popc_3insn_patch; - while (p3 < &__popc_3insn_patch_end) { - unsigned long i, addr = p3->addr; - - for (i = 0; i < 3; i++) { - *(unsigned int *) (addr + (i * 4)) = p3->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p3++; - } - - p6 = &__popc_6insn_patch; - while (p6 < &__popc_6insn_patch_end) { - unsigned long i, addr = p6->addr; - - for (i = 0; i < 6; i++) { - *(unsigned int *) (addr + (i * 4)) = p6->insns[i]; - wmb(); - __asm__ __volatile__("flush %0" - : : "r" (addr + (i * 4))); - } - - p6++; - } -} - #ifdef CONFIG_SMP void __init boot_cpu_id_too_large(int cpu) { @@ -315,154 +278,6 @@ void __init boot_cpu_id_too_large(int cpu) } #endif -/* On Ultra, we support all of the v8 capabilities. */ -unsigned long sparc64_elf_hwcap = (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | - HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV | - HWCAP_SPARC_V9); -EXPORT_SYMBOL(sparc64_elf_hwcap); - -static const char *hwcaps[] = { - "flush", "stbar", "swap", "muldiv", "v9", - "ultra3", "blkinit", "n2", - - /* These strings are as they appear in the machine description - * 'hwcap-list' property for cpu nodes. - */ - "mul32", "div32", "fsmuld", "v8plus", "popc", "vis", "vis2", - "ASIBlkInit", "fmaf", "vis3", "hpc", "random", "trans", "fjfmau", - "ima", "cspare", -}; - -void cpucap_info(struct seq_file *m) -{ - unsigned long caps = sparc64_elf_hwcap; - int i, printed = 0; - - seq_puts(m, "cpucaps\t\t: "); - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - if (caps & bit) { - seq_printf(m, "%s%s", - printed ? "," : "", hwcaps[i]); - printed++; - } - } - seq_putc(m, '\n'); -} - -static void __init report_hwcaps(unsigned long caps) -{ - int i, printed = 0; - - printk(KERN_INFO "CPU CAPS: ["); - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - if (caps & bit) { - printk(KERN_CONT "%s%s", - printed ? "," : "", hwcaps[i]); - if (++printed == 8) { - printk(KERN_CONT "]\n"); - printk(KERN_INFO "CPU CAPS: ["); - printed = 0; - } - } - } - printk(KERN_CONT "]\n"); -} - -static unsigned long __init mdesc_cpu_hwcap_list(void) -{ - struct mdesc_handle *hp; - unsigned long caps = 0; - const char *prop; - int len; - u64 pn; - - hp = mdesc_grab(); - if (!hp) - return 0; - - pn = mdesc_node_by_name(hp, MDESC_NODE_NULL, "cpu"); - if (pn == MDESC_NODE_NULL) - goto out; - - prop = mdesc_get_property(hp, pn, "hwcap-list", &len); - if (!prop) - goto out; - - while (len) { - int i, plen; - - for (i = 0; i < ARRAY_SIZE(hwcaps); i++) { - unsigned long bit = 1UL << i; - - if (!strcmp(prop, hwcaps[i])) { - caps |= bit; - break; - } - } - - plen = strlen(prop) + 1; - prop += plen; - len -= plen; - } - -out: - mdesc_release(hp); - return caps; -} - -/* This yields a mask that user programs can use to figure out what - * instruction set this cpu supports. - */ -static void __init init_sparc64_elf_hwcap(void) -{ - unsigned long cap = sparc64_elf_hwcap; - unsigned long mdesc_caps; - - if (tlb_type == cheetah || tlb_type == cheetah_plus) - cap |= HWCAP_SPARC_ULTRA3; - else if (tlb_type == hypervisor) { - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= HWCAP_SPARC_BLKINIT; - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= HWCAP_SPARC_N2; - } - - cap |= (AV_SPARC_MUL32 | AV_SPARC_DIV32 | AV_SPARC_V8PLUS); - - mdesc_caps = mdesc_cpu_hwcap_list(); - if (!mdesc_caps) { - if (tlb_type == spitfire) - cap |= AV_SPARC_VIS; - if (tlb_type == cheetah || tlb_type == cheetah_plus) - cap |= AV_SPARC_VIS | AV_SPARC_VIS2; - if (tlb_type == cheetah_plus) - cap |= AV_SPARC_POPC; - if (tlb_type == hypervisor) { - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA1) - cap |= AV_SPARC_ASI_BLK_INIT; - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA2 || - sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= (AV_SPARC_VIS | AV_SPARC_VIS2 | - AV_SPARC_ASI_BLK_INIT | - AV_SPARC_POPC); - if (sun4v_chip_type == SUN4V_CHIP_NIAGARA3) - cap |= (AV_SPARC_VIS3 | AV_SPARC_HPC | - AV_SPARC_FMAF); - } - } - sparc64_elf_hwcap = cap | mdesc_caps; - - report_hwcaps(sparc64_elf_hwcap); - - if (sparc64_elf_hwcap & AV_SPARC_POPC) - popc_patch(); -} - void __init setup_arch(char **cmdline_p) { /* Initialize PROM console and command line. */ @@ -522,7 +337,6 @@ void __init setup_arch(char **cmdline_p) init_cur_cpu_trap(current_thread_info()); paging_init(); - init_sparc64_elf_hwcap(); } extern int stop_a_enabled; diff --git a/trunk/arch/sparc/kernel/sparc_ksyms_64.c b/trunk/arch/sparc/kernel/sparc_ksyms_64.c index 83b47ab02d96..372ad59c4cba 100644 --- a/trunk/arch/sparc/kernel/sparc_ksyms_64.c +++ b/trunk/arch/sparc/kernel/sparc_ksyms_64.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include @@ -39,15 +38,5 @@ EXPORT_SYMBOL(sun4v_niagara_setperf); EXPORT_SYMBOL(sun4v_niagara2_getperf); EXPORT_SYMBOL(sun4v_niagara2_setperf); -/* from hweight.S */ -EXPORT_SYMBOL(__arch_hweight8); -EXPORT_SYMBOL(__arch_hweight16); -EXPORT_SYMBOL(__arch_hweight32); -EXPORT_SYMBOL(__arch_hweight64); - -/* from ffs_ffz.S */ -EXPORT_SYMBOL(ffs); -EXPORT_SYMBOL(__ffs); - /* Exporting a symbol from /init/main.c */ EXPORT_SYMBOL(saved_command_line); diff --git a/trunk/arch/sparc/kernel/sstate.c b/trunk/arch/sparc/kernel/sstate.c index c59af546f522..8cdbe5946b43 100644 --- a/trunk/arch/sparc/kernel/sstate.c +++ b/trunk/arch/sparc/kernel/sstate.c @@ -14,10 +14,15 @@ #include #include -#include "kernel.h" - static int hv_supports_soft_state; +static unsigned long kimage_addr_to_ra(const char *p) +{ + unsigned long val = (unsigned long) p; + + return kern_base + (val - KERNBASE); +} + static void do_set_sstate(unsigned long state, const char *msg) { unsigned long err; diff --git a/trunk/arch/sparc/kernel/unaligned_64.c b/trunk/arch/sparc/kernel/unaligned_64.c index 76e4ac1a13e1..35cff1673aa4 100644 --- a/trunk/arch/sparc/kernel/unaligned_64.c +++ b/trunk/arch/sparc/kernel/unaligned_64.c @@ -22,7 +22,6 @@ #include #include #include -#include #include enum direction { @@ -374,11 +373,16 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn) } } +static char popc_helper[] = { +0, 1, 1, 2, 1, 2, 2, 3, +1, 2, 2, 3, 2, 3, 3, 4, +}; + int handle_popc(u32 insn, struct pt_regs *regs) { - int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; - int ret, rd = ((insn >> 25) & 0x1f); u64 value; + int ret, i, rd = ((insn >> 25) & 0x1f); + int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; perf_sw_event(PERF_COUNT_SW_EMULATION_FAULTS, 1, regs, 0); if (insn & 0x2000) { @@ -388,7 +392,10 @@ int handle_popc(u32 insn, struct pt_regs *regs) maybe_flush_windows(0, insn & 0x1f, rd, from_kernel); value = fetch_reg(insn & 0x1f, regs); } - ret = hweight64(value); + for (ret = 0, i = 0; i < 16; i++) { + ret += popc_helper[value & 0xf]; + value >>= 4; + } if (rd < 16) { if (rd) regs->u_regs[rd] = ret; diff --git a/trunk/arch/sparc/kernel/vmlinux.lds.S b/trunk/arch/sparc/kernel/vmlinux.lds.S index 0e1605697b49..c0220759003e 100644 --- a/trunk/arch/sparc/kernel/vmlinux.lds.S +++ b/trunk/arch/sparc/kernel/vmlinux.lds.S @@ -107,26 +107,7 @@ SECTIONS *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } - .swapper_tsb_phys_patch : { - __swapper_tsb_phys_patch = .; - *(.swapper_tsb_phys_patch) - __swapper_tsb_phys_patch_end = .; - } - .swapper_4m_tsb_phys_patch : { - __swapper_4m_tsb_phys_patch = .; - *(.swapper_4m_tsb_phys_patch) - __swapper_4m_tsb_phys_patch_end = .; - } - .popc_3insn_patch : { - __popc_3insn_patch = .; - *(.popc_3insn_patch) - __popc_3insn_patch_end = .; - } - .popc_6insn_patch : { - __popc_6insn_patch = .; - *(.popc_6insn_patch) - __popc_6insn_patch_end = .; - } + PERCPU_SECTION(SMP_CACHE_BYTES) . = ALIGN(PAGE_SIZE); diff --git a/trunk/arch/sparc/lib/Makefile b/trunk/arch/sparc/lib/Makefile index a3fc4375a150..7f01b8fce8bc 100644 --- a/trunk/arch/sparc/lib/Makefile +++ b/trunk/arch/sparc/lib/Makefile @@ -31,13 +31,13 @@ lib-$(CONFIG_SPARC64) += NGmemcpy.o NGcopy_from_user.o NGcopy_to_user.o lib-$(CONFIG_SPARC64) += NGpatch.o NGpage.o NGbzero.o lib-$(CONFIG_SPARC64) += NG2memcpy.o NG2copy_from_user.o NG2copy_to_user.o -lib-$(CONFIG_SPARC64) += NG2patch.o +lib-$(CONFIG_SPARC64) += NG2patch.o NG2page.o lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o -lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o +lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o obj-y += iomap.o obj-$(CONFIG_SPARC32) += atomic32.o diff --git a/trunk/arch/sparc/lib/NG2page.S b/trunk/arch/sparc/lib/NG2page.S new file mode 100644 index 000000000000..73b6b7c72cbf --- /dev/null +++ b/trunk/arch/sparc/lib/NG2page.S @@ -0,0 +1,61 @@ +/* NG2page.S: Niagara-2 optimized clear and copy page. + * + * Copyright (C) 2007 (davem@davemloft.net) + */ + +#include +#include +#include + + .text + .align 32 + + /* This is heavily simplified from the sun4u variants + * because Niagara-2 does not have any D-cache aliasing issues. + */ +NG2copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ + prefetch [%o1 + 0x00], #one_read + prefetch [%o1 + 0x40], #one_read + VISEntryHalf + set PAGE_SIZE, %g7 + sub %o0, %o1, %g3 +1: stxa %g0, [%o1 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 + ldda [%o1] ASI_BLK_P, %f0 + stda %f0, [%o1 + %g3] ASI_BLK_P + add %o1, 64, %o1 + bne,pt %xcc, 1b + prefetch [%o1 + 0x40], #one_read + membar #Sync + VISExitHalf + retl + nop + +#define BRANCH_ALWAYS 0x10680000 +#define NOP 0x01000000 +#define NG_DO_PATCH(OLD, NEW) \ + sethi %hi(NEW), %g1; \ + or %g1, %lo(NEW), %g1; \ + sethi %hi(OLD), %g2; \ + or %g2, %lo(OLD), %g2; \ + sub %g1, %g2, %g1; \ + sethi %hi(BRANCH_ALWAYS), %g3; \ + sll %g1, 11, %g1; \ + srl %g1, 11 + 2, %g1; \ + or %g3, %lo(BRANCH_ALWAYS), %g3; \ + or %g3, %g1, %g3; \ + stw %g3, [%g2]; \ + sethi %hi(NOP), %g3; \ + or %g3, %lo(NOP), %g3; \ + stw %g3, [%g2 + 0x4]; \ + flush %g2; + + .globl niagara2_patch_pageops + .type niagara2_patch_pageops,#function +niagara2_patch_pageops: + NG_DO_PATCH(copy_user_page, NG2copy_user_page) + NG_DO_PATCH(_clear_page, NGclear_page) + NG_DO_PATCH(clear_user_page, NGclear_user_page) + retl + nop + .size niagara2_patch_pageops,.-niagara2_patch_pageops diff --git a/trunk/arch/sparc/lib/NGpage.S b/trunk/arch/sparc/lib/NGpage.S index b9e790b9c6b8..428920de05ba 100644 --- a/trunk/arch/sparc/lib/NGpage.S +++ b/trunk/arch/sparc/lib/NGpage.S @@ -16,91 +16,55 @@ */ NGcopy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ - save %sp, -192, %sp - rd %asi, %g3 - wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + prefetch [%o1 + 0x00], #one_read + mov 8, %g1 + mov 16, %g2 + mov 24, %g3 set PAGE_SIZE, %g7 - prefetch [%i1 + 0x00], #one_read - prefetch [%i1 + 0x40], #one_read -1: prefetch [%i1 + 0x80], #one_read - prefetch [%i1 + 0xc0], #one_read - ldda [%i1 + 0x00] %asi, %o2 - ldda [%i1 + 0x10] %asi, %o4 - ldda [%i1 + 0x20] %asi, %l2 - ldda [%i1 + 0x30] %asi, %l4 - stxa %o2, [%i0 + 0x00] %asi - stxa %o3, [%i0 + 0x08] %asi - stxa %o4, [%i0 + 0x10] %asi - stxa %o5, [%i0 + 0x18] %asi - stxa %l2, [%i0 + 0x20] %asi - stxa %l3, [%i0 + 0x28] %asi - stxa %l4, [%i0 + 0x30] %asi - stxa %l5, [%i0 + 0x38] %asi - ldda [%i1 + 0x40] %asi, %o2 - ldda [%i1 + 0x50] %asi, %o4 - ldda [%i1 + 0x60] %asi, %l2 - ldda [%i1 + 0x70] %asi, %l4 - stxa %o2, [%i0 + 0x40] %asi - stxa %o3, [%i0 + 0x48] %asi - stxa %o4, [%i0 + 0x50] %asi - stxa %o5, [%i0 + 0x58] %asi - stxa %l2, [%i0 + 0x60] %asi - stxa %l3, [%i0 + 0x68] %asi - stxa %l4, [%i0 + 0x70] %asi - stxa %l5, [%i0 + 0x78] %asi - add %i1, 128, %i1 - subcc %g7, 128, %g7 +1: ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 + ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 + prefetch [%o1 + 0x40], #one_read + add %o1, 32, %o1 + stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + ldda [%o1 + %g0] ASI_BLK_INIT_QUAD_LDD_P, %o2 + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + ldda [%o1 + %g2] ASI_BLK_INIT_QUAD_LDD_P, %o4 + add %o1, 32, %o1 + add %o0, 32, %o0 + stxa %o2, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %o3, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %o4, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %o5, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 bne,pt %xcc, 1b - add %i0, 128, %i0 - wr %g3, 0x0, %asi + add %o0, 32, %o0 membar #Sync - ret - restore + retl + nop - .align 32 + .globl NGclear_page, NGclear_user_page NGclear_page: /* %o0=dest */ NGclear_user_page: /* %o0=dest, %o1=vaddr */ - rd %asi, %g3 - wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi + mov 8, %g1 + mov 16, %g2 + mov 24, %g3 set PAGE_SIZE, %g7 -1: stxa %g0, [%o0 + 0x00] %asi - stxa %g0, [%o0 + 0x08] %asi - stxa %g0, [%o0 + 0x10] %asi - stxa %g0, [%o0 + 0x18] %asi - stxa %g0, [%o0 + 0x20] %asi - stxa %g0, [%o0 + 0x28] %asi - stxa %g0, [%o0 + 0x30] %asi - stxa %g0, [%o0 + 0x38] %asi - stxa %g0, [%o0 + 0x40] %asi - stxa %g0, [%o0 + 0x48] %asi - stxa %g0, [%o0 + 0x50] %asi - stxa %g0, [%o0 + 0x58] %asi - stxa %g0, [%o0 + 0x60] %asi - stxa %g0, [%o0 + 0x68] %asi - stxa %g0, [%o0 + 0x70] %asi - stxa %g0, [%o0 + 0x78] %asi - stxa %g0, [%o0 + 0x80] %asi - stxa %g0, [%o0 + 0x88] %asi - stxa %g0, [%o0 + 0x90] %asi - stxa %g0, [%o0 + 0x98] %asi - stxa %g0, [%o0 + 0xa0] %asi - stxa %g0, [%o0 + 0xa8] %asi - stxa %g0, [%o0 + 0xb0] %asi - stxa %g0, [%o0 + 0xb8] %asi - stxa %g0, [%o0 + 0xc0] %asi - stxa %g0, [%o0 + 0xc8] %asi - stxa %g0, [%o0 + 0xd0] %asi - stxa %g0, [%o0 + 0xd8] %asi - stxa %g0, [%o0 + 0xe0] %asi - stxa %g0, [%o0 + 0xe8] %asi - stxa %g0, [%o0 + 0xf0] %asi - stxa %g0, [%o0 + 0xf8] %asi - subcc %g7, 256, %g7 +1: stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + add %o0, 32, %o0 + stxa %g0, [%o0 + %g0] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g1] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g2] ASI_BLK_INIT_QUAD_LDD_P + stxa %g0, [%o0 + %g3] ASI_BLK_INIT_QUAD_LDD_P + subcc %g7, 64, %g7 bne,pt %xcc, 1b - add %o0, 256, %o0 - wr %g3, 0x0, %asi + add %o0, 32, %o0 membar #Sync retl nop diff --git a/trunk/arch/sparc/lib/atomic32.c b/trunk/arch/sparc/lib/atomic32.c index 1d32b54089aa..8600eb2461b5 100644 --- a/trunk/arch/sparc/lib/atomic32.c +++ b/trunk/arch/sparc/lib/atomic32.c @@ -65,7 +65,7 @@ int __atomic_add_unless(atomic_t *v, int a, int u) if (ret != u) v->counter += a; spin_unlock_irqrestore(ATOMIC_HASH(v), flags); - return ret; + return ret != u; } EXPORT_SYMBOL(__atomic_add_unless); diff --git a/trunk/arch/sparc/lib/ffs.S b/trunk/arch/sparc/lib/ffs.S deleted file mode 100644 index b39389f69899..000000000000 --- a/trunk/arch/sparc/lib/ffs.S +++ /dev/null @@ -1,84 +0,0 @@ -#include - - .register %g2,#scratch - - .text - .align 32 - -ENTRY(ffs) - brnz,pt %o0, 1f - mov 1, %o1 - retl - clr %o0 - nop - nop -ENTRY(__ffs) - sllx %o0, 32, %g1 /* 1 */ - srlx %o0, 32, %g2 - - clr %o1 /* 2 */ - movrz %g1, %g2, %o0 - - movrz %g1, 32, %o1 /* 3 */ -1: clr %o2 - - sllx %o0, (64 - 16), %g1 /* 4 */ - srlx %o0, 16, %g2 - - movrz %g1, %g2, %o0 /* 5 */ - clr %o3 - - movrz %g1, 16, %o2 /* 6 */ - clr %o4 - - and %o0, 0xff, %g1 /* 7 */ - srlx %o0, 8, %g2 - - movrz %g1, %g2, %o0 /* 8 */ - clr %o5 - - movrz %g1, 8, %o3 /* 9 */ - add %o2, %o1, %o2 - - and %o0, 0xf, %g1 /* 10 */ - srlx %o0, 4, %g2 - - movrz %g1, %g2, %o0 /* 11 */ - add %o2, %o3, %o2 - - movrz %g1, 4, %o4 /* 12 */ - - and %o0, 0x3, %g1 /* 13 */ - srlx %o0, 2, %g2 - - movrz %g1, %g2, %o0 /* 14 */ - add %o2, %o4, %o2 - - movrz %g1, 2, %o5 /* 15 */ - - and %o0, 0x1, %g1 /* 16 */ - - add %o2, %o5, %o2 /* 17 */ - xor %g1, 0x1, %g1 - - retl /* 18 */ - add %o2, %g1, %o0 -ENDPROC(ffs) -ENDPROC(__ffs) - - .section .popc_6insn_patch, "ax" - .word ffs - brz,pn %o0, 98f - neg %o0, %g1 - xnor %o0, %g1, %o1 - popc %o1, %o0 -98: retl - nop - .word __ffs - neg %o0, %g1 - xnor %o0, %g1, %o1 - popc %o1, %o0 - retl - sub %o0, 1, %o0 - nop - .previous diff --git a/trunk/arch/sparc/lib/hweight.S b/trunk/arch/sparc/lib/hweight.S deleted file mode 100644 index 95414e0a6808..000000000000 --- a/trunk/arch/sparc/lib/hweight.S +++ /dev/null @@ -1,51 +0,0 @@ -#include - - .text - .align 32 -ENTRY(__arch_hweight8) - ba,pt %xcc, __sw_hweight8 - nop - nop -ENDPROC(__arch_hweight8) - .section .popc_3insn_patch, "ax" - .word __arch_hweight8 - sllx %o0, 64-8, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight16) - ba,pt %xcc, __sw_hweight16 - nop - nop -ENDPROC(__arch_hweight16) - .section .popc_3insn_patch, "ax" - .word __arch_hweight16 - sllx %o0, 64-16, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight32) - ba,pt %xcc, __sw_hweight32 - nop - nop -ENDPROC(__arch_hweight32) - .section .popc_3insn_patch, "ax" - .word __arch_hweight32 - sllx %o0, 64-32, %g1 - retl - popc %g1, %o0 - .previous - -ENTRY(__arch_hweight64) - ba,pt %xcc, __sw_hweight64 - nop - nop -ENDPROC(__arch_hweight64) - .section .popc_3insn_patch, "ax" - .word __arch_hweight64 - retl - popc %o0, %o0 - nop - .previous diff --git a/trunk/arch/sparc/mm/init_64.c b/trunk/arch/sparc/mm/init_64.c index 581531dbc8b5..3fd8e18bed80 100644 --- a/trunk/arch/sparc/mm/init_64.c +++ b/trunk/arch/sparc/mm/init_64.c @@ -1597,44 +1597,6 @@ static void __init tsb_phys_patch(void) static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; -static void patch_one_ktsb_phys(unsigned int *start, unsigned int *end, unsigned long pa) -{ - pa >>= KTSB_PHYS_SHIFT; - - while (start < end) { - unsigned int *ia = (unsigned int *)(unsigned long)*start; - - ia[0] = (ia[0] & ~0x3fffff) | (pa >> 10); - __asm__ __volatile__("flush %0" : : "r" (ia)); - - ia[1] = (ia[1] & ~0x3ff) | (pa & 0x3ff); - __asm__ __volatile__("flush %0" : : "r" (ia + 1)); - - start++; - } -} - -static void ktsb_phys_patch(void) -{ - extern unsigned int __swapper_tsb_phys_patch; - extern unsigned int __swapper_tsb_phys_patch_end; - unsigned long ktsb_pa; - - ktsb_pa = kern_base + ((unsigned long)&swapper_tsb[0] - KERNBASE); - patch_one_ktsb_phys(&__swapper_tsb_phys_patch, - &__swapper_tsb_phys_patch_end, ktsb_pa); -#ifndef CONFIG_DEBUG_PAGEALLOC - { - extern unsigned int __swapper_4m_tsb_phys_patch; - extern unsigned int __swapper_4m_tsb_phys_patch_end; - ktsb_pa = (kern_base + - ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); - patch_one_ktsb_phys(&__swapper_4m_tsb_phys_patch, - &__swapper_4m_tsb_phys_patch_end, ktsb_pa); - } -#endif -} - static void __init sun4v_ktsb_init(void) { unsigned long ktsb_pa; @@ -1754,10 +1716,8 @@ void __init paging_init(void) sun4u_pgprot_init(); if (tlb_type == cheetah_plus || - tlb_type == hypervisor) { + tlb_type == hypervisor) tsb_phys_patch(); - ktsb_phys_patch(); - } if (tlb_type == hypervisor) { sun4v_patch_tlb_handlers(); diff --git a/trunk/arch/tile/Kconfig b/trunk/arch/tile/Kconfig index b30f71ac0d06..0249b8b4db54 100644 --- a/trunk/arch/tile/Kconfig +++ b/trunk/arch/tile/Kconfig @@ -12,7 +12,6 @@ config TILE select GENERIC_PENDING_IRQ if SMP select GENERIC_IRQ_SHOW select SYS_HYPERVISOR - select ARCH_HAVE_NMI_SAFE_CMPXCHG if !M386 # FIXME: investigate whether we need/want these options. # select HAVE_IOREMAP_PROT diff --git a/trunk/arch/tile/include/asm/Kbuild b/trunk/arch/tile/include/asm/Kbuild index aec60dc06007..849ab2fa1f5c 100644 --- a/trunk/arch/tile/include/asm/Kbuild +++ b/trunk/arch/tile/include/asm/Kbuild @@ -2,41 +2,3 @@ include include/asm-generic/Kbuild.asm header-y += ucontext.h header-y += hardwall.h - -generic-y += bug.h -generic-y += bugs.h -generic-y += cputime.h -generic-y += device.h -generic-y += div64.h -generic-y += emergency-restart.h -generic-y += errno.h -generic-y += fb.h -generic-y += fcntl.h -generic-y += ioctl.h -generic-y += ioctls.h -generic-y += ipc.h -generic-y += ipcbuf.h -generic-y += irq_regs.h -generic-y += kdebug.h -generic-y += local.h -generic-y += module.h -generic-y += msgbuf.h -generic-y += mutex.h -generic-y += param.h -generic-y += parport.h -generic-y += poll.h -generic-y += posix_types.h -generic-y += resource.h -generic-y += scatterlist.h -generic-y += sembuf.h -generic-y += serial.h -generic-y += shmbuf.h -generic-y += shmparam.h -generic-y += socket.h -generic-y += sockios.h -generic-y += statfs.h -generic-y += termbits.h -generic-y += termios.h -generic-y += types.h -generic-y += ucontext.h -generic-y += xor.h diff --git a/trunk/arch/tile/include/asm/bug.h b/trunk/arch/tile/include/asm/bug.h new file mode 100644 index 000000000000..b12fd89e42e9 --- /dev/null +++ b/trunk/arch/tile/include/asm/bug.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/bugs.h b/trunk/arch/tile/include/asm/bugs.h new file mode 100644 index 000000000000..61791e1ad9f5 --- /dev/null +++ b/trunk/arch/tile/include/asm/bugs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/cputime.h b/trunk/arch/tile/include/asm/cputime.h new file mode 100644 index 000000000000..6d68ad7e0ea3 --- /dev/null +++ b/trunk/arch/tile/include/asm/cputime.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/device.h b/trunk/arch/tile/include/asm/device.h new file mode 100644 index 000000000000..f0a4c256403b --- /dev/null +++ b/trunk/arch/tile/include/asm/device.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/div64.h b/trunk/arch/tile/include/asm/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/trunk/arch/tile/include/asm/div64.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/emergency-restart.h b/trunk/arch/tile/include/asm/emergency-restart.h new file mode 100644 index 000000000000..3711bd9d50bd --- /dev/null +++ b/trunk/arch/tile/include/asm/emergency-restart.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/errno.h b/trunk/arch/tile/include/asm/errno.h new file mode 100644 index 000000000000..4c82b503d92f --- /dev/null +++ b/trunk/arch/tile/include/asm/errno.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/fb.h b/trunk/arch/tile/include/asm/fb.h new file mode 100644 index 000000000000..3a4988e8df45 --- /dev/null +++ b/trunk/arch/tile/include/asm/fb.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/fcntl.h b/trunk/arch/tile/include/asm/fcntl.h new file mode 100644 index 000000000000..46ab12db5739 --- /dev/null +++ b/trunk/arch/tile/include/asm/fcntl.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/fixmap.h b/trunk/arch/tile/include/asm/fixmap.h index c66f7933beaa..51537ff9265a 100644 --- a/trunk/arch/tile/include/asm/fixmap.h +++ b/trunk/arch/tile/include/asm/fixmap.h @@ -75,6 +75,12 @@ extern void __set_fixmap(enum fixed_addresses idx, #define set_fixmap(idx, phys) \ __set_fixmap(idx, phys, PAGE_KERNEL) +/* + * Some hardware wants to get fixmapped without caching. + */ +#define set_fixmap_nocache(idx, phys) \ + __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) + #define clear_fixmap(idx) \ __set_fixmap(idx, 0, __pgprot(0)) diff --git a/trunk/arch/tile/include/asm/ioctl.h b/trunk/arch/tile/include/asm/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/trunk/arch/tile/include/asm/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/ioctls.h b/trunk/arch/tile/include/asm/ioctls.h new file mode 100644 index 000000000000..ec34c760665e --- /dev/null +++ b/trunk/arch/tile/include/asm/ioctls.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/ipc.h b/trunk/arch/tile/include/asm/ipc.h new file mode 100644 index 000000000000..a46e3d9c2a3f --- /dev/null +++ b/trunk/arch/tile/include/asm/ipc.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/ipcbuf.h b/trunk/arch/tile/include/asm/ipcbuf.h new file mode 100644 index 000000000000..84c7e51cb6d0 --- /dev/null +++ b/trunk/arch/tile/include/asm/ipcbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/irq_regs.h b/trunk/arch/tile/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/trunk/arch/tile/include/asm/irq_regs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/kdebug.h b/trunk/arch/tile/include/asm/kdebug.h new file mode 100644 index 000000000000..6ece1b037665 --- /dev/null +++ b/trunk/arch/tile/include/asm/kdebug.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/local.h b/trunk/arch/tile/include/asm/local.h new file mode 100644 index 000000000000..c11c530f74d0 --- /dev/null +++ b/trunk/arch/tile/include/asm/local.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/module.h b/trunk/arch/tile/include/asm/module.h new file mode 100644 index 000000000000..1e4b79fe8584 --- /dev/null +++ b/trunk/arch/tile/include/asm/module.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/msgbuf.h b/trunk/arch/tile/include/asm/msgbuf.h new file mode 100644 index 000000000000..809134c644a6 --- /dev/null +++ b/trunk/arch/tile/include/asm/msgbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/mutex.h b/trunk/arch/tile/include/asm/mutex.h new file mode 100644 index 000000000000..ff6101aa2c71 --- /dev/null +++ b/trunk/arch/tile/include/asm/mutex.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/param.h b/trunk/arch/tile/include/asm/param.h new file mode 100644 index 000000000000..965d45427975 --- /dev/null +++ b/trunk/arch/tile/include/asm/param.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/parport.h b/trunk/arch/tile/include/asm/parport.h new file mode 100644 index 000000000000..cf252af64590 --- /dev/null +++ b/trunk/arch/tile/include/asm/parport.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/poll.h b/trunk/arch/tile/include/asm/poll.h new file mode 100644 index 000000000000..c98509d3149e --- /dev/null +++ b/trunk/arch/tile/include/asm/poll.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/posix_types.h b/trunk/arch/tile/include/asm/posix_types.h new file mode 100644 index 000000000000..22cae6230ceb --- /dev/null +++ b/trunk/arch/tile/include/asm/posix_types.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/resource.h b/trunk/arch/tile/include/asm/resource.h new file mode 100644 index 000000000000..04bc4db8921b --- /dev/null +++ b/trunk/arch/tile/include/asm/resource.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/scatterlist.h b/trunk/arch/tile/include/asm/scatterlist.h new file mode 100644 index 000000000000..35d786fe93ae --- /dev/null +++ b/trunk/arch/tile/include/asm/scatterlist.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/sembuf.h b/trunk/arch/tile/include/asm/sembuf.h new file mode 100644 index 000000000000..7673b83cfef7 --- /dev/null +++ b/trunk/arch/tile/include/asm/sembuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/serial.h b/trunk/arch/tile/include/asm/serial.h new file mode 100644 index 000000000000..a0cb0caff152 --- /dev/null +++ b/trunk/arch/tile/include/asm/serial.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/shmbuf.h b/trunk/arch/tile/include/asm/shmbuf.h new file mode 100644 index 000000000000..83c05fc2de38 --- /dev/null +++ b/trunk/arch/tile/include/asm/shmbuf.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/shmparam.h b/trunk/arch/tile/include/asm/shmparam.h new file mode 100644 index 000000000000..93f30deb95d0 --- /dev/null +++ b/trunk/arch/tile/include/asm/shmparam.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/socket.h b/trunk/arch/tile/include/asm/socket.h new file mode 100644 index 000000000000..6b71384b9d8b --- /dev/null +++ b/trunk/arch/tile/include/asm/socket.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/sockios.h b/trunk/arch/tile/include/asm/sockios.h new file mode 100644 index 000000000000..def6d4746ee7 --- /dev/null +++ b/trunk/arch/tile/include/asm/sockios.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/statfs.h b/trunk/arch/tile/include/asm/statfs.h new file mode 100644 index 000000000000..0b91fe198c20 --- /dev/null +++ b/trunk/arch/tile/include/asm/statfs.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/termbits.h b/trunk/arch/tile/include/asm/termbits.h new file mode 100644 index 000000000000..3935b106de79 --- /dev/null +++ b/trunk/arch/tile/include/asm/termbits.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/termios.h b/trunk/arch/tile/include/asm/termios.h new file mode 100644 index 000000000000..280d78a9d966 --- /dev/null +++ b/trunk/arch/tile/include/asm/termios.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/types.h b/trunk/arch/tile/include/asm/types.h new file mode 100644 index 000000000000..b9e79bc580dd --- /dev/null +++ b/trunk/arch/tile/include/asm/types.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/ucontext.h b/trunk/arch/tile/include/asm/ucontext.h new file mode 100644 index 000000000000..9bc07b9f30fb --- /dev/null +++ b/trunk/arch/tile/include/asm/ucontext.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/asm/xor.h b/trunk/arch/tile/include/asm/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/trunk/arch/tile/include/asm/xor.h @@ -0,0 +1 @@ +#include diff --git a/trunk/arch/tile/include/hv/drv_srom_intf.h b/trunk/arch/tile/include/hv/drv_srom_intf.h deleted file mode 100644 index 6395faa6d9e6..000000000000 --- a/trunk/arch/tile/include/hv/drv_srom_intf.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2011 Tilera Corporation. All Rights Reserved. - * - * 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, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - */ - -/** - * @file drv_srom_intf.h - * Interface definitions for the SPI Flash ROM driver. - */ - -#ifndef _SYS_HV_INCLUDE_DRV_SROM_INTF_H -#define _SYS_HV_INCLUDE_DRV_SROM_INTF_H - -/** Read this offset to get the total device size. */ -#define SROM_TOTAL_SIZE_OFF 0xF0000000 - -/** Read this offset to get the device sector size. */ -#define SROM_SECTOR_SIZE_OFF 0xF0000004 - -/** Read this offset to get the device page size. */ -#define SROM_PAGE_SIZE_OFF 0xF0000008 - -/** Write this offset to flush any pending writes. */ -#define SROM_FLUSH_OFF 0xF1000000 - -/** Write this offset, plus the byte offset of the start of a sector, to - * erase a sector. Any write data is ignored, but there must be at least - * one byte of write data. Only applies when the driver is in MTD mode. - */ -#define SROM_ERASE_OFF 0xF2000000 - -#endif /* _SYS_HV_INCLUDE_DRV_SROM_INTF_H */ diff --git a/trunk/arch/tile/kernel/time.c b/trunk/arch/tile/kernel/time.c index f6f50f2a5e37..c4be58cc5d50 100644 --- a/trunk/arch/tile/kernel/time.c +++ b/trunk/arch/tile/kernel/time.c @@ -78,6 +78,7 @@ static struct clocksource cycle_counter_cs = { .rating = 300, .read = clocksource_get_cycles, .mask = CLOCKSOURCE_MASK(64), + .shift = 22, /* typical value, e.g. x86 tsc uses this */ .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -90,6 +91,8 @@ void __init setup_clock(void) cycles_per_sec = hv_sysconf(HV_SYSCONF_CPU_SPEED); sched_clock_mult = clocksource_hz2mult(cycles_per_sec, SCHED_CLOCK_SHIFT); + cycle_counter_cs.mult = + clocksource_hz2mult(cycles_per_sec, cycle_counter_cs.shift); } void __init calibrate_delay(void) @@ -104,7 +107,7 @@ void __init calibrate_delay(void) void __init time_init(void) { /* Initialize and register the clock source. */ - clocksource_register_hz(&cycle_counter_cs, cycles_per_sec); + clocksource_register(&cycle_counter_cs); /* Start up the tile-timer interrupt source on the boot cpu. */ setup_tile_timer(); diff --git a/trunk/arch/tile/mm/init.c b/trunk/arch/tile/mm/init.c index 7309988c9794..4e10c4023028 100644 --- a/trunk/arch/tile/mm/init.c +++ b/trunk/arch/tile/mm/init.c @@ -836,7 +836,8 @@ void __init mem_init(void) #endif #ifdef CONFIG_FLATMEM - BUG_ON(!mem_map); + if (!mem_map) + BUG(); #endif #ifdef CONFIG_HIGHMEM diff --git a/trunk/arch/x86/Kconfig b/trunk/arch/x86/Kconfig index 6a47bb22657f..7cf916fc1ce7 100644 --- a/trunk/arch/x86/Kconfig +++ b/trunk/arch/x86/Kconfig @@ -72,7 +72,6 @@ config X86 select USE_GENERIC_SMP_HELPERS if SMP select HAVE_BPF_JIT if (X86_64 && NET) select CLKEVT_I8253 - select ARCH_HAVE_NMI_SAFE_CMPXCHG config INSTRUCTION_DECODER def_bool (KPROBES || PERF_EVENTS) diff --git a/trunk/arch/x86/include/asm/desc.h b/trunk/arch/x86/include/asm/desc.h index 41935fadfdfc..7b439d9aea2a 100644 --- a/trunk/arch/x86/include/asm/desc.h +++ b/trunk/arch/x86/include/asm/desc.h @@ -27,8 +27,8 @@ static inline void fill_ldt(struct desc_struct *desc, const struct user_desc *in desc->base2 = (info->base_addr & 0xff000000) >> 24; /* - * Don't allow setting of the lm bit. It would confuse - * user_64bit_mode and would get overridden by sysret anyway. + * Don't allow setting of the lm bit. It is useless anyway + * because 64bit system calls require __USER_CS: */ desc->l = 0; } diff --git a/trunk/arch/x86/include/asm/io.h b/trunk/arch/x86/include/asm/io.h index d8e8eefbe24c..d02804d650c4 100644 --- a/trunk/arch/x86/include/asm/io.h +++ b/trunk/arch/x86/include/asm/io.h @@ -40,6 +40,8 @@ #include #include +#include + #define build_mmio_read(name, size, type, reg, barrier) \ static inline type name(const volatile void __iomem *addr) \ { type ret; asm volatile("mov" size " %1,%0":reg (ret) \ @@ -332,7 +334,6 @@ extern void fixup_early_ioremap(void); extern bool is_early_ioremap_ptep(pte_t *ptep); #ifdef CONFIG_XEN -#include struct bio_vec; extern bool xen_biovec_phys_mergeable(const struct bio_vec *vec1, diff --git a/trunk/arch/x86/include/asm/irq_vectors.h b/trunk/arch/x86/include/asm/irq_vectors.h index 7e50f06393aa..f9a320984a10 100644 --- a/trunk/arch/x86/include/asm/irq_vectors.h +++ b/trunk/arch/x86/include/asm/irq_vectors.h @@ -17,6 +17,7 @@ * Vectors 0 ... 31 : system traps and exceptions - hardcoded events * Vectors 32 ... 127 : device interrupts * Vector 128 : legacy int80 syscall interface + * Vector 204 : legacy x86_64 vsyscall emulation * Vectors 129 ... INVALIDATE_TLB_VECTOR_START-1 except 204 : device interrupts * Vectors INVALIDATE_TLB_VECTOR_START ... 255 : special interrupts * @@ -50,6 +51,9 @@ #ifdef CONFIG_X86_32 # define SYSCALL_VECTOR 0x80 #endif +#ifdef CONFIG_X86_64 +# define VSYSCALL_EMU_VECTOR 0xcc +#endif /* * Vectors 0x30-0x3f are used for ISA interrupts. diff --git a/trunk/arch/x86/include/asm/paravirt_types.h b/trunk/arch/x86/include/asm/paravirt_types.h index 8e8b9a4987ee..2c7652163111 100644 --- a/trunk/arch/x86/include/asm/paravirt_types.h +++ b/trunk/arch/x86/include/asm/paravirt_types.h @@ -41,7 +41,6 @@ #include #include -#include struct page; struct thread_struct; @@ -64,11 +63,6 @@ struct paravirt_callee_save { struct pv_info { unsigned int kernel_rpl; int shared_kernel_pmd; - -#ifdef CONFIG_X86_64 - u16 extra_user_64bit_cs; /* __USER_CS if none */ -#endif - int paravirt_enabled; const char *name; }; diff --git a/trunk/arch/x86/include/asm/processor.h b/trunk/arch/x86/include/asm/processor.h index 0d1171c97729..219371546afd 100644 --- a/trunk/arch/x86/include/asm/processor.h +++ b/trunk/arch/x86/include/asm/processor.h @@ -751,6 +751,8 @@ static inline void __sti_mwait(unsigned long eax, unsigned long ecx) :: "a" (eax), "c" (ecx)); } +extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); + extern void select_idle_routine(const struct cpuinfo_x86 *c); extern void init_amd_e400_c1e_mask(void); diff --git a/trunk/arch/x86/include/asm/ptrace.h b/trunk/arch/x86/include/asm/ptrace.h index 35664547125b..94e7618fcac8 100644 --- a/trunk/arch/x86/include/asm/ptrace.h +++ b/trunk/arch/x86/include/asm/ptrace.h @@ -131,9 +131,6 @@ struct pt_regs { #ifdef __KERNEL__ #include -#ifdef CONFIG_PARAVIRT -#include -#endif struct cpuinfo_x86; struct task_struct; @@ -190,22 +187,6 @@ static inline int v8086_mode(struct pt_regs *regs) #endif } -#ifdef CONFIG_X86_64 -static inline bool user_64bit_mode(struct pt_regs *regs) -{ -#ifndef CONFIG_PARAVIRT - /* - * On non-paravirt systems, this is the only long mode CPL 3 - * selector. We do not allow long mode selectors in the LDT. - */ - return regs->cs == __USER_CS; -#else - /* Headers are too twisted for this to go in paravirt.h. */ - return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; -#endif -} -#endif - /* * X86_32 CPUs don't save ss and esp if the CPU is already in kernel mode * when it traps. The previous stack will be directly underneath the saved diff --git a/trunk/arch/x86/include/asm/traps.h b/trunk/arch/x86/include/asm/traps.h index 0012d0902c5f..2bae0a513b40 100644 --- a/trunk/arch/x86/include/asm/traps.h +++ b/trunk/arch/x86/include/asm/traps.h @@ -40,6 +40,7 @@ asmlinkage void alignment_check(void); asmlinkage void machine_check(void); #endif /* CONFIG_X86_MCE */ asmlinkage void simd_coprocessor_error(void); +asmlinkage void emulate_vsyscall(void); dotraplinkage void do_divide_error(struct pt_regs *, long); dotraplinkage void do_debug(struct pt_regs *, long); @@ -66,6 +67,7 @@ dotraplinkage void do_alignment_check(struct pt_regs *, long); dotraplinkage void do_machine_check(struct pt_regs *, long); #endif dotraplinkage void do_simd_coprocessor_error(struct pt_regs *, long); +dotraplinkage void do_emulate_vsyscall(struct pt_regs *, long); #ifdef CONFIG_X86_32 dotraplinkage void do_iret_error(struct pt_regs *, long); #endif diff --git a/trunk/arch/x86/include/asm/unistd_64.h b/trunk/arch/x86/include/asm/unistd_64.h index d92641cc7acc..705bf139288c 100644 --- a/trunk/arch/x86/include/asm/unistd_64.h +++ b/trunk/arch/x86/include/asm/unistd_64.h @@ -681,8 +681,6 @@ __SYSCALL(__NR_syncfs, sys_syncfs) __SYSCALL(__NR_sendmmsg, sys_sendmmsg) #define __NR_setns 308 __SYSCALL(__NR_setns, sys_setns) -#define __NR_getcpu 309 -__SYSCALL(__NR_getcpu, sys_getcpu) #ifndef __NO_STUBS #define __ARCH_WANT_OLD_READDIR diff --git a/trunk/arch/x86/include/asm/vsyscall.h b/trunk/arch/x86/include/asm/vsyscall.h index eaea1d31f753..60107072c28b 100644 --- a/trunk/arch/x86/include/asm/vsyscall.h +++ b/trunk/arch/x86/include/asm/vsyscall.h @@ -27,12 +27,6 @@ extern struct timezone sys_tz; extern void map_vsyscall(void); -/* - * Called on instruction fetch fault in vsyscall page. - * Returns true if handled. - */ -extern bool emulate_vsyscall(struct pt_regs *regs, unsigned long address); - #endif /* __KERNEL__ */ #endif /* _ASM_X86_VSYSCALL_H */ diff --git a/trunk/arch/x86/kernel/Makefile b/trunk/arch/x86/kernel/Makefile index 82f2912155a5..04105574c8e9 100644 --- a/trunk/arch/x86/kernel/Makefile +++ b/trunk/arch/x86/kernel/Makefile @@ -17,6 +17,19 @@ CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_early_printk.o = -pg endif +# +# vsyscalls (which work on the user stack) should have +# no stack-protector checks: +# +nostackp := $(call cc-option, -fno-stack-protector) +CFLAGS_vsyscall_64.o := $(PROFILING) -g0 $(nostackp) +CFLAGS_hpet.o := $(nostackp) +CFLAGS_paravirt.o := $(nostackp) +GCOV_PROFILE_vsyscall_64.o := n +GCOV_PROFILE_hpet.o := n +GCOV_PROFILE_tsc.o := n +GCOV_PROFILE_paravirt.o := n + obj-y := process_$(BITS).o signal.o entry_$(BITS).o obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o obj-y += time.o ioport.o ldt.o dumpstack.o diff --git a/trunk/arch/x86/kernel/acpi/cstate.c b/trunk/arch/x86/kernel/acpi/cstate.c index f50e7fb2a201..5812404a0d4c 100644 --- a/trunk/arch/x86/kernel/acpi/cstate.c +++ b/trunk/arch/x86/kernel/acpi/cstate.c @@ -149,29 +149,6 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu, } EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe); -/* - * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, - * which can obviate IPI to trigger checking of need_resched. - * We execute MONITOR against need_resched and enter optimized wait state - * through MWAIT. Whenever someone changes need_resched, we would be woken - * up from MWAIT (without an IPI). - * - * New with Core Duo processors, MWAIT can take some hints based on CPU - * capability. - */ -void mwait_idle_with_hints(unsigned long ax, unsigned long cx) -{ - if (!need_resched()) { - if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) - clflush((void *)¤t_thread_info()->flags); - - __monitor((void *)¤t_thread_info()->flags, 0, 0); - smp_mb(); - if (!need_resched()) - __mwait(ax, cx); - } -} - void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx) { unsigned int cpu = smp_processor_id(); diff --git a/trunk/arch/x86/kernel/cpu/perf_event_intel.c b/trunk/arch/x86/kernel/cpu/perf_event_intel.c index f88af2c2a561..45fbb8f7f549 100644 --- a/trunk/arch/x86/kernel/cpu/perf_event_intel.c +++ b/trunk/arch/x86/kernel/cpu/perf_event_intel.c @@ -1590,7 +1590,6 @@ static __init int intel_pmu_init(void) break; case 42: /* SandyBridge */ - case 45: /* SandyBridge, "Romely-EP" */ memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, sizeof(hw_cache_event_ids)); diff --git a/trunk/arch/x86/kernel/entry_64.S b/trunk/arch/x86/kernel/entry_64.S index 6419bb05ecd5..e13329d800c8 100644 --- a/trunk/arch/x86/kernel/entry_64.S +++ b/trunk/arch/x86/kernel/entry_64.S @@ -1111,6 +1111,7 @@ zeroentry spurious_interrupt_bug do_spurious_interrupt_bug zeroentry coprocessor_error do_coprocessor_error errorentry alignment_check do_alignment_check zeroentry simd_coprocessor_error do_simd_coprocessor_error +zeroentry emulate_vsyscall do_emulate_vsyscall /* Reload gs selector with exception handling */ diff --git a/trunk/arch/x86/kernel/paravirt.c b/trunk/arch/x86/kernel/paravirt.c index d90272e6bc40..613a7931ecc1 100644 --- a/trunk/arch/x86/kernel/paravirt.c +++ b/trunk/arch/x86/kernel/paravirt.c @@ -307,10 +307,6 @@ struct pv_info pv_info = { .paravirt_enabled = 0, .kernel_rpl = 0, .shared_kernel_pmd = 1, /* Only used when CONFIG_X86_PAE is set */ - -#ifdef CONFIG_X86_64 - .extra_user_64bit_cs = __USER_CS, -#endif }; struct pv_init_ops pv_init_ops = { diff --git a/trunk/arch/x86/kernel/process.c b/trunk/arch/x86/kernel/process.c index e7e3b019c439..e1ba8cb24e4e 100644 --- a/trunk/arch/x86/kernel/process.c +++ b/trunk/arch/x86/kernel/process.c @@ -438,6 +438,29 @@ void cpu_idle_wait(void) } EXPORT_SYMBOL_GPL(cpu_idle_wait); +/* + * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, + * which can obviate IPI to trigger checking of need_resched. + * We execute MONITOR against need_resched and enter optimized wait state + * through MWAIT. Whenever someone changes need_resched, we would be woken + * up from MWAIT (without an IPI). + * + * New with Core Duo processors, MWAIT can take some hints based on CPU + * capability. + */ +void mwait_idle_with_hints(unsigned long ax, unsigned long cx) +{ + if (!need_resched()) { + if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR)) + clflush((void *)¤t_thread_info()->flags); + + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) + __mwait(ax, cx); + } +} + /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { diff --git a/trunk/arch/x86/kernel/process_32.c b/trunk/arch/x86/kernel/process_32.c index 7a3b65107a27..a3d0dc59067b 100644 --- a/trunk/arch/x86/kernel/process_32.c +++ b/trunk/arch/x86/kernel/process_32.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -110,8 +109,7 @@ void cpu_idle(void) local_irq_disable(); /* Don't trace irqs off for idle */ stop_critical_timings(); - if (cpuidle_idle_call()) - pm_idle(); + pm_idle(); start_critical_timings(); } tick_nohz_restart_sched_tick(); diff --git a/trunk/arch/x86/kernel/process_64.c b/trunk/arch/x86/kernel/process_64.c index f693e44e1bf6..ca6f7ab8df33 100644 --- a/trunk/arch/x86/kernel/process_64.c +++ b/trunk/arch/x86/kernel/process_64.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include @@ -137,8 +136,7 @@ void cpu_idle(void) enter_idle(); /* Don't trace irqs off for idle */ stop_critical_timings(); - if (cpuidle_idle_call()) - pm_idle(); + pm_idle(); start_critical_timings(); /* In many cases the interrupt that ended idle diff --git a/trunk/arch/x86/kernel/step.c b/trunk/arch/x86/kernel/step.c index c346d1161488..7977f0cfe339 100644 --- a/trunk/arch/x86/kernel/step.c +++ b/trunk/arch/x86/kernel/step.c @@ -74,7 +74,7 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs) #ifdef CONFIG_X86_64 case 0x40 ... 0x4f: - if (!user_64bit_mode(regs)) + if (regs->cs != __USER_CS) /* 32-bit mode: register increment */ return 0; /* 64-bit mode: REX prefix */ diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index 6913369c234c..9682ec50180c 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -872,6 +872,12 @@ void __init trap_init(void) set_bit(SYSCALL_VECTOR, used_vectors); #endif +#ifdef CONFIG_X86_64 + BUG_ON(test_bit(VSYSCALL_EMU_VECTOR, used_vectors)); + set_system_intr_gate(VSYSCALL_EMU_VECTOR, &emulate_vsyscall); + set_bit(VSYSCALL_EMU_VECTOR, used_vectors); +#endif + /* * Should be a barrier for any external CPU state: */ diff --git a/trunk/arch/x86/kernel/vmlinux.lds.S b/trunk/arch/x86/kernel/vmlinux.lds.S index 0f703f10901a..4aa9c54a9b76 100644 --- a/trunk/arch/x86/kernel/vmlinux.lds.S +++ b/trunk/arch/x86/kernel/vmlinux.lds.S @@ -71,6 +71,7 @@ PHDRS { text PT_LOAD FLAGS(5); /* R_E */ data PT_LOAD FLAGS(6); /* RW_ */ #ifdef CONFIG_X86_64 + user PT_LOAD FLAGS(5); /* R_E */ #ifdef CONFIG_SMP percpu PT_LOAD FLAGS(6); /* RW_ */ #endif @@ -153,16 +154,44 @@ SECTIONS #ifdef CONFIG_X86_64 - . = ALIGN(PAGE_SIZE); +#define VSYSCALL_ADDR (-10*1024*1024) + +#define VLOAD_OFFSET (VSYSCALL_ADDR - __vsyscall_0 + LOAD_OFFSET) +#define VLOAD(x) (ADDR(x) - VLOAD_OFFSET) + +#define VVIRT_OFFSET (VSYSCALL_ADDR - __vsyscall_0) +#define VVIRT(x) (ADDR(x) - VVIRT_OFFSET) + + . = ALIGN(4096); + __vsyscall_0 = .; + + . = VSYSCALL_ADDR; + .vsyscall : AT(VLOAD(.vsyscall)) { + *(.vsyscall_0) + + . = 1024; + *(.vsyscall_1) + + . = 2048; + *(.vsyscall_2) + + . = 4096; /* Pad the whole page. */ + } :user =0xcc + . = ALIGN(__vsyscall_0 + PAGE_SIZE, PAGE_SIZE); + +#undef VSYSCALL_ADDR +#undef VLOAD_OFFSET +#undef VLOAD +#undef VVIRT_OFFSET +#undef VVIRT + __vvar_page = .; .vvar : AT(ADDR(.vvar) - LOAD_OFFSET) { - /* work around gold bug 13023 */ - __vvar_beginning_hack = .; - /* Place all vvars at the offsets in asm/vvar.h. */ -#define EMIT_VVAR(name, offset) \ - . = __vvar_beginning_hack + offset; \ + /* Place all vvars at the offsets in asm/vvar.h. */ +#define EMIT_VVAR(name, offset) \ + . = offset; \ *(.vvar_ ## name) #define __VVAR_KERNEL_LDS #include diff --git a/trunk/arch/x86/kernel/vsyscall_64.c b/trunk/arch/x86/kernel/vsyscall_64.c index 18ae83dd1cd7..dda7dff9cef7 100644 --- a/trunk/arch/x86/kernel/vsyscall_64.c +++ b/trunk/arch/x86/kernel/vsyscall_64.c @@ -18,6 +18,9 @@ * use the vDSO. */ +/* Disable profiling for userspace code: */ +#define DISABLE_BRANCH_PROFILING + #include #include #include @@ -47,36 +50,12 @@ #include #include -#define CREATE_TRACE_POINTS -#include "vsyscall_trace.h" - DEFINE_VVAR(int, vgetcpu_mode); DEFINE_VVAR(struct vsyscall_gtod_data, vsyscall_gtod_data) = { .lock = __SEQLOCK_UNLOCKED(__vsyscall_gtod_data.lock), }; -static enum { EMULATE, NATIVE, NONE } vsyscall_mode = EMULATE; - -static int __init vsyscall_setup(char *str) -{ - if (str) { - if (!strcmp("emulate", str)) - vsyscall_mode = EMULATE; - else if (!strcmp("native", str)) - vsyscall_mode = NATIVE; - else if (!strcmp("none", str)) - vsyscall_mode = NONE; - else - return -EINVAL; - - return 0; - } - - return -EINVAL; -} -early_param("vsyscall", vsyscall_setup); - void update_vsyscall_tz(void) { unsigned long flags; @@ -121,7 +100,7 @@ static void warn_bad_vsyscall(const char *level, struct pt_regs *regs, printk("%s%s[%d] %s ip:%lx cs:%lx sp:%lx ax:%lx si:%lx di:%lx\n", level, tsk->comm, task_pid_nr(tsk), - message, regs->ip, regs->cs, + message, regs->ip - 2, regs->cs, regs->sp, regs->ax, regs->si, regs->di); } @@ -139,39 +118,46 @@ static int addr_to_vsyscall_nr(unsigned long addr) return nr; } -bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) +void dotraplinkage do_emulate_vsyscall(struct pt_regs *regs, long error_code) { struct task_struct *tsk; unsigned long caller; int vsyscall_nr; long ret; + local_irq_enable(); + /* - * No point in checking CS -- the only way to get here is a user mode - * trap to a high address, which means that we're in 64-bit user code. + * Real 64-bit user mode code has cs == __USER_CS. Anything else + * is bogus. */ + if (regs->cs != __USER_CS) { + /* + * If we trapped from kernel mode, we might as well OOPS now + * instead of returning to some random address and OOPSing + * then. + */ + BUG_ON(!user_mode(regs)); - WARN_ON_ONCE(address != regs->ip); - - if (vsyscall_mode == NONE) { - warn_bad_vsyscall(KERN_INFO, regs, - "vsyscall attempted with vsyscall=none"); - return false; + /* Compat mode and non-compat 32-bit CS should both segfault. */ + warn_bad_vsyscall(KERN_WARNING, regs, + "illegal int 0xcc from 32-bit mode"); + goto sigsegv; } - vsyscall_nr = addr_to_vsyscall_nr(address); - - trace_emulate_vsyscall(vsyscall_nr); - + /* + * x86-ism here: regs->ip points to the instruction after the int 0xcc, + * and int 0xcc is two bytes long. + */ + vsyscall_nr = addr_to_vsyscall_nr(regs->ip - 2); if (vsyscall_nr < 0) { warn_bad_vsyscall(KERN_WARNING, regs, - "misaligned vsyscall (exploit attempt or buggy program) -- look up the vsyscall kernel parameter if you need a workaround"); + "illegal int 0xcc (exploit attempt?)"); goto sigsegv; } if (get_user(caller, (unsigned long __user *)regs->sp) != 0) { - warn_bad_vsyscall(KERN_WARNING, regs, - "vsyscall with bad stack (exploit attempt?)"); + warn_bad_vsyscall(KERN_WARNING, regs, "int 0xcc with bad stack (exploit attempt?)"); goto sigsegv; } @@ -216,11 +202,13 @@ bool emulate_vsyscall(struct pt_regs *regs, unsigned long address) regs->ip = caller; regs->sp += 8; - return true; + local_irq_disable(); + return; sigsegv: + regs->ip -= 2; /* The faulting instruction should be the int 0xcc. */ force_sig(SIGSEGV, current); - return true; + local_irq_disable(); } /* @@ -268,21 +256,15 @@ cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) void __init map_vsyscall(void) { - extern char __vsyscall_page; - unsigned long physaddr_vsyscall = __pa_symbol(&__vsyscall_page); + extern char __vsyscall_0; + unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); extern char __vvar_page; unsigned long physaddr_vvar_page = __pa_symbol(&__vvar_page); - __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_vsyscall, - vsyscall_mode == NATIVE - ? PAGE_KERNEL_VSYSCALL - : PAGE_KERNEL_VVAR); - BUILD_BUG_ON((unsigned long)__fix_to_virt(VSYSCALL_FIRST_PAGE) != - (unsigned long)VSYSCALL_START); - + /* Note that VSYSCALL_MAPPED_PAGES must agree with the code below. */ + __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); __set_fixmap(VVAR_PAGE, physaddr_vvar_page, PAGE_KERNEL_VVAR); - BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) != - (unsigned long)VVAR_ADDRESS); + BUILD_BUG_ON((unsigned long)__fix_to_virt(VVAR_PAGE) != (unsigned long)VVAR_ADDRESS); } static int __init vsyscall_init(void) diff --git a/trunk/arch/x86/kernel/vsyscall_emu_64.S b/trunk/arch/x86/kernel/vsyscall_emu_64.S index c9596a9af159..ffa845eae5ca 100644 --- a/trunk/arch/x86/kernel/vsyscall_emu_64.S +++ b/trunk/arch/x86/kernel/vsyscall_emu_64.S @@ -7,31 +7,21 @@ */ #include - #include -#include -#include - -__PAGE_ALIGNED_DATA - .globl __vsyscall_page - .balign PAGE_SIZE, 0xcc - .type __vsyscall_page, @object -__vsyscall_page: - - mov $__NR_gettimeofday, %rax - syscall - ret - .balign 1024, 0xcc - mov $__NR_time, %rax - syscall - ret +/* The unused parts of the page are filled with 0xcc by the linker script. */ - .balign 1024, 0xcc - mov $__NR_getcpu, %rax - syscall - ret +.section .vsyscall_0, "a" +ENTRY(vsyscall_0) + int $VSYSCALL_EMU_VECTOR +END(vsyscall_0) - .balign 4096, 0xcc +.section .vsyscall_1, "a" +ENTRY(vsyscall_1) + int $VSYSCALL_EMU_VECTOR +END(vsyscall_1) - .size __vsyscall_page, 4096 +.section .vsyscall_2, "a" +ENTRY(vsyscall_2) + int $VSYSCALL_EMU_VECTOR +END(vsyscall_2) diff --git a/trunk/arch/x86/kernel/vsyscall_trace.h b/trunk/arch/x86/kernel/vsyscall_trace.h deleted file mode 100644 index a8b2edec54fe..000000000000 --- a/trunk/arch/x86/kernel/vsyscall_trace.h +++ /dev/null @@ -1,29 +0,0 @@ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM vsyscall - -#if !defined(__VSYSCALL_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) -#define __VSYSCALL_TRACE_H - -#include - -TRACE_EVENT(emulate_vsyscall, - - TP_PROTO(int nr), - - TP_ARGS(nr), - - TP_STRUCT__entry(__field(int, nr)), - - TP_fast_assign( - __entry->nr = nr; - ), - - TP_printk("nr = %d", __entry->nr) -); - -#endif - -#undef TRACE_INCLUDE_PATH -#define TRACE_INCLUDE_PATH ../../arch/x86/kernel -#define TRACE_INCLUDE_FILE vsyscall_trace -#include diff --git a/trunk/arch/x86/mm/fault.c b/trunk/arch/x86/mm/fault.c index 247aae3dc008..4d09df054e39 100644 --- a/trunk/arch/x86/mm/fault.c +++ b/trunk/arch/x86/mm/fault.c @@ -105,7 +105,7 @@ check_prefetch_opcode(struct pt_regs *regs, unsigned char *instr, * but for now it's good enough to assume that long * mode only uses well known segments or kernel. */ - return (!user_mode(regs) || user_64bit_mode(regs)); + return (!user_mode(regs)) || (regs->cs == __USER_CS); #endif case 0x60: /* 0x64 thru 0x67 are valid prefixes in all modes. */ @@ -720,18 +720,6 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, if (is_errata100(regs, address)) return; -#ifdef CONFIG_X86_64 - /* - * Instruction fetch faults in the vsyscall page might need - * emulation. - */ - if (unlikely((error_code & PF_INSTR) && - ((address & ~0xfff) == VSYSCALL_START))) { - if (emulate_vsyscall(regs, address)) - return; - } -#endif - if (unlikely(show_unhandled_signals)) show_signal_msg(regs, error_code, address, tsk); diff --git a/trunk/arch/x86/platform/mrst/Makefile b/trunk/arch/x86/platform/mrst/Makefile index 1ea38775a6d3..f61ccdd49341 100644 --- a/trunk/arch/x86/platform/mrst/Makefile +++ b/trunk/arch/x86/platform/mrst/Makefile @@ -1,4 +1,3 @@ obj-$(CONFIG_X86_MRST) += mrst.o obj-$(CONFIG_X86_MRST) += vrtc.o obj-$(CONFIG_EARLY_PRINTK_MRST) += early_printk_mrst.o -obj-$(CONFIG_X86_MRST) += pmu.o diff --git a/trunk/arch/x86/platform/mrst/pmu.c b/trunk/arch/x86/platform/mrst/pmu.c deleted file mode 100644 index 9281da7d91bd..000000000000 --- a/trunk/arch/x86/platform/mrst/pmu.c +++ /dev/null @@ -1,817 +0,0 @@ -/* - * mrst/pmu.c - driver for MRST Power Management Unit - * - * Copyright (c) 2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "pmu.h" - -#define IPCMSG_FW_REVISION 0xF4 - -struct mrst_device { - u16 pci_dev_num; /* DEBUG only */ - u16 lss; - u16 latest_request; - unsigned int pci_state_counts[PCI_D3cold + 1]; /* DEBUG only */ -}; - -/* - * comlete list of MRST PCI devices - */ -static struct mrst_device mrst_devs[] = { -/* 0 */ { 0x0800, LSS_SPI0 }, /* Moorestown SPI Ctrl 0 */ -/* 1 */ { 0x0801, LSS_SPI1 }, /* Moorestown SPI Ctrl 1 */ -/* 2 */ { 0x0802, LSS_I2C0 }, /* Moorestown I2C 0 */ -/* 3 */ { 0x0803, LSS_I2C1 }, /* Moorestown I2C 1 */ -/* 4 */ { 0x0804, LSS_I2C2 }, /* Moorestown I2C 2 */ -/* 5 */ { 0x0805, LSS_KBD }, /* Moorestown Keyboard Ctrl */ -/* 6 */ { 0x0806, LSS_USB_HC }, /* Moorestown USB Ctrl */ -/* 7 */ { 0x0807, LSS_SD_HC0 }, /* Moorestown SD Host Ctrl 0 */ -/* 8 */ { 0x0808, LSS_SD_HC1 }, /* Moorestown SD Host Ctrl 1 */ -/* 9 */ { 0x0809, LSS_NAND }, /* Moorestown NAND Ctrl */ -/* 10 */ { 0x080a, LSS_AUDIO }, /* Moorestown Audio Ctrl */ -/* 11 */ { 0x080b, LSS_IMAGING }, /* Moorestown ISP */ -/* 12 */ { 0x080c, LSS_SECURITY }, /* Moorestown Security Controller */ -/* 13 */ { 0x080d, LSS_DISPLAY }, /* Moorestown External Displays */ -/* 14 */ { 0x080e, 0 }, /* Moorestown SCU IPC */ -/* 15 */ { 0x080f, LSS_GPIO }, /* Moorestown GPIO Controller */ -/* 16 */ { 0x0810, 0 }, /* Moorestown Power Management Unit */ -/* 17 */ { 0x0811, LSS_USB_OTG }, /* Moorestown OTG Ctrl */ -/* 18 */ { 0x0812, LSS_SPI2 }, /* Moorestown SPI Ctrl 2 */ -/* 19 */ { 0x0813, 0 }, /* Moorestown SC DMA */ -/* 20 */ { 0x0814, LSS_AUDIO_LPE }, /* Moorestown LPE DMA */ -/* 21 */ { 0x0815, LSS_AUDIO_SSP }, /* Moorestown SSP0 */ - -/* 22 */ { 0x084F, LSS_SD_HC2 }, /* Moorestown SD Host Ctrl 2 */ - -/* 23 */ { 0x4102, 0 }, /* Lincroft */ -/* 24 */ { 0x4110, 0 }, /* Lincroft */ -}; - -/* n.b. We ignore PCI-id 0x815 in LSS9 b/c MeeGo has no driver for it */ -static u16 mrst_lss9_pci_ids[] = {0x080a, 0x0814, 0}; -static u16 mrst_lss10_pci_ids[] = {0x0800, 0x0801, 0x0802, 0x0803, - 0x0804, 0x0805, 0x080f, 0}; - -/* handle concurrent SMP invokations of pmu_pci_set_power_state() */ -static spinlock_t mrst_pmu_power_state_lock; - -static unsigned int wake_counters[MRST_NUM_LSS]; /* DEBUG only */ -static unsigned int pmu_irq_stats[INT_INVALID + 1]; /* DEBUG only */ - -static int graphics_is_off; -static int lss_s0i3_enabled; -static bool mrst_pmu_s0i3_enable; - -/* debug counters */ -static u32 pmu_wait_ready_calls; -static u32 pmu_wait_ready_udelays; -static u32 pmu_wait_ready_udelays_max; -static u32 pmu_wait_done_calls; -static u32 pmu_wait_done_udelays; -static u32 pmu_wait_done_udelays_max; -static u32 pmu_set_power_state_entry; -static u32 pmu_set_power_state_send_cmd; - -static struct mrst_device *pci_id_2_mrst_dev(u16 pci_dev_num) -{ - int index = 0; - - if ((pci_dev_num >= 0x0800) && (pci_dev_num <= 0x815)) - index = pci_dev_num - 0x800; - else if (pci_dev_num == 0x084F) - index = 22; - else if (pci_dev_num == 0x4102) - index = 23; - else if (pci_dev_num == 0x4110) - index = 24; - - if (pci_dev_num != mrst_devs[index].pci_dev_num) { - WARN_ONCE(1, FW_BUG "Unknown PCI device 0x%04X\n", pci_dev_num); - return 0; - } - - return &mrst_devs[index]; -} - -/** - * mrst_pmu_validate_cstates - * @dev: cpuidle_device - * - * Certain states are not appropriate for governor to pick in some cases. - * This function will be called as cpuidle_device's prepare callback and - * thus tells governor to ignore such states when selecting the next state - * to enter. - */ - -#define IDLE_STATE4_IS_C6 4 -#define IDLE_STATE5_IS_S0I3 5 - -int mrst_pmu_invalid_cstates(void) -{ - int cpu = smp_processor_id(); - - /* - * Demote to C4 if the PMU is busy. - * Since LSS changes leave the busy bit clear... - * busy means either the PMU is waiting for an ACK-C6 that - * isn't coming due to an MWAIT that returned immediately; - * or we returned from S0i3 successfully, and the PMU - * is not done sending us interrupts. - */ - if (pmu_read_busy_status()) - return 1 << IDLE_STATE4_IS_C6 | 1 << IDLE_STATE5_IS_S0I3; - - /* - * Disallow S0i3 if: PMU is not initialized, or CPU1 is active, - * or if device LSS is insufficient, or the GPU is active, - * or if it has been explicitly disabled. - */ - if (!pmu_reg || !cpumask_equal(cpu_online_mask, cpumask_of(cpu)) || - !lss_s0i3_enabled || !graphics_is_off || !mrst_pmu_s0i3_enable) - return 1 << IDLE_STATE5_IS_S0I3; - else - return 0; -} - -/* - * pmu_update_wake_counters(): read PM_WKS, update wake_counters[] - * DEBUG only. - */ -static void pmu_update_wake_counters(void) -{ - int lss; - u32 wake_status; - - wake_status = pmu_read_wks(); - - for (lss = 0; lss < MRST_NUM_LSS; ++lss) { - if (wake_status & (1 << lss)) - wake_counters[lss]++; - } -} - -int mrst_pmu_s0i3_entry(void) -{ - int status; - - /* Clear any possible error conditions */ - pmu_write_ics(0x300); - - /* set wake control to current D-states */ - pmu_write_wssc(S0I3_SSS_TARGET); - - status = mrst_s0i3_entry(PM_S0I3_COMMAND, &pmu_reg->pm_cmd); - pmu_update_wake_counters(); - return status; -} - -/* poll for maximum of 5ms for busy bit to clear */ -static int pmu_wait_ready(void) -{ - int udelays; - - pmu_wait_ready_calls++; - - for (udelays = 0; udelays < 500; ++udelays) { - if (udelays > pmu_wait_ready_udelays_max) - pmu_wait_ready_udelays_max = udelays; - - if (pmu_read_busy_status() == 0) - return 0; - - udelay(10); - pmu_wait_ready_udelays++; - } - - /* - * if this fires, observe - * /sys/kernel/debug/mrst_pmu_wait_ready_calls - * /sys/kernel/debug/mrst_pmu_wait_ready_udelays - */ - WARN_ONCE(1, "SCU not ready for 5ms"); - return -EBUSY; -} -/* poll for maximum of 50ms us for busy bit to clear */ -static int pmu_wait_done(void) -{ - int udelays; - - pmu_wait_done_calls++; - - for (udelays = 0; udelays < 500; ++udelays) { - if (udelays > pmu_wait_done_udelays_max) - pmu_wait_done_udelays_max = udelays; - - if (pmu_read_busy_status() == 0) - return 0; - - udelay(100); - pmu_wait_done_udelays++; - } - - /* - * if this fires, observe - * /sys/kernel/debug/mrst_pmu_wait_done_calls - * /sys/kernel/debug/mrst_pmu_wait_done_udelays - */ - WARN_ONCE(1, "SCU not done for 50ms"); - return -EBUSY; -} - -u32 mrst_pmu_msi_is_disabled(void) -{ - return pmu_msi_is_disabled(); -} - -void mrst_pmu_enable_msi(void) -{ - pmu_msi_enable(); -} - -/** - * pmu_irq - pmu driver interrupt handler - * Context: interrupt context - */ -static irqreturn_t pmu_irq(int irq, void *dummy) -{ - union pmu_pm_ics pmu_ics; - - pmu_ics.value = pmu_read_ics(); - - if (!pmu_ics.bits.pending) - return IRQ_NONE; - - switch (pmu_ics.bits.cause) { - case INT_SPURIOUS: - case INT_CMD_DONE: - case INT_CMD_ERR: - case INT_WAKE_RX: - case INT_SS_ERROR: - case INT_S0IX_MISS: - case INT_NO_ACKC6: - pmu_irq_stats[pmu_ics.bits.cause]++; - break; - default: - pmu_irq_stats[INT_INVALID]++; - } - - pmu_write_ics(pmu_ics.value); /* Clear pending interrupt */ - - return IRQ_HANDLED; -} - -/* - * Translate PCI power management to MRST LSS D-states - */ -static int pci_2_mrst_state(int lss, pci_power_t pci_state) -{ - switch (pci_state) { - case PCI_D0: - if (SSMSK(D0i1, lss) & D0I1_ACG_SSS_TARGET) - return D0i1; - else - return D0; - case PCI_D1: - return D0i1; - case PCI_D2: - return D0i2; - case PCI_D3hot: - case PCI_D3cold: - return D0i3; - default: - WARN(1, "pci_state %d\n", pci_state); - return 0; - } -} - -static int pmu_issue_command(u32 pm_ssc) -{ - union pmu_pm_set_cfg_cmd_t command; - - if (pmu_read_busy_status()) { - pr_debug("pmu is busy, Operation not permitted\n"); - return -1; - } - - /* - * enable interrupts in PMU so that interrupts are - * propagated when ioc bit for a particular set - * command is set - */ - - pmu_irq_enable(); - - /* Configure the sub systems for pmu2 */ - - pmu_write_ssc(pm_ssc); - - /* - * Send the set config command for pmu its configured - * for mode CM_IMMEDIATE & hence with No Trigger - */ - - command.pmu2_params.d_param.cfg_mode = CM_IMMEDIATE; - command.pmu2_params.d_param.cfg_delay = 0; - command.pmu2_params.d_param.rsvd = 0; - - /* construct the command to send SET_CFG to particular PMU */ - command.pmu2_params.d_param.cmd = SET_CFG_CMD; - command.pmu2_params.d_param.ioc = 0; - command.pmu2_params.d_param.mode_id = 0; - command.pmu2_params.d_param.sys_state = SYS_STATE_S0I0; - - /* write the value of PM_CMD into particular PMU */ - pr_debug("pmu command being written %x\n", - command.pmu_pm_set_cfg_cmd_value); - - pmu_write_cmd(command.pmu_pm_set_cfg_cmd_value); - - return 0; -} - -static u16 pmu_min_lss_pci_req(u16 *ids, u16 pci_state) -{ - u16 existing_request; - int i; - - for (i = 0; ids[i]; ++i) { - struct mrst_device *mrst_dev; - - mrst_dev = pci_id_2_mrst_dev(ids[i]); - if (unlikely(!mrst_dev)) - continue; - - existing_request = mrst_dev->latest_request; - if (existing_request < pci_state) - pci_state = existing_request; - } - return pci_state; -} - -/** - * pmu_pci_set_power_state - Callback function is used by all the PCI devices - * for a platform specific device power on/shutdown. - */ - -int pmu_pci_set_power_state(struct pci_dev *pdev, pci_power_t pci_state) -{ - u32 old_sss, new_sss; - int status = 0; - struct mrst_device *mrst_dev; - - pmu_set_power_state_entry++; - - BUG_ON(pdev->vendor != PCI_VENDOR_ID_INTEL); - BUG_ON(pci_state < PCI_D0 || pci_state > PCI_D3cold); - - mrst_dev = pci_id_2_mrst_dev(pdev->device); - if (unlikely(!mrst_dev)) - return -ENODEV; - - mrst_dev->pci_state_counts[pci_state]++; /* count invocations */ - - /* PMU driver calls self as part of PCI initialization, ignore */ - if (pdev->device == PCI_DEV_ID_MRST_PMU) - return 0; - - BUG_ON(!pmu_reg); /* SW bug if called before initialized */ - - spin_lock(&mrst_pmu_power_state_lock); - - if (pdev->d3_delay) { - dev_dbg(&pdev->dev, "d3_delay %d, should be 0\n", - pdev->d3_delay); - pdev->d3_delay = 0; - } - /* - * If Lincroft graphics, simply remember state - */ - if ((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY - && !((pdev->class & PCI_SUB_CLASS_MASK) >> 8)) { - if (pci_state == PCI_D0) - graphics_is_off = 0; - else - graphics_is_off = 1; - goto ret; - } - - if (!mrst_dev->lss) - goto ret; /* device with no LSS */ - - if (mrst_dev->latest_request == pci_state) - goto ret; /* no change */ - - mrst_dev->latest_request = pci_state; /* record latest request */ - - /* - * LSS9 and LSS10 contain multiple PCI devices. - * Use the lowest numbered (highest power) state in the LSS - */ - if (mrst_dev->lss == 9) - pci_state = pmu_min_lss_pci_req(mrst_lss9_pci_ids, pci_state); - else if (mrst_dev->lss == 10) - pci_state = pmu_min_lss_pci_req(mrst_lss10_pci_ids, pci_state); - - status = pmu_wait_ready(); - if (status) - goto ret; - - old_sss = pmu_read_sss(); - new_sss = old_sss & ~SSMSK(3, mrst_dev->lss); - new_sss |= SSMSK(pci_2_mrst_state(mrst_dev->lss, pci_state), - mrst_dev->lss); - - if (new_sss == old_sss) - goto ret; /* nothing to do */ - - pmu_set_power_state_send_cmd++; - - status = pmu_issue_command(new_sss); - - if (unlikely(status != 0)) { - dev_err(&pdev->dev, "Failed to Issue a PM command\n"); - goto ret; - } - - if (pmu_wait_done()) - goto ret; - - lss_s0i3_enabled = - ((pmu_read_sss() & S0I3_SSS_TARGET) == S0I3_SSS_TARGET); -ret: - spin_unlock(&mrst_pmu_power_state_lock); - return status; -} - -#ifdef CONFIG_DEBUG_FS -static char *d0ix_names[] = {"D0", "D0i1", "D0i2", "D0i3"}; - -static inline const char *d0ix_name(int state) -{ - return d0ix_names[(int) state]; -} - -static int debug_mrst_pmu_show(struct seq_file *s, void *unused) -{ - struct pci_dev *pdev = NULL; - u32 cur_pmsss; - int lss; - - seq_printf(s, "0x%08X D0I1_ACG_SSS_TARGET\n", D0I1_ACG_SSS_TARGET); - - cur_pmsss = pmu_read_sss(); - - seq_printf(s, "0x%08X S0I3_SSS_TARGET\n", S0I3_SSS_TARGET); - - seq_printf(s, "0x%08X Current SSS ", cur_pmsss); - seq_printf(s, lss_s0i3_enabled ? "\n" : "[BLOCKS s0i3]\n"); - - if (cpumask_equal(cpu_online_mask, cpumask_of(0))) - seq_printf(s, "cpu0 is only cpu online\n"); - else - seq_printf(s, "cpu0 is NOT only cpu online [BLOCKS S0i3]\n"); - - seq_printf(s, "GFX: %s\n", graphics_is_off ? "" : "[BLOCKS s0i3]"); - - - for_each_pci_dev(pdev) { - int pos; - u16 pmcsr; - struct mrst_device *mrst_dev; - int i; - - mrst_dev = pci_id_2_mrst_dev(pdev->device); - - seq_printf(s, "%s %04x/%04X %-16.16s ", - dev_name(&pdev->dev), - pdev->vendor, pdev->device, - dev_driver_string(&pdev->dev)); - - if (unlikely (!mrst_dev)) { - seq_printf(s, " UNKNOWN\n"); - continue; - } - - if (mrst_dev->lss) - seq_printf(s, "LSS %2d %-4s ", mrst_dev->lss, - d0ix_name(((cur_pmsss >> - (mrst_dev->lss * 2)) & 0x3))); - else - seq_printf(s, " "); - - /* PCI PM config space setting */ - pos = pci_find_capability(pdev, PCI_CAP_ID_PM); - if (pos != 0) { - pci_read_config_word(pdev, pos + PCI_PM_CTRL, &pmcsr); - seq_printf(s, "PCI-%-4s", - pci_power_name(pmcsr & PCI_PM_CTRL_STATE_MASK)); - } else { - seq_printf(s, " "); - } - - seq_printf(s, " %s ", pci_power_name(mrst_dev->latest_request)); - for (i = 0; i <= PCI_D3cold; ++i) - seq_printf(s, "%d ", mrst_dev->pci_state_counts[i]); - - if (mrst_dev->lss) { - unsigned int lssmask; - - lssmask = SSMSK(D0i3, mrst_dev->lss); - - if ((lssmask & S0I3_SSS_TARGET) && - ((lssmask & cur_pmsss) != - (lssmask & S0I3_SSS_TARGET))) - seq_printf(s , "[BLOCKS s0i3]"); - } - - seq_printf(s, "\n"); - } - seq_printf(s, "Wake Counters:\n"); - for (lss = 0; lss < MRST_NUM_LSS; ++lss) - seq_printf(s, "LSS%d %d\n", lss, wake_counters[lss]); - - seq_printf(s, "Interrupt Counters:\n"); - seq_printf(s, - "INT_SPURIOUS \t%8u\n" "INT_CMD_DONE \t%8u\n" - "INT_CMD_ERR \t%8u\n" "INT_WAKE_RX \t%8u\n" - "INT_SS_ERROR \t%8u\n" "INT_S0IX_MISS\t%8u\n" - "INT_NO_ACKC6 \t%8u\n" "INT_INVALID \t%8u\n", - pmu_irq_stats[INT_SPURIOUS], pmu_irq_stats[INT_CMD_DONE], - pmu_irq_stats[INT_CMD_ERR], pmu_irq_stats[INT_WAKE_RX], - pmu_irq_stats[INT_SS_ERROR], pmu_irq_stats[INT_S0IX_MISS], - pmu_irq_stats[INT_NO_ACKC6], pmu_irq_stats[INT_INVALID]); - - seq_printf(s, "mrst_pmu_wait_ready_calls %8d\n", - pmu_wait_ready_calls); - seq_printf(s, "mrst_pmu_wait_ready_udelays %8d\n", - pmu_wait_ready_udelays); - seq_printf(s, "mrst_pmu_wait_ready_udelays_max %8d\n", - pmu_wait_ready_udelays_max); - seq_printf(s, "mrst_pmu_wait_done_calls %8d\n", - pmu_wait_done_calls); - seq_printf(s, "mrst_pmu_wait_done_udelays %8d\n", - pmu_wait_done_udelays); - seq_printf(s, "mrst_pmu_wait_done_udelays_max %8d\n", - pmu_wait_done_udelays_max); - seq_printf(s, "mrst_pmu_set_power_state_entry %8d\n", - pmu_set_power_state_entry); - seq_printf(s, "mrst_pmu_set_power_state_send_cmd %8d\n", - pmu_set_power_state_send_cmd); - seq_printf(s, "SCU busy: %d\n", pmu_read_busy_status()); - - return 0; -} - -static int debug_mrst_pmu_open(struct inode *inode, struct file *file) -{ - return single_open(file, debug_mrst_pmu_show, NULL); -} - -static const struct file_operations devices_state_operations = { - .open = debug_mrst_pmu_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; -#endif /* DEBUG_FS */ - -/* - * Validate SCU PCI shim PCI vendor capability byte - * against LSS hard-coded in mrst_devs[] above. - * DEBUG only. - */ -static void pmu_scu_firmware_debug(void) -{ - struct pci_dev *pdev = NULL; - - for_each_pci_dev(pdev) { - struct mrst_device *mrst_dev; - u8 pci_config_lss; - int pos; - - mrst_dev = pci_id_2_mrst_dev(pdev->device); - if (unlikely(!mrst_dev)) { - printk(KERN_ERR FW_BUG "pmu: Unknown " - "PCI device 0x%04X\n", pdev->device); - continue; - } - - if (mrst_dev->lss == 0) - continue; /* no LSS in our table */ - - pos = pci_find_capability(pdev, PCI_CAP_ID_VNDR); - if (!pos != 0) { - printk(KERN_ERR FW_BUG "pmu: 0x%04X " - "missing PCI Vendor Capability\n", - pdev->device); - continue; - } - pci_read_config_byte(pdev, pos + 4, &pci_config_lss); - if (!(pci_config_lss & PCI_VENDOR_CAP_LOG_SS_MASK)) { - printk(KERN_ERR FW_BUG "pmu: 0x%04X " - "invalid PCI Vendor Capability 0x%x " - " expected LSS 0x%X\n", - pdev->device, pci_config_lss, mrst_dev->lss); - continue; - } - pci_config_lss &= PCI_VENDOR_CAP_LOG_ID_MASK; - - if (mrst_dev->lss == pci_config_lss) - continue; - - printk(KERN_ERR FW_BUG "pmu: 0x%04X LSS = %d, expected %d\n", - pdev->device, pci_config_lss, mrst_dev->lss); - } -} - -/** - * pmu_probe - */ -static int __devinit pmu_probe(struct pci_dev *pdev, - const struct pci_device_id *pci_id) -{ - int ret; - struct mrst_pmu_reg *pmu; - - /* Init the device */ - ret = pci_enable_device(pdev); - if (ret) { - dev_err(&pdev->dev, "Unable to Enable PCI device\n"); - return ret; - } - - ret = pci_request_regions(pdev, MRST_PMU_DRV_NAME); - if (ret < 0) { - dev_err(&pdev->dev, "Cannot obtain PCI resources, aborting\n"); - goto out_err1; - } - - /* Map the memory of PMU reg base */ - pmu = pci_iomap(pdev, 0, 0); - if (!pmu) { - dev_err(&pdev->dev, "Unable to map the PMU address space\n"); - ret = -ENOMEM; - goto out_err2; - } - -#ifdef CONFIG_DEBUG_FS - /* /sys/kernel/debug/mrst_pmu */ - (void) debugfs_create_file("mrst_pmu", S_IFREG | S_IRUGO, - NULL, NULL, &devices_state_operations); -#endif - pmu_reg = pmu; /* success */ - - if (request_irq(pdev->irq, pmu_irq, 0, MRST_PMU_DRV_NAME, NULL)) { - dev_err(&pdev->dev, "Registering isr has failed\n"); - ret = -1; - goto out_err3; - } - - pmu_scu_firmware_debug(); - - pmu_write_wkc(S0I3_WAKE_SOURCES); /* Enable S0i3 wakeup sources */ - - pmu_wait_ready(); - - pmu_write_ssc(D0I1_ACG_SSS_TARGET); /* Enable Auto-Clock_Gating */ - pmu_write_cmd(0x201); - - spin_lock_init(&mrst_pmu_power_state_lock); - - /* Enable the hardware interrupt */ - pmu_irq_enable(); - return 0; - -out_err3: - free_irq(pdev->irq, NULL); - pci_iounmap(pdev, pmu_reg); - pmu_reg = NULL; -out_err2: - pci_release_region(pdev, 0); -out_err1: - pci_disable_device(pdev); - return ret; -} - -static void __devexit pmu_remove(struct pci_dev *pdev) -{ - dev_err(&pdev->dev, "Mid PM pmu_remove called\n"); - - /* Freeing up the irq */ - free_irq(pdev->irq, NULL); - - pci_iounmap(pdev, pmu_reg); - pmu_reg = NULL; - - /* disable the current PCI device */ - pci_release_region(pdev, 0); - pci_disable_device(pdev); -} - -static DEFINE_PCI_DEVICE_TABLE(pmu_pci_ids) = { - { PCI_VDEVICE(INTEL, PCI_DEV_ID_MRST_PMU), 0 }, - { } -}; - -MODULE_DEVICE_TABLE(pci, pmu_pci_ids); - -static struct pci_driver driver = { - .name = MRST_PMU_DRV_NAME, - .id_table = pmu_pci_ids, - .probe = pmu_probe, - .remove = __devexit_p(pmu_remove), -}; - -/** - * pmu_pci_register - register the PMU driver as PCI device - */ -static int __init pmu_pci_register(void) -{ - return pci_register_driver(&driver); -} - -/* Register and probe via fs_initcall() to preceed device_initcall() */ -fs_initcall(pmu_pci_register); - -static void __exit mid_pci_cleanup(void) -{ - pci_unregister_driver(&driver); -} - -static int ia_major; -static int ia_minor; - -static int pmu_sfi_parse_oem(struct sfi_table_header *table) -{ - struct sfi_table_simple *sb; - - sb = (struct sfi_table_simple *)table; - ia_major = (sb->pentry[1] >> 0) & 0xFFFF; - ia_minor = (sb->pentry[1] >> 16) & 0xFFFF; - printk(KERN_INFO "mrst_pmu: IA FW version v%x.%x\n", - ia_major, ia_minor); - - return 0; -} - -static int __init scu_fw_check(void) -{ - int ret; - u32 fw_version; - - if (!pmu_reg) - return 0; /* this driver didn't probe-out */ - - sfi_table_parse("OEMB", NULL, NULL, pmu_sfi_parse_oem); - - if (ia_major < 0x6005 || ia_minor < 0x1525) { - WARN(1, "mrst_pmu: IA FW version too old\n"); - return -1; - } - - ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0, - &fw_version, 1); - - if (ret) { - WARN(1, "mrst_pmu: IPC FW version? %d\n", ret); - } else { - int scu_major = (fw_version >> 8) & 0xFF; - int scu_minor = (fw_version >> 0) & 0xFF; - - printk(KERN_INFO "mrst_pmu: firmware v%x\n", fw_version); - - if ((scu_major >= 0xC0) && (scu_minor >= 0x49)) { - printk(KERN_INFO "mrst_pmu: enabling S0i3\n"); - mrst_pmu_s0i3_enable = true; - } else { - WARN(1, "mrst_pmu: S0i3 disabled, old firmware %X.%X", - scu_major, scu_minor); - } - } - return 0; -} -late_initcall(scu_fw_check); -module_exit(mid_pci_cleanup); diff --git a/trunk/arch/x86/platform/mrst/pmu.h b/trunk/arch/x86/platform/mrst/pmu.h deleted file mode 100644 index bfbfe64b167b..000000000000 --- a/trunk/arch/x86/platform/mrst/pmu.h +++ /dev/null @@ -1,234 +0,0 @@ -/* - * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c - * - * Copyright (c) 2011, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef _MRST_PMU_H_ -#define _MRST_PMU_H_ - -#define PCI_DEV_ID_MRST_PMU 0x0810 -#define MRST_PMU_DRV_NAME "mrst_pmu" -#define PCI_SUB_CLASS_MASK 0xFF00 - -#define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F -#define PCI_VENDOR_CAP_LOG_SS_MASK 0x80 - -#define SUB_SYS_ALL_D0I1 0x01155555 -#define S0I3_WAKE_SOURCES 0x00001FFF - -#define PM_S0I3_COMMAND \ - ((0 << 31) | /* Reserved */ \ - (0 << 30) | /* Core must be idle */ \ - (0xc2 << 22) | /* ACK C6 trigger */ \ - (3 << 19) | /* Trigger on DMI message */ \ - (3 << 16) | /* Enter S0i3 */ \ - (0 << 13) | /* Numeric mode ID (sw) */ \ - (3 << 9) | /* Trigger mode */ \ - (0 << 8) | /* Do not interrupt */ \ - (1 << 0)) /* Set configuration */ - -#define LSS_DMI 0 -#define LSS_SD_HC0 1 -#define LSS_SD_HC1 2 -#define LSS_NAND 3 -#define LSS_IMAGING 4 -#define LSS_SECURITY 5 -#define LSS_DISPLAY 6 -#define LSS_USB_HC 7 -#define LSS_USB_OTG 8 -#define LSS_AUDIO 9 -#define LSS_AUDIO_LPE 9 -#define LSS_AUDIO_SSP 9 -#define LSS_I2C0 10 -#define LSS_I2C1 10 -#define LSS_I2C2 10 -#define LSS_KBD 10 -#define LSS_SPI0 10 -#define LSS_SPI1 10 -#define LSS_SPI2 10 -#define LSS_GPIO 10 -#define LSS_SRAM 11 /* used by SCU, do not touch */ -#define LSS_SD_HC2 12 -/* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */ -#define MRST_NUM_LSS 13 - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) - -#define SSMSK(mask, lss) ((mask) << ((lss) * 2)) -#define D0 0 -#define D0i1 1 -#define D0i2 2 -#define D0i3 3 - -#define S0I3_SSS_TARGET ( \ - SSMSK(D0i1, LSS_DMI) | \ - SSMSK(D0i3, LSS_SD_HC0) | \ - SSMSK(D0i3, LSS_SD_HC1) | \ - SSMSK(D0i3, LSS_NAND) | \ - SSMSK(D0i3, LSS_SD_HC2) | \ - SSMSK(D0i3, LSS_IMAGING) | \ - SSMSK(D0i3, LSS_SECURITY) | \ - SSMSK(D0i3, LSS_DISPLAY) | \ - SSMSK(D0i3, LSS_USB_HC) | \ - SSMSK(D0i3, LSS_USB_OTG) | \ - SSMSK(D0i3, LSS_AUDIO) | \ - SSMSK(D0i1, LSS_I2C0)) - -/* - * D0i1 on Langwell is Autonomous Clock Gating (ACG). - * Enable ACG on every LSS except camera and audio - */ -#define D0I1_ACG_SSS_TARGET \ - (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO)) - -enum cm_mode { - CM_NOP, /* ignore the config mode value */ - CM_IMMEDIATE, - CM_DELAY, - CM_TRIGGER, - CM_INVALID -}; - -enum sys_state { - SYS_STATE_S0I0, - SYS_STATE_S0I1, - SYS_STATE_S0I2, - SYS_STATE_S0I3, - SYS_STATE_S3, - SYS_STATE_S5 -}; - -#define SET_CFG_CMD 1 - -enum int_status { - INT_SPURIOUS = 0, - INT_CMD_DONE = 1, - INT_CMD_ERR = 2, - INT_WAKE_RX = 3, - INT_SS_ERROR = 4, - INT_S0IX_MISS = 5, - INT_NO_ACKC6 = 6, - INT_INVALID = 7, -}; - -/* PMU register interface */ -static struct mrst_pmu_reg { - u32 pm_sts; /* 0x00 */ - u32 pm_cmd; /* 0x04 */ - u32 pm_ics; /* 0x08 */ - u32 _resv1; /* 0x0C */ - u32 pm_wkc[2]; /* 0x10 */ - u32 pm_wks[2]; /* 0x18 */ - u32 pm_ssc[4]; /* 0x20 */ - u32 pm_sss[4]; /* 0x30 */ - u32 pm_wssc[4]; /* 0x40 */ - u32 pm_c3c4; /* 0x50 */ - u32 pm_c5c6; /* 0x54 */ - u32 pm_msi_disable; /* 0x58 */ -} *pmu_reg; - -static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); } -static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); } -static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); } -static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); } - -static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); } -static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); } -static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); } -static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); } -static inline void pmu_write_wssc(u32 arg) - { writel(arg, &pmu_reg->pm_wssc[0]); } - -static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); } -static inline u32 pmu_msi_is_disabled(void) - { return readl(&pmu_reg->pm_msi_disable); } - -union pmu_pm_ics { - struct { - u32 cause:8; - u32 enable:1; - u32 pending:1; - u32 reserved:22; - } bits; - u32 value; -}; - -static inline void pmu_irq_enable(void) -{ - union pmu_pm_ics pmu_ics; - - pmu_ics.value = pmu_read_ics(); - pmu_ics.bits.enable = 1; - pmu_write_ics(pmu_ics.value); -} - -union pmu_pm_status { - struct { - u32 pmu_rev:8; - u32 pmu_busy:1; - u32 mode_id:4; - u32 Reserved:19; - } pmu_status_parts; - u32 pmu_status_value; -}; - -static inline int pmu_read_busy_status(void) -{ - union pmu_pm_status result; - - result.pmu_status_value = pmu_read_sts(); - - return result.pmu_status_parts.pmu_busy; -} - -/* pmu set config parameters */ -struct cfg_delay_param_t { - u32 cmd:8; - u32 ioc:1; - u32 cfg_mode:4; - u32 mode_id:3; - u32 sys_state:3; - u32 cfg_delay:8; - u32 rsvd:5; -}; - -struct cfg_trig_param_t { - u32 cmd:8; - u32 ioc:1; - u32 cfg_mode:4; - u32 mode_id:3; - u32 sys_state:3; - u32 cfg_trig_type:3; - u32 cfg_trig_val:8; - u32 cmbi:1; - u32 rsvd1:1; -}; - -union pmu_pm_set_cfg_cmd_t { - union { - struct cfg_delay_param_t d_param; - struct cfg_trig_param_t t_param; - } pmu2_params; - u32 pmu_pm_set_cfg_cmd_value; -}; - -#ifdef FUTURE_PATCH -extern int mrst_s0i3_entry(u32 regval, u32 *regaddr); -#else -static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; } -#endif -#endif diff --git a/trunk/arch/x86/vdso/vdso.S b/trunk/arch/x86/vdso/vdso.S index 01f5e3b4613c..1b979c12ba85 100644 --- a/trunk/arch/x86/vdso/vdso.S +++ b/trunk/arch/x86/vdso/vdso.S @@ -9,7 +9,6 @@ __PAGE_ALIGNED_DATA vdso_start: .incbin "arch/x86/vdso/vdso.so" vdso_end: - .align PAGE_SIZE /* extra data here leaks to userspace. */ .previous diff --git a/trunk/arch/x86/xen/Makefile b/trunk/arch/x86/xen/Makefile index 3326204e251f..45e94aca5bce 100644 --- a/trunk/arch/x86/xen/Makefile +++ b/trunk/arch/x86/xen/Makefile @@ -15,7 +15,7 @@ obj-y := enlighten.o setup.o multicalls.o mmu.o irq.o \ grant-table.o suspend.o platform-pci-unplug.o \ p2m.o -obj-$(CONFIG_FTRACE) += trace.o +obj-$(CONFIG_FUNCTION_TRACER) += trace.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o diff --git a/trunk/arch/x86/xen/enlighten.c b/trunk/arch/x86/xen/enlighten.c index e2345af01af0..974a528458a0 100644 --- a/trunk/arch/x86/xen/enlighten.c +++ b/trunk/arch/x86/xen/enlighten.c @@ -951,10 +951,6 @@ static const struct pv_info xen_info __initconst = { .paravirt_enabled = 1, .shared_kernel_pmd = 0, -#ifdef CONFIG_X86_64 - .extra_user_64bit_cs = FLAT_USER_CS64, -#endif - .name = "Xen", }; diff --git a/trunk/arch/x86/xen/mmu.c b/trunk/arch/x86/xen/mmu.c index 8cce339db5e7..f987bde77c49 100644 --- a/trunk/arch/x86/xen/mmu.c +++ b/trunk/arch/x86/xen/mmu.c @@ -1916,7 +1916,6 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) # endif #else case VSYSCALL_LAST_PAGE ... VSYSCALL_FIRST_PAGE: - case VVAR_PAGE: #endif case FIX_TEXT_POKE0: case FIX_TEXT_POKE1: @@ -1957,8 +1956,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot) #ifdef CONFIG_X86_64 /* Replicate changes to map the vsyscall page into the user pagetable vsyscall mapping. */ - if ((idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) || - idx == VVAR_PAGE) { + if (idx >= VSYSCALL_LAST_PAGE && idx <= VSYSCALL_FIRST_PAGE) { unsigned long vaddr = __fix_to_virt(idx); set_pte_vaddr_pud(level3_user_vsyscall, vaddr, pte); } diff --git a/trunk/arch/x86/xen/setup.c b/trunk/arch/x86/xen/setup.c index df118a825f39..60aeeb56948f 100644 --- a/trunk/arch/x86/xen/setup.c +++ b/trunk/arch/x86/xen/setup.c @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -93,6 +92,8 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, if (end <= start) return 0; + printk(KERN_INFO "xen_release_chunk: looking at area pfn %lx-%lx: ", + start, end); for(pfn = start; pfn < end; pfn++) { unsigned long mfn = pfn_to_mfn(pfn); @@ -105,14 +106,14 @@ static unsigned long __init xen_release_chunk(phys_addr_t start_addr, ret = HYPERVISOR_memory_op(XENMEM_decrease_reservation, &reservation); - WARN(ret != 1, "Failed to release pfn %lx err=%d\n", pfn, ret); + WARN(ret != 1, "Failed to release memory %lx-%lx err=%d\n", + start, end, ret); if (ret == 1) { __set_phys_to_machine(pfn, INVALID_P2M_ENTRY); len++; } } - printk(KERN_INFO "Freeing %lx-%lx pfn range: %lu pages freed\n", - start, end, len); + printk(KERN_CONT "%ld pages freed\n", len); return len; } @@ -138,7 +139,7 @@ static unsigned long __init xen_return_unused_memory(unsigned long max_pfn, if (last_end < max_addr) released += xen_release_chunk(last_end, max_addr); - printk(KERN_INFO "released %lu pages of unused memory\n", released); + printk(KERN_INFO "released %ld pages of unused memory\n", released); return released; } @@ -425,7 +426,7 @@ void __init xen_arch_setup(void) #ifdef CONFIG_X86_32 boot_cpu_data.hlt_works_ok = 1; #endif - disable_cpuidle(); + pm_idle = default_idle; boot_option_idle_override = IDLE_HALT; fiddle_vdso(); diff --git a/trunk/arch/x86/xen/trace.c b/trunk/arch/x86/xen/trace.c index 520022d1a181..734beba2a08c 100644 --- a/trunk/arch/x86/xen/trace.c +++ b/trunk/arch/x86/xen/trace.c @@ -1,5 +1,4 @@ #include -#include #define N(x) [__HYPERVISOR_##x] = "("#x")" static const char *xen_hypercall_names[] = { diff --git a/trunk/block/blk-core.c b/trunk/block/blk-core.c index b627558c461f..b850bedad229 100644 --- a/trunk/block/blk-core.c +++ b/trunk/block/blk-core.c @@ -1368,10 +1368,8 @@ static bool should_fail_request(struct hd_struct *part, unsigned int bytes) static int __init fail_make_request_debugfs(void) { - struct dentry *dir = fault_create_debugfs_attr("fail_make_request", - NULL, &fail_make_request); - - return IS_ERR(dir) ? PTR_ERR(dir) : 0; + return init_fault_attr_dentries(&fail_make_request, + "fail_make_request"); } late_initcall(fail_make_request_debugfs); diff --git a/trunk/block/blk-timeout.c b/trunk/block/blk-timeout.c index 780354888958..4f0c06c7a338 100644 --- a/trunk/block/blk-timeout.c +++ b/trunk/block/blk-timeout.c @@ -28,10 +28,7 @@ int blk_should_fake_timeout(struct request_queue *q) static int __init fail_io_timeout_debugfs(void) { - struct dentry *dir = fault_create_debugfs_attr("fail_io_timeout", - NULL, &fail_io_timeout); - - return IS_ERR(dir) ? PTR_ERR(dir) : 0; + return init_fault_attr_dentries(&fail_io_timeout, "fail_io_timeout"); } late_initcall(fail_io_timeout_debugfs); diff --git a/trunk/crypto/md5.c b/trunk/crypto/md5.c index 7febeaab923b..30efc7dad891 100644 --- a/trunk/crypto/md5.c +++ b/trunk/crypto/md5.c @@ -21,9 +21,99 @@ #include #include #include -#include #include +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +#define MD5STEP(f, w, x, y, z, in, s) \ + (w += f(x, y, z) + in, w = (w<>(32-s)) + x) + +static void md5_transform(u32 *hash, u32 const *in) +{ + u32 a, b, c, d; + + a = hash[0]; + b = hash[1]; + c = hash[2]; + d = hash[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; +} + /* XXX: this stuff can be optimized */ static inline void le32_to_cpu_array(u32 *buf, unsigned int words) { diff --git a/trunk/drivers/acpi/acpica/acglobal.h b/trunk/drivers/acpi/acpica/acglobal.h index 76dc02f15574..73863d86f022 100644 --- a/trunk/drivers/acpi/acpica/acglobal.h +++ b/trunk/drivers/acpi/acpica/acglobal.h @@ -126,12 +126,6 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); -/* - * Disable runtime checking and repair of values returned by control methods. - * Use only if the repair is causing a problem on a particular machine. - */ -u8 ACPI_INIT_GLOBAL(acpi_gbl_disable_auto_repair, FALSE); - /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT; diff --git a/trunk/drivers/acpi/acpica/aclocal.h b/trunk/drivers/acpi/acpica/aclocal.h index 5552125d8340..c7f743ca395b 100644 --- a/trunk/drivers/acpi/acpica/aclocal.h +++ b/trunk/drivers/acpi/acpica/aclocal.h @@ -357,7 +357,6 @@ struct acpi_predefined_data { char *pathname; const union acpi_predefined_info *predefined; union acpi_operand_object *parent_package; - struct acpi_namespace_node *node; u32 flags; u8 node_flags; }; diff --git a/trunk/drivers/acpi/acpica/acpredef.h b/trunk/drivers/acpi/acpica/acpredef.h index c445cca490ea..94e73c97cf85 100644 --- a/trunk/drivers/acpi/acpica/acpredef.h +++ b/trunk/drivers/acpi/acpica/acpredef.h @@ -468,7 +468,6 @@ static const union acpi_predefined_info predefined_names[] = {{"_SWS", 0, ACPI_RTYPE_INTEGER}}, {{"_TC1", 0, ACPI_RTYPE_INTEGER}}, {{"_TC2", 0, ACPI_RTYPE_INTEGER}}, - {{"_TDL", 0, ACPI_RTYPE_INTEGER}}, {{"_TIP", 1, ACPI_RTYPE_INTEGER}}, {{"_TIV", 1, ACPI_RTYPE_INTEGER}}, {{"_TMP", 0, ACPI_RTYPE_INTEGER}}, diff --git a/trunk/drivers/acpi/acpica/nspredef.c b/trunk/drivers/acpi/acpica/nspredef.c index c845c8089f39..9fb03fa8ffde 100644 --- a/trunk/drivers/acpi/acpica/nspredef.c +++ b/trunk/drivers/acpi/acpica/nspredef.c @@ -193,20 +193,14 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, } /* - * Return value validation and possible repair. + * 1) We have a return value, but if one wasn't expected, just exit, this is + * not a problem. For example, if the "Implicit Return" feature is + * enabled, methods will always return a value. * - * 1) Don't perform return value validation/repair if this feature - * has been disabled via a global option. - * - * 2) We have a return value, but if one wasn't expected, just exit, - * this is not a problem. For example, if the "Implicit Return" - * feature is enabled, methods will always return a value. - * - * 3) If the return value can be of any type, then we cannot perform - * any validation, just exit. + * 2) If the return value can be of any type, then we cannot perform any + * validation, exit. */ - if (acpi_gbl_disable_auto_repair || - (!predefined->info.expected_btypes) || + if ((!predefined->info.expected_btypes) || (predefined->info.expected_btypes == ACPI_RTYPE_ALL)) { goto cleanup; } @@ -218,7 +212,6 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node, goto cleanup; } data->predefined = predefined; - data->node = node; data->node_flags = node->flags; data->pathname = pathname; diff --git a/trunk/drivers/acpi/acpica/nsrepair2.c b/trunk/drivers/acpi/acpica/nsrepair2.c index 024c4f263f87..973883babee1 100644 --- a/trunk/drivers/acpi/acpica/nsrepair2.c +++ b/trunk/drivers/acpi/acpica/nsrepair2.c @@ -503,21 +503,6 @@ acpi_ns_repair_TSS(struct acpi_predefined_data *data, { union acpi_operand_object *return_object = *return_object_ptr; acpi_status status; - struct acpi_namespace_node *node; - - /* - * We can only sort the _TSS return package if there is no _PSS in the - * same scope. This is because if _PSS is present, the ACPI specification - * dictates that the _TSS Power Dissipation field is to be ignored, and - * therefore some BIOSs leave garbage values in the _TSS Power field(s). - * In this case, it is best to just return the _TSS package as-is. - * (May, 2011) - */ - status = - acpi_ns_get_node(data->node, "^_PSS", ACPI_NS_NO_UPSEARCH, &node); - if (ACPI_SUCCESS(status)) { - return (AE_OK); - } status = acpi_ns_check_sorted_list(data, return_object, 5, 1, ACPI_SORT_DESCENDING, diff --git a/trunk/drivers/acpi/acpica/tbinstal.c b/trunk/drivers/acpi/acpica/tbinstal.c index 62365f6075dd..48db0944ce4a 100644 --- a/trunk/drivers/acpi/acpica/tbinstal.c +++ b/trunk/drivers/acpi/acpica/tbinstal.c @@ -126,29 +126,12 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index) } /* - * Validate the incoming table signature. - * - * 1) Originally, we checked the table signature for "SSDT" or "PSDT". - * 2) We added support for OEMx tables, signature "OEM". - * 3) Valid tables were encountered with a null signature, so we just - * gave up on validating the signature, (05/2008). - * 4) We encountered non-AML tables such as the MADT, which caused - * interpreter errors and kernel faults. So now, we once again allow - * only "SSDT", "OEMx", and now, also a null signature. (05/2011). + * Originally, we checked the table signature for "SSDT" or "PSDT" here. + * Next, we added support for OEMx tables, signature "OEM". + * Valid tables were encountered with a null signature, so we've just + * given up on validating the signature, since it seems to be a waste + * of code. The original code was removed (05/2008). */ - if ((table_desc->pointer->signature[0] != 0x00) && - (!ACPI_COMPARE_NAME(table_desc->pointer->signature, ACPI_SIG_SSDT)) - && (ACPI_STRNCMP(table_desc->pointer->signature, "OEM", 3))) { - ACPI_ERROR((AE_INFO, - "Table has invalid signature [%4.4s] (0x%8.8X), must be SSDT or OEMx", - acpi_ut_valid_acpi_name(*(u32 *)table_desc-> - pointer-> - signature) ? table_desc-> - pointer->signature : "????", - *(u32 *)table_desc->pointer->signature)); - - return_ACPI_STATUS(AE_BAD_SIGNATURE); - } (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES); diff --git a/trunk/drivers/acpi/apei/Kconfig b/trunk/drivers/acpi/apei/Kconfig index c34aa51af4ee..f739a70b1c70 100644 --- a/trunk/drivers/acpi/apei/Kconfig +++ b/trunk/drivers/acpi/apei/Kconfig @@ -10,11 +10,9 @@ config ACPI_APEI error injection. config ACPI_APEI_GHES - bool "APEI Generic Hardware Error Source" + tristate "APEI Generic Hardware Error Source" depends on ACPI_APEI && X86 select ACPI_HED - select LLIST - select GENERIC_ALLOCATOR help Generic Hardware Error Source provides a way to report platform hardware errors (such as that from chipset). It @@ -32,13 +30,6 @@ config ACPI_APEI_PCIEAER PCIe AER errors may be reported via APEI firmware first mode. Turn on this option to enable the corresponding support. -config ACPI_APEI_MEMORY_FAILURE - bool "APEI memory error recovering support" - depends on ACPI_APEI && MEMORY_FAILURE - help - Memory errors may be reported via APEI firmware first mode. - Turn on this option to enable the memory recovering support. - config ACPI_APEI_EINJ tristate "APEI Error INJection (EINJ)" depends on ACPI_APEI && DEBUG_FS diff --git a/trunk/drivers/acpi/apei/apei-base.c b/trunk/drivers/acpi/apei/apei-base.c index 8041248fce9b..4a904a4bf05f 100644 --- a/trunk/drivers/acpi/apei/apei-base.c +++ b/trunk/drivers/acpi/apei/apei-base.c @@ -157,10 +157,9 @@ EXPORT_SYMBOL_GPL(apei_exec_noop); * Interpret the specified action. Go through whole action table, * execute all instructions belong to the action. */ -int __apei_exec_run(struct apei_exec_context *ctx, u8 action, - bool optional) +int apei_exec_run(struct apei_exec_context *ctx, u8 action) { - int rc = -ENOENT; + int rc; u32 i, ip; struct acpi_whea_header *entry; apei_exec_ins_func_t run; @@ -199,9 +198,9 @@ int __apei_exec_run(struct apei_exec_context *ctx, u8 action, goto rewind; } - return !optional && rc < 0 ? rc : 0; + return 0; } -EXPORT_SYMBOL_GPL(__apei_exec_run); +EXPORT_SYMBOL_GPL(apei_exec_run); typedef int (*apei_exec_entry_func_t)(struct apei_exec_context *ctx, struct acpi_whea_header *entry, @@ -604,29 +603,3 @@ struct dentry *apei_get_debugfs_dir(void) return dapei; } EXPORT_SYMBOL_GPL(apei_get_debugfs_dir); - -int apei_osc_setup(void) -{ - static u8 whea_uuid_str[] = "ed855e0c-6c90-47bf-a62a-26de0fc5ad5c"; - acpi_handle handle; - u32 capbuf[3]; - struct acpi_osc_context context = { - .uuid_str = whea_uuid_str, - .rev = 1, - .cap.length = sizeof(capbuf), - .cap.pointer = capbuf, - }; - - capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; - capbuf[OSC_SUPPORT_TYPE] = 0; - capbuf[OSC_CONTROL_TYPE] = 0; - - if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)) - || ACPI_FAILURE(acpi_run_osc(handle, &context))) - return -EIO; - else { - kfree(context.ret.pointer); - return 0; - } -} -EXPORT_SYMBOL_GPL(apei_osc_setup); diff --git a/trunk/drivers/acpi/apei/apei-internal.h b/trunk/drivers/acpi/apei/apei-internal.h index f57050e7a5e7..ef0581f2094d 100644 --- a/trunk/drivers/acpi/apei/apei-internal.h +++ b/trunk/drivers/acpi/apei/apei-internal.h @@ -50,18 +50,7 @@ static inline u64 apei_exec_ctx_get_output(struct apei_exec_context *ctx) return ctx->value; } -int __apei_exec_run(struct apei_exec_context *ctx, u8 action, bool optional); - -static inline int apei_exec_run(struct apei_exec_context *ctx, u8 action) -{ - return __apei_exec_run(ctx, action, 0); -} - -/* It is optional whether the firmware provides the action */ -static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 action) -{ - return __apei_exec_run(ctx, action, 1); -} +int apei_exec_run(struct apei_exec_context *ctx, u8 action); /* Common instruction implementation */ @@ -124,6 +113,4 @@ void apei_estatus_print(const char *pfx, const struct acpi_hest_generic_status *estatus); int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); int apei_estatus_check(const struct acpi_hest_generic_status *estatus); - -int apei_osc_setup(void); #endif diff --git a/trunk/drivers/acpi/apei/einj.c b/trunk/drivers/acpi/apei/einj.c index 589b96c38704..f74b2ea11f21 100644 --- a/trunk/drivers/acpi/apei/einj.c +++ b/trunk/drivers/acpi/apei/einj.c @@ -46,8 +46,7 @@ * Some BIOSes allow parameters to the SET_ERROR_TYPE entries in the * EINJ table through an unpublished extension. Use with caution as * most will ignore the parameter and make their own choice of address - * for error injection. This extension is used only if - * param_extension module parameter is specified. + * for error injection. */ struct einj_parameter { u64 type; @@ -66,9 +65,6 @@ struct einj_parameter { ((struct acpi_whea_header *)((char *)(tab) + \ sizeof(struct acpi_table_einj))) -static bool param_extension; -module_param(param_extension, bool, 0); - static struct acpi_table_einj *einj_tab; static struct apei_resources einj_resources; @@ -289,7 +285,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) einj_exec_ctx_init(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_EINJ_BEGIN_OPERATION); + rc = apei_exec_run(&ctx, ACPI_EINJ_BEGIN_OPERATION); if (rc) return rc; apei_exec_ctx_set_input(&ctx, type); @@ -327,7 +323,7 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) rc = __einj_error_trigger(trigger_paddr); if (rc) return rc; - rc = apei_exec_run_optional(&ctx, ACPI_EINJ_END_OPERATION); + rc = apei_exec_run(&ctx, ACPI_EINJ_END_OPERATION); return rc; } @@ -493,6 +489,14 @@ static int __init einj_init(void) einj_debug_dir, NULL, &error_type_fops); if (!fentry) goto err_cleanup; + fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR, + einj_debug_dir, &error_param1); + if (!fentry) + goto err_cleanup; + fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR, + einj_debug_dir, &error_param2); + if (!fentry) + goto err_cleanup; fentry = debugfs_create_file("error_inject", S_IWUSR, einj_debug_dir, NULL, &error_inject_fops); if (!fentry) @@ -509,23 +513,12 @@ static int __init einj_init(void) rc = apei_exec_pre_map_gars(&ctx); if (rc) goto err_release; - if (param_extension) { - param_paddr = einj_get_parameter_address(); - if (param_paddr) { - einj_param = ioremap(param_paddr, sizeof(*einj_param)); - rc = -ENOMEM; - if (!einj_param) - goto err_unmap; - fentry = debugfs_create_x64("param1", S_IRUSR | S_IWUSR, - einj_debug_dir, &error_param1); - if (!fentry) - goto err_unmap; - fentry = debugfs_create_x64("param2", S_IRUSR | S_IWUSR, - einj_debug_dir, &error_param2); - if (!fentry) - goto err_unmap; - } else - pr_warn(EINJ_PFX "Parameter extension is not supported.\n"); + param_paddr = einj_get_parameter_address(); + if (param_paddr) { + einj_param = ioremap(param_paddr, sizeof(*einj_param)); + rc = -ENOMEM; + if (!einj_param) + goto err_unmap; } pr_info(EINJ_PFX "Error INJection is initialized.\n"); @@ -533,8 +526,6 @@ static int __init einj_init(void) return 0; err_unmap: - if (einj_param) - iounmap(einj_param); apei_exec_post_unmap_gars(&ctx); err_release: apei_resources_release(&einj_resources); diff --git a/trunk/drivers/acpi/apei/erst-dbg.c b/trunk/drivers/acpi/apei/erst-dbg.c index 903549df809b..a4cfb64c86a1 100644 --- a/trunk/drivers/acpi/apei/erst-dbg.c +++ b/trunk/drivers/acpi/apei/erst-dbg.c @@ -33,7 +33,7 @@ #define ERST_DBG_PFX "ERST DBG: " -#define ERST_DBG_RECORD_LEN_MAX 0x4000 +#define ERST_DBG_RECORD_LEN_MAX 4096 static void *erst_dbg_buf; static unsigned int erst_dbg_buf_len; @@ -213,10 +213,6 @@ static struct miscdevice erst_dbg_dev = { static __init int erst_dbg_init(void) { - if (erst_disable) { - pr_info(ERST_DBG_PFX "ERST support is disabled.\n"); - return -ENODEV; - } return misc_register(&erst_dbg_dev); } diff --git a/trunk/drivers/acpi/apei/erst.c b/trunk/drivers/acpi/apei/erst.c index 2ca59dc69f7f..6053f4780df9 100644 --- a/trunk/drivers/acpi/apei/erst.c +++ b/trunk/drivers/acpi/apei/erst.c @@ -642,7 +642,7 @@ static int __erst_write_to_storage(u64 offset) int rc; erst_exec_ctx_init(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_WRITE); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_WRITE); if (rc) return rc; apei_exec_ctx_set_input(&ctx, offset); @@ -666,7 +666,7 @@ static int __erst_write_to_storage(u64 offset) if (rc) return rc; val = apei_exec_ctx_get_output(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); + rc = apei_exec_run(&ctx, ACPI_ERST_END); if (rc) return rc; @@ -681,7 +681,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset) int rc; erst_exec_ctx_init(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_READ); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_READ); if (rc) return rc; apei_exec_ctx_set_input(&ctx, offset); @@ -709,7 +709,7 @@ static int __erst_read_from_storage(u64 record_id, u64 offset) if (rc) return rc; val = apei_exec_ctx_get_output(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); + rc = apei_exec_run(&ctx, ACPI_ERST_END); if (rc) return rc; @@ -724,7 +724,7 @@ static int __erst_clear_from_storage(u64 record_id) int rc; erst_exec_ctx_init(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_BEGIN_CLEAR); + rc = apei_exec_run(&ctx, ACPI_ERST_BEGIN_CLEAR); if (rc) return rc; apei_exec_ctx_set_input(&ctx, record_id); @@ -748,7 +748,7 @@ static int __erst_clear_from_storage(u64 record_id) if (rc) return rc; val = apei_exec_ctx_get_output(&ctx); - rc = apei_exec_run_optional(&ctx, ACPI_ERST_END); + rc = apei_exec_run(&ctx, ACPI_ERST_END); if (rc) return rc; diff --git a/trunk/drivers/acpi/apei/ghes.c b/trunk/drivers/acpi/apei/ghes.c index 0784f99a4665..f703b2881153 100644 --- a/trunk/drivers/acpi/apei/ghes.c +++ b/trunk/drivers/acpi/apei/ghes.c @@ -12,7 +12,7 @@ * For more information about Generic Hardware Error Source, please * refer to ACPI Specification version 4.0, section 17.3.2.6 * - * Copyright 2010,2011 Intel Corp. + * Copyright 2010 Intel Corp. * Author: Huang Ying * * This program is free software; you can redistribute it and/or @@ -42,9 +42,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -56,30 +53,6 @@ #define GHES_PFX "GHES: " #define GHES_ESTATUS_MAX_SIZE 65536 -#define GHES_ESOURCE_PREALLOC_MAX_SIZE 65536 - -#define GHES_ESTATUS_POOL_MIN_ALLOC_ORDER 3 - -/* This is just an estimation for memory pool allocation */ -#define GHES_ESTATUS_CACHE_AVG_SIZE 512 - -#define GHES_ESTATUS_CACHES_SIZE 4 - -#define GHES_ESTATUS_IN_CACHE_MAX_NSEC 10000000000ULL -/* Prevent too many caches are allocated because of RCU */ -#define GHES_ESTATUS_CACHE_ALLOCED_MAX (GHES_ESTATUS_CACHES_SIZE * 3 / 2) - -#define GHES_ESTATUS_CACHE_LEN(estatus_len) \ - (sizeof(struct ghes_estatus_cache) + (estatus_len)) -#define GHES_ESTATUS_FROM_CACHE(estatus_cache) \ - ((struct acpi_hest_generic_status *) \ - ((struct ghes_estatus_cache *)(estatus_cache) + 1)) - -#define GHES_ESTATUS_NODE_LEN(estatus_len) \ - (sizeof(struct ghes_estatus_node) + (estatus_len)) -#define GHES_ESTATUS_FROM_NODE(estatus_node) \ - ((struct acpi_hest_generic_status *) \ - ((struct ghes_estatus_node *)(estatus_node) + 1)) /* * One struct ghes is created for each generic hardware error source. @@ -104,22 +77,6 @@ struct ghes { }; }; -struct ghes_estatus_node { - struct llist_node llnode; - struct acpi_hest_generic *generic; -}; - -struct ghes_estatus_cache { - u32 estatus_len; - atomic_t count; - struct acpi_hest_generic *generic; - unsigned long long time_in; - struct rcu_head rcu; -}; - -int ghes_disable; -module_param_named(disable, ghes_disable, bool, 0); - static int ghes_panic_timeout __read_mostly = 30; /* @@ -164,22 +121,6 @@ static struct vm_struct *ghes_ioremap_area; static DEFINE_RAW_SPINLOCK(ghes_ioremap_lock_nmi); static DEFINE_SPINLOCK(ghes_ioremap_lock_irq); -/* - * printk is not safe in NMI context. So in NMI handler, we allocate - * required memory from lock-less memory allocator - * (ghes_estatus_pool), save estatus into it, put them into lock-less - * list (ghes_estatus_llist), then delay printk into IRQ context via - * irq_work (ghes_proc_irq_work). ghes_estatus_size_request record - * required pool size by all NMI error source. - */ -static struct gen_pool *ghes_estatus_pool; -static unsigned long ghes_estatus_pool_size_request; -static struct llist_head ghes_estatus_llist; -static struct irq_work ghes_proc_irq_work; - -struct ghes_estatus_cache *ghes_estatus_caches[GHES_ESTATUS_CACHES_SIZE]; -static atomic_t ghes_estatus_cache_alloced; - static int ghes_ioremap_init(void) { ghes_ioremap_area = __get_vm_area(PAGE_SIZE * GHES_IOREMAP_PAGES, @@ -239,55 +180,6 @@ static void ghes_iounmap_irq(void __iomem *vaddr_ptr) __flush_tlb_one(vaddr); } -static int ghes_estatus_pool_init(void) -{ - ghes_estatus_pool = gen_pool_create(GHES_ESTATUS_POOL_MIN_ALLOC_ORDER, -1); - if (!ghes_estatus_pool) - return -ENOMEM; - return 0; -} - -static void ghes_estatus_pool_free_chunk_page(struct gen_pool *pool, - struct gen_pool_chunk *chunk, - void *data) -{ - free_page(chunk->start_addr); -} - -static void ghes_estatus_pool_exit(void) -{ - gen_pool_for_each_chunk(ghes_estatus_pool, - ghes_estatus_pool_free_chunk_page, NULL); - gen_pool_destroy(ghes_estatus_pool); -} - -static int ghes_estatus_pool_expand(unsigned long len) -{ - unsigned long i, pages, size, addr; - int ret; - - ghes_estatus_pool_size_request += PAGE_ALIGN(len); - size = gen_pool_size(ghes_estatus_pool); - if (size >= ghes_estatus_pool_size_request) - return 0; - pages = (ghes_estatus_pool_size_request - size) / PAGE_SIZE; - for (i = 0; i < pages; i++) { - addr = __get_free_page(GFP_KERNEL); - if (!addr) - return -ENOMEM; - ret = gen_pool_add(ghes_estatus_pool, addr, PAGE_SIZE, -1); - if (ret) - return ret; - } - - return 0; -} - -static void ghes_estatus_pool_shrink(unsigned long len) -{ - ghes_estatus_pool_size_request -= PAGE_ALIGN(len); -} - static struct ghes *ghes_new(struct acpi_hest_generic *generic) { struct ghes *ghes; @@ -449,196 +341,43 @@ static void ghes_clear_estatus(struct ghes *ghes) ghes->flags &= ~GHES_TO_CLEAR; } -static void ghes_do_proc(const struct acpi_hest_generic_status *estatus) +static void ghes_do_proc(struct ghes *ghes) { - int sev, sec_sev; + int sev, processed = 0; struct acpi_hest_generic_data *gdata; - sev = ghes_severity(estatus->error_severity); - apei_estatus_for_each_section(estatus, gdata) { - sec_sev = ghes_severity(gdata->error_severity); + sev = ghes_severity(ghes->estatus->error_severity); + apei_estatus_for_each_section(ghes->estatus, gdata) { +#ifdef CONFIG_X86_MCE if (!uuid_le_cmp(*(uuid_le *)gdata->section_type, CPER_SEC_PLATFORM_MEM)) { - struct cper_sec_mem_err *mem_err; - mem_err = (struct cper_sec_mem_err *)(gdata+1); -#ifdef CONFIG_X86_MCE - apei_mce_report_mem_error(sev == GHES_SEV_CORRECTED, - mem_err); -#endif -#ifdef CONFIG_ACPI_APEI_MEMORY_FAILURE - if (sev == GHES_SEV_RECOVERABLE && - sec_sev == GHES_SEV_RECOVERABLE && - mem_err->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) { - unsigned long pfn; - pfn = mem_err->physical_addr >> PAGE_SHIFT; - memory_failure_queue(pfn, 0, 0); - } -#endif + apei_mce_report_mem_error( + sev == GHES_SEV_CORRECTED, + (struct cper_sec_mem_err *)(gdata+1)); + processed = 1; } +#endif } } -static void __ghes_print_estatus(const char *pfx, - const struct acpi_hest_generic *generic, - const struct acpi_hest_generic_status *estatus) +static void ghes_print_estatus(const char *pfx, struct ghes *ghes) { + /* Not more than 2 messages every 5 seconds */ + static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2); + if (pfx == NULL) { - if (ghes_severity(estatus->error_severity) <= + if (ghes_severity(ghes->estatus->error_severity) <= GHES_SEV_CORRECTED) pfx = KERN_WARNING HW_ERR; else pfx = KERN_ERR HW_ERR; } - printk("%s""Hardware error from APEI Generic Hardware Error Source: %d\n", - pfx, generic->header.source_id); - apei_estatus_print(pfx, estatus); -} - -static int ghes_print_estatus(const char *pfx, - const struct acpi_hest_generic *generic, - const struct acpi_hest_generic_status *estatus) -{ - /* Not more than 2 messages every 5 seconds */ - static DEFINE_RATELIMIT_STATE(ratelimit_corrected, 5*HZ, 2); - static DEFINE_RATELIMIT_STATE(ratelimit_uncorrected, 5*HZ, 2); - struct ratelimit_state *ratelimit; - - if (ghes_severity(estatus->error_severity) <= GHES_SEV_CORRECTED) - ratelimit = &ratelimit_corrected; - else - ratelimit = &ratelimit_uncorrected; - if (__ratelimit(ratelimit)) { - __ghes_print_estatus(pfx, generic, estatus); - return 1; + if (__ratelimit(&ratelimit)) { + printk( + "%s""Hardware error from APEI Generic Hardware Error Source: %d\n", + pfx, ghes->generic->header.source_id); + apei_estatus_print(pfx, ghes->estatus); } - return 0; -} - -/* - * GHES error status reporting throttle, to report more kinds of - * errors, instead of just most frequently occurred errors. - */ -static int ghes_estatus_cached(struct acpi_hest_generic_status *estatus) -{ - u32 len; - int i, cached = 0; - unsigned long long now; - struct ghes_estatus_cache *cache; - struct acpi_hest_generic_status *cache_estatus; - - len = apei_estatus_len(estatus); - rcu_read_lock(); - for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { - cache = rcu_dereference(ghes_estatus_caches[i]); - if (cache == NULL) - continue; - if (len != cache->estatus_len) - continue; - cache_estatus = GHES_ESTATUS_FROM_CACHE(cache); - if (memcmp(estatus, cache_estatus, len)) - continue; - atomic_inc(&cache->count); - now = sched_clock(); - if (now - cache->time_in < GHES_ESTATUS_IN_CACHE_MAX_NSEC) - cached = 1; - break; - } - rcu_read_unlock(); - return cached; -} - -static struct ghes_estatus_cache *ghes_estatus_cache_alloc( - struct acpi_hest_generic *generic, - struct acpi_hest_generic_status *estatus) -{ - int alloced; - u32 len, cache_len; - struct ghes_estatus_cache *cache; - struct acpi_hest_generic_status *cache_estatus; - - alloced = atomic_add_return(1, &ghes_estatus_cache_alloced); - if (alloced > GHES_ESTATUS_CACHE_ALLOCED_MAX) { - atomic_dec(&ghes_estatus_cache_alloced); - return NULL; - } - len = apei_estatus_len(estatus); - cache_len = GHES_ESTATUS_CACHE_LEN(len); - cache = (void *)gen_pool_alloc(ghes_estatus_pool, cache_len); - if (!cache) { - atomic_dec(&ghes_estatus_cache_alloced); - return NULL; - } - cache_estatus = GHES_ESTATUS_FROM_CACHE(cache); - memcpy(cache_estatus, estatus, len); - cache->estatus_len = len; - atomic_set(&cache->count, 0); - cache->generic = generic; - cache->time_in = sched_clock(); - return cache; -} - -static void ghes_estatus_cache_free(struct ghes_estatus_cache *cache) -{ - u32 len; - - len = apei_estatus_len(GHES_ESTATUS_FROM_CACHE(cache)); - len = GHES_ESTATUS_CACHE_LEN(len); - gen_pool_free(ghes_estatus_pool, (unsigned long)cache, len); - atomic_dec(&ghes_estatus_cache_alloced); -} - -static void ghes_estatus_cache_rcu_free(struct rcu_head *head) -{ - struct ghes_estatus_cache *cache; - - cache = container_of(head, struct ghes_estatus_cache, rcu); - ghes_estatus_cache_free(cache); -} - -static void ghes_estatus_cache_add( - struct acpi_hest_generic *generic, - struct acpi_hest_generic_status *estatus) -{ - int i, slot = -1, count; - unsigned long long now, duration, period, max_period = 0; - struct ghes_estatus_cache *cache, *slot_cache = NULL, *new_cache; - - new_cache = ghes_estatus_cache_alloc(generic, estatus); - if (new_cache == NULL) - return; - rcu_read_lock(); - now = sched_clock(); - for (i = 0; i < GHES_ESTATUS_CACHES_SIZE; i++) { - cache = rcu_dereference(ghes_estatus_caches[i]); - if (cache == NULL) { - slot = i; - slot_cache = NULL; - break; - } - duration = now - cache->time_in; - if (duration >= GHES_ESTATUS_IN_CACHE_MAX_NSEC) { - slot = i; - slot_cache = cache; - break; - } - count = atomic_read(&cache->count); - period = duration; - do_div(period, (count + 1)); - if (period > max_period) { - max_period = period; - slot = i; - slot_cache = cache; - } - } - /* new_cache must be put into array after its contents are written */ - smp_wmb(); - if (slot != -1 && cmpxchg(ghes_estatus_caches + slot, - slot_cache, new_cache) == slot_cache) { - if (slot_cache) - call_rcu(&slot_cache->rcu, ghes_estatus_cache_rcu_free); - } else - ghes_estatus_cache_free(new_cache); - rcu_read_unlock(); } static int ghes_proc(struct ghes *ghes) @@ -648,11 +387,9 @@ static int ghes_proc(struct ghes *ghes) rc = ghes_read_estatus(ghes, 0); if (rc) goto out; - if (!ghes_estatus_cached(ghes->estatus)) { - if (ghes_print_estatus(NULL, ghes->generic, ghes->estatus)) - ghes_estatus_cache_add(ghes->generic, ghes->estatus); - } - ghes_do_proc(ghes->estatus); + ghes_print_estatus(NULL, ghes); + ghes_do_proc(ghes); + out: ghes_clear_estatus(ghes); return 0; @@ -710,45 +447,6 @@ static int ghes_notify_sci(struct notifier_block *this, return ret; } -static void ghes_proc_in_irq(struct irq_work *irq_work) -{ - struct llist_node *llnode, *next, *tail = NULL; - struct ghes_estatus_node *estatus_node; - struct acpi_hest_generic *generic; - struct acpi_hest_generic_status *estatus; - u32 len, node_len; - - /* - * Because the time order of estatus in list is reversed, - * revert it back to proper order. - */ - llnode = llist_del_all(&ghes_estatus_llist); - while (llnode) { - next = llnode->next; - llnode->next = tail; - tail = llnode; - llnode = next; - } - llnode = tail; - while (llnode) { - next = llnode->next; - estatus_node = llist_entry(llnode, struct ghes_estatus_node, - llnode); - estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - len = apei_estatus_len(estatus); - node_len = GHES_ESTATUS_NODE_LEN(len); - ghes_do_proc(estatus); - if (!ghes_estatus_cached(estatus)) { - generic = estatus_node->generic; - if (ghes_print_estatus(NULL, generic, estatus)) - ghes_estatus_cache_add(generic, estatus); - } - gen_pool_free(ghes_estatus_pool, (unsigned long)estatus_node, - node_len); - llnode = next; - } -} - static int ghes_notify_nmi(struct notifier_block *this, unsigned long cmd, void *data) { @@ -778,8 +476,7 @@ static int ghes_notify_nmi(struct notifier_block *this, if (sev_global >= GHES_SEV_PANIC) { oops_begin(); - __ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global->generic, - ghes_global->estatus); + ghes_print_estatus(KERN_EMERG HW_ERR, ghes_global); /* reboot to log the error! */ if (panic_timeout == 0) panic_timeout = ghes_panic_timeout; @@ -787,34 +484,12 @@ static int ghes_notify_nmi(struct notifier_block *this, } list_for_each_entry_rcu(ghes, &ghes_nmi, list) { -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - u32 len, node_len; - struct ghes_estatus_node *estatus_node; - struct acpi_hest_generic_status *estatus; -#endif if (!(ghes->flags & GHES_TO_CLEAR)) continue; -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - if (ghes_estatus_cached(ghes->estatus)) - goto next; - /* Save estatus for further processing in IRQ context */ - len = apei_estatus_len(ghes->estatus); - node_len = GHES_ESTATUS_NODE_LEN(len); - estatus_node = (void *)gen_pool_alloc(ghes_estatus_pool, - node_len); - if (estatus_node) { - estatus_node->generic = ghes->generic; - estatus = GHES_ESTATUS_FROM_NODE(estatus_node); - memcpy(estatus, ghes->estatus, len); - llist_add(&estatus_node->llnode, &ghes_estatus_llist); - } -next: -#endif + /* Do not print estatus because printk is not NMI safe */ + ghes_do_proc(ghes); ghes_clear_estatus(ghes); } -#ifdef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - irq_work_queue(&ghes_proc_irq_work); -#endif out: raw_spin_unlock(&ghes_nmi_lock); @@ -829,26 +504,10 @@ static struct notifier_block ghes_notifier_nmi = { .notifier_call = ghes_notify_nmi, }; -static unsigned long ghes_esource_prealloc_size( - const struct acpi_hest_generic *generic) -{ - unsigned long block_length, prealloc_records, prealloc_size; - - block_length = min_t(unsigned long, generic->error_block_length, - GHES_ESTATUS_MAX_SIZE); - prealloc_records = max_t(unsigned long, - generic->records_to_preallocate, 1); - prealloc_size = min_t(unsigned long, block_length * prealloc_records, - GHES_ESOURCE_PREALLOC_MAX_SIZE); - - return prealloc_size; -} - static int __devinit ghes_probe(struct platform_device *ghes_dev) { struct acpi_hest_generic *generic; struct ghes *ghes = NULL; - unsigned long len; int rc = -EINVAL; generic = *(struct acpi_hest_generic **)ghes_dev->dev.platform_data; @@ -914,8 +573,6 @@ static int __devinit ghes_probe(struct platform_device *ghes_dev) mutex_unlock(&ghes_list_mutex); break; case ACPI_HEST_NOTIFY_NMI: - len = ghes_esource_prealloc_size(generic); - ghes_estatus_pool_expand(len); mutex_lock(&ghes_list_mutex); if (list_empty(&ghes_nmi)) register_die_notifier(&ghes_notifier_nmi); @@ -940,7 +597,6 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev) { struct ghes *ghes; struct acpi_hest_generic *generic; - unsigned long len; ghes = platform_get_drvdata(ghes_dev); generic = ghes->generic; @@ -971,8 +627,6 @@ static int __devexit ghes_remove(struct platform_device *ghes_dev) * freed after NMI handler finishes. */ synchronize_rcu(); - len = ghes_esource_prealloc_size(generic); - ghes_estatus_pool_shrink(len); break; default: BUG(); @@ -1008,43 +662,15 @@ static int __init ghes_init(void) return -EINVAL; } - if (ghes_disable) { - pr_info(GHES_PFX "GHES is not enabled!\n"); - return -EINVAL; - } - - init_irq_work(&ghes_proc_irq_work, ghes_proc_in_irq); - rc = ghes_ioremap_init(); if (rc) goto err; - rc = ghes_estatus_pool_init(); - if (rc) - goto err_ioremap_exit; - - rc = ghes_estatus_pool_expand(GHES_ESTATUS_CACHE_AVG_SIZE * - GHES_ESTATUS_CACHE_ALLOCED_MAX); - if (rc) - goto err_pool_exit; - rc = platform_driver_register(&ghes_platform_driver); if (rc) - goto err_pool_exit; - - rc = apei_osc_setup(); - if (rc == 0 && osc_sb_apei_support_acked) - pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\n"); - else if (rc == 0 && !osc_sb_apei_support_acked) - pr_info(GHES_PFX "APEI firmware first mode is enabled by WHEA _OSC.\n"); - else if (rc && osc_sb_apei_support_acked) - pr_info(GHES_PFX "APEI firmware first mode is enabled by APEI bit.\n"); - else - pr_info(GHES_PFX "Failed to enable APEI firmware first mode.\n"); + goto err_ioremap_exit; return 0; -err_pool_exit: - ghes_estatus_pool_exit(); err_ioremap_exit: ghes_ioremap_exit(); err: @@ -1054,7 +680,6 @@ static int __init ghes_init(void) static void __exit ghes_exit(void) { platform_driver_unregister(&ghes_platform_driver); - ghes_estatus_pool_exit(); ghes_ioremap_exit(); } diff --git a/trunk/drivers/acpi/apei/hest.c b/trunk/drivers/acpi/apei/hest.c index 05fee06f4d6e..181bc2f7bb74 100644 --- a/trunk/drivers/acpi/apei/hest.c +++ b/trunk/drivers/acpi/apei/hest.c @@ -231,17 +231,16 @@ void __init acpi_hest_init(void) goto err; } - if (!ghes_disable) { - rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); - if (rc) - goto err; - rc = hest_ghes_dev_register(ghes_count); - if (rc) - goto err; + rc = apei_hest_parse(hest_parse_ghes_count, &ghes_count); + if (rc) + goto err; + + rc = hest_ghes_dev_register(ghes_count); + if (!rc) { + pr_info(HEST_PFX "Table parsing has been initialized.\n"); + return; } - pr_info(HEST_PFX "Table parsing has been initialized.\n"); - return; err: hest_disable = 1; } diff --git a/trunk/drivers/acpi/battery.c b/trunk/drivers/acpi/battery.c index 7711d94a0409..2c661353e8f2 100644 --- a/trunk/drivers/acpi/battery.c +++ b/trunk/drivers/acpi/battery.c @@ -55,9 +55,6 @@ #define ACPI_BATTERY_NOTIFY_INFO 0x81 #define ACPI_BATTERY_NOTIFY_THRESHOLD 0x82 -/* Battery power unit: 0 means mW, 1 means mA */ -#define ACPI_BATTERY_POWER_UNIT_MA 1 - #define _COMPONENT ACPI_BATTERY_COMPONENT ACPI_MODULE_NAME("battery"); @@ -94,12 +91,16 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids); enum { ACPI_BATTERY_ALARM_PRESENT, ACPI_BATTERY_XINFO_PRESENT, + /* For buggy DSDTs that report negative 16-bit values for either + * charging or discharging current and/or report 0 as 65536 + * due to bad math. + */ + ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, }; struct acpi_battery { struct mutex lock; - struct mutex sysfs_lock; struct power_supply bat; struct acpi_device *device; struct notifier_block pm_nb; @@ -300,8 +301,7 @@ static enum power_supply_property energy_battery_props[] = { #ifdef CONFIG_ACPI_PROCFS_POWER inline char *acpi_battery_units(struct acpi_battery *battery) { - return (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) ? - "mA" : "mW"; + return (battery->power_unit)?"mA":"mW"; } #endif @@ -461,17 +461,9 @@ static int acpi_battery_get_state(struct acpi_battery *battery) battery->update_time = jiffies; kfree(buffer.pointer); - /* For buggy DSDTs that report negative 16-bit values for either - * charging or discharging current and/or report 0 as 65536 - * due to bad math. - */ - if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA && - battery->rate_now != ACPI_BATTERY_VALUE_UNKNOWN && - (s16)(battery->rate_now) < 0) { + if (test_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags) && + battery->rate_now != -1) battery->rate_now = abs((s16)battery->rate_now); - printk_once(KERN_WARNING FW_BUG "battery: (dis)charge rate" - " invalid.\n"); - } if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags) && battery->capacity_now >= 0 && battery->capacity_now <= 100) @@ -552,7 +544,7 @@ static int sysfs_add_battery(struct acpi_battery *battery) { int result; - if (battery->power_unit == ACPI_BATTERY_POWER_UNIT_MA) { + if (battery->power_unit) { battery->bat.properties = charge_battery_props; battery->bat.num_properties = ARRAY_SIZE(charge_battery_props); @@ -574,16 +566,18 @@ static int sysfs_add_battery(struct acpi_battery *battery) static void sysfs_remove_battery(struct acpi_battery *battery) { - mutex_lock(&battery->sysfs_lock); - if (!battery->bat.dev) { - mutex_unlock(&battery->sysfs_lock); + if (!battery->bat.dev) return; - } - device_remove_file(battery->bat.dev, &alarm_attr); power_supply_unregister(&battery->bat); battery->bat.dev = NULL; - mutex_unlock(&battery->sysfs_lock); +} + +static void acpi_battery_quirks(struct acpi_battery *battery) +{ + if (dmi_name_in_vendors("Acer") && battery->power_unit) { + set_bit(ACPI_BATTERY_QUIRK_SIGNED16_CURRENT, &battery->flags); + } } /* @@ -598,7 +592,7 @@ static void sysfs_remove_battery(struct acpi_battery *battery) * * Handle this correctly so that they won't break userspace. */ -static void acpi_battery_quirks(struct acpi_battery *battery) +static void acpi_battery_quirks2(struct acpi_battery *battery) { if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) return ; @@ -629,15 +623,13 @@ static int acpi_battery_update(struct acpi_battery *battery) result = acpi_battery_get_info(battery); if (result) return result; + acpi_battery_quirks(battery); acpi_battery_init_alarm(battery); } - if (!battery->bat.dev) { - result = sysfs_add_battery(battery); - if (result) - return result; - } + if (!battery->bat.dev) + sysfs_add_battery(battery); result = acpi_battery_get_state(battery); - acpi_battery_quirks(battery); + acpi_battery_quirks2(battery); return result; } @@ -871,7 +863,7 @@ DECLARE_FILE_FUNCTIONS(alarm); }, \ } -static const struct battery_file { +static struct battery_file { struct file_operations ops; mode_t mode; const char *name; @@ -956,12 +948,9 @@ static int battery_notify(struct notifier_block *nb, struct acpi_battery *battery = container_of(nb, struct acpi_battery, pm_nb); switch (mode) { - case PM_POST_HIBERNATION: case PM_POST_SUSPEND: - if (battery->bat.dev) { - sysfs_remove_battery(battery); - sysfs_add_battery(battery); - } + sysfs_remove_battery(battery); + sysfs_add_battery(battery); break; } @@ -983,38 +972,28 @@ static int acpi_battery_add(struct acpi_device *device) strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); device->driver_data = battery; mutex_init(&battery->lock); - mutex_init(&battery->sysfs_lock); if (ACPI_SUCCESS(acpi_get_handle(battery->device->handle, "_BIX", &handle))) set_bit(ACPI_BATTERY_XINFO_PRESENT, &battery->flags); - result = acpi_battery_update(battery); - if (result) - goto fail; + acpi_battery_update(battery); #ifdef CONFIG_ACPI_PROCFS_POWER result = acpi_battery_add_fs(device); #endif - if (result) { + if (!result) { + printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", + ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), + device->status.battery_present ? "present" : "absent"); + } else { #ifdef CONFIG_ACPI_PROCFS_POWER acpi_battery_remove_fs(device); #endif - goto fail; + kfree(battery); } - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n", - ACPI_BATTERY_DEVICE_NAME, acpi_device_bid(device), - device->status.battery_present ? "present" : "absent"); - battery->pm_nb.notifier_call = battery_notify; register_pm_notifier(&battery->pm_nb); return result; - -fail: - sysfs_remove_battery(battery); - mutex_destroy(&battery->lock); - mutex_destroy(&battery->sysfs_lock); - kfree(battery); - return result; } static int acpi_battery_remove(struct acpi_device *device, int type) @@ -1030,7 +1009,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type) #endif sysfs_remove_battery(battery); mutex_destroy(&battery->lock); - mutex_destroy(&battery->sysfs_lock); kfree(battery); return 0; } diff --git a/trunk/drivers/acpi/bus.c b/trunk/drivers/acpi/bus.c index 437ddbf0c49a..d1e06c182cdb 100644 --- a/trunk/drivers/acpi/bus.c +++ b/trunk/drivers/acpi/bus.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include @@ -520,7 +519,6 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context) } EXPORT_SYMBOL(acpi_run_osc); -bool osc_sb_apei_support_acked; static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48"; static void acpi_bus_osc_support(void) { @@ -543,19 +541,11 @@ static void acpi_bus_osc_support(void) #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; #endif - - if (!ghes_disable) - capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_APEI_SUPPORT; if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) return; - if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) { - u32 *capbuf_ret = context.ret.pointer; - if (context.ret.length > OSC_SUPPORT_TYPE) - osc_sb_apei_support_acked = - capbuf_ret[OSC_SUPPORT_TYPE] & OSC_SB_APEI_SUPPORT; + if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) kfree(context.ret.pointer); - } - /* do we need to check other returned cap? Sounds no */ + /* do we need to check the returned cap? Sounds no */ } /* -------------------------------------------------------------------------- diff --git a/trunk/drivers/acpi/dock.c b/trunk/drivers/acpi/dock.c index 19a61136d848..1864ad3cf895 100644 --- a/trunk/drivers/acpi/dock.c +++ b/trunk/drivers/acpi/dock.c @@ -77,7 +77,7 @@ struct dock_dependent_device { struct list_head list; struct list_head hotplug_list; acpi_handle handle; - const struct acpi_dock_ops *ops; + struct acpi_dock_ops *ops; void *context; }; @@ -589,7 +589,7 @@ EXPORT_SYMBOL_GPL(unregister_dock_notifier); * the dock driver after _DCK is executed. */ int -register_hotplug_dock_device(acpi_handle handle, const struct acpi_dock_ops *ops, +register_hotplug_dock_device(acpi_handle handle, struct acpi_dock_ops *ops, void *context) { struct dock_dependent_device *dd; diff --git a/trunk/drivers/acpi/ec_sys.c b/trunk/drivers/acpi/ec_sys.c index 22f918bacd35..05b44201a614 100644 --- a/trunk/drivers/acpi/ec_sys.c +++ b/trunk/drivers/acpi/ec_sys.c @@ -92,7 +92,7 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf, return count; } -static const struct file_operations acpi_ec_io_ops = { +static struct file_operations acpi_ec_io_ops = { .owner = THIS_MODULE, .open = acpi_ec_open_io, .read = acpi_ec_read_io, diff --git a/trunk/drivers/acpi/fan.c b/trunk/drivers/acpi/fan.c index 0f0356ca1a9e..467479f07c1f 100644 --- a/trunk/drivers/acpi/fan.c +++ b/trunk/drivers/acpi/fan.c @@ -110,7 +110,7 @@ fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state) return result; } -static const struct thermal_cooling_device_ops fan_cooling_ops = { +static struct thermal_cooling_device_ops fan_cooling_ops = { .get_max_state = fan_get_max_state, .get_cur_state = fan_get_cur_state, .set_cur_state = fan_set_cur_state, diff --git a/trunk/drivers/acpi/osl.c b/trunk/drivers/acpi/osl.c index fa32f584229f..372f9b70f7f4 100644 --- a/trunk/drivers/acpi/osl.c +++ b/trunk/drivers/acpi/osl.c @@ -155,7 +155,7 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) { if (!strcmp("Linux", interface)) { - printk_once(KERN_NOTICE FW_BUG PREFIX + printk(KERN_NOTICE FW_BUG PREFIX "BIOS _OSI(Linux) query %s%s\n", osi_linux.enable ? "honored" : "ignored", osi_linux.cmdline ? " via cmdline" : @@ -237,23 +237,8 @@ void acpi_os_vprintf(const char *fmt, va_list args) #endif } -#ifdef CONFIG_KEXEC -static unsigned long acpi_rsdp; -static int __init setup_acpi_rsdp(char *arg) -{ - acpi_rsdp = simple_strtoul(arg, NULL, 16); - return 0; -} -early_param("acpi_rsdp", setup_acpi_rsdp); -#endif - acpi_physical_address __init acpi_os_get_root_pointer(void) { -#ifdef CONFIG_KEXEC - if (acpi_rsdp) - return acpi_rsdp; -#endif - if (efi_enabled) { if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) return efi.acpi20; @@ -1098,13 +1083,7 @@ struct osi_setup_entry { bool enable; }; -static struct osi_setup_entry __initdata - osi_setup_entries[OSI_STRING_ENTRIES_MAX] = { - {"Module Device", true}, - {"Processor Device", true}, - {"3.0 _SCP Extensions", true}, - {"Processor Aggregator Device", true}, -}; +static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; void __init acpi_osi_setup(char *str) { diff --git a/trunk/drivers/acpi/pci_irq.c b/trunk/drivers/acpi/pci_irq.c index 7f9eba9a0b02..f907cfbfa13c 100644 --- a/trunk/drivers/acpi/pci_irq.c +++ b/trunk/drivers/acpi/pci_irq.c @@ -303,61 +303,6 @@ void acpi_pci_irq_del_prt(struct pci_bus *bus) /* -------------------------------------------------------------------------- PCI Interrupt Routing Support -------------------------------------------------------------------------- */ -#ifdef CONFIG_X86_IO_APIC -extern int noioapicquirk; -extern int noioapicreroute; - -static int bridge_has_boot_interrupt_variant(struct pci_bus *bus) -{ - struct pci_bus *bus_it; - - for (bus_it = bus ; bus_it ; bus_it = bus_it->parent) { - if (!bus_it->self) - return 0; - if (bus_it->self->irq_reroute_variant) - return bus_it->self->irq_reroute_variant; - } - return 0; -} - -/* - * Some chipsets (e.g. Intel 6700PXH) generate a legacy INTx when the IRQ - * entry in the chipset's IO-APIC is masked (as, e.g. the RT kernel does - * during interrupt handling). When this INTx generation cannot be disabled, - * we reroute these interrupts to their legacy equivalent to get rid of - * spurious interrupts. - */ -static int acpi_reroute_boot_interrupt(struct pci_dev *dev, - struct acpi_prt_entry *entry) -{ - if (noioapicquirk || noioapicreroute) { - return 0; - } else { - switch (bridge_has_boot_interrupt_variant(dev->bus)) { - case 0: - /* no rerouting necessary */ - return 0; - case INTEL_IRQ_REROUTE_VARIANT: - /* - * Remap according to INTx routing table in 6700PXH - * specs, intel order number 302628-002, section - * 2.15.2. Other chipsets (80332, ...) have the same - * mapping and are handled here as well. - */ - dev_info(&dev->dev, "PCI IRQ %d -> rerouted to legacy " - "IRQ %d\n", entry->index, - (entry->index % 4) + 16); - entry->index = (entry->index % 4) + 16; - return 1; - default: - dev_warn(&dev->dev, "Cannot reroute IRQ %d to legacy " - "IRQ: unknown mapping\n", entry->index); - return -1; - } - } -} -#endif /* CONFIG_X86_IO_APIC */ - static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) { struct acpi_prt_entry *entry; @@ -366,9 +311,6 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin) entry = acpi_pci_irq_find_prt_entry(dev, pin); if (entry) { -#ifdef CONFIG_X86_IO_APIC - acpi_reroute_boot_interrupt(dev, entry); -#endif /* CONFIG_X86_IO_APIC */ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %s[%c] _PRT entry\n", pci_name(dev), pin_name(pin))); return entry; diff --git a/trunk/drivers/acpi/pci_root.c b/trunk/drivers/acpi/pci_root.c index 2672c798272f..d06078d660ad 100644 --- a/trunk/drivers/acpi/pci_root.c +++ b/trunk/drivers/acpi/pci_root.c @@ -485,8 +485,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) root->secondary.end = 0xFF; printk(KERN_WARNING FW_BUG PREFIX "no secondary bus range in _CRS\n"); - status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, - NULL, &bus); + status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN, NULL, &bus); if (ACPI_SUCCESS(status)) root->secondary.start = bus; else if (status == AE_NOT_FOUND) diff --git a/trunk/drivers/acpi/processor_thermal.c b/trunk/drivers/acpi/processor_thermal.c index 870550d6a4bf..79cb65332894 100644 --- a/trunk/drivers/acpi/processor_thermal.c +++ b/trunk/drivers/acpi/processor_thermal.c @@ -244,7 +244,7 @@ processor_set_cur_state(struct thermal_cooling_device *cdev, return result; } -const struct thermal_cooling_device_ops processor_cooling_ops = { +struct thermal_cooling_device_ops processor_cooling_ops = { .get_max_state = processor_get_max_state, .get_cur_state = processor_get_cur_state, .set_cur_state = processor_set_cur_state, diff --git a/trunk/drivers/acpi/sbs.c b/trunk/drivers/acpi/sbs.c index 6e36d0c0057c..50658ff887d9 100644 --- a/trunk/drivers/acpi/sbs.c +++ b/trunk/drivers/acpi/sbs.c @@ -130,9 +130,6 @@ struct acpi_sbs { #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) -static int acpi_sbs_remove(struct acpi_device *device, int type); -static int acpi_battery_get_state(struct acpi_battery *battery); - static inline int battery_scale(int log) { int scale = 1; @@ -198,8 +195,6 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, if ((!battery->present) && psp != POWER_SUPPLY_PROP_PRESENT) return -ENODEV; - - acpi_battery_get_state(battery); switch (psp) { case POWER_SUPPLY_PROP_STATUS: if (battery->rate_now < 0) @@ -230,17 +225,11 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_POWER_NOW: val->intval = abs(battery->rate_now) * acpi_battery_ipscale(battery) * 1000; - val->intval *= (acpi_battery_mode(battery)) ? - (battery->voltage_now * - acpi_battery_vscale(battery) / 1000) : 1; break; case POWER_SUPPLY_PROP_CURRENT_AVG: case POWER_SUPPLY_PROP_POWER_AVG: val->intval = abs(battery->rate_avg) * acpi_battery_ipscale(battery) * 1000; - val->intval *= (acpi_battery_mode(battery)) ? - (battery->voltage_now * - acpi_battery_vscale(battery) / 1000) : 1; break; case POWER_SUPPLY_PROP_CAPACITY: val->intval = battery->state_of_charge; @@ -914,6 +903,8 @@ static void acpi_sbs_callback(void *context) } } +static int acpi_sbs_remove(struct acpi_device *device, int type); + static int acpi_sbs_add(struct acpi_device *device) { struct acpi_sbs *sbs; diff --git a/trunk/drivers/acpi/sleep.c b/trunk/drivers/acpi/sleep.c index 3ed80b2ca907..6c949602cbd1 100644 --- a/trunk/drivers/acpi/sleep.c +++ b/trunk/drivers/acpi/sleep.c @@ -428,22 +428,6 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), }, }, - { - .callback = init_old_suspend_ordering, - .ident = "Asus A8N-SLI DELUXE", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI DELUXE"), - }, - }, - { - .callback = init_old_suspend_ordering, - .ident = "Asus A8N-SLI Premium", - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), - DMI_MATCH(DMI_BOARD_NAME, "A8N-SLI Premium"), - }, - }, {}, }; #endif /* CONFIG_SUSPEND */ diff --git a/trunk/drivers/acpi/sysfs.c b/trunk/drivers/acpi/sysfs.c index c538d0ef10ff..77255f250dbb 100644 --- a/trunk/drivers/acpi/sysfs.c +++ b/trunk/drivers/acpi/sysfs.c @@ -149,12 +149,12 @@ static int param_get_debug_level(char *buffer, const struct kernel_param *kp) return result; } -static const struct kernel_param_ops param_ops_debug_layer = { +static struct kernel_param_ops param_ops_debug_layer = { .set = param_set_uint, .get = param_get_debug_layer, }; -static const struct kernel_param_ops param_ops_debug_level = { +static struct kernel_param_ops param_ops_debug_level = { .set = param_set_uint, .get = param_get_debug_level, }; diff --git a/trunk/drivers/acpi/thermal.c b/trunk/drivers/acpi/thermal.c index 48fbc647b178..2607e17b520f 100644 --- a/trunk/drivers/acpi/thermal.c +++ b/trunk/drivers/acpi/thermal.c @@ -812,7 +812,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, thermal_zone_unbind_cooling_device); } -static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { +static struct thermal_zone_device_ops acpi_thermal_zone_ops = { .bind = acpi_thermal_bind_cooling_device, .unbind = acpi_thermal_unbind_cooling_device, .get_temp = thermal_get_temp, diff --git a/trunk/drivers/acpi/video.c b/trunk/drivers/acpi/video.c index 08a44b532f7c..ada4b4d9bdc8 100644 --- a/trunk/drivers/acpi/video.c +++ b/trunk/drivers/acpi/video.c @@ -307,7 +307,7 @@ video_set_cur_state(struct thermal_cooling_device *cooling_dev, unsigned long st return acpi_video_device_lcd_set_level(video, level); } -static const struct thermal_cooling_device_ops video_cooling_ops = { +static struct thermal_cooling_device_ops video_cooling_ops = { .get_max_state = video_get_max_state, .get_cur_state = video_get_cur_state, .set_cur_state = video_set_cur_state, diff --git a/trunk/drivers/ata/libata-acpi.c b/trunk/drivers/ata/libata-acpi.c index bb7c5f1085cc..e0a5b555cee1 100644 --- a/trunk/drivers/ata/libata-acpi.c +++ b/trunk/drivers/ata/libata-acpi.c @@ -218,12 +218,12 @@ static void ata_acpi_dev_uevent(acpi_handle handle, u32 event, void *data) ata_acpi_uevent(dev->link->ap, dev, event); } -static const struct acpi_dock_ops ata_acpi_dev_dock_ops = { +static struct acpi_dock_ops ata_acpi_dev_dock_ops = { .handler = ata_acpi_dev_notify_dock, .uevent = ata_acpi_dev_uevent, }; -static const struct acpi_dock_ops ata_acpi_ap_dock_ops = { +static struct acpi_dock_ops ata_acpi_ap_dock_ops = { .handler = ata_acpi_ap_notify_dock, .uevent = ata_acpi_ap_uevent, }; diff --git a/trunk/drivers/base/power/domain.c b/trunk/drivers/base/power/domain.c index e18566a0fedd..be8714aa9dd6 100644 --- a/trunk/drivers/base/power/domain.c +++ b/trunk/drivers/base/power/domain.c @@ -80,6 +80,7 @@ static void genpd_set_active(struct generic_pm_domain *genpd) int pm_genpd_poweron(struct generic_pm_domain *genpd) { struct generic_pm_domain *parent = genpd->parent; + DEFINE_WAIT(wait); int ret = 0; start: @@ -111,7 +112,7 @@ int pm_genpd_poweron(struct generic_pm_domain *genpd) } if (genpd->power_on) { - ret = genpd->power_on(genpd); + int ret = genpd->power_on(genpd); if (ret) goto out; } diff --git a/trunk/drivers/base/power/runtime.c b/trunk/drivers/base/power/runtime.c index acb3f83b8079..8dc247c974af 100644 --- a/trunk/drivers/base/power/runtime.c +++ b/trunk/drivers/base/power/runtime.c @@ -226,17 +226,11 @@ static int rpm_idle(struct device *dev, int rpmflags) callback = NULL; if (callback) { - if (dev->power.irq_safe) - spin_unlock(&dev->power.lock); - else - spin_unlock_irq(&dev->power.lock); + spin_unlock_irq(&dev->power.lock); callback(dev); - if (dev->power.irq_safe) - spin_lock(&dev->power.lock); - else - spin_lock_irq(&dev->power.lock); + spin_lock_irq(&dev->power.lock); } dev->power.idle_notification = false; diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 423fd56bf612..49502bc5360a 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -616,16 +616,5 @@ config MSM_SMD_PKT Enables userspace clients to read and write to some packet SMD ports via device interface for MSM chipset. -config TILE_SROM - bool "Character-device access via hypervisor to the Tilera SPI ROM" - depends on TILE - default y - ---help--- - This device provides character-level read-write access - to the SROM, typically via the "0", "1", and "2" devices - in /dev/srom/. The Tilera hypervisor makes the flash - device appear much like a simple EEPROM, and knows - how to partition a single ROM for multiple purposes. - endmenu diff --git a/trunk/drivers/char/Makefile b/trunk/drivers/char/Makefile index 32762ba769c2..7a00672bd85d 100644 --- a/trunk/drivers/char/Makefile +++ b/trunk/drivers/char/Makefile @@ -63,5 +63,3 @@ obj-$(CONFIG_RAMOOPS) += ramoops.o obj-$(CONFIG_JS_RTC) += js-rtc.o js-rtc-y = rtc.o - -obj-$(CONFIG_TILE_SROM) += tile-srom.o diff --git a/trunk/drivers/char/ramoops.c b/trunk/drivers/char/ramoops.c index 810aff9e750f..fca0c51bbc90 100644 --- a/trunk/drivers/char/ramoops.c +++ b/trunk/drivers/char/ramoops.c @@ -147,14 +147,6 @@ static int __init ramoops_probe(struct platform_device *pdev) cxt->phys_addr = pdata->mem_address; cxt->record_size = pdata->record_size; cxt->dump_oops = pdata->dump_oops; - /* - * Update the module parameter variables as well so they are visible - * through /sys/module/ramoops/parameters/ - */ - mem_size = pdata->mem_size; - mem_address = pdata->mem_address; - record_size = pdata->record_size; - dump_oops = pdata->dump_oops; if (!request_mem_region(cxt->phys_addr, cxt->size, "ramoops")) { pr_err("request mem region failed\n"); diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index c35a785005b0..729281961f22 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -1300,14 +1300,345 @@ ctl_table random_table[] = { }; #endif /* CONFIG_SYSCTL */ -static u32 random_int_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; +/******************************************************************** + * + * Random functions for networking + * + ********************************************************************/ + +/* + * TCP initial sequence number picking. This uses the random number + * generator to pick an initial secret value. This value is hashed + * along with the TCP endpoint information to provide a unique + * starting point for each pair of TCP endpoints. This defeats + * attacks which rely on guessing the initial TCP sequence number. + * This algorithm was suggested by Steve Bellovin. + * + * Using a very strong hash was taking an appreciable amount of the total + * TCP connection establishment time, so this is a weaker hash, + * compensated for by changing the secret periodically. + */ + +/* F, G and H are basic MD4 functions: selection, majority, parity */ +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) +#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* + * The generic round function. The application is so specific that + * we don't bother protecting all the arguments with parens, as is generally + * good macro practice, in favor of extra legibility. + * Rotation is separate from addition to prevent recomputation + */ +#define ROUND(f, a, b, c, d, x, s) \ + (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s))) +#define K1 0 +#define K2 013240474631UL +#define K3 015666365641UL + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + +static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12]) +{ + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; + + /* Round 1 */ + ROUND(F, a, b, c, d, in[ 0] + K1, 3); + ROUND(F, d, a, b, c, in[ 1] + K1, 7); + ROUND(F, c, d, a, b, in[ 2] + K1, 11); + ROUND(F, b, c, d, a, in[ 3] + K1, 19); + ROUND(F, a, b, c, d, in[ 4] + K1, 3); + ROUND(F, d, a, b, c, in[ 5] + K1, 7); + ROUND(F, c, d, a, b, in[ 6] + K1, 11); + ROUND(F, b, c, d, a, in[ 7] + K1, 19); + ROUND(F, a, b, c, d, in[ 8] + K1, 3); + ROUND(F, d, a, b, c, in[ 9] + K1, 7); + ROUND(F, c, d, a, b, in[10] + K1, 11); + ROUND(F, b, c, d, a, in[11] + K1, 19); + + /* Round 2 */ + ROUND(G, a, b, c, d, in[ 1] + K2, 3); + ROUND(G, d, a, b, c, in[ 3] + K2, 5); + ROUND(G, c, d, a, b, in[ 5] + K2, 9); + ROUND(G, b, c, d, a, in[ 7] + K2, 13); + ROUND(G, a, b, c, d, in[ 9] + K2, 3); + ROUND(G, d, a, b, c, in[11] + K2, 5); + ROUND(G, c, d, a, b, in[ 0] + K2, 9); + ROUND(G, b, c, d, a, in[ 2] + K2, 13); + ROUND(G, a, b, c, d, in[ 4] + K2, 3); + ROUND(G, d, a, b, c, in[ 6] + K2, 5); + ROUND(G, c, d, a, b, in[ 8] + K2, 9); + ROUND(G, b, c, d, a, in[10] + K2, 13); + + /* Round 3 */ + ROUND(H, a, b, c, d, in[ 3] + K3, 3); + ROUND(H, d, a, b, c, in[ 7] + K3, 9); + ROUND(H, c, d, a, b, in[11] + K3, 11); + ROUND(H, b, c, d, a, in[ 2] + K3, 15); + ROUND(H, a, b, c, d, in[ 6] + K3, 3); + ROUND(H, d, a, b, c, in[10] + K3, 9); + ROUND(H, c, d, a, b, in[ 1] + K3, 11); + ROUND(H, b, c, d, a, in[ 5] + K3, 15); + ROUND(H, a, b, c, d, in[ 9] + K3, 3); + ROUND(H, d, a, b, c, in[ 0] + K3, 9); + ROUND(H, c, d, a, b, in[ 4] + K3, 11); + ROUND(H, b, c, d, a, in[ 8] + K3, 15); + + return buf[1] + b; /* "most hashed" word */ + /* Alternative: return sum of all words? */ +} +#endif + +#undef ROUND +#undef F +#undef G +#undef H +#undef K1 +#undef K2 +#undef K3 + +/* This should not be decreased so low that ISNs wrap too fast. */ +#define REKEY_INTERVAL (300 * HZ) +/* + * Bit layout of the tcp sequence numbers (before adding current time): + * bit 24-31: increased after every key exchange + * bit 0-23: hash(source,dest) + * + * The implementation is similar to the algorithm described + * in the Appendix of RFC 1185, except that + * - it uses a 1 MHz clock instead of a 250 kHz clock + * - it performs a rekey every 5 minutes, which is equivalent + * to a (source,dest) tulple dependent forward jump of the + * clock by 0..2^(HASH_BITS+1) + * + * Thus the average ISN wraparound time is 68 minutes instead of + * 4.55 hours. + * + * SMP cleanup and lock avoidance with poor man's RCU. + * Manfred Spraul + * + */ +#define COUNT_BITS 8 +#define COUNT_MASK ((1 << COUNT_BITS) - 1) +#define HASH_BITS 24 +#define HASH_MASK ((1 << HASH_BITS) - 1) -static int __init random_int_secret_init(void) +static struct keydata { + __u32 count; /* already shifted to the final position */ + __u32 secret[12]; +} ____cacheline_aligned ip_keydata[2]; + +static unsigned int ip_cnt; + +static void rekey_seq_generator(struct work_struct *work); + +static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator); + +/* + * Lock avoidance: + * The ISN generation runs lockless - it's just a hash over random data. + * State changes happen every 5 minutes when the random key is replaced. + * Synchronization is performed by having two copies of the hash function + * state and rekey_seq_generator always updates the inactive copy. + * The copy is then activated by updating ip_cnt. + * The implementation breaks down if someone blocks the thread + * that processes SYN requests for more than 5 minutes. Should never + * happen, and even if that happens only a not perfectly compliant + * ISN is generated, nothing fatal. + */ +static void rekey_seq_generator(struct work_struct *work) { - get_random_bytes(random_int_secret, sizeof(random_int_secret)); + struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)]; + + get_random_bytes(keyptr->secret, sizeof(keyptr->secret)); + keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS; + smp_wmb(); + ip_cnt++; + schedule_delayed_work(&rekey_work, + round_jiffies_relative(REKEY_INTERVAL)); +} + +static inline struct keydata *get_keyptr(void) +{ + struct keydata *keyptr = &ip_keydata[ip_cnt & 1]; + + smp_rmb(); + + return keyptr; +} + +static __init int seqgen_init(void) +{ + rekey_seq_generator(NULL); return 0; } -late_initcall(random_int_secret_init); +late_initcall(seqgen_init); + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, + __be16 sport, __be16 dport) +{ + __u32 seq; + __u32 hash[12]; + struct keydata *keyptr = get_keyptr(); + + /* The procedure is the same as for IPv4, but addresses are longer. + * Thus we must use twothirdsMD4Transform. + */ + + memcpy(hash, saddr, 16); + hash[4] = ((__force u16)sport << 16) + (__force u16)dport; + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); + + seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK; + seq += keyptr->count; + + seq += ktime_to_ns(ktime_get_real()); + + return seq; +} +EXPORT_SYMBOL(secure_tcpv6_sequence_number); +#endif + +/* The code below is shamelessly stolen from secure_tcp_sequence_number(). + * All blames to Andrey V. Savochkin . + */ +__u32 secure_ip_id(__be32 daddr) +{ + struct keydata *keyptr; + __u32 hash[4]; + + keyptr = get_keyptr(); + + /* + * Pick a unique starting offset for each IP destination. + * The dest ip address is placed in the starting vector, + * which is then hashed with random data. + */ + hash[0] = (__force __u32)daddr; + hash[1] = keyptr->secret[9]; + hash[2] = keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return half_md4_transform(hash, keyptr->secret); +} + +__u32 secure_ipv6_id(const __be32 daddr[4]) +{ + const struct keydata *keyptr; + __u32 hash[4]; + + keyptr = get_keyptr(); + + hash[0] = (__force __u32)daddr[0]; + hash[1] = (__force __u32)daddr[1]; + hash[2] = (__force __u32)daddr[2]; + hash[3] = (__force __u32)daddr[3]; + + return half_md4_transform(hash, keyptr->secret); +} + +#ifdef CONFIG_INET + +__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) +{ + __u32 seq; + __u32 hash[4]; + struct keydata *keyptr = get_keyptr(); + + /* + * Pick a unique starting offset for each TCP connection endpoints + * (saddr, daddr, sport, dport). + * Note that the words are placed into the starting vector, which is + * then mixed with a partial MD4 over random data. + */ + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; + hash[3] = keyptr->secret[11]; + + seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK; + seq += keyptr->count; + /* + * As close as possible to RFC 793, which + * suggests using a 250 kHz clock. + * Further reading shows this assumes 2 Mb/s networks. + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but + * we also need to limit the resolution so that the u32 seq + * overlaps less than one time per MSL (2 minutes). + * Choosing a clock of 64 ns period is OK. (period of 274 s) + */ + seq += ktime_to_ns(ktime_get_real()) >> 6; + + return seq; +} + +/* Generate secure starting point for ephemeral IPV4 transport port search */ +u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) +{ + struct keydata *keyptr = get_keyptr(); + u32 hash[4]; + + /* + * Pick a unique starting offset for each ephemeral port search + * (saddr, daddr, dport) and 48bits of random data. + */ + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = (__force u32)dport ^ keyptr->secret[10]; + hash[3] = keyptr->secret[11]; + + return half_md4_transform(hash, keyptr->secret); +} +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); + +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) +u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport) +{ + struct keydata *keyptr = get_keyptr(); + u32 hash[12]; + + memcpy(hash, saddr, 16); + hash[4] = (__force u32)dport; + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7); + + return twothirdsMD4Transform((const __u32 *)daddr, hash); +} +#endif + +#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) +/* Similar to secure_tcp_sequence_number but generate a 48 bit value + * bit's 32-47 increase every key exchange + * 0-31 hash(source, dest) + */ +u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport) +{ + u64 seq; + __u32 hash[4]; + struct keydata *keyptr = get_keyptr(); + + hash[0] = (__force u32)saddr; + hash[1] = (__force u32)daddr; + hash[2] = ((__force u16)sport << 16) + (__force u16)dport; + hash[3] = keyptr->secret[11]; + + seq = half_md4_transform(hash, keyptr->secret); + seq |= ((u64)keyptr->count) << (32 - HASH_BITS); + + seq += ktime_to_ns(ktime_get_real()); + seq &= (1ull << 48) - 1; + + return seq; +} +EXPORT_SYMBOL(secure_dccp_sequence_number); +#endif + +#endif /* CONFIG_INET */ + /* * Get a random word for internal kernel use only. Similar to urandom but @@ -1315,15 +1646,17 @@ late_initcall(random_int_secret_init); * value is not cryptographically secure but for several uses the cost of * depleting entropy is too high */ -DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); +DEFINE_PER_CPU(__u32 [4], get_random_int_hash); unsigned int get_random_int(void) { + struct keydata *keyptr; __u32 *hash = get_cpu_var(get_random_int_hash); - unsigned int ret; + int ret; + keyptr = get_keyptr(); hash[0] += current->pid + jiffies + get_cycles(); - md5_transform(hash, random_int_secret); - ret = hash[0]; + + ret = half_md4_transform(hash, keyptr->secret); put_cpu_var(get_random_int_hash); return ret; diff --git a/trunk/drivers/char/tile-srom.c b/trunk/drivers/char/tile-srom.c deleted file mode 100644 index cf3ee008dca2..000000000000 --- a/trunk/drivers/char/tile-srom.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * Copyright 2011 Tilera Corporation. All Rights Reserved. - * - * 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, version 2. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for - * more details. - * - * SPI Flash ROM driver - * - * This source code is derived from code provided in "Linux Device - * Drivers, Third Edition", by Jonathan Corbet, Alessandro Rubini, and - * Greg Kroah-Hartman, published by O'Reilly Media, Inc. - */ - -#include -#include -#include -#include /* printk() */ -#include /* kmalloc() */ -#include /* everything... */ -#include /* error codes */ -#include /* size_t */ -#include -#include /* O_ACCMODE */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Size of our hypervisor I/O requests. We break up large transfers - * so that we don't spend large uninterrupted spans of time in the - * hypervisor. Erasing an SROM sector takes a significant fraction of - * a second, so if we allowed the user to, say, do one I/O to write the - * entire ROM, we'd get soft lockup timeouts, or worse. - */ -#define SROM_CHUNK_SIZE ((size_t)4096) - -/* - * When hypervisor is busy (e.g. erasing), poll the status periodically. - */ - -/* - * Interval to poll the state in msec - */ -#define SROM_WAIT_TRY_INTERVAL 20 - -/* - * Maximum times to poll the state - */ -#define SROM_MAX_WAIT_TRY_TIMES 1000 - -struct srom_dev { - int hv_devhdl; /* Handle for hypervisor device */ - u32 total_size; /* Size of this device */ - u32 sector_size; /* Size of a sector */ - u32 page_size; /* Size of a page */ - struct mutex lock; /* Allow only one accessor at a time */ -}; - -static int srom_major; /* Dynamic major by default */ -module_param(srom_major, int, 0); -MODULE_AUTHOR("Tilera Corporation"); -MODULE_LICENSE("GPL"); - -static int srom_devs; /* Number of SROM partitions */ -static struct cdev srom_cdev; -static struct class *srom_class; -static struct srom_dev *srom_devices; - -/* - * Handle calling the hypervisor and managing EAGAIN/EBUSY. - */ - -static ssize_t _srom_read(int hv_devhdl, void *buf, - loff_t off, size_t count) -{ - int retval, retries = SROM_MAX_WAIT_TRY_TIMES; - for (;;) { - retval = hv_dev_pread(hv_devhdl, 0, (HV_VirtAddr)buf, - count, off); - if (retval >= 0) - return retval; - if (retval == HV_EAGAIN) - continue; - if (retval == HV_EBUSY && --retries > 0) { - msleep(SROM_WAIT_TRY_INTERVAL); - continue; - } - pr_err("_srom_read: error %d\n", retval); - return -EIO; - } -} - -static ssize_t _srom_write(int hv_devhdl, const void *buf, - loff_t off, size_t count) -{ - int retval, retries = SROM_MAX_WAIT_TRY_TIMES; - for (;;) { - retval = hv_dev_pwrite(hv_devhdl, 0, (HV_VirtAddr)buf, - count, off); - if (retval >= 0) - return retval; - if (retval == HV_EAGAIN) - continue; - if (retval == HV_EBUSY && --retries > 0) { - msleep(SROM_WAIT_TRY_INTERVAL); - continue; - } - pr_err("_srom_write: error %d\n", retval); - return -EIO; - } -} - -/** - * srom_open() - Device open routine. - * @inode: Inode for this device. - * @filp: File for this specific open of the device. - * - * Returns zero, or an error code. - */ -static int srom_open(struct inode *inode, struct file *filp) -{ - filp->private_data = &srom_devices[iminor(inode)]; - return 0; -} - - -/** - * srom_release() - Device release routine. - * @inode: Inode for this device. - * @filp: File for this specific open of the device. - * - * Returns zero, or an error code. - */ -static int srom_release(struct inode *inode, struct file *filp) -{ - struct srom_dev *srom = filp->private_data; - char dummy; - - /* Make sure we've flushed anything written to the ROM. */ - mutex_lock(&srom->lock); - if (srom->hv_devhdl >= 0) - _srom_write(srom->hv_devhdl, &dummy, SROM_FLUSH_OFF, 1); - mutex_unlock(&srom->lock); - - filp->private_data = NULL; - - return 0; -} - - -/** - * srom_read() - Read data from the device. - * @filp: File for this specific open of the device. - * @buf: User's data buffer. - * @count: Number of bytes requested. - * @f_pos: File position. - * - * Returns number of bytes read, or an error code. - */ -static ssize_t srom_read(struct file *filp, char __user *buf, - size_t count, loff_t *f_pos) -{ - int retval = 0; - void *kernbuf; - struct srom_dev *srom = filp->private_data; - - kernbuf = kmalloc(SROM_CHUNK_SIZE, GFP_KERNEL); - if (!kernbuf) - return -ENOMEM; - - if (mutex_lock_interruptible(&srom->lock)) { - retval = -ERESTARTSYS; - kfree(kernbuf); - return retval; - } - - while (count) { - int hv_retval; - int bytes_this_pass = min(count, SROM_CHUNK_SIZE); - - hv_retval = _srom_read(srom->hv_devhdl, kernbuf, - *f_pos, bytes_this_pass); - if (hv_retval > 0) { - if (copy_to_user(buf, kernbuf, hv_retval) != 0) { - retval = -EFAULT; - break; - } - } else if (hv_retval <= 0) { - if (retval == 0) - retval = hv_retval; - break; - } - - retval += hv_retval; - *f_pos += hv_retval; - buf += hv_retval; - count -= hv_retval; - } - - mutex_unlock(&srom->lock); - kfree(kernbuf); - - return retval; -} - -/** - * srom_write() - Write data to the device. - * @filp: File for this specific open of the device. - * @buf: User's data buffer. - * @count: Number of bytes requested. - * @f_pos: File position. - * - * Returns number of bytes written, or an error code. - */ -static ssize_t srom_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - int retval = 0; - void *kernbuf; - struct srom_dev *srom = filp->private_data; - - kernbuf = kmalloc(SROM_CHUNK_SIZE, GFP_KERNEL); - if (!kernbuf) - return -ENOMEM; - - if (mutex_lock_interruptible(&srom->lock)) { - retval = -ERESTARTSYS; - kfree(kernbuf); - return retval; - } - - while (count) { - int hv_retval; - int bytes_this_pass = min(count, SROM_CHUNK_SIZE); - - if (copy_from_user(kernbuf, buf, bytes_this_pass) != 0) { - retval = -EFAULT; - break; - } - - hv_retval = _srom_write(srom->hv_devhdl, kernbuf, - *f_pos, bytes_this_pass); - if (hv_retval <= 0) { - if (retval == 0) - retval = hv_retval; - break; - } - - retval += hv_retval; - *f_pos += hv_retval; - buf += hv_retval; - count -= hv_retval; - } - - mutex_unlock(&srom->lock); - kfree(kernbuf); - - return retval; -} - -/* Provide our own implementation so we can use srom->total_size. */ -loff_t srom_llseek(struct file *filp, loff_t offset, int origin) -{ - struct srom_dev *srom = filp->private_data; - - if (mutex_lock_interruptible(&srom->lock)) - return -ERESTARTSYS; - - switch (origin) { - case SEEK_END: - offset += srom->total_size; - break; - case SEEK_CUR: - offset += filp->f_pos; - break; - } - - if (offset < 0 || offset > srom->total_size) { - offset = -EINVAL; - } else { - filp->f_pos = offset; - filp->f_version = 0; - } - - mutex_unlock(&srom->lock); - - return offset; -} - -static ssize_t total_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct srom_dev *srom = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", srom->total_size); -} - -static ssize_t sector_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct srom_dev *srom = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", srom->sector_size); -} - -static ssize_t page_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct srom_dev *srom = dev_get_drvdata(dev); - return sprintf(buf, "%u\n", srom->page_size); -} - -static struct device_attribute srom_dev_attrs[] = { - __ATTR(total_size, S_IRUGO, total_show, NULL), - __ATTR(sector_size, S_IRUGO, sector_show, NULL), - __ATTR(page_size, S_IRUGO, page_show, NULL), - __ATTR_NULL -}; - -static char *srom_devnode(struct device *dev, mode_t *mode) -{ - *mode = S_IRUGO | S_IWUSR; - return kasprintf(GFP_KERNEL, "srom/%s", dev_name(dev)); -} - -/* - * The fops - */ -static const struct file_operations srom_fops = { - .owner = THIS_MODULE, - .llseek = srom_llseek, - .read = srom_read, - .write = srom_write, - .open = srom_open, - .release = srom_release, -}; - -/** - * srom_setup_minor() - Initialize per-minor information. - * @srom: Per-device SROM state. - * @index: Device to set up. - */ -static int srom_setup_minor(struct srom_dev *srom, int index) -{ - struct device *dev; - int devhdl = srom->hv_devhdl; - - mutex_init(&srom->lock); - - if (_srom_read(devhdl, &srom->total_size, - SROM_TOTAL_SIZE_OFF, sizeof(srom->total_size)) < 0) - return -EIO; - if (_srom_read(devhdl, &srom->sector_size, - SROM_SECTOR_SIZE_OFF, sizeof(srom->sector_size)) < 0) - return -EIO; - if (_srom_read(devhdl, &srom->page_size, - SROM_PAGE_SIZE_OFF, sizeof(srom->page_size)) < 0) - return -EIO; - - dev = device_create(srom_class, &platform_bus, - MKDEV(srom_major, index), srom, "%d", index); - return IS_ERR(dev) ? PTR_ERR(dev) : 0; -} - -/** srom_init() - Initialize the driver's module. */ -static int srom_init(void) -{ - int result, i; - dev_t dev = MKDEV(srom_major, 0); - - /* - * Start with a plausible number of partitions; the krealloc() call - * below will yield about log(srom_devs) additional allocations. - */ - srom_devices = kzalloc(4 * sizeof(struct srom_dev), GFP_KERNEL); - - /* Discover the number of srom partitions. */ - for (i = 0; ; i++) { - int devhdl; - char buf[20]; - struct srom_dev *new_srom_devices = - krealloc(srom_devices, (i+1) * sizeof(struct srom_dev), - GFP_KERNEL | __GFP_ZERO); - if (!new_srom_devices) { - result = -ENOMEM; - goto fail_mem; - } - srom_devices = new_srom_devices; - sprintf(buf, "srom/0/%d", i); - devhdl = hv_dev_open((HV_VirtAddr)buf, 0); - if (devhdl < 0) { - if (devhdl != HV_ENODEV) - pr_notice("srom/%d: hv_dev_open failed: %d.\n", - i, devhdl); - break; - } - srom_devices[i].hv_devhdl = devhdl; - } - srom_devs = i; - - /* Bail out early if we have no partitions at all. */ - if (srom_devs == 0) { - result = -ENODEV; - goto fail_mem; - } - - /* Register our major, and accept a dynamic number. */ - if (srom_major) - result = register_chrdev_region(dev, srom_devs, "srom"); - else { - result = alloc_chrdev_region(&dev, 0, srom_devs, "srom"); - srom_major = MAJOR(dev); - } - if (result < 0) - goto fail_mem; - - /* Register a character device. */ - cdev_init(&srom_cdev, &srom_fops); - srom_cdev.owner = THIS_MODULE; - srom_cdev.ops = &srom_fops; - result = cdev_add(&srom_cdev, dev, srom_devs); - if (result < 0) - goto fail_chrdev; - - /* Create a sysfs class. */ - srom_class = class_create(THIS_MODULE, "srom"); - if (IS_ERR(srom_class)) { - result = PTR_ERR(srom_class); - goto fail_cdev; - } - srom_class->dev_attrs = srom_dev_attrs; - srom_class->devnode = srom_devnode; - - /* Do per-partition initialization */ - for (i = 0; i < srom_devs; i++) { - result = srom_setup_minor(srom_devices + i, i); - if (result < 0) - goto fail_class; - } - - return 0; - -fail_class: - for (i = 0; i < srom_devs; i++) - device_destroy(srom_class, MKDEV(srom_major, i)); - class_destroy(srom_class); -fail_cdev: - cdev_del(&srom_cdev); -fail_chrdev: - unregister_chrdev_region(dev, srom_devs); -fail_mem: - kfree(srom_devices); - return result; -} - -/** srom_cleanup() - Clean up the driver's module. */ -static void srom_cleanup(void) -{ - int i; - for (i = 0; i < srom_devs; i++) - device_destroy(srom_class, MKDEV(srom_major, i)); - class_destroy(srom_class); - cdev_del(&srom_cdev); - unregister_chrdev_region(MKDEV(srom_major, 0), srom_devs); - kfree(srom_devices); -} - -module_init(srom_init); -module_exit(srom_cleanup); diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 3f4051a7c5a7..7fc2f108f490 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -80,7 +80,7 @@ enum tis_defaults { static LIST_HEAD(tis_chips); static DEFINE_SPINLOCK(tis_lock); -#if defined(CONFIG_PNP) && defined(CONFIG_ACPI) +#ifdef CONFIG_PNP static int is_itpm(struct pnp_dev *dev) { struct acpi_device *acpi = pnp_acpi_device(dev); @@ -93,11 +93,6 @@ static int is_itpm(struct pnp_dev *dev) return 0; } -#else -static inline int is_itpm(struct pnp_dev *dev) -{ - return 0; -} #endif static int check_locality(struct tpm_chip *chip, int l) diff --git a/trunk/drivers/connector/cn_proc.c b/trunk/drivers/connector/cn_proc.c index e55814bc0d06..3ee1fdb31ea7 100644 --- a/trunk/drivers/connector/cn_proc.c +++ b/trunk/drivers/connector/cn_proc.c @@ -57,7 +57,6 @@ void proc_fork_connector(struct task_struct *task) struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; struct timespec ts; - struct task_struct *parent; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -68,11 +67,8 @@ void proc_fork_connector(struct task_struct *task) ktime_get_ts(&ts); /* get high res monotonic timestamp */ put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns); ev->what = PROC_EVENT_FORK; - rcu_read_lock(); - parent = rcu_dereference(task->real_parent); - ev->event_data.fork.parent_pid = parent->pid; - ev->event_data.fork.parent_tgid = parent->tgid; - rcu_read_unlock(); + ev->event_data.fork.parent_pid = task->real_parent->pid; + ev->event_data.fork.parent_tgid = task->real_parent->tgid; ev->event_data.fork.child_pid = task->pid; ev->event_data.fork.child_tgid = task->tgid; diff --git a/trunk/drivers/cpuidle/cpuidle.c b/trunk/drivers/cpuidle/cpuidle.c index d4c542372886..bf5092455a8f 100644 --- a/trunk/drivers/cpuidle/cpuidle.c +++ b/trunk/drivers/cpuidle/cpuidle.c @@ -25,19 +25,9 @@ DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices); DEFINE_MUTEX(cpuidle_lock); LIST_HEAD(cpuidle_detected_devices); +static void (*pm_idle_old)(void); static int enabled_devices; -static int off __read_mostly; -static int initialized __read_mostly; - -int cpuidle_disabled(void) -{ - return off; -} -void disable_cpuidle(void) -{ - off = 1; -} #if defined(CONFIG_ARCH_HAS_CPU_IDLE_WAIT) static void cpuidle_kick_cpus(void) @@ -56,23 +46,25 @@ static int __cpuidle_register_device(struct cpuidle_device *dev); * cpuidle_idle_call - the main idle loop * * NOTE: no locks or semaphores should be used here - * return non-zero on failure */ -int cpuidle_idle_call(void) +static void cpuidle_idle_call(void) { struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices); struct cpuidle_state *target_state; int next_state; - if (off) - return -ENODEV; - - if (!initialized) - return -ENODEV; - /* check if the device is ready */ - if (!dev || !dev->enabled) - return -EBUSY; + if (!dev || !dev->enabled) { + if (pm_idle_old) + pm_idle_old(); + else +#if defined(CONFIG_ARCH_HAS_DEFAULT_IDLE) + default_idle(); +#else + local_irq_enable(); +#endif + return; + } #if 0 /* shows regressions, re-enable for 2.6.29 */ @@ -97,7 +89,7 @@ int cpuidle_idle_call(void) next_state = cpuidle_curr_governor->select(dev); if (need_resched()) { local_irq_enable(); - return 0; + return; } target_state = &dev->states[next_state]; @@ -122,8 +114,6 @@ int cpuidle_idle_call(void) /* give the governor an opportunity to reflect on the outcome */ if (cpuidle_curr_governor->reflect) cpuidle_curr_governor->reflect(dev); - - return 0; } /** @@ -131,10 +121,10 @@ int cpuidle_idle_call(void) */ void cpuidle_install_idle_handler(void) { - if (enabled_devices) { + if (enabled_devices && (pm_idle != cpuidle_idle_call)) { /* Make sure all changes finished before we switch to new idle */ smp_wmb(); - initialized = 1; + pm_idle = cpuidle_idle_call; } } @@ -143,8 +133,8 @@ void cpuidle_install_idle_handler(void) */ void cpuidle_uninstall_idle_handler(void) { - if (enabled_devices) { - initialized = 0; + if (enabled_devices && pm_idle_old && (pm_idle != pm_idle_old)) { + pm_idle = pm_idle_old; cpuidle_kick_cpus(); } } @@ -437,8 +427,7 @@ static int __init cpuidle_init(void) { int ret; - if (cpuidle_disabled()) - return -ENODEV; + pm_idle_old = pm_idle; ret = cpuidle_add_class_sysfs(&cpu_sysdev_class); if (ret) @@ -449,5 +438,4 @@ static int __init cpuidle_init(void) return 0; } -module_param(off, int, 0444); core_initcall(cpuidle_init); diff --git a/trunk/drivers/cpuidle/cpuidle.h b/trunk/drivers/cpuidle/cpuidle.h index 38c3fd8b9d76..33e50d556f17 100644 --- a/trunk/drivers/cpuidle/cpuidle.h +++ b/trunk/drivers/cpuidle/cpuidle.h @@ -13,7 +13,6 @@ extern struct list_head cpuidle_governors; extern struct list_head cpuidle_detected_devices; extern struct mutex cpuidle_lock; extern spinlock_t cpuidle_driver_lock; -extern int cpuidle_disabled(void); /* idle loop */ extern void cpuidle_install_idle_handler(void); diff --git a/trunk/drivers/cpuidle/driver.c b/trunk/drivers/cpuidle/driver.c index 3f7e3cedd133..fd1601e3d125 100644 --- a/trunk/drivers/cpuidle/driver.c +++ b/trunk/drivers/cpuidle/driver.c @@ -26,9 +26,6 @@ int cpuidle_register_driver(struct cpuidle_driver *drv) if (!drv) return -EINVAL; - if (cpuidle_disabled()) - return -ENODEV; - spin_lock(&cpuidle_driver_lock); if (cpuidle_curr_driver) { spin_unlock(&cpuidle_driver_lock); diff --git a/trunk/drivers/cpuidle/governor.c b/trunk/drivers/cpuidle/governor.c index ea2f8e7aa24a..724c164d31c9 100644 --- a/trunk/drivers/cpuidle/governor.c +++ b/trunk/drivers/cpuidle/governor.c @@ -81,9 +81,6 @@ int cpuidle_register_governor(struct cpuidle_governor *gov) if (!gov || !gov->select) return -EINVAL; - if (cpuidle_disabled()) - return -ENODEV; - mutex_lock(&cpuidle_lock); if (__cpuidle_find_governor(gov->name) == NULL) { ret = 0; diff --git a/trunk/drivers/dma/amba-pl08x.c b/trunk/drivers/dma/amba-pl08x.c index be21e3f138a8..196a7378d332 100644 --- a/trunk/drivers/dma/amba-pl08x.c +++ b/trunk/drivers/dma/amba-pl08x.c @@ -80,7 +80,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/dma/dmaengine.c b/trunk/drivers/dma/dmaengine.c index b48967b499da..26374b2a55a2 100644 --- a/trunk/drivers/dma/dmaengine.c +++ b/trunk/drivers/dma/dmaengine.c @@ -62,9 +62,9 @@ #include static DEFINE_MUTEX(dma_list_mutex); -static DEFINE_IDR(dma_idr); static LIST_HEAD(dma_device_list); static long dmaengine_ref_count; +static struct idr dma_idr; /* --- sysfs implementation --- */ @@ -1050,6 +1050,8 @@ EXPORT_SYMBOL_GPL(dma_run_dependencies); static int __init dma_bus_init(void) { + idr_init(&dma_idr); + mutex_init(&dma_list_mutex); return class_register(&dma_devclass); } arch_initcall(dma_bus_init); diff --git a/trunk/drivers/dma/ioat/dma_v3.c b/trunk/drivers/dma/ioat/dma_v3.c index f519c93a61e7..d845dc4b7103 100644 --- a/trunk/drivers/dma/ioat/dma_v3.c +++ b/trunk/drivers/dma/ioat/dma_v3.c @@ -73,10 +73,10 @@ /* provide a lookup table for setting the source address in the base or * extended descriptor of an xor or pq descriptor */ -static const u8 xor_idx_to_desc = 0xe0; -static const u8 xor_idx_to_field[] = { 1, 4, 5, 6, 7, 0, 1, 2 }; -static const u8 pq_idx_to_desc = 0xf8; -static const u8 pq_idx_to_field[] = { 1, 4, 5, 0, 1, 2, 4, 5 }; +static const u8 xor_idx_to_desc __read_mostly = 0xd0; +static const u8 xor_idx_to_field[] __read_mostly = { 1, 4, 5, 6, 7, 0, 1, 2 }; +static const u8 pq_idx_to_desc __read_mostly = 0xf8; +static const u8 pq_idx_to_field[] __read_mostly = { 1, 4, 5, 0, 1, 2, 4, 5 }; static dma_addr_t xor_get_src(struct ioat_raw_descriptor *descs[2], int idx) { diff --git a/trunk/drivers/dma/ioat/pci.c b/trunk/drivers/dma/ioat/pci.c index 5e3a40f79945..fab37d1cf48d 100644 --- a/trunk/drivers/dma/ioat/pci.c +++ b/trunk/drivers/dma/ioat/pci.c @@ -72,17 +72,6 @@ static struct pci_device_id ioat_pci_tbl[] = { { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_JSF8) }, { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_JSF9) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB0) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB1) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB2) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB3) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB4) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB5) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB6) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB7) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB8) }, - { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT_SNB9) }, - { 0, } }; MODULE_DEVICE_TABLE(pci, ioat_pci_tbl); diff --git a/trunk/drivers/eisa/pci_eisa.c b/trunk/drivers/eisa/pci_eisa.c index cdae207028a7..30da70d06a6d 100644 --- a/trunk/drivers/eisa/pci_eisa.c +++ b/trunk/drivers/eisa/pci_eisa.c @@ -45,13 +45,13 @@ static int __init pci_eisa_init(struct pci_dev *pdev, return 0; } -static struct pci_device_id pci_eisa_pci_tbl[] = { +static struct pci_device_id __initdata pci_eisa_pci_tbl[] = { { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_EISA << 8, 0xffff00, 0 }, { 0, } }; -static struct pci_driver __refdata pci_eisa_driver = { +static struct pci_driver __initdata pci_eisa_driver = { .name = "pci_eisa", .id_table = pci_eisa_pci_tbl, .probe = pci_eisa_init, diff --git a/trunk/drivers/firmware/efivars.c b/trunk/drivers/firmware/efivars.c index eb80b549ed8d..eacb05e6cfb3 100644 --- a/trunk/drivers/firmware/efivars.c +++ b/trunk/drivers/firmware/efivars.c @@ -157,7 +157,7 @@ utf16_strnlen(efi_char16_t *s, size_t maxlength) return length; } -static inline unsigned long +static unsigned long utf16_strlen(efi_char16_t *s) { return utf16_strnlen(s, ~0UL); @@ -580,8 +580,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type, return -1; } -static u64 efi_pstore_write(enum pstore_type_id type, unsigned int part, - size_t size, struct pstore_info *psi) +static u64 efi_pstore_write(enum pstore_type_id type, int part, size_t size, + struct pstore_info *psi) { return 0; } diff --git a/trunk/drivers/gpu/drm/drm_debugfs.c b/trunk/drivers/gpu/drm/drm_debugfs.c index 9d2668a50872..9d8c892d07c9 100644 --- a/trunk/drivers/gpu/drm/drm_debugfs.c +++ b/trunk/drivers/gpu/drm/drm_debugfs.c @@ -90,6 +90,7 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, struct drm_device *dev = minor->dev; struct dentry *ent; struct drm_info_node *tmp; + char name[64]; int i, ret; for (i = 0; i < count; i++) { @@ -107,9 +108,6 @@ int drm_debugfs_create_files(struct drm_info_list *files, int count, ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, root, tmp, &drm_debugfs_fops); if (!ent) { - char name[64]; - strncpy(name, root->d_name.name, - min(root->d_name.len, 64U)); DRM_ERROR("Cannot create /sys/kernel/debug/dri/%s/%s\n", name, files[i].name); kfree(tmp); diff --git a/trunk/drivers/gpu/drm/drm_edid.c b/trunk/drivers/gpu/drm/drm_edid.c index 7425e5c9bd75..756af4d7ec74 100644 --- a/trunk/drivers/gpu/drm/drm_edid.c +++ b/trunk/drivers/gpu/drm/drm_edid.c @@ -127,23 +127,6 @@ static const u8 edid_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; - /* - * Sanity check the header of the base EDID block. Return 8 if the header - * is perfect, down to 0 if it's totally wrong. - */ -int drm_edid_header_is_valid(const u8 *raw_edid) -{ - int i, score = 0; - - for (i = 0; i < sizeof(edid_header); i++) - if (raw_edid[i] == edid_header[i]) - score++; - - return score; -} -EXPORT_SYMBOL(drm_edid_header_is_valid); - - /* * Sanity check the EDID block (base or extension). Return 0 if the block * doesn't check out, or 1 if it's valid. @@ -156,7 +139,12 @@ drm_edid_block_valid(u8 *raw_edid) struct edid *edid = (struct edid *)raw_edid; if (raw_edid[0] == 0x00) { - int score = drm_edid_header_is_valid(raw_edid); + int score = 0; + + for (i = 0; i < sizeof(edid_header); i++) + if (raw_edid[i] == edid_header[i]) + score++; + if (score == 8) ; else if (score >= 6) { DRM_DEBUG("Fixing EDID header, your hardware may be failing\n"); @@ -1451,8 +1439,6 @@ EXPORT_SYMBOL(drm_detect_monitor_audio); static void drm_add_display_info(struct edid *edid, struct drm_display_info *info) { - u8 *edid_ext; - info->width_mm = edid->width_cm * 10; info->height_mm = edid->height_cm * 10; @@ -1497,13 +1483,6 @@ static void drm_add_display_info(struct edid *edid, info->color_formats = DRM_COLOR_FORMAT_YCRCB444; if (info->color_formats & DRM_EDID_FEATURE_RGB_YCRCB422) info->color_formats = DRM_COLOR_FORMAT_YCRCB422; - - /* Get data from CEA blocks if present */ - edid_ext = drm_find_cea_extension(edid); - if (!edid_ext) - return; - - info->cea_rev = edid_ext[1]; } /** diff --git a/trunk/drivers/gpu/drm/drm_irq.c b/trunk/drivers/gpu/drm/drm_irq.c index 3830e9e478c0..2022a5c966bb 100644 --- a/trunk/drivers/gpu/drm/drm_irq.c +++ b/trunk/drivers/gpu/drm/drm_irq.c @@ -291,14 +291,11 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state) if (!dev->irq_enabled) return; - if (state) { - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); - } else { - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); - if (dev->driver->irq_postinstall) - dev->driver->irq_postinstall(dev); + if (state) + dev->driver->irq_uninstall(dev); + else { + dev->driver->irq_preinstall(dev); + dev->driver->irq_postinstall(dev); } } @@ -341,8 +338,7 @@ int drm_irq_install(struct drm_device *dev) DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); /* Before installing handler */ - if (dev->driver->irq_preinstall) - dev->driver->irq_preinstall(dev); + dev->driver->irq_preinstall(dev); /* Install handler */ if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) @@ -367,16 +363,11 @@ int drm_irq_install(struct drm_device *dev) vga_client_register(dev->pdev, (void *)dev, drm_irq_vgaarb_nokms, NULL); /* After installing handler */ - if (dev->driver->irq_postinstall) - ret = dev->driver->irq_postinstall(dev); - + ret = dev->driver->irq_postinstall(dev); if (ret < 0) { mutex_lock(&dev->struct_mutex); dev->irq_enabled = 0; mutex_unlock(&dev->struct_mutex); - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - vga_client_register(dev->pdev, NULL, NULL, NULL); - free_irq(drm_dev_to_irq(dev), dev); } return ret; @@ -422,8 +413,7 @@ int drm_irq_uninstall(struct drm_device *dev) if (!drm_core_check_feature(dev, DRIVER_MODESET)) vga_client_register(dev->pdev, NULL, NULL, NULL); - if (dev->driver->irq_uninstall) - dev->driver->irq_uninstall(dev); + dev->driver->irq_uninstall(dev); free_irq(drm_dev_to_irq(dev), dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_debugfs.c b/trunk/drivers/gpu/drm/i915/i915_debugfs.c index a8ab6263e0d7..e2662497d50f 100644 --- a/trunk/drivers/gpu/drm/i915/i915_debugfs.c +++ b/trunk/drivers/gpu/drm/i915/i915_debugfs.c @@ -1338,155 +1338,6 @@ static const struct file_operations i915_wedged_fops = { .llseek = default_llseek, }; -static int -i915_max_freq_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - -static ssize_t -i915_max_freq_read(struct file *filp, - char __user *ubuf, - size_t max, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; - char buf[80]; - int len; - - len = snprintf(buf, sizeof (buf), - "max freq: %d\n", dev_priv->max_delay * 50); - - if (len > sizeof (buf)) - len = sizeof (buf); - - return simple_read_from_buffer(ubuf, max, ppos, buf, len); -} - -static ssize_t -i915_max_freq_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - struct drm_i915_private *dev_priv = dev->dev_private; - char buf[20]; - int val = 1; - - if (cnt > 0) { - if (cnt > sizeof (buf) - 1) - return -EINVAL; - - if (copy_from_user(buf, ubuf, cnt)) - return -EFAULT; - buf[cnt] = 0; - - val = simple_strtoul(buf, NULL, 0); - } - - DRM_DEBUG_DRIVER("Manually setting max freq to %d\n", val); - - /* - * Turbo will still be enabled, but won't go above the set value. - */ - dev_priv->max_delay = val / 50; - - gen6_set_rps(dev, val / 50); - - return cnt; -} - -static const struct file_operations i915_max_freq_fops = { - .owner = THIS_MODULE, - .open = i915_max_freq_open, - .read = i915_max_freq_read, - .write = i915_max_freq_write, - .llseek = default_llseek, -}; - -static int -i915_cache_sharing_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - -static ssize_t -i915_cache_sharing_read(struct file *filp, - char __user *ubuf, - size_t max, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; - char buf[80]; - u32 snpcr; - int len; - - mutex_lock(&dev_priv->dev->struct_mutex); - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - mutex_unlock(&dev_priv->dev->struct_mutex); - - len = snprintf(buf, sizeof (buf), - "%d\n", (snpcr & GEN6_MBC_SNPCR_MASK) >> - GEN6_MBC_SNPCR_SHIFT); - - if (len > sizeof (buf)) - len = sizeof (buf); - - return simple_read_from_buffer(ubuf, max, ppos, buf, len); -} - -static ssize_t -i915_cache_sharing_write(struct file *filp, - const char __user *ubuf, - size_t cnt, - loff_t *ppos) -{ - struct drm_device *dev = filp->private_data; - struct drm_i915_private *dev_priv = dev->dev_private; - char buf[20]; - u32 snpcr; - int val = 1; - - if (cnt > 0) { - if (cnt > sizeof (buf) - 1) - return -EINVAL; - - if (copy_from_user(buf, ubuf, cnt)) - return -EFAULT; - buf[cnt] = 0; - - val = simple_strtoul(buf, NULL, 0); - } - - if (val < 0 || val > 3) - return -EINVAL; - - DRM_DEBUG_DRIVER("Manually setting uncore sharing to %d\n", val); - - /* Update the cache sharing policy here as well */ - snpcr = I915_READ(GEN6_MBCUNIT_SNPCR); - snpcr &= ~GEN6_MBC_SNPCR_MASK; - snpcr |= (val << GEN6_MBC_SNPCR_SHIFT); - I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr); - - return cnt; -} - -static const struct file_operations i915_cache_sharing_fops = { - .owner = THIS_MODULE, - .open = i915_cache_sharing_open, - .read = i915_cache_sharing_read, - .write = i915_cache_sharing_write, - .llseek = default_llseek, -}; - /* As the drm_debugfs_init() routines are called before dev->dev_private is * allocated we need to hook into the minor for release. */ static int @@ -1586,36 +1437,6 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); } -static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_max_freq", - S_IRUGO | S_IWUSR, - root, dev, - &i915_max_freq_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops); -} - -static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_cache_sharing", - S_IRUGO | S_IWUSR, - root, dev, - &i915_cache_sharing_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops); -} - static struct drm_info_list i915_debugfs_list[] = { {"i915_capabilities", i915_capabilities, 0}, {"i915_gem_objects", i915_gem_object_info, 0}, @@ -1667,12 +1488,6 @@ int i915_debugfs_init(struct drm_minor *minor) return ret; ret = i915_forcewake_create(minor->debugfs_root, minor); - if (ret) - return ret; - ret = i915_max_freq_create(minor->debugfs_root, minor); - if (ret) - return ret; - ret = i915_cache_sharing_create(minor->debugfs_root, minor); if (ret) return ret; @@ -1689,10 +1504,6 @@ void i915_debugfs_cleanup(struct drm_minor *minor) 1, minor); drm_debugfs_remove_files((struct drm_info_list *) &i915_wedged_fops, 1, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_max_freq_fops, - 1, minor); - drm_debugfs_remove_files((struct drm_info_list *) &i915_cache_sharing_fops, - 1, minor); } #endif /* CONFIG_DEBUG_FS */ diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index 8a3942c4f099..12712824a6d2 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -61,6 +61,7 @@ static void i915_write_hws_pga(struct drm_device *dev) static int i915_init_phys_hws(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev_priv); /* Program Hardware Status Page */ dev_priv->status_page_dmah = @@ -70,9 +71,10 @@ static int i915_init_phys_hws(struct drm_device *dev) DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } + ring->status_page.page_addr = + (void __force __iomem *)dev_priv->status_page_dmah->vaddr; - memset_io((void __force __iomem *)dev_priv->status_page_dmah->vaddr, - 0, PAGE_SIZE); + memset_io(ring->status_page.page_addr, 0, PAGE_SIZE); i915_write_hws_pga(dev); diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index feb4f164fd1b..6867e193d85e 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -544,7 +544,6 @@ typedef struct drm_i915_private { u32 savePIPEB_LINK_M1; u32 savePIPEB_LINK_N1; u32 saveMCHBAR_RENDER_STANDBY; - u32 savePCH_PORT_HOTPLUG; struct { /** Bridge to intel-gtt-ko */ diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index a546a71fb060..d1cd8b89f47d 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -3112,7 +3112,7 @@ i915_gem_object_pin_to_display_plane(struct drm_i915_gem_object *obj, if (pipelined != obj->ring) { ret = i915_gem_object_wait_rendering(obj); - if (ret == -ERESTARTSYS) + if (ret) return ret; } diff --git a/trunk/drivers/gpu/drm/i915/i915_irq.c b/trunk/drivers/gpu/drm/i915/i915_irq.c index 02f96fd0d52d..23d1ae67d279 100644 --- a/trunk/drivers/gpu/drm/i915/i915_irq.c +++ b/trunk/drivers/gpu/drm/i915/i915_irq.c @@ -306,15 +306,12 @@ static void i915_hotplug_work_func(struct work_struct *work) struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *encoder; - mutex_lock(&mode_config->mutex); DRM_DEBUG_KMS("running encoder hotplug functions\n"); list_for_each_entry(encoder, &mode_config->encoder_list, base.head) if (encoder->hot_plug) encoder->hot_plug(encoder); - mutex_unlock(&mode_config->mutex); - /* Just fire off a uevent and let userspace tell us what to do */ drm_helper_hpd_irq_event(dev); } diff --git a/trunk/drivers/gpu/drm/i915/i915_reg.h b/trunk/drivers/gpu/drm/i915/i915_reg.h index d1331f771e2f..02db299f621a 100644 --- a/trunk/drivers/gpu/drm/i915/i915_reg.h +++ b/trunk/drivers/gpu/drm/i915/i915_reg.h @@ -78,14 +78,6 @@ #define GRDOM_RENDER (1<<2) #define GRDOM_MEDIA (3<<2) -#define GEN6_MBCUNIT_SNPCR 0x900c /* for LLC config */ -#define GEN6_MBC_SNPCR_SHIFT 21 -#define GEN6_MBC_SNPCR_MASK (3<<21) -#define GEN6_MBC_SNPCR_MAX (0<<21) -#define GEN6_MBC_SNPCR_MED (1<<21) -#define GEN6_MBC_SNPCR_LOW (2<<21) -#define GEN6_MBC_SNPCR_MIN (3<<21) /* only 1/16th of the cache is shared */ - #define GEN6_GDRST 0x941c #define GEN6_GRDOM_FULL (1 << 0) #define GEN6_GRDOM_RENDER (1 << 1) @@ -1514,7 +1506,6 @@ #define VIDEO_DIP_SELECT_AVI (0 << 19) #define VIDEO_DIP_SELECT_VENDOR (1 << 19) #define VIDEO_DIP_SELECT_SPD (3 << 19) -#define VIDEO_DIP_SELECT_MASK (3 << 19) #define VIDEO_DIP_FREQ_ONCE (0 << 16) #define VIDEO_DIP_FREQ_VSYNC (1 << 16) #define VIDEO_DIP_FREQ_2VSYNC (2 << 16) @@ -2093,6 +2084,9 @@ #define DP_PIPEB_SELECT (1 << 30) #define DP_PIPE_MASK (1 << 30) +#define DP_PIPE_ENABLED(V, P) \ + (((V) & (DP_PIPE_MASK | DP_PORT_EN)) == ((P) << 30 | DP_PORT_EN)) + /* Link training mode - select a suitable mode for each stage */ #define DP_LINK_TRAIN_PAT_1 (0 << 28) #define DP_LINK_TRAIN_PAT_2 (1 << 28) @@ -3030,20 +3024,6 @@ #define _TRANSA_DP_LINK_M2 0xe0048 #define _TRANSA_DP_LINK_N2 0xe004c -/* Per-transcoder DIP controls */ - -#define _VIDEO_DIP_CTL_A 0xe0200 -#define _VIDEO_DIP_DATA_A 0xe0208 -#define _VIDEO_DIP_GCP_A 0xe0210 - -#define _VIDEO_DIP_CTL_B 0xe1200 -#define _VIDEO_DIP_DATA_B 0xe1208 -#define _VIDEO_DIP_GCP_B 0xe1210 - -#define TVIDEO_DIP_CTL(pipe) _PIPE(pipe, _VIDEO_DIP_CTL_A, _VIDEO_DIP_CTL_B) -#define TVIDEO_DIP_DATA(pipe) _PIPE(pipe, _VIDEO_DIP_DATA_A, _VIDEO_DIP_DATA_B) -#define TVIDEO_DIP_GCP(pipe) _PIPE(pipe, _VIDEO_DIP_GCP_A, _VIDEO_DIP_GCP_B) - #define _TRANS_HTOTAL_B 0xe1000 #define _TRANS_HBLANK_B 0xe1004 #define _TRANS_HSYNC_B 0xe1008 @@ -3096,16 +3076,6 @@ #define TRANS_6BPC (2<<5) #define TRANS_12BPC (3<<5) -#define _TRANSA_CHICKEN2 0xf0064 -#define _TRANSB_CHICKEN2 0xf1064 -#define TRANS_CHICKEN2(pipe) _PIPE(pipe, _TRANSA_CHICKEN2, _TRANSB_CHICKEN2) -#define TRANS_AUTOTRAIN_GEN_STALL_DIS (1<<31) - -#define SOUTH_CHICKEN1 0xc2000 -#define FDIA_PHASE_SYNC_SHIFT_OVR 19 -#define FDIA_PHASE_SYNC_SHIFT_EN 18 -#define FDI_PHASE_SYNC_OVR(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_OVR - ((pipe) * 2))) -#define FDI_PHASE_SYNC_EN(pipe) (1<<(FDIA_PHASE_SYNC_SHIFT_EN - ((pipe) * 2))) #define SOUTH_CHICKEN2 0xc2004 #define DPLS_EDP_PPS_FIX_DIS (1<<0) diff --git a/trunk/drivers/gpu/drm/i915/i915_suspend.c b/trunk/drivers/gpu/drm/i915/i915_suspend.c index 87677d60d0df..285758603ac8 100644 --- a/trunk/drivers/gpu/drm/i915/i915_suspend.c +++ b/trunk/drivers/gpu/drm/i915/i915_suspend.c @@ -812,7 +812,6 @@ int i915_save_state(struct drm_device *dev) dev_priv->saveFDI_RXB_IMR = I915_READ(_FDI_RXB_IMR); dev_priv->saveMCHBAR_RENDER_STANDBY = I915_READ(RSTDBYCTL); - dev_priv->savePCH_PORT_HOTPLUG = I915_READ(PCH_PORT_HOTPLUG); } else { dev_priv->saveIER = I915_READ(IER); dev_priv->saveIMR = I915_READ(IMR); @@ -864,7 +863,6 @@ int i915_restore_state(struct drm_device *dev) I915_WRITE(GTIMR, dev_priv->saveGTIMR); I915_WRITE(_FDI_RXA_IMR, dev_priv->saveFDI_RXA_IMR); I915_WRITE(_FDI_RXB_IMR, dev_priv->saveFDI_RXB_IMR); - I915_WRITE(PCH_PORT_HOTPLUG, dev_priv->savePCH_PORT_HOTPLUG); } else { I915_WRITE(IER, dev_priv->saveIER); I915_WRITE(IMR, dev_priv->saveIMR); diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 35364e68a091..393a39922e53 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -980,29 +980,11 @@ static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, pipe_name(pipe)); } -static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, enum pipe pipe, - int reg, u32 port_sel, u32 val) -{ - if ((val & DP_PORT_EN) == 0) - return false; - - if (HAS_PCH_CPT(dev_priv->dev)) { - u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); - u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); - if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) - return false; - } else { - if ((val & DP_PIPE_MASK) != (pipe << 30)) - return false; - } - return true; -} - static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg, u32 port_sel) + enum pipe pipe, int reg) { u32 val = I915_READ(reg); - WARN(dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val), + WARN(DP_PIPE_ENABLED(val, pipe), "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } @@ -1022,9 +1004,9 @@ static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, int reg; u32 val; - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); - assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); + assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B); + assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C); + assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D); reg = PCH_ADPA; val = I915_READ(reg); @@ -1294,17 +1276,6 @@ static void intel_disable_pipe(struct drm_i915_private *dev_priv, intel_wait_for_pipe_off(dev_priv->dev, pipe); } -/* - * Plane regs are double buffered, going from enabled->disabled needs a - * trigger in order to latch. The display address reg provides this. - */ -static void intel_flush_display_plane(struct drm_i915_private *dev_priv, - enum plane plane) -{ - I915_WRITE(DSPADDR(plane), I915_READ(DSPADDR(plane))); - I915_WRITE(DSPSURF(plane), I915_READ(DSPSURF(plane))); -} - /** * intel_enable_plane - enable a display plane on a given pipe * @dev_priv: i915 private structure @@ -1328,10 +1299,20 @@ static void intel_enable_plane(struct drm_i915_private *dev_priv, return; I915_WRITE(reg, val | DISPLAY_PLANE_ENABLE); - intel_flush_display_plane(dev_priv, plane); intel_wait_for_vblank(dev_priv->dev, pipe); } +/* + * Plane regs are double buffered, going from enabled->disabled needs a + * trigger in order to latch. The display address reg provides this. + */ +static void intel_flush_display_plane(struct drm_i915_private *dev_priv, + enum plane plane) +{ + u32 reg = DSPADDR(plane); + I915_WRITE(reg, I915_READ(reg)); +} + /** * intel_disable_plane - disable a display plane * @dev_priv: i915 private structure @@ -1357,24 +1338,19 @@ static void intel_disable_plane(struct drm_i915_private *dev_priv, } static void disable_pch_dp(struct drm_i915_private *dev_priv, - enum pipe pipe, int reg, u32 port_sel) + enum pipe pipe, int reg) { u32 val = I915_READ(reg); - if (dp_pipe_enabled(dev_priv, pipe, reg, port_sel, val)) { - DRM_DEBUG_KMS("Disabling pch dp %x on pipe %d\n", reg, pipe); + if (DP_PIPE_ENABLED(val, pipe)) I915_WRITE(reg, val & ~DP_PORT_EN); - } } static void disable_pch_hdmi(struct drm_i915_private *dev_priv, enum pipe pipe, int reg) { u32 val = I915_READ(reg); - if (HDMI_PIPE_ENABLED(val, pipe)) { - DRM_DEBUG_KMS("Disabling pch HDMI %x on pipe %d\n", - reg, pipe); + if (HDMI_PIPE_ENABLED(val, pipe)) I915_WRITE(reg, val & ~PORT_ENABLE); - } } /* Disable any ports connected to this transcoder */ @@ -1386,9 +1362,9 @@ static void intel_disable_pch_ports(struct drm_i915_private *dev_priv, val = I915_READ(PCH_PP_CONTROL); I915_WRITE(PCH_PP_CONTROL, val | PANEL_UNLOCK_REGS); - disable_pch_dp(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); - disable_pch_dp(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); - disable_pch_dp(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); + disable_pch_dp(dev_priv, pipe, PCH_DP_B); + disable_pch_dp(dev_priv, pipe, PCH_DP_C); + disable_pch_dp(dev_priv, pipe, PCH_DP_D); reg = PCH_ADPA; val = I915_READ(reg); @@ -2120,7 +2096,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, /* no fb bound */ if (!crtc->fb) { - DRM_ERROR("No FB bound\n"); + DRM_DEBUG_KMS("No FB bound\n"); return 0; } @@ -2129,7 +2105,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, case 1: break; default: - DRM_ERROR("no plane for crtc\n"); return -EINVAL; } @@ -2139,7 +2114,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, NULL); if (ret != 0) { mutex_unlock(&dev->struct_mutex); - DRM_ERROR("pin & fence failed\n"); return ret; } @@ -2168,7 +2142,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (ret) { i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); - DRM_ERROR("failed to update base address\n"); return ret; } @@ -2275,18 +2248,6 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc) FDI_FE_ERRC_ENABLE); } -static void cpt_phase_pointer_enable(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 flags = I915_READ(SOUTH_CHICKEN1); - - flags |= FDI_PHASE_SYNC_OVR(pipe); - I915_WRITE(SOUTH_CHICKEN1, flags); /* once to unlock... */ - flags |= FDI_PHASE_SYNC_EN(pipe); - I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to enable */ - POSTING_READ(SOUTH_CHICKEN1); -} - /* The FDI link training functions for ILK/Ibexpeak. */ static void ironlake_fdi_link_train(struct drm_crtc *crtc) { @@ -2437,9 +2398,6 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc) POSTING_READ(reg); udelay(150); - if (HAS_PCH_CPT(dev)) - cpt_phase_pointer_enable(dev, pipe); - for (i = 0; i < 4; i++ ) { reg = FDI_TX_CTL(pipe); temp = I915_READ(reg); @@ -2556,9 +2514,6 @@ static void ivb_manual_fdi_link_train(struct drm_crtc *crtc) POSTING_READ(reg); udelay(150); - if (HAS_PCH_CPT(dev)) - cpt_phase_pointer_enable(dev, pipe); - for (i = 0; i < 4; i++ ) { reg = FDI_TX_CTL(pipe); temp = I915_READ(reg); @@ -2668,17 +2623,6 @@ static void ironlake_fdi_pll_enable(struct drm_crtc *crtc) } } -static void cpt_phase_pointer_disable(struct drm_device *dev, int pipe) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - u32 flags = I915_READ(SOUTH_CHICKEN1); - - flags &= ~(FDI_PHASE_SYNC_EN(pipe)); - I915_WRITE(SOUTH_CHICKEN1, flags); /* once to disable... */ - flags &= ~(FDI_PHASE_SYNC_OVR(pipe)); - I915_WRITE(SOUTH_CHICKEN1, flags); /* then again to lock */ - POSTING_READ(SOUTH_CHICKEN1); -} static void ironlake_fdi_disable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -2708,8 +2652,6 @@ static void ironlake_fdi_disable(struct drm_crtc *crtc) I915_WRITE(FDI_RX_CHICKEN(pipe), I915_READ(FDI_RX_CHICKEN(pipe) & ~FDI_RX_PHASE_SYNC_POINTER_EN)); - } else if (HAS_PCH_CPT(dev)) { - cpt_phase_pointer_disable(dev, pipe); } /* still set train pattern 1 */ @@ -2920,18 +2862,14 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) I915_WRITE(PF_WIN_SZ(pipe), dev_priv->pch_pf_size); } - /* - * On ILK+ LUT must be loaded before the pipe is running but with - * clocks enabled - */ - intel_crtc_load_lut(crtc); - intel_enable_pipe(dev_priv, pipe, is_pch_port); intel_enable_plane(dev_priv, plane, pipe); if (is_pch_port) ironlake_pch_enable(crtc); + intel_crtc_load_lut(crtc); + mutex_lock(&dev->struct_mutex); intel_update_fbc(dev); mutex_unlock(&dev->struct_mutex); @@ -4600,9 +4538,7 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, if (connector->encoder != encoder) continue; - /* Don't use an invalid EDID bpc value */ - if (connector->display_info.bpc && - connector->display_info.bpc < display_bpc) { + if (connector->display_info.bpc < display_bpc) { DRM_DEBUG_DRIVER("clamping display bpc (was %d) to EDID reported max of %d\n", display_bpc, connector->display_info.bpc); display_bpc = connector->display_info.bpc; } @@ -5217,8 +5153,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, temp |= PIPE_12BPC; break; default: - WARN(1, "intel_choose_pipe_bpp returned invalid value %d\n", - pipe_bpp); + WARN(1, "intel_choose_pipe_bpp returned invalid value\n"); temp |= PIPE_8BPC; pipe_bpp = 24; break; @@ -5303,7 +5238,7 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, } else if (is_sdvo && is_tv) factor = 20; - if (clock.m < factor * clock.n) + if (clock.m1 < factor * clock.n) fp |= FP_CB_TUNE; dpll = 0; @@ -5581,8 +5516,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, drm_vblank_post_modeset(dev, pipe); - intel_crtc->dpms_mode = DRM_MODE_DPMS_ON; - return ret; } @@ -7781,12 +7714,10 @@ static void gen6_init_clock_gating(struct drm_device *dev) ILK_DPARB_CLK_GATE | ILK_DPFD_CLK_GATE); - for_each_pipe(pipe) { + for_each_pipe(pipe) I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); - intel_flush_display_plane(dev_priv, pipe); - } } static void ivybridge_init_clock_gating(struct drm_device *dev) @@ -7803,12 +7734,10 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); - for_each_pipe(pipe) { + for_each_pipe(pipe) I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | DISPPLANE_TRICKLE_FEED_DISABLE); - intel_flush_display_plane(dev_priv, pipe); - } } static void g4x_init_clock_gating(struct drm_device *dev) @@ -7891,7 +7820,6 @@ static void ibx_init_clock_gating(struct drm_device *dev) static void cpt_init_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - int pipe; /* * On Ibex Peak and Cougar Point, we need to disable clock @@ -7901,9 +7829,6 @@ static void cpt_init_clock_gating(struct drm_device *dev) I915_WRITE(SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE); I915_WRITE(SOUTH_CHICKEN2, I915_READ(SOUTH_CHICKEN2) | DPLS_EDP_PPS_FIX_DIS); - /* Without this, mode sets may fail silently on FDI */ - for_each_pipe(pipe) - I915_WRITE(TRANS_CHICKEN2(pipe), TRANS_AUTOTRAIN_GEN_STALL_DIS); } static void ironlake_teardown_rc6(struct drm_device *dev) @@ -8253,9 +8178,6 @@ struct intel_quirk intel_quirks[] = { /* Lenovo U160 cannot use SSC on LVDS */ { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, - - /* Sony Vaio Y cannot use SSC on LVDS */ - { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, }; static void intel_init_quirks(struct drm_device *dev) diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 0feae908bb37..f797fb58ba9c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -50,10 +50,9 @@ struct intel_dp { bool has_audio; int force_audio; uint32_t color_range; - int dpms_mode; uint8_t link_bw; uint8_t lane_count; - uint8_t dpcd[8]; + uint8_t dpcd[4]; struct i2c_adapter adapter; struct i2c_algo_dp_aux_data algo; bool is_pch_edp; @@ -317,17 +316,9 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else precharge = 5; - /* Try to wait for any previous AUX channel activity */ - for (try = 0; try < 3; try++) { - status = I915_READ(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - msleep(1); - } - - if (try == 3) { - WARN(1, "dp_aux_ch not started status 0x%08x\n", - I915_READ(ch_ctl)); + if (I915_READ(ch_ctl) & DP_AUX_CH_CTL_SEND_BUSY) { + DRM_ERROR("dp_aux_ch not started status 0x%08x\n", + I915_READ(ch_ctl)); return -EBUSY; } @@ -779,7 +770,6 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, memset(intel_dp->link_configuration, 0, DP_LINK_CONFIGURATION_SIZE); intel_dp->link_configuration[0] = intel_dp->link_bw; intel_dp->link_configuration[1] = intel_dp->lane_count; - intel_dp->link_configuration[8] = DP_SET_ANSI_8B10B; /* * Check for DPCD version > 1.1 and enhanced framing support @@ -1021,8 +1011,6 @@ static void intel_dp_commit(struct drm_encoder *encoder) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); - - intel_dp->dpms_mode = DRM_MODE_DPMS_ON; } static void @@ -1057,7 +1045,6 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) if (is_edp(intel_dp)) ironlake_edp_backlight_on(dev); } - intel_dp->dpms_mode = mode; } /* @@ -1347,16 +1334,10 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) u32 reg; uint32_t DP = intel_dp->DP; - /* - * On CPT we have to enable the port in training pattern 1, which - * will happen below in intel_dp_set_link_train. Otherwise, enable - * the port and wait for it to become active. - */ - if (!HAS_PCH_CPT(dev)) { - I915_WRITE(intel_dp->output_reg, intel_dp->DP); - POSTING_READ(intel_dp->output_reg); - intel_wait_for_vblank(dev, intel_crtc->pipe); - } + /* Enable output, wait for it to become active */ + I915_WRITE(intel_dp->output_reg, intel_dp->DP); + POSTING_READ(intel_dp->output_reg); + intel_wait_for_vblank(dev, intel_crtc->pipe); /* Write the link configuration data */ intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET, @@ -1389,8 +1370,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) reg = DP | DP_LINK_TRAIN_PAT_1; if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_1 | - DP_LINK_SCRAMBLING_DISABLE)) + DP_TRAINING_PATTERN_1)) break; /* Set training pattern 1 */ @@ -1465,8 +1445,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) /* channel eq pattern */ if (!intel_dp_set_link_train(intel_dp, reg, - DP_TRAINING_PATTERN_2 | - DP_LINK_SCRAMBLING_DISABLE)) + DP_TRAINING_PATTERN_2)) break; udelay(400); @@ -1580,18 +1559,6 @@ intel_dp_link_down(struct intel_dp *intel_dp) POSTING_READ(intel_dp->output_reg); } -static bool -intel_dp_get_dpcd(struct intel_dp *intel_dp) -{ - if (intel_dp_aux_native_read_retry(intel_dp, 0x000, intel_dp->dpcd, - sizeof (intel_dp->dpcd)) && - (intel_dp->dpcd[DP_DPCD_REV] != 0)) { - return true; - } - - return false; -} - /* * According to DP spec * 5.1.2: @@ -1604,44 +1571,36 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) static void intel_dp_check_link_status(struct intel_dp *intel_dp) { - if (intel_dp->dpms_mode != DRM_MODE_DPMS_ON) - return; + int ret; if (!intel_dp->base.base.crtc) return; - /* Try to read receiver status if the link appears to be up */ if (!intel_dp_get_link_status(intel_dp)) { intel_dp_link_down(intel_dp); return; } - /* Now read the DPCD to see if it's actually running */ - if (!intel_dp_get_dpcd(intel_dp)) { + /* Try to read receiver status if the link appears to be up */ + ret = intel_dp_aux_native_read(intel_dp, + 0x000, intel_dp->dpcd, + sizeof (intel_dp->dpcd)); + if (ret != sizeof(intel_dp->dpcd)) { intel_dp_link_down(intel_dp); return; } if (!intel_channel_eq_ok(intel_dp)) { - DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", - drm_get_encoder_name(&intel_dp->base.base)); intel_dp_start_link_train(intel_dp); intel_dp_complete_link_train(intel_dp); } } -static enum drm_connector_status -intel_dp_detect_dpcd(struct intel_dp *intel_dp) -{ - if (intel_dp_get_dpcd(intel_dp)) - return connector_status_connected; - return connector_status_disconnected; -} - static enum drm_connector_status ironlake_dp_detect(struct intel_dp *intel_dp) { enum drm_connector_status status; + bool ret; /* Can't disconnect eDP, but you can close the lid... */ if (is_edp(intel_dp)) { @@ -1651,7 +1610,15 @@ ironlake_dp_detect(struct intel_dp *intel_dp) return status; } - return intel_dp_detect_dpcd(intel_dp); + status = connector_status_disconnected; + ret = intel_dp_aux_native_read_retry(intel_dp, + 0x000, intel_dp->dpcd, + sizeof (intel_dp->dpcd)); + if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) + status = connector_status_connected; + DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], + intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); + return status; } static enum drm_connector_status @@ -1659,6 +1626,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; + enum drm_connector_status status; uint32_t temp, bit; switch (intel_dp->output_reg) { @@ -1680,7 +1648,15 @@ g4x_dp_detect(struct intel_dp *intel_dp) if ((temp & bit) == 0) return connector_status_disconnected; - return intel_dp_detect_dpcd(intel_dp); + status = connector_status_disconnected; + if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, + sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) + { + if (intel_dp->dpcd[DP_DPCD_REV] != 0) + status = connector_status_connected; + } + + return status; } /** @@ -1703,12 +1679,6 @@ intel_dp_detect(struct drm_connector *connector, bool force) status = ironlake_dp_detect(intel_dp); else status = g4x_dp_detect(intel_dp); - - DRM_DEBUG_KMS("DPCD: %02hx%02hx%02hx%02hx%02hx%02hx%02hx%02hx\n", - intel_dp->dpcd[0], intel_dp->dpcd[1], intel_dp->dpcd[2], - intel_dp->dpcd[3], intel_dp->dpcd[4], intel_dp->dpcd[5], - intel_dp->dpcd[6], intel_dp->dpcd[7]); - if (status != connector_status_connected) return status; @@ -1954,7 +1924,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) return; intel_dp->output_reg = output_reg; - intel_dp->dpms_mode = -1; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { @@ -2031,7 +2000,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) /* Cache some DPCD data in the eDP case */ if (is_edp(intel_dp)) { - bool ret; + int ret; u32 pp_on, pp_div; pp_on = I915_READ(PCH_PP_ON_DELAYS); @@ -2044,9 +2013,11 @@ intel_dp_init(struct drm_device *dev, int output_reg) dev_priv->panel_t12 *= 100; /* t12 in 100ms units */ ironlake_edp_panel_vdd_on(intel_dp); - ret = intel_dp_get_dpcd(intel_dp); + ret = intel_dp_aux_native_read(intel_dp, DP_DPCD_REV, + intel_dp->dpcd, + sizeof(intel_dp->dpcd)); ironlake_edp_panel_vdd_off(intel_dp); - if (ret) { + if (ret == sizeof(intel_dp->dpcd)) { if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) dev_priv->no_aux_handshake = intel_dp->dpcd[DP_MAX_DOWNSPREAD] & diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 7b330e76a435..6e990f9760ef 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -178,28 +178,10 @@ struct intel_crtc { #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) -#define DIP_HEADER_SIZE 5 - #define DIP_TYPE_AVI 0x82 #define DIP_VERSION_AVI 0x2 #define DIP_LEN_AVI 13 -#define DIP_TYPE_SPD 0x3 -#define DIP_VERSION_SPD 0x1 -#define DIP_LEN_SPD 25 -#define DIP_SPD_UNKNOWN 0 -#define DIP_SPD_DSTB 0x1 -#define DIP_SPD_DVDP 0x2 -#define DIP_SPD_DVHS 0x3 -#define DIP_SPD_HDDVR 0x4 -#define DIP_SPD_DVC 0x5 -#define DIP_SPD_DSC 0x6 -#define DIP_SPD_VCD 0x7 -#define DIP_SPD_GAME 0x8 -#define DIP_SPD_PC 0x9 -#define DIP_SPD_BD 0xa -#define DIP_SPD_SCD 0xb - struct dip_infoframe { uint8_t type; /* HB0 */ uint8_t ver; /* HB1 */ @@ -224,11 +206,6 @@ struct dip_infoframe { uint16_t left_bar_end; uint16_t right_bar_start; } avi; - struct { - uint8_t vn[8]; - uint8_t pd[16]; - uint8_t sdi; - } spd; uint8_t payload[27]; } __attribute__ ((packed)) body; } __attribute__((packed)); diff --git a/trunk/drivers/gpu/drm/i915/intel_hdmi.c b/trunk/drivers/gpu/drm/i915/intel_hdmi.c index 226ba830f383..1ed8e6903915 100644 --- a/trunk/drivers/gpu/drm/i915/intel_hdmi.c +++ b/trunk/drivers/gpu/drm/i915/intel_hdmi.c @@ -45,8 +45,6 @@ struct intel_hdmi { bool has_hdmi_sink; bool has_audio; int force_audio; - void (*write_infoframe)(struct drm_encoder *encoder, - struct dip_infoframe *frame); }; static struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder) @@ -60,70 +58,37 @@ static struct intel_hdmi *intel_attached_hdmi(struct drm_connector *connector) struct intel_hdmi, base); } -void intel_dip_infoframe_csum(struct dip_infoframe *frame) +void intel_dip_infoframe_csum(struct dip_infoframe *avi_if) { - uint8_t *data = (uint8_t *)frame; + uint8_t *data = (uint8_t *)avi_if; uint8_t sum = 0; unsigned i; - frame->checksum = 0; - frame->ecc = 0; + avi_if->checksum = 0; + avi_if->ecc = 0; - /* Header isn't part of the checksum */ - for (i = 5; i < frame->len; i++) + for (i = 0; i < sizeof(*avi_if); i++) sum += data[i]; - frame->checksum = 0x100 - sum; + avi_if->checksum = 0x100 - sum; } -static u32 intel_infoframe_index(struct dip_infoframe *frame) -{ - u32 flags = 0; - - switch (frame->type) { - case DIP_TYPE_AVI: - flags |= VIDEO_DIP_SELECT_AVI; - break; - case DIP_TYPE_SPD: - flags |= VIDEO_DIP_SELECT_SPD; - break; - default: - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); - break; - } - - return flags; -} - -static u32 intel_infoframe_flags(struct dip_infoframe *frame) -{ - u32 flags = 0; - - switch (frame->type) { - case DIP_TYPE_AVI: - flags |= VIDEO_DIP_ENABLE_AVI | VIDEO_DIP_FREQ_VSYNC; - break; - case DIP_TYPE_SPD: - flags |= VIDEO_DIP_ENABLE_SPD | VIDEO_DIP_FREQ_2VSYNC; - break; - default: - DRM_DEBUG_DRIVER("unknown info frame type %d\n", frame->type); - break; - } - - return flags; -} - -static void i9xx_write_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) +static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder) { - uint32_t *data = (uint32_t *)frame; + struct dip_infoframe avi_if = { + .type = DIP_TYPE_AVI, + .ver = DIP_VERSION_AVI, + .len = DIP_LEN_AVI, + }; + uint32_t *data = (uint32_t *)&avi_if; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - u32 port, flags, val = I915_READ(VIDEO_DIP_CTL); - unsigned i, len = DIP_HEADER_SIZE + frame->len; + u32 port; + unsigned i; + if (!intel_hdmi->has_hdmi_sink) + return; /* XXX first guess at handling video port, is this corrent? */ if (intel_hdmi->sdvox_reg == SDVOB) @@ -133,87 +98,18 @@ static void i9xx_write_infoframe(struct drm_encoder *encoder, else return; - flags = intel_infoframe_index(frame); - - val &= ~VIDEO_DIP_SELECT_MASK; + I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port | + VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC); - I915_WRITE(VIDEO_DIP_CTL, val | port | flags); - - for (i = 0; i < len; i += 4) { + intel_dip_infoframe_csum(&avi_if); + for (i = 0; i < sizeof(avi_if); i += 4) { I915_WRITE(VIDEO_DIP_DATA, *data); data++; } - flags |= intel_infoframe_flags(frame); - - I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | val | port | flags); -} - -static void ironlake_write_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) -{ - uint32_t *data = (uint32_t *)frame; - struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_crtc *crtc = encoder->crtc; - struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - int reg = TVIDEO_DIP_CTL(intel_crtc->pipe); - unsigned i, len = DIP_HEADER_SIZE + frame->len; - u32 flags, val = I915_READ(reg); - - intel_wait_for_vblank(dev, intel_crtc->pipe); - - flags = intel_infoframe_index(frame); - - val &= ~VIDEO_DIP_SELECT_MASK; - - I915_WRITE(reg, val | flags); - - for (i = 0; i < len; i += 4) { - I915_WRITE(TVIDEO_DIP_DATA(intel_crtc->pipe), *data); - data++; - } - - flags |= intel_infoframe_flags(frame); - - I915_WRITE(reg, VIDEO_DIP_ENABLE | val | flags); -} -static void intel_set_infoframe(struct drm_encoder *encoder, - struct dip_infoframe *frame) -{ - struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); - - if (!intel_hdmi->has_hdmi_sink) - return; - - intel_dip_infoframe_csum(frame); - intel_hdmi->write_infoframe(encoder, frame); -} - -static void intel_hdmi_set_avi_infoframe(struct drm_encoder *encoder) -{ - struct dip_infoframe avi_if = { - .type = DIP_TYPE_AVI, - .ver = DIP_VERSION_AVI, - .len = DIP_LEN_AVI, - }; - - intel_set_infoframe(encoder, &avi_if); -} - -static void intel_hdmi_set_spd_infoframe(struct drm_encoder *encoder) -{ - struct dip_infoframe spd_if; - - memset(&spd_if, 0, sizeof(spd_if)); - spd_if.type = DIP_TYPE_SPD; - spd_if.ver = DIP_VERSION_SPD; - spd_if.len = DIP_LEN_SPD; - strcpy(spd_if.body.spd.vn, "Intel"); - strcpy(spd_if.body.spd.pd, "Integrated gfx"); - spd_if.body.spd.sdi = DIP_SPD_PC; - - intel_set_infoframe(encoder, &spd_if); + I915_WRITE(VIDEO_DIP_CTL, VIDEO_DIP_ENABLE | port | + VIDEO_DIP_SELECT_AVI | VIDEO_DIP_FREQ_VSYNC | + VIDEO_DIP_ENABLE_AVI); } static void intel_hdmi_mode_set(struct drm_encoder *encoder, @@ -260,7 +156,6 @@ static void intel_hdmi_mode_set(struct drm_encoder *encoder, POSTING_READ(intel_hdmi->sdvox_reg); intel_hdmi_set_avi_infoframe(encoder); - intel_hdmi_set_spd_infoframe(encoder); } static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) @@ -538,11 +433,6 @@ void intel_hdmi_init(struct drm_device *dev, int sdvox_reg) intel_hdmi->sdvox_reg = sdvox_reg; - if (!HAS_PCH_SPLIT(dev)) - intel_hdmi->write_infoframe = i9xx_write_infoframe; - else - intel_hdmi->write_infoframe = ironlake_write_infoframe; - drm_encoder_helper_add(&intel_encoder->base, &intel_hdmi_helper_funcs); intel_hdmi_add_properties(intel_hdmi, connector); diff --git a/trunk/drivers/gpu/drm/i915/intel_lvds.c b/trunk/drivers/gpu/drm/i915/intel_lvds.c index 2e8ddfcba40c..b28f7bd9f88a 100644 --- a/trunk/drivers/gpu/drm/i915/intel_lvds.c +++ b/trunk/drivers/gpu/drm/i915/intel_lvds.c @@ -688,14 +688,6 @@ static const struct dmi_system_id intel_no_lvds[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"), }, }, - { - .callback = intel_no_lvds_dmi_callback, - .ident = "Dell OptiPlex FX170", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), - DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex FX170"), - }, - }, { .callback = intel_no_lvds_dmi_callback, .ident = "AOpen Mini PC", diff --git a/trunk/drivers/gpu/drm/i915/intel_panel.c b/trunk/drivers/gpu/drm/i915/intel_panel.c index 05f500cd9c24..a06ff07a4d3b 100644 --- a/trunk/drivers/gpu/drm/i915/intel_panel.c +++ b/trunk/drivers/gpu/drm/i915/intel_panel.c @@ -83,15 +83,11 @@ intel_pch_panel_fitting(struct drm_device *dev, u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; if (scaled_width > scaled_height) { /* pillar */ width = scaled_height / mode->vdisplay; - if (width & 1) - width++; x = (adjusted_mode->hdisplay - width + 1) / 2; y = 0; height = adjusted_mode->vdisplay; } else if (scaled_width < scaled_height) { /* letter */ height = scaled_width / mode->hdisplay; - if (height & 1) - height++; y = (adjusted_mode->vdisplay - height + 1) / 2; x = 0; width = adjusted_mode->hdisplay; diff --git a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c index 47b9b2777038..e9615685a39c 100644 --- a/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/trunk/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1321,9 +1321,6 @@ int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) ring->get_seqno = pc_render_get_seqno; } - if (!I915_NEED_GFX_HWS(dev)) - ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; - ring->dev = dev; INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); diff --git a/trunk/drivers/gpu/drm/radeon/Makefile b/trunk/drivers/gpu/drm/radeon/Makefile index 9f363e0c4b60..3896ef811102 100644 --- a/trunk/drivers/gpu/drm/radeon/Makefile +++ b/trunk/drivers/gpu/drm/radeon/Makefile @@ -5,7 +5,6 @@ ccflags-y := -Iinclude/drm hostprogs-y := mkregtable -clean-files := rn50_reg_safe.h r100_reg_safe.h r200_reg_safe.h rv515_reg_safe.h r300_reg_safe.h r420_reg_safe.h rs600_reg_safe.h r600_reg_safe.h evergreen_reg_safe.h cayman_reg_safe.h quiet_cmd_mkregtable = MKREGTABLE $@ cmd_mkregtable = $(obj)/mkregtable $< > $@ diff --git a/trunk/drivers/gpu/drm/radeon/atom.c b/trunk/drivers/gpu/drm/radeon/atom.c index e88c64417a8a..ebdb0fdb8348 100644 --- a/trunk/drivers/gpu/drm/radeon/atom.c +++ b/trunk/drivers/gpu/drm/radeon/atom.c @@ -1245,9 +1245,6 @@ struct atom_context *atom_parse(struct card_info *card, void *bios) char name[512]; int i; - if (!ctx) - return NULL; - ctx->card = card; ctx->bios = bios; diff --git a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c index a134790903d3..189e86522b5b 100644 --- a/trunk/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/trunk/drivers/gpu/drm/radeon/evergreen_cs.c @@ -428,7 +428,7 @@ static inline int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u3 last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); i = (reg >> 7); - if (i >= last_reg) { + if (i > last_reg) { dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/radeon/r600_cs.c b/trunk/drivers/gpu/drm/radeon/r600_cs.c index cf83aa05a684..db8ef1905d5f 100644 --- a/trunk/drivers/gpu/drm/radeon/r600_cs.c +++ b/trunk/drivers/gpu/drm/radeon/r600_cs.c @@ -915,11 +915,12 @@ static inline int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx { struct r600_cs_track *track = (struct r600_cs_track *)p->track; struct radeon_cs_reloc *reloc; + u32 last_reg = ARRAY_SIZE(r600_reg_safe_bm); u32 m, i, tmp, *ib; int r; i = (reg >> 7); - if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { + if (i > last_reg) { dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); return -EINVAL; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_combios.c b/trunk/drivers/gpu/drm/radeon/radeon_combios.c index e0138b674aca..a74217cd192f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_combios.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_combios.c @@ -2557,7 +2557,6 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) u16 offset, misc, misc2 = 0; u8 rev, blocks, tmp; int state_index = 0; - struct radeon_i2c_bus_rec i2c_bus; rdev->pm.default_power_state_index = -1; @@ -2576,6 +2575,7 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) offset = combios_get_table_offset(dev, COMBIOS_OVERDRIVE_INFO_TABLE); if (offset) { u8 thermal_controller = 0, gpio = 0, i2c_addr = 0, clk_bit = 0, data_bit = 0; + struct radeon_i2c_bus_rec i2c_bus; rev = RBIOS8(offset); @@ -2617,25 +2617,6 @@ void radeon_combios_get_power_modes(struct radeon_device *rdev) i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); } } - } else { - /* boards with a thermal chip, but no overdrive table */ - - /* Asus 9600xt has an f75375 on the monid bus */ - if ((dev->pdev->device == 0x4152) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0xc002)) { - i2c_bus = combios_setup_i2c_bus(rdev, DDC_MONID, 0, 0); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = "f75375"; - info.addr = 0x28; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - DRM_INFO("Possible %s thermal controller at 0x%02x\n", - name, info.addr); - } - } } if (rdev->flags & RADEON_IS_MOBILITY) { diff --git a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c index 6d6b5f16bc09..9792d4ffdc86 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_connectors.c @@ -430,45 +430,6 @@ int radeon_connector_set_property(struct drm_connector *connector, struct drm_pr return 0; } -/* - * Some integrated ATI Radeon chipset implementations (e. g. - * Asus M2A-VM HDMI) may indicate the availability of a DDC, - * even when there's no monitor connected. For these connectors - * following DDC probe extension will be applied: check also for the - * availability of EDID with at least a correct EDID header. Only then, - * DDC is assumed to be available. This prevents drm_get_edid() and - * drm_edid_block_valid() from periodically dumping data and kernel - * errors into the logs and onto the terminal. - */ -static bool radeon_connector_needs_extended_probe(struct radeon_device *dev, - uint32_t supported_device, - int connector_type) -{ - /* Asus M2A-VM HDMI board sends data to i2c bus even, - * if HDMI add-on card is not plugged in or HDMI is disabled in - * BIOS. Valid DDC can only be assumed, if also a valid EDID header - * can be retrieved via i2c bus during DDC probe */ - if ((dev->pdev->device == 0x791e) && - (dev->pdev->subsystem_vendor == 0x1043) && - (dev->pdev->subsystem_device == 0x826d)) { - if ((connector_type == DRM_MODE_CONNECTOR_HDMIA) && - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return true; - } - /* ECS A740GM-M with ATI RADEON 2100 sends data to i2c bus - * for a DVI connector that is not implemented */ - if ((dev->pdev->device == 0x796e) && - (dev->pdev->subsystem_vendor == 0x1019) && - (dev->pdev->subsystem_device == 0x2615)) { - if ((connector_type == DRM_MODE_CONNECTOR_DVID) && - (supported_device == ATOM_DEVICE_DFP2_SUPPORT)) - return true; - } - - /* Default: no EDID header probe required for DDC probing */ - return false; -} - static void radeon_fixup_lvds_native_mode(struct drm_encoder *encoder, struct drm_connector *connector) { @@ -700,8 +661,7 @@ radeon_vga_detect(struct drm_connector *connector, bool force) ret = connector_status_disconnected; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe); + dret = radeon_ddc_probe(radeon_connector); if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); @@ -873,8 +833,7 @@ radeon_dvi_detect(struct drm_connector *connector, bool force) bool dret = false; if (radeon_connector->ddc_bus) - dret = radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe); + dret = radeon_ddc_probe(radeon_connector); if (dret) { if (radeon_connector->edid) { kfree(radeon_connector->edid); @@ -1292,8 +1251,7 @@ radeon_dp_detect(struct drm_connector *connector, bool force) if (radeon_dp_getdpcd(radeon_connector)) ret = connector_status_connected; } else { - if (radeon_ddc_probe(radeon_connector, - radeon_connector->requires_extended_probe)) + if (radeon_ddc_probe(radeon_connector)) ret = connector_status_connected; } } @@ -1448,9 +1406,6 @@ radeon_add_atom_connector(struct drm_device *dev, radeon_connector->shared_ddc = shared_ddc; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; - radeon_connector->requires_extended_probe = - radeon_connector_needs_extended_probe(rdev, supported_device, - connector_type); radeon_connector->router = *router; if (router->ddc_valid || router->cd_valid) { radeon_connector->router_bus = radeon_i2c_lookup(rdev, &router->i2c_info); @@ -1797,9 +1752,6 @@ radeon_add_legacy_connector(struct drm_device *dev, radeon_connector->devices = supported_device; radeon_connector->connector_object_id = connector_object_id; radeon_connector->hpd = *hpd; - radeon_connector->requires_extended_probe = - radeon_connector_needs_extended_probe(rdev, supported_device, - connector_type); switch (connector_type) { case DRM_MODE_CONNECTOR_VGA: drm_connector_init(dev, &radeon_connector->base, &radeon_vga_connector_funcs, connector_type); diff --git a/trunk/drivers/gpu/drm/radeon/radeon_device.c b/trunk/drivers/gpu/drm/radeon/radeon_device.c index 440e6ecccc40..7cfaa7e2f3b5 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_device.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_device.c @@ -704,9 +704,8 @@ int radeon_device_init(struct radeon_device *rdev, rdev->gpu_lockup = false; rdev->accel_working = false; - DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X 0x%04X:0x%04X).\n", - radeon_family_name[rdev->family], pdev->vendor, pdev->device, - pdev->subsystem_vendor, pdev->subsystem_device); + DRM_INFO("initializing kernel modesetting (%s 0x%04X:0x%04X).\n", + radeon_family_name[rdev->family], pdev->vendor, pdev->device); /* mutex initialization are all done here so we * can recall function without having locking issues */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_display.c b/trunk/drivers/gpu/drm/radeon/radeon_display.c index 1a858944e4f3..28f4655905bc 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_display.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_display.c @@ -751,17 +751,8 @@ static int radeon_ddc_dump(struct drm_connector *connector) if (!radeon_connector->ddc_bus) return -1; edid = drm_get_edid(connector, &radeon_connector->ddc_bus->adapter); - /* Log EDID retrieval status here. In particular with regard to - * connectors with requires_extended_probe flag set, that will prevent - * function radeon_dvi_detect() to fetch EDID on this connector, - * as long as there is no valid EDID header found */ if (edid) { - DRM_INFO("Radeon display connector %s: Found valid EDID", - drm_get_connector_name(connector)); kfree(edid); - } else { - DRM_INFO("Radeon display connector %s: No monitor connected or invalid EDID", - drm_get_connector_name(connector)); } return ret; } diff --git a/trunk/drivers/gpu/drm/radeon/radeon_drv.c b/trunk/drivers/gpu/drm/radeon/radeon_drv.c index e71d2ed7fa11..85f033f19a8a 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_drv.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_drv.c @@ -50,8 +50,8 @@ * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK, clock crystal query * 2.9.0 - r600 tiling (s3tc,rgtc) working, SET_PREDICATION packet 3 on r600 + eg, backend query - * 2.10.0 - fusion 2D tiling - * 2.11.0 - backend map, initial compute support for the CS checker + * 2.10.0 - fusion 2D tiling, initial compute support for the CS checker + * 2.11.0 - backend map */ #define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MINOR 11 diff --git a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c index 6c111c1fa3f9..781196db792f 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/trunk/drivers/gpu/drm/radeon/radeon_i2c.c @@ -32,17 +32,17 @@ * radeon_ddc_probe * */ -bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_extended_probe) +bool radeon_ddc_probe(struct radeon_connector *radeon_connector) { - u8 out = 0x0; - u8 buf[8]; + u8 out_buf[] = { 0x0, 0x0}; + u8 buf[2]; int ret; struct i2c_msg msgs[] = { { .addr = 0x50, .flags = 0, .len = 1, - .buf = &out, + .buf = out_buf, }, { .addr = 0x50, @@ -52,31 +52,15 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool requires_e } }; - /* Read 8 bytes from i2c for extended probe of EDID header */ - if (requires_extended_probe) - msgs[1].len = 8; - /* on hw with routers, select right port */ if (radeon_connector->router.ddc_valid) radeon_router_select_ddc_port(radeon_connector); ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2); - if (ret != 2) - /* Couldn't find an accessible DDC on this connector */ - return false; - if (requires_extended_probe) { - /* Probe also for valid EDID header - * EDID header starts with: - * 0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00. - * Only the first 6 bytes must be valid as - * drm_edid_block_valid() can fix the last 2 bytes */ - if (drm_edid_header_is_valid(buf) < 6) { - /* Couldn't find an accessible EDID on this - * connector */ - return false; - } - } - return true; + if (ret == 2) + return true; + + return false; } /* bit banging i2c */ diff --git a/trunk/drivers/gpu/drm/radeon/radeon_mode.h b/trunk/drivers/gpu/drm/radeon/radeon_mode.h index d09031c03e26..6df4e3cec0c2 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_mode.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_mode.h @@ -438,9 +438,6 @@ struct radeon_connector { struct radeon_i2c_chan *ddc_bus; /* some systems have an hdmi and vga port with a shared ddc line */ bool shared_ddc; - /* for some Radeon chip families we apply an additional EDID header - check as part of the DDC probe */ - bool requires_extended_probe; bool use_digital; /* we need to mind the EDID between detect and get modes due to analog/digital/tvencoder */ @@ -517,8 +514,7 @@ extern void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c, u8 val); extern void radeon_router_select_ddc_port(struct radeon_connector *radeon_connector); extern void radeon_router_select_cd_port(struct radeon_connector *radeon_connector); -extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector, - bool requires_extended_probe); +extern bool radeon_ddc_probe(struct radeon_connector *radeon_connector); extern int radeon_ddc_get_modes(struct radeon_connector *radeon_connector); extern struct drm_encoder *radeon_best_encoder(struct drm_connector *connector); diff --git a/trunk/drivers/ide/cy82c693.c b/trunk/drivers/ide/cy82c693.c index 67cbcfa35122..3be60da52123 100644 --- a/trunk/drivers/ide/cy82c693.c +++ b/trunk/drivers/ide/cy82c693.c @@ -141,8 +141,6 @@ static void cy82c693_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) pci_write_config_byte(dev, CY82_IDE_SLAVE_IOW, time_16); pci_write_config_byte(dev, CY82_IDE_SLAVE_8BIT, time_8); } - if (hwif->index > 0) - pci_dev_put(dev); } static void __devinit init_iops_cy82c693(ide_hwif_t *hwif) diff --git a/trunk/drivers/ide/ide_platform.c b/trunk/drivers/ide/ide_platform.c index 962693b10a1c..542603b394e4 100644 --- a/trunk/drivers/ide/ide_platform.c +++ b/trunk/drivers/ide/ide_platform.c @@ -19,7 +19,6 @@ #include #include #include -#include #include static void __devinit plat_ide_setup_ports(struct ide_hw *hw, @@ -96,10 +95,7 @@ static int __devinit plat_ide_probe(struct platform_device *pdev) plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start); hw.dev = &pdev->dev; - d.irq_flags = res_irq->flags & IRQF_TRIGGER_MASK; - if (res_irq->flags & IORESOURCE_IRQ_SHAREABLE) - d.irq_flags |= IRQF_SHARED; - + d.irq_flags = res_irq->flags; if (mmio) d.host_flags |= IDE_HFLAG_MMIO; diff --git a/trunk/drivers/input/keyboard/gpio_keys.c b/trunk/drivers/input/keyboard/gpio_keys.c index 67df91af8424..ce281d152275 100644 --- a/trunk/drivers/input/keyboard/gpio_keys.c +++ b/trunk/drivers/input/keyboard/gpio_keys.c @@ -483,7 +483,7 @@ static int gpio_keys_get_devtree_pdata(struct device *dev, buttons = kzalloc(pdata->nbuttons * (sizeof *buttons), GFP_KERNEL); if (!buttons) - return -ENOMEM; + return -ENODEV; pp = NULL; i = 0; diff --git a/trunk/drivers/input/keyboard/lm8323.c b/trunk/drivers/input/keyboard/lm8323.c index 756348a7f93a..ab0acaf7fe8f 100644 --- a/trunk/drivers/input/keyboard/lm8323.c +++ b/trunk/drivers/input/keyboard/lm8323.c @@ -754,11 +754,8 @@ static int __devinit lm8323_probe(struct i2c_client *client, device_remove_file(&client->dev, &dev_attr_disable_kp); fail2: while (--pwm >= 0) - if (lm->pwm[pwm].enabled) { - device_remove_file(lm->pwm[pwm].cdev.dev, - &dev_attr_time); + if (lm->pwm[pwm].enabled) led_classdev_unregister(&lm->pwm[pwm].cdev); - } fail1: input_free_device(idev); kfree(lm); @@ -778,10 +775,8 @@ static int __devexit lm8323_remove(struct i2c_client *client) device_remove_file(&lm->client->dev, &dev_attr_disable_kp); for (i = 0; i < 3; i++) - if (lm->pwm[i].enabled) { - device_remove_file(lm->pwm[i].cdev.dev, &dev_attr_time); + if (lm->pwm[i].enabled) led_classdev_unregister(&lm->pwm[i].cdev); - } kfree(lm); diff --git a/trunk/drivers/input/keyboard/tegra-kbc.c b/trunk/drivers/input/keyboard/tegra-kbc.c index f270447ba951..da3828fc2c09 100644 --- a/trunk/drivers/input/keyboard/tegra-kbc.c +++ b/trunk/drivers/input/keyboard/tegra-kbc.c @@ -19,7 +19,6 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include #include #include #include @@ -38,7 +37,7 @@ #define KBC_ROW_SCAN_DLY 5 /* KBC uses a 32KHz clock so a cycle = 1/32Khz */ -#define KBC_CYCLE_MS 32 +#define KBC_CYCLE_USEC 32 /* KBC Registers */ @@ -648,7 +647,7 @@ static int __devinit tegra_kbc_probe(struct platform_device *pdev) debounce_cnt = min(pdata->debounce_cnt, KBC_MAX_DEBOUNCE_CNT); scan_time_rows = (KBC_ROW_SCAN_TIME + debounce_cnt) * num_rows; kbc->repoll_dly = KBC_ROW_SCAN_DLY + scan_time_rows + pdata->repeat_cnt; - kbc->repoll_dly = DIV_ROUND_UP(kbc->repoll_dly, KBC_CYCLE_MS); + kbc->repoll_dly = ((kbc->repoll_dly * KBC_CYCLE_USEC) + 999) / 1000; input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; diff --git a/trunk/drivers/input/misc/kxtj9.c b/trunk/drivers/input/misc/kxtj9.c index 783597a9a64a..c456f63b6bae 100644 --- a/trunk/drivers/input/misc/kxtj9.c +++ b/trunk/drivers/input/misc/kxtj9.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/trunk/drivers/input/misc/mma8450.c b/trunk/drivers/input/misc/mma8450.c index 6c76cf792991..20f8f9284f02 100644 --- a/trunk/drivers/input/misc/mma8450.c +++ b/trunk/drivers/input/misc/mma8450.c @@ -24,7 +24,6 @@ #include #include #include -#include #define MMA8450_DRV_NAME "mma8450" @@ -230,17 +229,10 @@ static const struct i2c_device_id mma8450_id[] = { }; MODULE_DEVICE_TABLE(i2c, mma8450_id); -static const struct of_device_id mma8450_dt_ids[] = { - { .compatible = "fsl,mma8450", }, - { /* sentinel */ } -}; -MODULE_DEVICE_TABLE(i2c, mma8450_dt_ids); - static struct i2c_driver mma8450_driver = { .driver = { .name = MMA8450_DRV_NAME, .owner = THIS_MODULE, - .of_match_table = mma8450_dt_ids, }, .probe = mma8450_probe, .remove = __devexit_p(mma8450_remove), diff --git a/trunk/drivers/input/mouse/hgpk.c b/trunk/drivers/input/mouse/hgpk.c index 4d17d9f3320b..95577c15ae56 100644 --- a/trunk/drivers/input/mouse/hgpk.c +++ b/trunk/drivers/input/mouse/hgpk.c @@ -32,7 +32,6 @@ #define DEBUG #include #include -#include #include #include #include diff --git a/trunk/drivers/input/serio/xilinx_ps2.c b/trunk/drivers/input/serio/xilinx_ps2.c index d64c5a43aaad..80baa53da5b1 100644 --- a/trunk/drivers/input/serio/xilinx_ps2.c +++ b/trunk/drivers/input/serio/xilinx_ps2.c @@ -23,7 +23,7 @@ #include #include #include -#include + #include #include diff --git a/trunk/drivers/input/touchscreen/ad7879.c b/trunk/drivers/input/touchscreen/ad7879.c index 131f9d1c921b..bc3b5187f3a3 100644 --- a/trunk/drivers/input/touchscreen/ad7879.c +++ b/trunk/drivers/input/touchscreen/ad7879.c @@ -249,14 +249,12 @@ static void __ad7879_enable(struct ad7879 *ts) static void __ad7879_disable(struct ad7879 *ts) { - u16 reg = (ts->cmd_crtl2 & ~AD7879_PM(-1)) | - AD7879_PM(AD7879_PM_SHUTDOWN); disable_irq(ts->irq); if (del_timer_sync(&ts->timer)) ad7879_ts_event_release(ts); - ad7879_write(ts, AD7879_REG_CTRL2, reg); + ad7879_write(ts, AD7879_REG_CTRL2, AD7879_PM(AD7879_PM_SHUTDOWN)); } diff --git a/trunk/drivers/md/Kconfig b/trunk/drivers/md/Kconfig index f75a66e7d312..8420129fc5ee 100644 --- a/trunk/drivers/md/Kconfig +++ b/trunk/drivers/md/Kconfig @@ -241,13 +241,12 @@ config DM_MIRROR needed for live data migration tools such as 'pvmove'. config DM_RAID - tristate "RAID 1/4/5/6 target (EXPERIMENTAL)" + tristate "RAID 4/5/6 target (EXPERIMENTAL)" depends on BLK_DEV_DM && EXPERIMENTAL - select MD_RAID1 select MD_RAID456 select BLK_DEV_MD ---help--- - A dm target that supports RAID1, RAID4, RAID5 and RAID6 mappings + A dm target that supports RAID4, RAID5 and RAID6 mappings A RAID-5 set of N drives with a capacity of C MB per drive provides the capacity of C * (N - 1) MB, and protects against a failure diff --git a/trunk/drivers/md/dm-crypt.c b/trunk/drivers/md/dm-crypt.c index 49da55c1528a..bae6c4e23d3f 100644 --- a/trunk/drivers/md/dm-crypt.c +++ b/trunk/drivers/md/dm-crypt.c @@ -30,6 +30,7 @@ #include #define DM_MSG_PREFIX "crypt" +#define MESG_STR(x) x, sizeof(x) /* * context holding the current state of a multi-part conversion @@ -238,7 +239,7 @@ static int crypt_iv_plain_gen(struct crypt_config *cc, u8 *iv, struct dm_crypt_request *dmreq) { memset(iv, 0, cc->iv_size); - *(__le32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff); + *(u32 *)iv = cpu_to_le32(dmreq->iv_sector & 0xffffffff); return 0; } @@ -247,7 +248,7 @@ static int crypt_iv_plain64_gen(struct crypt_config *cc, u8 *iv, struct dm_crypt_request *dmreq) { memset(iv, 0, cc->iv_size); - *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector); + *(u64 *)iv = cpu_to_le64(dmreq->iv_sector); return 0; } @@ -414,7 +415,7 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, struct crypto_cipher *essiv_tfm = this_crypt_config(cc)->iv_private; memset(iv, 0, cc->iv_size); - *(__le64 *)iv = cpu_to_le64(dmreq->iv_sector); + *(u64 *)iv = cpu_to_le64(dmreq->iv_sector); crypto_cipher_encrypt_one(essiv_tfm, iv, iv); return 0; @@ -1574,17 +1575,11 @@ static int crypt_ctr_cipher(struct dm_target *ti, static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) { struct crypt_config *cc; - unsigned int key_size, opt_params; + unsigned int key_size; unsigned long long tmpll; int ret; - struct dm_arg_set as; - const char *opt_string; - - static struct dm_arg _args[] = { - {0, 1, "Invalid number of feature args"}, - }; - if (argc < 5) { + if (argc != 5) { ti->error = "Not enough arguments"; return -EINVAL; } @@ -1653,30 +1648,6 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) } cc->start = tmpll; - argv += 5; - argc -= 5; - - /* Optional parameters */ - if (argc) { - as.argc = argc; - as.argv = argv; - - ret = dm_read_arg_group(_args, &as, &opt_params, &ti->error); - if (ret) - goto bad; - - opt_string = dm_shift_arg(&as); - - if (opt_params == 1 && opt_string && - !strcasecmp(opt_string, "allow_discards")) - ti->num_discard_requests = 1; - else if (opt_params) { - ret = -EINVAL; - ti->error = "Invalid feature arguments"; - goto bad; - } - } - ret = -ENOMEM; cc->io_queue = alloc_workqueue("kcryptd_io", WQ_NON_REENTRANT| @@ -1711,16 +1682,9 @@ static int crypt_map(struct dm_target *ti, struct bio *bio, struct dm_crypt_io *io; struct crypt_config *cc; - /* - * If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues. - * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight - * - for REQ_DISCARD caller must use flush if IO ordering matters - */ - if (unlikely(bio->bi_rw & (REQ_FLUSH | REQ_DISCARD))) { + if (bio->bi_rw & REQ_FLUSH) { cc = ti->private; bio->bi_bdev = cc->dev->bdev; - if (bio_sectors(bio)) - bio->bi_sector = cc->start + dm_target_offset(ti, bio->bi_sector); return DM_MAPIO_REMAPPED; } @@ -1763,10 +1727,6 @@ static int crypt_status(struct dm_target *ti, status_type_t type, DMEMIT(" %llu %s %llu", (unsigned long long)cc->iv_offset, cc->dev->name, (unsigned long long)cc->start); - - if (ti->num_discard_requests) - DMEMIT(" 1 allow_discards"); - break; } return 0; @@ -1810,12 +1770,12 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) if (argc < 2) goto error; - if (!strcasecmp(argv[0], "key")) { + if (!strnicmp(argv[0], MESG_STR("key"))) { if (!test_bit(DM_CRYPT_SUSPENDED, &cc->flags)) { DMWARN("not suspended during key manipulation."); return -EINVAL; } - if (argc == 3 && !strcasecmp(argv[1], "set")) { + if (argc == 3 && !strnicmp(argv[1], MESG_STR("set"))) { ret = crypt_set_key(cc, argv[2]); if (ret) return ret; @@ -1823,7 +1783,7 @@ static int crypt_message(struct dm_target *ti, unsigned argc, char **argv) ret = cc->iv_gen_ops->init(cc); return ret; } - if (argc == 2 && !strcasecmp(argv[1], "wipe")) { + if (argc == 2 && !strnicmp(argv[1], MESG_STR("wipe"))) { if (cc->iv_gen_ops && cc->iv_gen_ops->wipe) { ret = cc->iv_gen_ops->wipe(cc); if (ret) @@ -1863,7 +1823,7 @@ static int crypt_iterate_devices(struct dm_target *ti, static struct target_type crypt_target = { .name = "crypt", - .version = {1, 11, 0}, + .version = {1, 10, 0}, .module = THIS_MODULE, .ctr = crypt_ctr, .dtr = crypt_dtr, diff --git a/trunk/drivers/md/dm-flakey.c b/trunk/drivers/md/dm-flakey.c index 89f73ca22cfa..ea790623c30b 100644 --- a/trunk/drivers/md/dm-flakey.c +++ b/trunk/drivers/md/dm-flakey.c @@ -1,6 +1,6 @@ /* * Copyright (C) 2003 Sistina Software (UK) Limited. - * Copyright (C) 2004, 2010-2011 Red Hat, Inc. All rights reserved. + * Copyright (C) 2004, 2010 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */ @@ -15,9 +15,6 @@ #define DM_MSG_PREFIX "flakey" -#define all_corrupt_bio_flags_match(bio, fc) \ - (((bio)->bi_rw & (fc)->corrupt_bio_flags) == (fc)->corrupt_bio_flags) - /* * Flakey: Used for testing only, simulates intermittent, * catastrophic device failure. @@ -28,189 +25,60 @@ struct flakey_c { sector_t start; unsigned up_interval; unsigned down_interval; - unsigned long flags; - unsigned corrupt_bio_byte; - unsigned corrupt_bio_rw; - unsigned corrupt_bio_value; - unsigned corrupt_bio_flags; -}; - -enum feature_flag_bits { - DROP_WRITES }; -static int parse_features(struct dm_arg_set *as, struct flakey_c *fc, - struct dm_target *ti) -{ - int r; - unsigned argc; - const char *arg_name; - - static struct dm_arg _args[] = { - {0, 6, "Invalid number of feature args"}, - {1, UINT_MAX, "Invalid corrupt bio byte"}, - {0, 255, "Invalid corrupt value to write into bio byte (0-255)"}, - {0, UINT_MAX, "Invalid corrupt bio flags mask"}, - }; - - /* No feature arguments supplied. */ - if (!as->argc) - return 0; - - r = dm_read_arg_group(_args, as, &argc, &ti->error); - if (r) - return r; - - while (argc) { - arg_name = dm_shift_arg(as); - argc--; - - /* - * drop_writes - */ - if (!strcasecmp(arg_name, "drop_writes")) { - if (test_and_set_bit(DROP_WRITES, &fc->flags)) { - ti->error = "Feature drop_writes duplicated"; - return -EINVAL; - } - - continue; - } - - /* - * corrupt_bio_byte - */ - if (!strcasecmp(arg_name, "corrupt_bio_byte")) { - if (!argc) - ti->error = "Feature corrupt_bio_byte requires parameters"; - - r = dm_read_arg(_args + 1, as, &fc->corrupt_bio_byte, &ti->error); - if (r) - return r; - argc--; - - /* - * Direction r or w? - */ - arg_name = dm_shift_arg(as); - if (!strcasecmp(arg_name, "w")) - fc->corrupt_bio_rw = WRITE; - else if (!strcasecmp(arg_name, "r")) - fc->corrupt_bio_rw = READ; - else { - ti->error = "Invalid corrupt bio direction (r or w)"; - return -EINVAL; - } - argc--; - - /* - * Value of byte (0-255) to write in place of correct one. - */ - r = dm_read_arg(_args + 2, as, &fc->corrupt_bio_value, &ti->error); - if (r) - return r; - argc--; - - /* - * Only corrupt bios with these flags set. - */ - r = dm_read_arg(_args + 3, as, &fc->corrupt_bio_flags, &ti->error); - if (r) - return r; - argc--; - - continue; - } - - ti->error = "Unrecognised flakey feature requested"; - return -EINVAL; - } - - if (test_bit(DROP_WRITES, &fc->flags) && (fc->corrupt_bio_rw == WRITE)) { - ti->error = "drop_writes is incompatible with corrupt_bio_byte with the WRITE flag set"; - return -EINVAL; - } - - return 0; -} - /* - * Construct a flakey mapping: - * [<#feature args> []*] - * - * Feature args: - * [drop_writes] - * [corrupt_bio_byte ] - * - * Nth_byte starts from 1 for the first byte. - * Direction is r for READ or w for WRITE. - * bio_flags is ignored if 0. + * Construct a flakey mapping: */ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv) { - static struct dm_arg _args[] = { - {0, UINT_MAX, "Invalid up interval"}, - {0, UINT_MAX, "Invalid down interval"}, - }; - - int r; struct flakey_c *fc; - unsigned long long tmpll; - struct dm_arg_set as; - const char *devname; + unsigned long long tmp; - as.argc = argc; - as.argv = argv; - - if (argc < 4) { - ti->error = "Invalid argument count"; + if (argc != 4) { + ti->error = "dm-flakey: Invalid argument count"; return -EINVAL; } - fc = kzalloc(sizeof(*fc), GFP_KERNEL); + fc = kmalloc(sizeof(*fc), GFP_KERNEL); if (!fc) { - ti->error = "Cannot allocate linear context"; + ti->error = "dm-flakey: Cannot allocate linear context"; return -ENOMEM; } fc->start_time = jiffies; - devname = dm_shift_arg(&as); - - if (sscanf(dm_shift_arg(&as), "%llu", &tmpll) != 1) { - ti->error = "Invalid device sector"; + if (sscanf(argv[1], "%llu", &tmp) != 1) { + ti->error = "dm-flakey: Invalid device sector"; goto bad; } - fc->start = tmpll; + fc->start = tmp; - r = dm_read_arg(_args, &as, &fc->up_interval, &ti->error); - if (r) + if (sscanf(argv[2], "%u", &fc->up_interval) != 1) { + ti->error = "dm-flakey: Invalid up interval"; goto bad; + } - r = dm_read_arg(_args, &as, &fc->down_interval, &ti->error); - if (r) + if (sscanf(argv[3], "%u", &fc->down_interval) != 1) { + ti->error = "dm-flakey: Invalid down interval"; goto bad; + } if (!(fc->up_interval + fc->down_interval)) { - ti->error = "Total (up + down) interval is zero"; + ti->error = "dm-flakey: Total (up + down) interval is zero"; goto bad; } if (fc->up_interval + fc->down_interval < fc->up_interval) { - ti->error = "Interval overflow"; + ti->error = "dm-flakey: Interval overflow"; goto bad; } - r = parse_features(&as, fc, ti); - if (r) - goto bad; - - if (dm_get_device(ti, devname, dm_table_get_mode(ti->table), &fc->dev)) { - ti->error = "Device lookup failed"; + if (dm_get_device(ti, argv[0], dm_table_get_mode(ti->table), &fc->dev)) { + ti->error = "dm-flakey: Device lookup failed"; goto bad; } ti->num_flush_requests = 1; - ti->num_discard_requests = 1; ti->private = fc; return 0; @@ -231,7 +99,7 @@ static sector_t flakey_map_sector(struct dm_target *ti, sector_t bi_sector) { struct flakey_c *fc = ti->private; - return fc->start + dm_target_offset(ti, bi_sector); + return fc->start + (bi_sector - ti->begin); } static void flakey_map_bio(struct dm_target *ti, struct bio *bio) @@ -243,25 +111,6 @@ static void flakey_map_bio(struct dm_target *ti, struct bio *bio) bio->bi_sector = flakey_map_sector(ti, bio->bi_sector); } -static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc) -{ - unsigned bio_bytes = bio_cur_bytes(bio); - char *data = bio_data(bio); - - /* - * Overwrite the Nth byte of the data returned. - */ - if (data && bio_bytes >= fc->corrupt_bio_byte) { - data[fc->corrupt_bio_byte - 1] = fc->corrupt_bio_value; - - DMDEBUG("Corrupting data bio=%p by writing %u to byte %u " - "(rw=%c bi_rw=%lu bi_sector=%llu cur_bytes=%u)\n", - bio, fc->corrupt_bio_value, fc->corrupt_bio_byte, - (bio_data_dir(bio) == WRITE) ? 'w' : 'r', - bio->bi_rw, (unsigned long long)bio->bi_sector, bio_bytes); - } -} - static int flakey_map(struct dm_target *ti, struct bio *bio, union map_info *map_context) { @@ -270,71 +119,18 @@ static int flakey_map(struct dm_target *ti, struct bio *bio, /* Are we alive ? */ elapsed = (jiffies - fc->start_time) / HZ; - if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) { - /* - * Flag this bio as submitted while down. - */ - map_context->ll = 1; - - /* - * Map reads as normal. - */ - if (bio_data_dir(bio) == READ) - goto map_bio; - - /* - * Drop writes? - */ - if (test_bit(DROP_WRITES, &fc->flags)) { - bio_endio(bio, 0); - return DM_MAPIO_SUBMITTED; - } - - /* - * Corrupt matching writes. - */ - if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == WRITE)) { - if (all_corrupt_bio_flags_match(bio, fc)) - corrupt_bio_data(bio, fc); - goto map_bio; - } - - /* - * By default, error all I/O. - */ + if (elapsed % (fc->up_interval + fc->down_interval) >= fc->up_interval) return -EIO; - } -map_bio: flakey_map_bio(ti, bio); return DM_MAPIO_REMAPPED; } -static int flakey_end_io(struct dm_target *ti, struct bio *bio, - int error, union map_info *map_context) -{ - struct flakey_c *fc = ti->private; - unsigned bio_submitted_while_down = map_context->ll; - - /* - * Corrupt successful READs while in down state. - * If flags were specified, only corrupt those that match. - */ - if (!error && bio_submitted_while_down && - (bio_data_dir(bio) == READ) && (fc->corrupt_bio_rw == READ) && - all_corrupt_bio_flags_match(bio, fc)) - corrupt_bio_data(bio, fc); - - return error; -} - static int flakey_status(struct dm_target *ti, status_type_t type, char *result, unsigned int maxlen) { - unsigned sz = 0; struct flakey_c *fc = ti->private; - unsigned drop_writes; switch (type) { case STATUSTYPE_INFO: @@ -342,22 +138,9 @@ static int flakey_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: - DMEMIT("%s %llu %u %u ", fc->dev->name, - (unsigned long long)fc->start, fc->up_interval, - fc->down_interval); - - drop_writes = test_bit(DROP_WRITES, &fc->flags); - DMEMIT("%u ", drop_writes + (fc->corrupt_bio_byte > 0) * 5); - - if (drop_writes) - DMEMIT("drop_writes "); - - if (fc->corrupt_bio_byte) - DMEMIT("corrupt_bio_byte %u %c %u %u ", - fc->corrupt_bio_byte, - (fc->corrupt_bio_rw == WRITE) ? 'w' : 'r', - fc->corrupt_bio_value, fc->corrupt_bio_flags); - + snprintf(result, maxlen, "%s %llu %u %u", fc->dev->name, + (unsigned long long)fc->start, fc->up_interval, + fc->down_interval); break; } return 0; @@ -394,12 +177,11 @@ static int flakey_iterate_devices(struct dm_target *ti, iterate_devices_callout_ static struct target_type flakey_target = { .name = "flakey", - .version = {1, 2, 0}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = flakey_ctr, .dtr = flakey_dtr, .map = flakey_map, - .end_io = flakey_end_io, .status = flakey_status, .ioctl = flakey_ioctl, .merge = flakey_merge, diff --git a/trunk/drivers/md/dm-io.c b/trunk/drivers/md/dm-io.c index ad2eba40e319..2067288f61f9 100644 --- a/trunk/drivers/md/dm-io.c +++ b/trunk/drivers/md/dm-io.c @@ -38,8 +38,6 @@ struct io { struct dm_io_client *client; io_notify_fn callback; void *context; - void *vma_invalidate_address; - unsigned long vma_invalidate_size; } __attribute__((aligned(DM_IO_MAX_REGIONS))); static struct kmem_cache *_dm_io_cache; @@ -118,10 +116,6 @@ static void dec_count(struct io *io, unsigned int region, int error) set_bit(region, &io->error_bits); if (atomic_dec_and_test(&io->count)) { - if (io->vma_invalidate_size) - invalidate_kernel_vmap_range(io->vma_invalidate_address, - io->vma_invalidate_size); - if (io->sleeper) wake_up_process(io->sleeper); @@ -165,9 +159,6 @@ struct dpages { unsigned context_u; void *context_ptr; - - void *vma_invalidate_address; - unsigned long vma_invalidate_size; }; /* @@ -386,9 +377,6 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions, io->sleeper = current; io->client = client; - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - dispatch_io(rw, num_regions, where, dp, io, 1); while (1) { @@ -427,21 +415,13 @@ static int async_io(struct dm_io_client *client, unsigned int num_regions, io->callback = fn; io->context = context; - io->vma_invalidate_address = dp->vma_invalidate_address; - io->vma_invalidate_size = dp->vma_invalidate_size; - dispatch_io(rw, num_regions, where, dp, io, 0); return 0; } -static int dp_init(struct dm_io_request *io_req, struct dpages *dp, - unsigned long size) +static int dp_init(struct dm_io_request *io_req, struct dpages *dp) { /* Set up dpages based on memory type */ - - dp->vma_invalidate_address = NULL; - dp->vma_invalidate_size = 0; - switch (io_req->mem.type) { case DM_IO_PAGE_LIST: list_dp_init(dp, io_req->mem.ptr.pl, io_req->mem.offset); @@ -452,11 +432,6 @@ static int dp_init(struct dm_io_request *io_req, struct dpages *dp, break; case DM_IO_VMA: - flush_kernel_vmap_range(io_req->mem.ptr.vma, size); - if ((io_req->bi_rw & RW_MASK) == READ) { - dp->vma_invalidate_address = io_req->mem.ptr.vma; - dp->vma_invalidate_size = size; - } vm_dp_init(dp, io_req->mem.ptr.vma); break; @@ -485,7 +460,7 @@ int dm_io(struct dm_io_request *io_req, unsigned num_regions, int r; struct dpages dp; - r = dp_init(io_req, &dp, (unsigned long)where->count << SECTOR_SHIFT); + r = dp_init(io_req, &dp); if (r) return r; diff --git a/trunk/drivers/md/dm-ioctl.c b/trunk/drivers/md/dm-ioctl.c index 2e9a3ca37bdd..4cacdad2270a 100644 --- a/trunk/drivers/md/dm-ioctl.c +++ b/trunk/drivers/md/dm-ioctl.c @@ -128,24 +128,6 @@ static struct hash_cell *__get_uuid_cell(const char *str) return NULL; } -static struct hash_cell *__get_dev_cell(uint64_t dev) -{ - struct mapped_device *md; - struct hash_cell *hc; - - md = dm_get_md(huge_decode_dev(dev)); - if (!md) - return NULL; - - hc = dm_get_mdptr(md); - if (!hc) { - dm_put(md); - return NULL; - } - - return hc; -} - /*----------------------------------------------------------------- * Inserting, removing and renaming a device. *---------------------------------------------------------------*/ @@ -736,45 +718,25 @@ static int dev_create(struct dm_ioctl *param, size_t param_size) */ static struct hash_cell *__find_device_hash_cell(struct dm_ioctl *param) { - struct hash_cell *hc = NULL; + struct mapped_device *md; + void *mdptr = NULL; - if (*param->uuid) { - if (*param->name || param->dev) - return NULL; + if (*param->uuid) + return __get_uuid_cell(param->uuid); - hc = __get_uuid_cell(param->uuid); - if (!hc) - return NULL; - } else if (*param->name) { - if (param->dev) - return NULL; + if (*param->name) + return __get_name_cell(param->name); - hc = __get_name_cell(param->name); - if (!hc) - return NULL; - } else if (param->dev) { - hc = __get_dev_cell(param->dev); - if (!hc) - return NULL; - } else - return NULL; - - /* - * Sneakily write in both the name and the uuid - * while we have the cell. - */ - strlcpy(param->name, hc->name, sizeof(param->name)); - if (hc->uuid) - strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); - else - param->uuid[0] = '\0'; + md = dm_get_md(huge_decode_dev(param->dev)); + if (!md) + goto out; - if (hc->new_map) - param->flags |= DM_INACTIVE_PRESENT_FLAG; - else - param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + mdptr = dm_get_mdptr(md); + if (!mdptr) + dm_put(md); - return hc; +out: + return mdptr; } static struct mapped_device *find_device(struct dm_ioctl *param) @@ -784,8 +746,24 @@ static struct mapped_device *find_device(struct dm_ioctl *param) down_read(&_hash_lock); hc = __find_device_hash_cell(param); - if (hc) + if (hc) { md = hc->md; + + /* + * Sneakily write in both the name and the uuid + * while we have the cell. + */ + strlcpy(param->name, hc->name, sizeof(param->name)); + if (hc->uuid) + strlcpy(param->uuid, hc->uuid, sizeof(param->uuid)); + else + param->uuid[0] = '\0'; + + if (hc->new_map) + param->flags |= DM_INACTIVE_PRESENT_FLAG; + else + param->flags &= ~DM_INACTIVE_PRESENT_FLAG; + } up_read(&_hash_lock); return md; @@ -1424,11 +1402,6 @@ static int target_message(struct dm_ioctl *param, size_t param_size) goto out; } - if (!argc) { - DMWARN("Empty message received."); - goto out; - } - table = dm_get_live_table(md); if (!table) goto out_argv; diff --git a/trunk/drivers/md/dm-kcopyd.c b/trunk/drivers/md/dm-kcopyd.c index f82147029636..320401dec104 100644 --- a/trunk/drivers/md/dm-kcopyd.c +++ b/trunk/drivers/md/dm-kcopyd.c @@ -224,6 +224,8 @@ struct kcopyd_job { unsigned int num_dests; struct dm_io_region dests[DM_KCOPYD_MAX_REGIONS]; + sector_t offset; + unsigned int nr_pages; struct page_list *pages; /* @@ -378,7 +380,7 @@ static int run_io_job(struct kcopyd_job *job) .bi_rw = job->rw, .mem.type = DM_IO_PAGE_LIST, .mem.ptr.pl = job->pages, - .mem.offset = 0, + .mem.offset = job->offset, .notify.fn = complete_io, .notify.context = job, .client = job->kc->io_client, @@ -395,9 +397,10 @@ static int run_io_job(struct kcopyd_job *job) static int run_pages_job(struct kcopyd_job *job) { int r; - unsigned nr_pages = dm_div_up(job->dests[0].count, PAGE_SIZE >> 9); - r = kcopyd_get_pages(job->kc, nr_pages, &job->pages); + job->nr_pages = dm_div_up(job->dests[0].count + job->offset, + PAGE_SIZE >> 9); + r = kcopyd_get_pages(job->kc, job->nr_pages, &job->pages); if (!r) { /* this job is ready for io */ push(&job->kc->io_jobs, job); @@ -599,6 +602,8 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, job->num_dests = num_dests; memcpy(&job->dests, dests, sizeof(*dests) * num_dests); + job->offset = 0; + job->nr_pages = 0; job->pages = NULL; job->fn = fn; @@ -617,37 +622,6 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, } EXPORT_SYMBOL(dm_kcopyd_copy); -void *dm_kcopyd_prepare_callback(struct dm_kcopyd_client *kc, - dm_kcopyd_notify_fn fn, void *context) -{ - struct kcopyd_job *job; - - job = mempool_alloc(kc->job_pool, GFP_NOIO); - - memset(job, 0, sizeof(struct kcopyd_job)); - job->kc = kc; - job->fn = fn; - job->context = context; - - atomic_inc(&kc->nr_jobs); - - return job; -} -EXPORT_SYMBOL(dm_kcopyd_prepare_callback); - -void dm_kcopyd_do_callback(void *j, int read_err, unsigned long write_err) -{ - struct kcopyd_job *job = j; - struct dm_kcopyd_client *kc = job->kc; - - job->read_err = read_err; - job->write_err = write_err; - - push(&kc->complete_jobs, job); - wake(kc); -} -EXPORT_SYMBOL(dm_kcopyd_do_callback); - /* * Cancels a kcopyd job, eg. someone might be deactivating a * mirror. diff --git a/trunk/drivers/md/dm-log-userspace-base.c b/trunk/drivers/md/dm-log-userspace-base.c index 1021c8986011..aa2e0c374ab3 100644 --- a/trunk/drivers/md/dm-log-userspace-base.c +++ b/trunk/drivers/md/dm-log-userspace-base.c @@ -394,7 +394,8 @@ static int flush_by_group(struct log_c *lc, struct list_head *flush_list) group[count] = fe->region; count++; - list_move(&fe->list, &tmp_list); + list_del(&fe->list); + list_add(&fe->list, &tmp_list); type = fe->type; if (count >= MAX_FLUSH_GROUP_COUNT) diff --git a/trunk/drivers/md/dm-log.c b/trunk/drivers/md/dm-log.c index 3b52bb72bd1f..948e3f4925bf 100644 --- a/trunk/drivers/md/dm-log.c +++ b/trunk/drivers/md/dm-log.c @@ -197,21 +197,15 @@ EXPORT_SYMBOL(dm_dirty_log_destroy); #define MIRROR_DISK_VERSION 2 #define LOG_OFFSET 2 -struct log_header_disk { - __le32 magic; +struct log_header { + uint32_t magic; /* * Simple, incrementing version. no backward * compatibility. */ - __le32 version; - __le64 nr_regions; -} __packed; - -struct log_header_core { - uint32_t magic; uint32_t version; - uint64_t nr_regions; + sector_t nr_regions; }; struct log_c { @@ -245,10 +239,10 @@ struct log_c { int log_dev_failed; int log_dev_flush_failed; struct dm_dev *log_dev; - struct log_header_core header; + struct log_header header; struct dm_io_region header_location; - struct log_header_disk *disk_header; + struct log_header *disk_header; }; /* @@ -257,34 +251,34 @@ struct log_c { */ static inline int log_test_bit(uint32_t *bs, unsigned bit) { - return test_bit_le(bit, bs) ? 1 : 0; + return test_bit_le(bit, (unsigned long *) bs) ? 1 : 0; } static inline void log_set_bit(struct log_c *l, uint32_t *bs, unsigned bit) { - __set_bit_le(bit, bs); + __test_and_set_bit_le(bit, (unsigned long *) bs); l->touched_cleaned = 1; } static inline void log_clear_bit(struct log_c *l, uint32_t *bs, unsigned bit) { - __clear_bit_le(bit, bs); + __test_and_clear_bit_le(bit, (unsigned long *) bs); l->touched_dirtied = 1; } /*---------------------------------------------------------------- * Header IO *--------------------------------------------------------------*/ -static void header_to_disk(struct log_header_core *core, struct log_header_disk *disk) +static void header_to_disk(struct log_header *core, struct log_header *disk) { disk->magic = cpu_to_le32(core->magic); disk->version = cpu_to_le32(core->version); disk->nr_regions = cpu_to_le64(core->nr_regions); } -static void header_from_disk(struct log_header_core *core, struct log_header_disk *disk) +static void header_from_disk(struct log_header *core, struct log_header *disk) { core->magic = le32_to_cpu(disk->magic); core->version = le32_to_cpu(disk->version); @@ -492,7 +486,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, memset(lc->sync_bits, (sync == NOSYNC) ? -1 : 0, bitset_size); lc->sync_count = (sync == NOSYNC) ? region_count : 0; - lc->recovering_bits = vzalloc(bitset_size); + lc->recovering_bits = vmalloc(bitset_size); if (!lc->recovering_bits) { DMWARN("couldn't allocate sync bitset"); vfree(lc->sync_bits); @@ -504,6 +498,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti, kfree(lc); return -ENOMEM; } + memset(lc->recovering_bits, 0, bitset_size); lc->sync_search = 0; log->context = lc; @@ -744,7 +739,8 @@ static int core_get_resync_work(struct dm_dirty_log *log, region_t *region) return 0; do { - *region = find_next_zero_bit_le(lc->sync_bits, + *region = find_next_zero_bit_le( + (unsigned long *) lc->sync_bits, lc->region_count, lc->sync_search); lc->sync_search = *region + 1; diff --git a/trunk/drivers/md/dm-mpath.c b/trunk/drivers/md/dm-mpath.c index 5e0090ef4182..c3547016f0f1 100644 --- a/trunk/drivers/md/dm-mpath.c +++ b/trunk/drivers/md/dm-mpath.c @@ -22,6 +22,7 @@ #include #define DM_MSG_PREFIX "multipath" +#define MESG_STR(x) x, sizeof(x) #define DM_PG_INIT_DELAY_MSECS 2000 #define DM_PG_INIT_DELAY_DEFAULT ((unsigned) -1) @@ -504,29 +505,80 @@ static void trigger_event(struct work_struct *work) * <#paths> <#per-path selector args> * [ []* ]+ ]+ *---------------------------------------------------------------*/ -static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg, +struct param { + unsigned min; + unsigned max; + char *error; +}; + +static int read_param(struct param *param, char *str, unsigned *v, char **error) +{ + if (!str || + (sscanf(str, "%u", v) != 1) || + (*v < param->min) || + (*v > param->max)) { + *error = param->error; + return -EINVAL; + } + + return 0; +} + +struct arg_set { + unsigned argc; + char **argv; +}; + +static char *shift(struct arg_set *as) +{ + char *r; + + if (as->argc) { + as->argc--; + r = *as->argv; + as->argv++; + return r; + } + + return NULL; +} + +static void consume(struct arg_set *as, unsigned n) +{ + BUG_ON (as->argc < n); + as->argc -= n; + as->argv += n; +} + +static int parse_path_selector(struct arg_set *as, struct priority_group *pg, struct dm_target *ti) { int r; struct path_selector_type *pst; unsigned ps_argc; - static struct dm_arg _args[] = { + static struct param _params[] = { {0, 1024, "invalid number of path selector args"}, }; - pst = dm_get_path_selector(dm_shift_arg(as)); + pst = dm_get_path_selector(shift(as)); if (!pst) { ti->error = "unknown path selector type"; return -EINVAL; } - r = dm_read_arg_group(_args, as, &ps_argc, &ti->error); + r = read_param(_params, shift(as), &ps_argc, &ti->error); if (r) { dm_put_path_selector(pst); return -EINVAL; } + if (ps_argc > as->argc) { + dm_put_path_selector(pst); + ti->error = "not enough arguments for path selector"; + return -EINVAL; + } + r = pst->create(&pg->ps, ps_argc, as->argv); if (r) { dm_put_path_selector(pst); @@ -535,12 +587,12 @@ static int parse_path_selector(struct dm_arg_set *as, struct priority_group *pg, } pg->ps.type = pst; - dm_consume_args(as, ps_argc); + consume(as, ps_argc); return 0; } -static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps, +static struct pgpath *parse_path(struct arg_set *as, struct path_selector *ps, struct dm_target *ti) { int r; @@ -557,7 +609,7 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps if (!p) return ERR_PTR(-ENOMEM); - r = dm_get_device(ti, dm_shift_arg(as), dm_table_get_mode(ti->table), + r = dm_get_device(ti, shift(as), dm_table_get_mode(ti->table), &p->path.dev); if (r) { ti->error = "error getting device"; @@ -608,16 +660,16 @@ static struct pgpath *parse_path(struct dm_arg_set *as, struct path_selector *ps return ERR_PTR(r); } -static struct priority_group *parse_priority_group(struct dm_arg_set *as, +static struct priority_group *parse_priority_group(struct arg_set *as, struct multipath *m) { - static struct dm_arg _args[] = { + static struct param _params[] = { {1, 1024, "invalid number of paths"}, {0, 1024, "invalid number of selector args"} }; int r; - unsigned i, nr_selector_args, nr_args; + unsigned i, nr_selector_args, nr_params; struct priority_group *pg; struct dm_target *ti = m->ti; @@ -641,26 +693,26 @@ static struct priority_group *parse_priority_group(struct dm_arg_set *as, /* * read the paths */ - r = dm_read_arg(_args, as, &pg->nr_pgpaths, &ti->error); + r = read_param(_params, shift(as), &pg->nr_pgpaths, &ti->error); if (r) goto bad; - r = dm_read_arg(_args + 1, as, &nr_selector_args, &ti->error); + r = read_param(_params + 1, shift(as), &nr_selector_args, &ti->error); if (r) goto bad; - nr_args = 1 + nr_selector_args; + nr_params = 1 + nr_selector_args; for (i = 0; i < pg->nr_pgpaths; i++) { struct pgpath *pgpath; - struct dm_arg_set path_args; + struct arg_set path_args; - if (as->argc < nr_args) { + if (as->argc < nr_params) { ti->error = "not enough path parameters"; r = -EINVAL; goto bad; } - path_args.argc = nr_args; + path_args.argc = nr_params; path_args.argv = as->argv; pgpath = parse_path(&path_args, &pg->ps, ti); @@ -671,7 +723,7 @@ static struct priority_group *parse_priority_group(struct dm_arg_set *as, pgpath->pg = pg; list_add_tail(&pgpath->list, &pg->pgpaths); - dm_consume_args(as, nr_args); + consume(as, nr_params); } return pg; @@ -681,23 +733,28 @@ static struct priority_group *parse_priority_group(struct dm_arg_set *as, return ERR_PTR(r); } -static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) +static int parse_hw_handler(struct arg_set *as, struct multipath *m) { unsigned hw_argc; int ret; struct dm_target *ti = m->ti; - static struct dm_arg _args[] = { + static struct param _params[] = { {0, 1024, "invalid number of hardware handler args"}, }; - if (dm_read_arg_group(_args, as, &hw_argc, &ti->error)) + if (read_param(_params, shift(as), &hw_argc, &ti->error)) return -EINVAL; if (!hw_argc) return 0; - m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); + if (hw_argc > as->argc) { + ti->error = "not enough arguments for hardware handler"; + return -EINVAL; + } + + m->hw_handler_name = kstrdup(shift(as), GFP_KERNEL); request_module("scsi_dh_%s", m->hw_handler_name); if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { ti->error = "unknown hardware handler type"; @@ -721,7 +778,7 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) for (i = 0, p+=j+1; i <= hw_argc - 2; i++, p+=j+1) j = sprintf(p, "%s", as->argv[i]); } - dm_consume_args(as, hw_argc - 1); + consume(as, hw_argc - 1); return 0; fail: @@ -730,20 +787,20 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) return ret; } -static int parse_features(struct dm_arg_set *as, struct multipath *m) +static int parse_features(struct arg_set *as, struct multipath *m) { int r; unsigned argc; struct dm_target *ti = m->ti; - const char *arg_name; + const char *param_name; - static struct dm_arg _args[] = { + static struct param _params[] = { {0, 5, "invalid number of feature args"}, {1, 50, "pg_init_retries must be between 1 and 50"}, {0, 60000, "pg_init_delay_msecs must be between 0 and 60000"}, }; - r = dm_read_arg_group(_args, as, &argc, &ti->error); + r = read_param(_params, shift(as), &argc, &ti->error); if (r) return -EINVAL; @@ -751,24 +808,26 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m) return 0; do { - arg_name = dm_shift_arg(as); + param_name = shift(as); argc--; - if (!strcasecmp(arg_name, "queue_if_no_path")) { + if (!strnicmp(param_name, MESG_STR("queue_if_no_path"))) { r = queue_if_no_path(m, 1, 0); continue; } - if (!strcasecmp(arg_name, "pg_init_retries") && + if (!strnicmp(param_name, MESG_STR("pg_init_retries")) && (argc >= 1)) { - r = dm_read_arg(_args + 1, as, &m->pg_init_retries, &ti->error); + r = read_param(_params + 1, shift(as), + &m->pg_init_retries, &ti->error); argc--; continue; } - if (!strcasecmp(arg_name, "pg_init_delay_msecs") && + if (!strnicmp(param_name, MESG_STR("pg_init_delay_msecs")) && (argc >= 1)) { - r = dm_read_arg(_args + 2, as, &m->pg_init_delay_msecs, &ti->error); + r = read_param(_params + 2, shift(as), + &m->pg_init_delay_msecs, &ti->error); argc--; continue; } @@ -783,15 +842,15 @@ static int parse_features(struct dm_arg_set *as, struct multipath *m) static int multipath_ctr(struct dm_target *ti, unsigned int argc, char **argv) { - /* target arguments */ - static struct dm_arg _args[] = { + /* target parameters */ + static struct param _params[] = { {0, 1024, "invalid number of priority groups"}, {0, 1024, "invalid initial priority group number"}, }; int r; struct multipath *m; - struct dm_arg_set as; + struct arg_set as; unsigned pg_count = 0; unsigned next_pg_num; @@ -812,11 +871,11 @@ static int multipath_ctr(struct dm_target *ti, unsigned int argc, if (r) goto bad; - r = dm_read_arg(_args, &as, &m->nr_priority_groups, &ti->error); + r = read_param(_params, shift(&as), &m->nr_priority_groups, &ti->error); if (r) goto bad; - r = dm_read_arg(_args + 1, &as, &next_pg_num, &ti->error); + r = read_param(_params + 1, shift(&as), &next_pg_num, &ti->error); if (r) goto bad; @@ -1446,10 +1505,10 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) } if (argc == 1) { - if (!strcasecmp(argv[0], "queue_if_no_path")) { + if (!strnicmp(argv[0], MESG_STR("queue_if_no_path"))) { r = queue_if_no_path(m, 1, 0); goto out; - } else if (!strcasecmp(argv[0], "fail_if_no_path")) { + } else if (!strnicmp(argv[0], MESG_STR("fail_if_no_path"))) { r = queue_if_no_path(m, 0, 0); goto out; } @@ -1460,18 +1519,18 @@ static int multipath_message(struct dm_target *ti, unsigned argc, char **argv) goto out; } - if (!strcasecmp(argv[0], "disable_group")) { + if (!strnicmp(argv[0], MESG_STR("disable_group"))) { r = bypass_pg_num(m, argv[1], 1); goto out; - } else if (!strcasecmp(argv[0], "enable_group")) { + } else if (!strnicmp(argv[0], MESG_STR("enable_group"))) { r = bypass_pg_num(m, argv[1], 0); goto out; - } else if (!strcasecmp(argv[0], "switch_group")) { + } else if (!strnicmp(argv[0], MESG_STR("switch_group"))) { r = switch_pg_num(m, argv[1]); goto out; - } else if (!strcasecmp(argv[0], "reinstate_path")) + } else if (!strnicmp(argv[0], MESG_STR("reinstate_path"))) action = reinstate_path; - else if (!strcasecmp(argv[0], "fail_path")) + else if (!strnicmp(argv[0], MESG_STR("fail_path"))) action = fail_path; else { DMWARN("Unrecognised multipath message received."); diff --git a/trunk/drivers/md/dm-raid.c b/trunk/drivers/md/dm-raid.c index a002dd85db1e..e5d8904fc8f6 100644 --- a/trunk/drivers/md/dm-raid.c +++ b/trunk/drivers/md/dm-raid.c @@ -8,19 +8,19 @@ #include #include "md.h" -#include "raid1.h" #include "raid5.h" +#include "dm.h" #include "bitmap.h" -#include - #define DM_MSG_PREFIX "raid" /* - * The following flags are used by dm-raid.c to set up the array state. - * They must be cleared before md_run is called. + * If the MD doesn't support MD_SYNC_STATE_FORCED yet, then + * make it so the flag doesn't set anything. */ -#define FirstUse 10 /* rdev flag */ +#ifndef MD_SYNC_STATE_FORCED +#define MD_SYNC_STATE_FORCED 0 +#endif struct raid_dev { /* @@ -43,15 +43,14 @@ struct raid_dev { /* * Flags for rs->print_flags field. */ -#define DMPF_SYNC 0x1 -#define DMPF_NOSYNC 0x2 -#define DMPF_REBUILD 0x4 -#define DMPF_DAEMON_SLEEP 0x8 -#define DMPF_MIN_RECOVERY_RATE 0x10 -#define DMPF_MAX_RECOVERY_RATE 0x20 -#define DMPF_MAX_WRITE_BEHIND 0x40 -#define DMPF_STRIPE_CACHE 0x80 -#define DMPF_REGION_SIZE 0X100 +#define DMPF_DAEMON_SLEEP 0x1 +#define DMPF_MAX_WRITE_BEHIND 0x2 +#define DMPF_SYNC 0x4 +#define DMPF_NOSYNC 0x8 +#define DMPF_STRIPE_CACHE 0x10 +#define DMPF_MIN_RECOVERY_RATE 0x20 +#define DMPF_MAX_RECOVERY_RATE 0x40 + struct raid_set { struct dm_target *ti; @@ -73,7 +72,6 @@ static struct raid_type { const unsigned level; /* RAID level. */ const unsigned algorithm; /* RAID algorithm. */ } raid_types[] = { - {"raid1", "RAID1 (mirroring)", 0, 2, 1, 0 /* NONE */}, {"raid4", "RAID4 (dedicated parity disk)", 1, 2, 5, ALGORITHM_PARITY_0}, {"raid5_la", "RAID5 (left asymmetric)", 1, 2, 5, ALGORITHM_LEFT_ASYMMETRIC}, {"raid5_ra", "RAID5 (right asymmetric)", 1, 2, 5, ALGORITHM_RIGHT_ASYMMETRIC}, @@ -107,8 +105,7 @@ static struct raid_set *context_alloc(struct dm_target *ti, struct raid_type *ra } sectors_per_dev = ti->len; - if ((raid_type->level > 1) && - sector_div(sectors_per_dev, (raid_devs - raid_type->parity_devs))) { + if (sector_div(sectors_per_dev, (raid_devs - raid_type->parity_devs))) { ti->error = "Target length not divisible by number of data devices"; return ERR_PTR(-EINVAL); } @@ -150,16 +147,9 @@ static void context_free(struct raid_set *rs) { int i; - for (i = 0; i < rs->md.raid_disks; i++) { - if (rs->dev[i].meta_dev) - dm_put_device(rs->ti, rs->dev[i].meta_dev); - if (rs->dev[i].rdev.sb_page) - put_page(rs->dev[i].rdev.sb_page); - rs->dev[i].rdev.sb_page = NULL; - rs->dev[i].rdev.sb_loaded = 0; + for (i = 0; i < rs->md.raid_disks; i++) if (rs->dev[i].data_dev) dm_put_device(rs->ti, rs->dev[i].data_dev); - } kfree(rs); } @@ -169,16 +159,7 @@ static void context_free(struct raid_set *rs) * : meta device name or '-' if missing * : data device name or '-' if missing * - * The following are permitted: - * - - - * - - * - * - * The following is not allowed: - * - - * - * This code parses those words. If there is a failure, - * the caller must use context_free to unwind the operations. + * This code parses those words. */ static int dev_parms(struct raid_set *rs, char **argv) { @@ -201,16 +182,8 @@ static int dev_parms(struct raid_set *rs, char **argv) rs->dev[i].rdev.mddev = &rs->md; if (strcmp(argv[0], "-")) { - ret = dm_get_device(rs->ti, argv[0], - dm_table_get_mode(rs->ti->table), - &rs->dev[i].meta_dev); - rs->ti->error = "RAID metadata device lookup failure"; - if (ret) - return ret; - - rs->dev[i].rdev.sb_page = alloc_page(GFP_KERNEL); - if (!rs->dev[i].rdev.sb_page) - return -ENOMEM; + rs->ti->error = "Metadata devices not supported"; + return -EINVAL; } if (!strcmp(argv[1], "-")) { @@ -220,10 +193,6 @@ static int dev_parms(struct raid_set *rs, char **argv) return -EINVAL; } - rs->ti->error = "No data device supplied with metadata device"; - if (rs->dev[i].meta_dev) - return -EINVAL; - continue; } @@ -235,10 +204,6 @@ static int dev_parms(struct raid_set *rs, char **argv) return ret; } - if (rs->dev[i].meta_dev) { - metadata_available = 1; - rs->dev[i].rdev.meta_bdev = rs->dev[i].meta_dev->bdev; - } rs->dev[i].rdev.bdev = rs->dev[i].data_dev->bdev; list_add(&rs->dev[i].rdev.same_set, &rs->md.disks); if (!test_bit(In_sync, &rs->dev[i].rdev.flags)) @@ -269,110 +234,34 @@ static int dev_parms(struct raid_set *rs, char **argv) return 0; } -/* - * validate_region_size - * @rs - * @region_size: region size in sectors. If 0, pick a size (4MiB default). - * - * Set rs->md.bitmap_info.chunksize (which really refers to 'region size'). - * Ensure that (ti->len/region_size < 2^21) - required by MD bitmap. - * - * Returns: 0 on success, -EINVAL on failure. - */ -static int validate_region_size(struct raid_set *rs, unsigned long region_size) -{ - unsigned long min_region_size = rs->ti->len / (1 << 21); - - if (!region_size) { - /* - * Choose a reasonable default. All figures in sectors. - */ - if (min_region_size > (1 << 13)) { - DMINFO("Choosing default region size of %lu sectors", - region_size); - region_size = min_region_size; - } else { - DMINFO("Choosing default region size of 4MiB"); - region_size = 1 << 13; /* sectors */ - } - } else { - /* - * Validate user-supplied value. - */ - if (region_size > rs->ti->len) { - rs->ti->error = "Supplied region size is too large"; - return -EINVAL; - } - - if (region_size < min_region_size) { - DMERR("Supplied region_size (%lu sectors) below minimum (%lu)", - region_size, min_region_size); - rs->ti->error = "Supplied region size is too small"; - return -EINVAL; - } - - if (!is_power_of_2(region_size)) { - rs->ti->error = "Region size is not a power of 2"; - return -EINVAL; - } - - if (region_size < rs->md.chunk_sectors) { - rs->ti->error = "Region size is smaller than the chunk size"; - return -EINVAL; - } - } - - /* - * Convert sectors to bytes. - */ - rs->md.bitmap_info.chunksize = (region_size << 9); - - return 0; -} - /* * Possible arguments are... + * RAID456: * [optional_args] * - * Argument definitions - * The number of sectors per disk that - * will form the "stripe" - * [[no]sync] Force or prevent recovery of the - * entire array + * Optional args: + * [[no]sync] Force or prevent recovery of the entire array * [rebuild ] Rebuild the drive indicated by the index - * [daemon_sleep ] Time between bitmap daemon work to - * clear bits + * [daemon_sleep ] Time between bitmap daemon work to clear bits * [min_recovery_rate ] Throttle RAID initialization * [max_recovery_rate ] Throttle RAID initialization - * [write_mostly ] Indicate a write mostly drive via index * [max_write_behind ] See '-write-behind=' (man mdadm) * [stripe_cache ] Stripe cache size for higher RAIDs - * [region_size ] Defines granularity of bitmap */ static int parse_raid_params(struct raid_set *rs, char **argv, unsigned num_raid_params) { unsigned i, rebuild_cnt = 0; - unsigned long value, region_size = 0; + unsigned long value; char *key; /* * First, parse the in-order required arguments - * "chunk_size" is the only argument of this type. */ - if ((strict_strtoul(argv[0], 10, &value) < 0)) { + if ((strict_strtoul(argv[0], 10, &value) < 0) || + !is_power_of_2(value) || (value < 8)) { rs->ti->error = "Bad chunk size"; return -EINVAL; - } else if (rs->raid_type->level == 1) { - if (value) - DMERR("Ignoring chunk size parameter for RAID 1"); - value = 0; - } else if (!is_power_of_2(value)) { - rs->ti->error = "Chunk size must be a power of 2"; - return -EINVAL; - } else if (value < 8) { - rs->ti->error = "Chunk size value is too small"; - return -EINVAL; } rs->md.new_chunk_sectors = rs->md.chunk_sectors = value; @@ -380,39 +269,22 @@ static int parse_raid_params(struct raid_set *rs, char **argv, num_raid_params--; /* - * We set each individual device as In_sync with a completed - * 'recovery_offset'. If there has been a device failure or - * replacement then one of the following cases applies: - * - * 1) User specifies 'rebuild'. - * - Device is reset when param is read. - * 2) A new device is supplied. - * - No matching superblock found, resets device. - * 3) Device failure was transient and returns on reload. - * - Failure noticed, resets device for bitmap replay. - * 4) Device hadn't completed recovery after previous failure. - * - Superblock is read and overrides recovery_offset. - * - * What is found in the superblocks of the devices is always - * authoritative, unless 'rebuild' or '[no]sync' was specified. + * Second, parse the unordered optional arguments */ - for (i = 0; i < rs->md.raid_disks; i++) { + for (i = 0; i < rs->md.raid_disks; i++) set_bit(In_sync, &rs->dev[i].rdev.flags); - rs->dev[i].rdev.recovery_offset = MaxSector; - } - /* - * Second, parse the unordered optional arguments - */ for (i = 0; i < num_raid_params; i++) { - if (!strcasecmp(argv[i], "nosync")) { + if (!strcmp(argv[i], "nosync")) { rs->md.recovery_cp = MaxSector; rs->print_flags |= DMPF_NOSYNC; + rs->md.flags |= MD_SYNC_STATE_FORCED; continue; } - if (!strcasecmp(argv[i], "sync")) { + if (!strcmp(argv[i], "sync")) { rs->md.recovery_cp = 0; rs->print_flags |= DMPF_SYNC; + rs->md.flags |= MD_SYNC_STATE_FORCED; continue; } @@ -428,13 +300,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv, return -EINVAL; } - if (!strcasecmp(key, "rebuild")) { - rebuild_cnt++; - if (((rs->raid_type->level != 1) && - (rebuild_cnt > rs->raid_type->parity_devs)) || - ((rs->raid_type->level == 1) && - (rebuild_cnt > (rs->md.raid_disks - 1)))) { - rs->ti->error = "Too many rebuild devices specified for given RAID type"; + if (!strcmp(key, "rebuild")) { + if (++rebuild_cnt > rs->raid_type->parity_devs) { + rs->ti->error = "Too many rebuild drives given"; return -EINVAL; } if (value > rs->md.raid_disks) { @@ -443,22 +311,7 @@ static int parse_raid_params(struct raid_set *rs, char **argv, } clear_bit(In_sync, &rs->dev[value].rdev.flags); rs->dev[value].rdev.recovery_offset = 0; - rs->print_flags |= DMPF_REBUILD; - } else if (!strcasecmp(key, "write_mostly")) { - if (rs->raid_type->level != 1) { - rs->ti->error = "write_mostly option is only valid for RAID1"; - return -EINVAL; - } - if (value > rs->md.raid_disks) { - rs->ti->error = "Invalid write_mostly drive index given"; - return -EINVAL; - } - set_bit(WriteMostly, &rs->dev[value].rdev.flags); - } else if (!strcasecmp(key, "max_write_behind")) { - if (rs->raid_type->level != 1) { - rs->ti->error = "max_write_behind option is only valid for RAID1"; - return -EINVAL; - } + } else if (!strcmp(key, "max_write_behind")) { rs->print_flags |= DMPF_MAX_WRITE_BEHIND; /* @@ -471,14 +324,14 @@ static int parse_raid_params(struct raid_set *rs, char **argv, return -EINVAL; } rs->md.bitmap_info.max_write_behind = value; - } else if (!strcasecmp(key, "daemon_sleep")) { + } else if (!strcmp(key, "daemon_sleep")) { rs->print_flags |= DMPF_DAEMON_SLEEP; if (!value || (value > MAX_SCHEDULE_TIMEOUT)) { rs->ti->error = "daemon sleep period out of range"; return -EINVAL; } rs->md.bitmap_info.daemon_sleep = value; - } else if (!strcasecmp(key, "stripe_cache")) { + } else if (!strcmp(key, "stripe_cache")) { rs->print_flags |= DMPF_STRIPE_CACHE; /* @@ -495,23 +348,20 @@ static int parse_raid_params(struct raid_set *rs, char **argv, rs->ti->error = "Bad stripe_cache size"; return -EINVAL; } - } else if (!strcasecmp(key, "min_recovery_rate")) { + } else if (!strcmp(key, "min_recovery_rate")) { rs->print_flags |= DMPF_MIN_RECOVERY_RATE; if (value > INT_MAX) { rs->ti->error = "min_recovery_rate out of range"; return -EINVAL; } rs->md.sync_speed_min = (int)value; - } else if (!strcasecmp(key, "max_recovery_rate")) { + } else if (!strcmp(key, "max_recovery_rate")) { rs->print_flags |= DMPF_MAX_RECOVERY_RATE; if (value > INT_MAX) { rs->ti->error = "max_recovery_rate out of range"; return -EINVAL; } rs->md.sync_speed_max = (int)value; - } else if (!strcasecmp(key, "region_size")) { - rs->print_flags |= DMPF_REGION_SIZE; - region_size = value; } else { DMERR("Unable to parse RAID parameter: %s", key); rs->ti->error = "Unable to parse RAID parameters"; @@ -519,19 +369,6 @@ static int parse_raid_params(struct raid_set *rs, char **argv, } } - if (validate_region_size(rs, region_size)) - return -EINVAL; - - if (rs->md.chunk_sectors) - rs->ti->split_io = rs->md.chunk_sectors; - else - rs->ti->split_io = region_size; - - if (rs->md.chunk_sectors) - rs->ti->split_io = rs->md.chunk_sectors; - else - rs->ti->split_io = region_size; - /* Assume there are no metadata devices until the drives are parsed */ rs->md.persistent = 0; rs->md.external = 1; @@ -550,351 +387,17 @@ static int raid_is_congested(struct dm_target_callbacks *cb, int bits) { struct raid_set *rs = container_of(cb, struct raid_set, callbacks); - if (rs->raid_type->level == 1) - return md_raid1_congested(&rs->md, bits); - return md_raid5_congested(&rs->md, bits); } -/* - * This structure is never routinely used by userspace, unlike md superblocks. - * Devices with this superblock should only ever be accessed via device-mapper. - */ -#define DM_RAID_MAGIC 0x64526D44 -struct dm_raid_superblock { - __le32 magic; /* "DmRd" */ - __le32 features; /* Used to indicate possible future changes */ - - __le32 num_devices; /* Number of devices in this array. (Max 64) */ - __le32 array_position; /* The position of this drive in the array */ - - __le64 events; /* Incremented by md when superblock updated */ - __le64 failed_devices; /* Bit field of devices to indicate failures */ - - /* - * This offset tracks the progress of the repair or replacement of - * an individual drive. - */ - __le64 disk_recovery_offset; - - /* - * This offset tracks the progress of the initial array - * synchronisation/parity calculation. - */ - __le64 array_resync_offset; - - /* - * RAID characteristics - */ - __le32 level; - __le32 layout; - __le32 stripe_sectors; - - __u8 pad[452]; /* Round struct to 512 bytes. */ - /* Always set to 0 when writing. */ -} __packed; - -static int read_disk_sb(mdk_rdev_t *rdev, int size) -{ - BUG_ON(!rdev->sb_page); - - if (rdev->sb_loaded) - return 0; - - if (!sync_page_io(rdev, 0, size, rdev->sb_page, READ, 1)) { - DMERR("Failed to read device superblock"); - return -EINVAL; - } - - rdev->sb_loaded = 1; - - return 0; -} - -static void super_sync(mddev_t *mddev, mdk_rdev_t *rdev) -{ - mdk_rdev_t *r, *t; - uint64_t failed_devices; - struct dm_raid_superblock *sb; - - sb = page_address(rdev->sb_page); - failed_devices = le64_to_cpu(sb->failed_devices); - - rdev_for_each(r, t, mddev) - if ((r->raid_disk >= 0) && test_bit(Faulty, &r->flags)) - failed_devices |= (1ULL << r->raid_disk); - - memset(sb, 0, sizeof(*sb)); - - sb->magic = cpu_to_le32(DM_RAID_MAGIC); - sb->features = cpu_to_le32(0); /* No features yet */ - - sb->num_devices = cpu_to_le32(mddev->raid_disks); - sb->array_position = cpu_to_le32(rdev->raid_disk); - - sb->events = cpu_to_le64(mddev->events); - sb->failed_devices = cpu_to_le64(failed_devices); - - sb->disk_recovery_offset = cpu_to_le64(rdev->recovery_offset); - sb->array_resync_offset = cpu_to_le64(mddev->recovery_cp); - - sb->level = cpu_to_le32(mddev->level); - sb->layout = cpu_to_le32(mddev->layout); - sb->stripe_sectors = cpu_to_le32(mddev->chunk_sectors); -} - -/* - * super_load - * - * This function creates a superblock if one is not found on the device - * and will decide which superblock to use if there's a choice. - * - * Return: 1 if use rdev, 0 if use refdev, -Exxx otherwise - */ -static int super_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev) -{ - int ret; - struct dm_raid_superblock *sb; - struct dm_raid_superblock *refsb; - uint64_t events_sb, events_refsb; - - rdev->sb_start = 0; - rdev->sb_size = sizeof(*sb); - - ret = read_disk_sb(rdev, rdev->sb_size); - if (ret) - return ret; - - sb = page_address(rdev->sb_page); - if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) { - super_sync(rdev->mddev, rdev); - - set_bit(FirstUse, &rdev->flags); - - /* Force writing of superblocks to disk */ - set_bit(MD_CHANGE_DEVS, &rdev->mddev->flags); - - /* Any superblock is better than none, choose that if given */ - return refdev ? 0 : 1; - } - - if (!refdev) - return 1; - - events_sb = le64_to_cpu(sb->events); - - refsb = page_address(refdev->sb_page); - events_refsb = le64_to_cpu(refsb->events); - - return (events_sb > events_refsb) ? 1 : 0; -} - -static int super_init_validation(mddev_t *mddev, mdk_rdev_t *rdev) -{ - int role; - struct raid_set *rs = container_of(mddev, struct raid_set, md); - uint64_t events_sb; - uint64_t failed_devices; - struct dm_raid_superblock *sb; - uint32_t new_devs = 0; - uint32_t rebuilds = 0; - mdk_rdev_t *r, *t; - struct dm_raid_superblock *sb2; - - sb = page_address(rdev->sb_page); - events_sb = le64_to_cpu(sb->events); - failed_devices = le64_to_cpu(sb->failed_devices); - - /* - * Initialise to 1 if this is a new superblock. - */ - mddev->events = events_sb ? : 1; - - /* - * Reshaping is not currently allowed - */ - if ((le32_to_cpu(sb->level) != mddev->level) || - (le32_to_cpu(sb->layout) != mddev->layout) || - (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors)) { - DMERR("Reshaping arrays not yet supported."); - return -EINVAL; - } - - /* We can only change the number of devices in RAID1 right now */ - if ((rs->raid_type->level != 1) && - (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) { - DMERR("Reshaping arrays not yet supported."); - return -EINVAL; - } - - if (!(rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC))) - mddev->recovery_cp = le64_to_cpu(sb->array_resync_offset); - - /* - * During load, we set FirstUse if a new superblock was written. - * There are two reasons we might not have a superblock: - * 1) The array is brand new - in which case, all of the - * devices must have their In_sync bit set. Also, - * recovery_cp must be 0, unless forced. - * 2) This is a new device being added to an old array - * and the new device needs to be rebuilt - in which - * case the In_sync bit will /not/ be set and - * recovery_cp must be MaxSector. - */ - rdev_for_each(r, t, mddev) { - if (!test_bit(In_sync, &r->flags)) { - if (!test_bit(FirstUse, &r->flags)) - DMERR("Superblock area of " - "rebuild device %d should have been " - "cleared.", r->raid_disk); - set_bit(FirstUse, &r->flags); - rebuilds++; - } else if (test_bit(FirstUse, &r->flags)) - new_devs++; - } - - if (!rebuilds) { - if (new_devs == mddev->raid_disks) { - DMINFO("Superblocks created for new array"); - set_bit(MD_ARRAY_FIRST_USE, &mddev->flags); - } else if (new_devs) { - DMERR("New device injected " - "into existing array without 'rebuild' " - "parameter specified"); - return -EINVAL; - } - } else if (new_devs) { - DMERR("'rebuild' devices cannot be " - "injected into an array with other first-time devices"); - return -EINVAL; - } else if (mddev->recovery_cp != MaxSector) { - DMERR("'rebuild' specified while array is not in-sync"); - return -EINVAL; - } - - /* - * Now we set the Faulty bit for those devices that are - * recorded in the superblock as failed. - */ - rdev_for_each(r, t, mddev) { - if (!r->sb_page) - continue; - sb2 = page_address(r->sb_page); - sb2->failed_devices = 0; - - /* - * Check for any device re-ordering. - */ - if (!test_bit(FirstUse, &r->flags) && (r->raid_disk >= 0)) { - role = le32_to_cpu(sb2->array_position); - if (role != r->raid_disk) { - if (rs->raid_type->level != 1) { - rs->ti->error = "Cannot change device " - "positions in RAID array"; - return -EINVAL; - } - DMINFO("RAID1 device #%d now at position #%d", - role, r->raid_disk); - } - - /* - * Partial recovery is performed on - * returning failed devices. - */ - if (failed_devices & (1 << role)) - set_bit(Faulty, &r->flags); - } - } - - return 0; -} - -static int super_validate(mddev_t *mddev, mdk_rdev_t *rdev) -{ - struct dm_raid_superblock *sb = page_address(rdev->sb_page); - - /* - * If mddev->events is not set, we know we have not yet initialized - * the array. - */ - if (!mddev->events && super_init_validation(mddev, rdev)) - return -EINVAL; - - mddev->bitmap_info.offset = 4096 >> 9; /* Enable bitmap creation */ - rdev->mddev->bitmap_info.default_offset = 4096 >> 9; - if (!test_bit(FirstUse, &rdev->flags)) { - rdev->recovery_offset = le64_to_cpu(sb->disk_recovery_offset); - if (rdev->recovery_offset != MaxSector) - clear_bit(In_sync, &rdev->flags); - } - - /* - * If a device comes back, set it as not In_sync and no longer faulty. - */ - if (test_bit(Faulty, &rdev->flags)) { - clear_bit(Faulty, &rdev->flags); - clear_bit(In_sync, &rdev->flags); - rdev->saved_raid_disk = rdev->raid_disk; - rdev->recovery_offset = 0; - } - - clear_bit(FirstUse, &rdev->flags); - - return 0; -} - -/* - * Analyse superblocks and select the freshest. - */ -static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs) -{ - int ret; - mdk_rdev_t *rdev, *freshest, *tmp; - mddev_t *mddev = &rs->md; - - freshest = NULL; - rdev_for_each(rdev, tmp, mddev) { - if (!rdev->meta_bdev) - continue; - - ret = super_load(rdev, freshest); - - switch (ret) { - case 1: - freshest = rdev; - break; - case 0: - break; - default: - ti->error = "Failed to load superblock"; - return ret; - } - } - - if (!freshest) - return 0; - - /* - * Validation of the freshest device provides the source of - * validation for the remaining devices. - */ - ti->error = "Unable to assemble array: Invalid superblocks"; - if (super_validate(mddev, freshest)) - return -EINVAL; - - rdev_for_each(rdev, tmp, mddev) - if ((rdev != freshest) && super_validate(mddev, rdev)) - return -EINVAL; - - return 0; -} - /* * Construct a RAID4/5/6 mapping: * Args: * <#raid_params> \ * <#raid_devs> { .. } * + * ** metadata devices are not supported yet, use '-' instead ** + * * varies by . See 'parse_raid_params' for * details on possible . */ @@ -962,12 +465,8 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) if (ret) goto bad; - rs->md.sync_super = super_sync; - ret = analyse_superblocks(ti, rs); - if (ret) - goto bad; - INIT_WORK(&rs->md.event_work, do_table_event); + ti->split_io = rs->md.chunk_sectors; ti->private = rs; mutex_lock(&rs->md.reconfig_mutex); @@ -983,7 +482,6 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv) rs->callbacks.congested_fn = raid_is_congested; dm_table_add_target_callbacks(ti->table, &rs->callbacks); - mddev_suspend(&rs->md); return 0; bad: @@ -1048,17 +546,12 @@ static int raid_status(struct dm_target *ti, status_type_t type, break; case STATUSTYPE_TABLE: /* The string you would use to construct this array */ - for (i = 0; i < rs->md.raid_disks; i++) { - if ((rs->print_flags & DMPF_REBUILD) && - rs->dev[i].data_dev && - !test_bit(In_sync, &rs->dev[i].rdev.flags)) - raid_param_cnt += 2; /* for rebuilds */ + for (i = 0; i < rs->md.raid_disks; i++) if (rs->dev[i].data_dev && - test_bit(WriteMostly, &rs->dev[i].rdev.flags)) - raid_param_cnt += 2; - } + !test_bit(In_sync, &rs->dev[i].rdev.flags)) + raid_param_cnt++; /* for rebuilds */ - raid_param_cnt += (hweight64(rs->print_flags & ~DMPF_REBUILD) * 2); + raid_param_cnt += (hweight64(rs->print_flags) * 2); if (rs->print_flags & (DMPF_SYNC | DMPF_NOSYNC)) raid_param_cnt--; @@ -1072,8 +565,7 @@ static int raid_status(struct dm_target *ti, status_type_t type, DMEMIT(" nosync"); for (i = 0; i < rs->md.raid_disks; i++) - if ((rs->print_flags & DMPF_REBUILD) && - rs->dev[i].data_dev && + if (rs->dev[i].data_dev && !test_bit(In_sync, &rs->dev[i].rdev.flags)) DMEMIT(" rebuild %u", i); @@ -1087,11 +579,6 @@ static int raid_status(struct dm_target *ti, status_type_t type, if (rs->print_flags & DMPF_MAX_RECOVERY_RATE) DMEMIT(" max_recovery_rate %d", rs->md.sync_speed_max); - for (i = 0; i < rs->md.raid_disks; i++) - if (rs->dev[i].data_dev && - test_bit(WriteMostly, &rs->dev[i].rdev.flags)) - DMEMIT(" write_mostly %u", i); - if (rs->print_flags & DMPF_MAX_WRITE_BEHIND) DMEMIT(" max_write_behind %lu", rs->md.bitmap_info.max_write_behind); @@ -1104,16 +591,9 @@ static int raid_status(struct dm_target *ti, status_type_t type, conf ? conf->max_nr_stripes * 2 : 0); } - if (rs->print_flags & DMPF_REGION_SIZE) - DMEMIT(" region_size %lu", - rs->md.bitmap_info.chunksize >> 9); - DMEMIT(" %d", rs->md.raid_disks); for (i = 0; i < rs->md.raid_disks; i++) { - if (rs->dev[i].meta_dev) - DMEMIT(" %s", rs->dev[i].meta_dev->name); - else - DMEMIT(" -"); + DMEMIT(" -"); /* metadata device */ if (rs->dev[i].data_dev) DMEMIT(" %s", rs->dev[i].data_dev->name); @@ -1170,13 +650,12 @@ static void raid_resume(struct dm_target *ti) { struct raid_set *rs = ti->private; - bitmap_load(&rs->md); mddev_resume(&rs->md); } static struct target_type raid_target = { .name = "raid", - .version = {1, 1, 0}, + .version = {1, 0, 0}, .module = THIS_MODULE, .ctr = raid_ctr, .dtr = raid_dtr, diff --git a/trunk/drivers/md/dm-snap-persistent.c b/trunk/drivers/md/dm-snap-persistent.c index d1f1d7017103..135c2f1fdbfc 100644 --- a/trunk/drivers/md/dm-snap-persistent.c +++ b/trunk/drivers/md/dm-snap-persistent.c @@ -58,30 +58,25 @@ #define NUM_SNAPSHOT_HDR_CHUNKS 1 struct disk_header { - __le32 magic; + uint32_t magic; /* * Is this snapshot valid. There is no way of recovering * an invalid snapshot. */ - __le32 valid; + uint32_t valid; /* * Simple, incrementing version. no backward * compatibility. */ - __le32 version; + uint32_t version; /* In sectors */ - __le32 chunk_size; -} __packed; + uint32_t chunk_size; +}; struct disk_exception { - __le64 old_chunk; - __le64 new_chunk; -} __packed; - -struct core_exception { uint64_t old_chunk; uint64_t new_chunk; }; @@ -174,9 +169,10 @@ static int alloc_area(struct pstore *ps) if (!ps->area) goto err_area; - ps->zero_area = vzalloc(len); + ps->zero_area = vmalloc(len); if (!ps->zero_area) goto err_zero_area; + memset(ps->zero_area, 0, len); ps->header_area = vmalloc(len); if (!ps->header_area) @@ -400,32 +396,32 @@ static struct disk_exception *get_exception(struct pstore *ps, uint32_t index) } static void read_exception(struct pstore *ps, - uint32_t index, struct core_exception *result) + uint32_t index, struct disk_exception *result) { - struct disk_exception *de = get_exception(ps, index); + struct disk_exception *e = get_exception(ps, index); /* copy it */ - result->old_chunk = le64_to_cpu(de->old_chunk); - result->new_chunk = le64_to_cpu(de->new_chunk); + result->old_chunk = le64_to_cpu(e->old_chunk); + result->new_chunk = le64_to_cpu(e->new_chunk); } static void write_exception(struct pstore *ps, - uint32_t index, struct core_exception *e) + uint32_t index, struct disk_exception *de) { - struct disk_exception *de = get_exception(ps, index); + struct disk_exception *e = get_exception(ps, index); /* copy it */ - de->old_chunk = cpu_to_le64(e->old_chunk); - de->new_chunk = cpu_to_le64(e->new_chunk); + e->old_chunk = cpu_to_le64(de->old_chunk); + e->new_chunk = cpu_to_le64(de->new_chunk); } static void clear_exception(struct pstore *ps, uint32_t index) { - struct disk_exception *de = get_exception(ps, index); + struct disk_exception *e = get_exception(ps, index); /* clear it */ - de->old_chunk = 0; - de->new_chunk = 0; + e->old_chunk = 0; + e->new_chunk = 0; } /* @@ -441,13 +437,13 @@ static int insert_exceptions(struct pstore *ps, { int r; unsigned int i; - struct core_exception e; + struct disk_exception de; /* presume the area is full */ *full = 1; for (i = 0; i < ps->exceptions_per_area; i++) { - read_exception(ps, i, &e); + read_exception(ps, i, &de); /* * If the new_chunk is pointing at the start of @@ -455,7 +451,7 @@ static int insert_exceptions(struct pstore *ps, * is we know that we've hit the end of the * exceptions. Therefore the area is not full. */ - if (e.new_chunk == 0LL) { + if (de.new_chunk == 0LL) { ps->current_committed = i; *full = 0; break; @@ -464,13 +460,13 @@ static int insert_exceptions(struct pstore *ps, /* * Keep track of the start of the free chunks. */ - if (ps->next_free <= e.new_chunk) - ps->next_free = e.new_chunk + 1; + if (ps->next_free <= de.new_chunk) + ps->next_free = de.new_chunk + 1; /* * Otherwise we add the exception to the snapshot. */ - r = callback(callback_context, e.old_chunk, e.new_chunk); + r = callback(callback_context, de.old_chunk, de.new_chunk); if (r) return r; } @@ -567,7 +563,7 @@ static int persistent_read_metadata(struct dm_exception_store *store, ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / sizeof(struct disk_exception); ps->callbacks = dm_vcalloc(ps->exceptions_per_area, - sizeof(*ps->callbacks)); + sizeof(*ps->callbacks)); if (!ps->callbacks) return -ENOMEM; @@ -645,12 +641,12 @@ static void persistent_commit_exception(struct dm_exception_store *store, { unsigned int i; struct pstore *ps = get_info(store); - struct core_exception ce; + struct disk_exception de; struct commit_callback *cb; - ce.old_chunk = e->old_chunk; - ce.new_chunk = e->new_chunk; - write_exception(ps, ps->current_committed++, &ce); + de.old_chunk = e->old_chunk; + de.new_chunk = e->new_chunk; + write_exception(ps, ps->current_committed++, &de); /* * Add the callback to the back of the array. This code @@ -674,7 +670,7 @@ static void persistent_commit_exception(struct dm_exception_store *store, * If we completely filled the current area, then wipe the next one. */ if ((ps->current_committed == ps->exceptions_per_area) && - zero_disk_area(ps, ps->current_area + 1)) + zero_disk_area(ps, ps->current_area + 1)) ps->valid = 0; /* @@ -705,7 +701,7 @@ static int persistent_prepare_merge(struct dm_exception_store *store, chunk_t *last_new_chunk) { struct pstore *ps = get_info(store); - struct core_exception ce; + struct disk_exception de; int nr_consecutive; int r; @@ -726,9 +722,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store, ps->current_committed = ps->exceptions_per_area; } - read_exception(ps, ps->current_committed - 1, &ce); - *last_old_chunk = ce.old_chunk; - *last_new_chunk = ce.new_chunk; + read_exception(ps, ps->current_committed - 1, &de); + *last_old_chunk = de.old_chunk; + *last_new_chunk = de.new_chunk; /* * Find number of consecutive chunks within the current area, @@ -737,9 +733,9 @@ static int persistent_prepare_merge(struct dm_exception_store *store, for (nr_consecutive = 1; nr_consecutive < ps->current_committed; nr_consecutive++) { read_exception(ps, ps->current_committed - 1 - nr_consecutive, - &ce); - if (ce.old_chunk != *last_old_chunk - nr_consecutive || - ce.new_chunk != *last_new_chunk - nr_consecutive) + &de); + if (de.old_chunk != *last_old_chunk - nr_consecutive || + de.new_chunk != *last_new_chunk - nr_consecutive) break; } @@ -757,7 +753,7 @@ static int persistent_commit_merge(struct dm_exception_store *store, for (i = 0; i < nr_merged; i++) clear_exception(ps, ps->current_committed - 1 - i); - r = area_io(ps, WRITE_FLUSH_FUA); + r = area_io(ps, WRITE); if (r < 0) return r; diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index 6f758870fc19..9ecff5f3023a 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -29,6 +29,16 @@ static const char dm_snapshot_merge_target_name[] = "snapshot-merge"; #define dm_target_is_snapshot_merge(ti) \ ((ti)->type->name == dm_snapshot_merge_target_name) +/* + * The percentage increment we will wake up users at + */ +#define WAKE_UP_PERCENT 5 + +/* + * kcopyd priority of snapshot operations + */ +#define SNAPSHOT_COPY_PRIORITY 2 + /* * The size of the mempool used to track chunks in use. */ @@ -170,13 +180,6 @@ struct dm_snap_pending_exception { * kcopyd. */ int started; - - /* - * For writing a complete chunk, bypassing the copy. - */ - struct bio *full_bio; - bio_end_io_t *full_bio_end_io; - void *full_bio_private; }; /* @@ -1052,7 +1055,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv) s = kmalloc(sizeof(*s), GFP_KERNEL); if (!s) { - ti->error = "Cannot allocate private snapshot structure"; + ti->error = "Cannot allocate snapshot context private " + "structure"; r = -ENOMEM; goto bad; } @@ -1376,7 +1380,6 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) struct dm_snapshot *s = pe->snap; struct bio *origin_bios = NULL; struct bio *snapshot_bios = NULL; - struct bio *full_bio = NULL; int error = 0; if (!success) { @@ -1412,15 +1415,10 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) */ dm_insert_exception(&s->complete, e); -out: + out: dm_remove_exception(&pe->e); snapshot_bios = bio_list_get(&pe->snapshot_bios); origin_bios = bio_list_get(&pe->origin_bios); - full_bio = pe->full_bio; - if (full_bio) { - full_bio->bi_end_io = pe->full_bio_end_io; - full_bio->bi_private = pe->full_bio_private; - } free_pending_exception(pe); increment_pending_exceptions_done_count(); @@ -1428,15 +1426,10 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) up_write(&s->lock); /* Submit any pending write bios */ - if (error) { - if (full_bio) - bio_io_error(full_bio); + if (error) error_bios(snapshot_bios); - } else { - if (full_bio) - bio_endio(full_bio, 0); + else flush_bios(snapshot_bios); - } retry_origin_bios(s, origin_bios); } @@ -1487,33 +1480,8 @@ static void start_copy(struct dm_snap_pending_exception *pe) dest.count = src.count; /* Hand over to kcopyd */ - dm_kcopyd_copy(s->kcopyd_client, &src, 1, &dest, 0, copy_callback, pe); -} - -static void full_bio_end_io(struct bio *bio, int error) -{ - void *callback_data = bio->bi_private; - - dm_kcopyd_do_callback(callback_data, 0, error ? 1 : 0); -} - -static void start_full_bio(struct dm_snap_pending_exception *pe, - struct bio *bio) -{ - struct dm_snapshot *s = pe->snap; - void *callback_data; - - pe->full_bio = bio; - pe->full_bio_end_io = bio->bi_end_io; - pe->full_bio_private = bio->bi_private; - - callback_data = dm_kcopyd_prepare_callback(s->kcopyd_client, - copy_callback, pe); - - bio->bi_end_io = full_bio_end_io; - bio->bi_private = callback_data; - - generic_make_request(bio); + dm_kcopyd_copy(s->kcopyd_client, + &src, 1, &dest, 0, copy_callback, pe); } static struct dm_snap_pending_exception * @@ -1551,7 +1519,6 @@ __find_pending_exception(struct dm_snapshot *s, bio_list_init(&pe->origin_bios); bio_list_init(&pe->snapshot_bios); pe->started = 0; - pe->full_bio = NULL; if (s->store->type->prepare_exception(s->store, &pe->e)) { free_pending_exception(pe); @@ -1645,19 +1612,10 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, } remap_exception(s, &pe->e, bio, chunk); + bio_list_add(&pe->snapshot_bios, bio); r = DM_MAPIO_SUBMITTED; - if (!pe->started && - bio->bi_size == (s->store->chunk_size << SECTOR_SHIFT)) { - pe->started = 1; - up_write(&s->lock); - start_full_bio(pe, bio); - goto out; - } - - bio_list_add(&pe->snapshot_bios, bio); - if (!pe->started) { /* this is protected by snap->lock */ pe->started = 1; @@ -1670,9 +1628,9 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio, map_context->ptr = track_chunk(s, chunk); } -out_unlock: + out_unlock: up_write(&s->lock); -out: + out: return r; } @@ -2016,7 +1974,7 @@ static int __origin_write(struct list_head *snapshots, sector_t sector, pe_to_start_now = pe; } -next_snapshot: + next_snapshot: up_write(&snap->lock); if (pe_to_start_now) { diff --git a/trunk/drivers/md/dm-table.c b/trunk/drivers/md/dm-table.c index 986b8754bb08..bfe9c2333cea 100644 --- a/trunk/drivers/md/dm-table.c +++ b/trunk/drivers/md/dm-table.c @@ -54,6 +54,7 @@ struct dm_table { sector_t *highs; struct dm_target *targets; + unsigned discards_supported:1; unsigned integrity_supported:1; /* @@ -153,11 +154,12 @@ void *dm_vcalloc(unsigned long nmemb, unsigned long elem_size) return NULL; size = nmemb * elem_size; - addr = vzalloc(size); + addr = vmalloc(size); + if (addr) + memset(addr, 0, size); return addr; } -EXPORT_SYMBOL(dm_vcalloc); /* * highs, and targets are managed as dynamic arrays during a @@ -207,6 +209,7 @@ int dm_table_create(struct dm_table **result, fmode_t mode, INIT_LIST_HEAD(&t->devices); INIT_LIST_HEAD(&t->target_callbacks); atomic_set(&t->holders, 0); + t->discards_supported = 1; if (!num_targets) num_targets = KEYS_PER_NODE; @@ -278,7 +281,6 @@ void dm_table_get(struct dm_table *t) { atomic_inc(&t->holders); } -EXPORT_SYMBOL(dm_table_get); void dm_table_put(struct dm_table *t) { @@ -288,7 +290,6 @@ void dm_table_put(struct dm_table *t) smp_mb__before_atomic_dec(); atomic_dec(&t->holders); } -EXPORT_SYMBOL(dm_table_put); /* * Checks to see if we need to extend highs or targets. @@ -454,14 +455,13 @@ static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode, * Add a device to the list, or just increment the usage count if * it's already present. */ -int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, - struct dm_dev **result) +static int __table_get_device(struct dm_table *t, struct dm_target *ti, + const char *path, fmode_t mode, struct dm_dev **result) { int r; dev_t uninitialized_var(dev); struct dm_dev_internal *dd; unsigned int major, minor; - struct dm_table *t = ti->table; BUG_ON(!t); @@ -509,7 +509,6 @@ int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, *result = &dd->dm_dev; return 0; } -EXPORT_SYMBOL(dm_get_device); int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) @@ -540,15 +539,23 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, * If not we'll force DM to use PAGE_SIZE or * smaller I/O, just to be safe. */ - if (dm_queue_merge_is_compulsory(q) && !ti->type->merge) + + if (q->merge_bvec_fn && !ti->type->merge) blk_limits_max_hw_sectors(limits, (unsigned int) (PAGE_SIZE >> 9)); return 0; } EXPORT_SYMBOL_GPL(dm_set_device_limits); +int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode, + struct dm_dev **result) +{ + return __table_get_device(ti->table, ti, path, mode, result); +} + + /* - * Decrement a device's use count and remove it if necessary. + * Decrement a devices use count and remove it if necessary. */ void dm_put_device(struct dm_target *ti, struct dm_dev *d) { @@ -561,7 +568,6 @@ void dm_put_device(struct dm_target *ti, struct dm_dev *d) kfree(dd); } } -EXPORT_SYMBOL(dm_put_device); /* * Checks to see if the target joins onto the end of the table. @@ -785,9 +791,8 @@ int dm_table_add_target(struct dm_table *t, const char *type, t->highs[t->num_targets++] = tgt->begin + tgt->len - 1; - if (!tgt->num_discard_requests && tgt->discards_supported) - DMWARN("%s: %s: ignoring discards_supported because num_discard_requests is zero.", - dm_device_name(t->md), type); + if (!tgt->num_discard_requests) + t->discards_supported = 0; return 0; @@ -797,63 +802,6 @@ int dm_table_add_target(struct dm_table *t, const char *type, return r; } -/* - * Target argument parsing helpers. - */ -static int validate_next_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, - unsigned *value, char **error, unsigned grouped) -{ - const char *arg_str = dm_shift_arg(arg_set); - - if (!arg_str || - (sscanf(arg_str, "%u", value) != 1) || - (*value < arg->min) || - (*value > arg->max) || - (grouped && arg_set->argc < *value)) { - *error = arg->error; - return -EINVAL; - } - - return 0; -} - -int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, - unsigned *value, char **error) -{ - return validate_next_arg(arg, arg_set, value, error, 0); -} -EXPORT_SYMBOL(dm_read_arg); - -int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, - unsigned *value, char **error) -{ - return validate_next_arg(arg, arg_set, value, error, 1); -} -EXPORT_SYMBOL(dm_read_arg_group); - -const char *dm_shift_arg(struct dm_arg_set *as) -{ - char *r; - - if (as->argc) { - as->argc--; - r = *as->argv; - as->argv++; - return r; - } - - return NULL; -} -EXPORT_SYMBOL(dm_shift_arg); - -void dm_consume_args(struct dm_arg_set *as, unsigned num_args) -{ - BUG_ON(as->argc < num_args); - as->argc -= num_args; - as->argv += num_args; -} -EXPORT_SYMBOL(dm_consume_args); - static int dm_table_set_type(struct dm_table *t) { unsigned i; @@ -1129,13 +1077,11 @@ void dm_table_event(struct dm_table *t) t->event_fn(t->event_context); mutex_unlock(&_event_lock); } -EXPORT_SYMBOL(dm_table_event); sector_t dm_table_get_size(struct dm_table *t) { return t->num_targets ? (t->highs[t->num_targets - 1] + 1) : 0; } -EXPORT_SYMBOL(dm_table_get_size); struct dm_target *dm_table_get_target(struct dm_table *t, unsigned int index) { @@ -1248,45 +1194,9 @@ static void dm_table_set_integrity(struct dm_table *t) blk_get_integrity(template_disk)); } -static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev, - sector_t start, sector_t len, void *data) -{ - unsigned flush = (*(unsigned *)data); - struct request_queue *q = bdev_get_queue(dev->bdev); - - return q && (q->flush_flags & flush); -} - -static bool dm_table_supports_flush(struct dm_table *t, unsigned flush) -{ - struct dm_target *ti; - unsigned i = 0; - - /* - * Require at least one underlying device to support flushes. - * t->devices includes internal dm devices such as mirror logs - * so we need to use iterate_devices here, which targets - * supporting flushes must provide. - */ - while (i < dm_table_get_num_targets(t)) { - ti = dm_table_get_target(t, i++); - - if (!ti->num_flush_requests) - continue; - - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, device_flush_capable, &flush)) - return 1; - } - - return 0; -} - void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, struct queue_limits *limits) { - unsigned flush = 0; - /* * Copy table's limits to the DM device's request_queue */ @@ -1297,13 +1207,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, else queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q); - if (dm_table_supports_flush(t, REQ_FLUSH)) { - flush |= REQ_FLUSH; - if (dm_table_supports_flush(t, REQ_FUA)) - flush |= REQ_FUA; - } - blk_queue_flush(q, flush); - dm_table_set_integrity(t); /* @@ -1334,7 +1237,6 @@ fmode_t dm_table_get_mode(struct dm_table *t) { return t->mode; } -EXPORT_SYMBOL(dm_table_get_mode); static void suspend_targets(struct dm_table *t, unsigned postsuspend) { @@ -1443,7 +1345,6 @@ struct mapped_device *dm_table_get_md(struct dm_table *t) { return t->md; } -EXPORT_SYMBOL(dm_table_get_md); static int device_discard_capable(struct dm_target *ti, struct dm_dev *dev, sector_t start, sector_t len, void *data) @@ -1458,19 +1359,19 @@ bool dm_table_supports_discards(struct dm_table *t) struct dm_target *ti; unsigned i = 0; + if (!t->discards_supported) + return 0; + /* * Unless any target used by the table set discards_supported, * require at least one underlying device to support discards. * t->devices includes internal dm devices such as mirror logs * so we need to use iterate_devices here, which targets - * supporting discard selectively must provide. + * supporting discard must provide. */ while (i < dm_table_get_num_targets(t)) { ti = dm_table_get_target(t, i++); - if (!ti->num_discard_requests) - continue; - if (ti->discards_supported) return 1; @@ -1481,3 +1382,13 @@ bool dm_table_supports_discards(struct dm_table *t) return 0; } + +EXPORT_SYMBOL(dm_vcalloc); +EXPORT_SYMBOL(dm_get_device); +EXPORT_SYMBOL(dm_put_device); +EXPORT_SYMBOL(dm_table_event); +EXPORT_SYMBOL(dm_table_get_size); +EXPORT_SYMBOL(dm_table_get_mode); +EXPORT_SYMBOL(dm_table_get_md); +EXPORT_SYMBOL(dm_table_put); +EXPORT_SYMBOL(dm_table_get); diff --git a/trunk/drivers/md/dm.c b/trunk/drivers/md/dm.c index 52b39f335bb3..0cf68b478878 100644 --- a/trunk/drivers/md/dm.c +++ b/trunk/drivers/md/dm.c @@ -37,8 +37,6 @@ static const char *_name = DM_NAME; static unsigned int major = 0; static unsigned int _major = 0; -static DEFINE_IDR(_minor_idr); - static DEFINE_SPINLOCK(_minor_lock); /* * For bio-based dm. @@ -111,7 +109,6 @@ EXPORT_SYMBOL_GPL(dm_get_rq_mapinfo); #define DMF_FREEING 3 #define DMF_DELETING 4 #define DMF_NOFLUSH_SUSPENDING 5 -#define DMF_MERGE_IS_OPTIONAL 6 /* * Work processed by per-device workqueue. @@ -316,12 +313,6 @@ static void __exit dm_exit(void) while (i--) _exits[i](); - - /* - * Should be empty by this point. - */ - idr_remove_all(&_minor_idr); - idr_destroy(&_minor_idr); } /* @@ -1180,8 +1171,7 @@ static int __clone_and_map_discard(struct clone_info *ci) /* * Even though the device advertised discard support, - * that does not mean every target supports it, and - * reconfiguration might also have changed that since the + * reconfiguration might have changed that since the * check was performed. */ if (!ti->num_discard_requests) @@ -1715,6 +1705,8 @@ static int dm_any_congested(void *congested_data, int bdi_bits) /*----------------------------------------------------------------- * An IDR is used to keep track of allocated minor numbers. *---------------------------------------------------------------*/ +static DEFINE_IDR(_minor_idr); + static void free_minor(int minor) { spin_lock(&_minor_lock); @@ -1808,6 +1800,7 @@ static void dm_init_md_queue(struct mapped_device *md) blk_queue_make_request(md->queue, dm_request); blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); blk_queue_merge_bvec(md->queue, dm_merge_bvec); + blk_queue_flush(md->queue, REQ_FLUSH | REQ_FUA); } /* @@ -1992,59 +1985,6 @@ static void __set_size(struct mapped_device *md, sector_t size) i_size_write(md->bdev->bd_inode, (loff_t)size << SECTOR_SHIFT); } -/* - * Return 1 if the queue has a compulsory merge_bvec_fn function. - * - * If this function returns 0, then the device is either a non-dm - * device without a merge_bvec_fn, or it is a dm device that is - * able to split any bios it receives that are too big. - */ -int dm_queue_merge_is_compulsory(struct request_queue *q) -{ - struct mapped_device *dev_md; - - if (!q->merge_bvec_fn) - return 0; - - if (q->make_request_fn == dm_request) { - dev_md = q->queuedata; - if (test_bit(DMF_MERGE_IS_OPTIONAL, &dev_md->flags)) - return 0; - } - - return 1; -} - -static int dm_device_merge_is_compulsory(struct dm_target *ti, - struct dm_dev *dev, sector_t start, - sector_t len, void *data) -{ - struct block_device *bdev = dev->bdev; - struct request_queue *q = bdev_get_queue(bdev); - - return dm_queue_merge_is_compulsory(q); -} - -/* - * Return 1 if it is acceptable to ignore merge_bvec_fn based - * on the properties of the underlying devices. - */ -static int dm_table_merge_is_optional(struct dm_table *table) -{ - unsigned i = 0; - struct dm_target *ti; - - while (i < dm_table_get_num_targets(table)) { - ti = dm_table_get_target(table, i++); - - if (ti->type->iterate_devices && - ti->type->iterate_devices(ti, dm_device_merge_is_compulsory, NULL)) - return 0; - } - - return 1; -} - /* * Returns old map, which caller must destroy. */ @@ -2055,7 +1995,6 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, struct request_queue *q = md->queue; sector_t size; unsigned long flags; - int merge_is_optional; size = dm_table_get_size(t); @@ -2081,16 +2020,10 @@ static struct dm_table *__bind(struct mapped_device *md, struct dm_table *t, __bind_mempools(md, t); - merge_is_optional = dm_table_merge_is_optional(t); - write_lock_irqsave(&md->map_lock, flags); old_map = md->map; md->map = t; dm_table_set_restrictions(t, q, limits); - if (merge_is_optional) - set_bit(DMF_MERGE_IS_OPTIONAL, &md->flags); - else - clear_bit(DMF_MERGE_IS_OPTIONAL, &md->flags); write_unlock_irqrestore(&md->map_lock, flags); return old_map; diff --git a/trunk/drivers/md/dm.h b/trunk/drivers/md/dm.h index 6745dbd278a4..1aaf16746da8 100644 --- a/trunk/drivers/md/dm.h +++ b/trunk/drivers/md/dm.h @@ -66,8 +66,6 @@ int dm_table_alloc_md_mempools(struct dm_table *t); void dm_table_free_md_mempools(struct dm_table *t); struct dm_md_mempools *dm_table_get_md_mempools(struct dm_table *t); -int dm_queue_merge_is_compulsory(struct request_queue *q); - void dm_lock_md_type(struct mapped_device *md); void dm_unlock_md_type(struct mapped_device *md); void dm_set_md_type(struct mapped_device *md, unsigned type); diff --git a/trunk/drivers/net/bnx2x/bnx2x_cmn.c b/trunk/drivers/net/bnx2x/bnx2x_cmn.c index 37e5790681ad..5b0dba6d4efa 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_cmn.c +++ b/trunk/drivers/net/bnx2x/bnx2x_cmn.c @@ -63,9 +63,8 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int index) fp->disable_tpa = ((bp->flags & TPA_ENABLE_FLAG) == 0); #ifdef BCM_CNIC - /* We don't want TPA on an FCoE L2 ring */ - if (IS_FCOE_FP(fp)) - fp->disable_tpa = 1; + /* We don't want TPA on FCoE, FWD and OOO L2 rings */ + bnx2x_fcoe(bp, disable_tpa) = 1; #endif } @@ -1405,9 +1404,10 @@ void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw) u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) { struct bnx2x *bp = netdev_priv(dev); - #ifdef BCM_CNIC - if (!NO_FCOE(bp)) { + if (NO_FCOE(bp)) + return skb_tx_hash(dev, skb); + else { struct ethhdr *hdr = (struct ethhdr *)skb->data; u16 ether_type = ntohs(hdr->h_proto); @@ -1424,7 +1424,8 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb) return bnx2x_fcoe_tx(bp, txq_index); } #endif - /* select a non-FCoE queue */ + /* Select a none-FCoE queue: if FCoE is enabled, exclude FCoE L2 ring + */ return __skb_tx_hash(dev, skb, BNX2X_NUM_ETH_QUEUES(bp)); } @@ -1447,28 +1448,6 @@ void bnx2x_set_num_queues(struct bnx2x *bp) bp->num_queues += NON_ETH_CONTEXT_USE; } -/** - * bnx2x_set_real_num_queues - configure netdev->real_num_[tx,rx]_queues - * - * @bp: Driver handle - * - * We currently support for at most 16 Tx queues for each CoS thus we will - * allocate a multiple of 16 for ETH L2 rings according to the value of the - * bp->max_cos. - * - * If there is an FCoE L2 queue the appropriate Tx queue will have the next - * index after all ETH L2 indices. - * - * If the actual number of Tx queues (for each CoS) is less than 16 then there - * will be the holes at the end of each group of 16 ETh L2 indices (0..15, - * 16..31,...) with indicies that are not coupled with any real Tx queue. - * - * The proper configuration of skb->queue_mapping is handled by - * bnx2x_select_queue() and __skb_tx_hash(). - * - * bnx2x_setup_tc() takes care of the proper TC mappings so that __skb_tx_hash() - * will return a proper Tx index if TC is enabled (netdev->num_tc > 0). - */ static inline int bnx2x_set_real_num_queues(struct bnx2x *bp) { int rc, tx, rx; @@ -2010,20 +1989,14 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) return -EINVAL; } - /* - * It's important to set the bp->state to the value different from - * BNX2X_STATE_OPEN and only then stop the Tx. Otherwise bnx2x_tx_int() - * may restart the Tx from the NAPI context (see bnx2x_tx_int()). - */ - bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; - smp_mb(); - /* Stop Tx */ bnx2x_tx_disable(bp); #ifdef BCM_CNIC bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); #endif + bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; + smp_mb(); bp->rx_mode = BNX2X_RX_MODE_NONE; diff --git a/trunk/drivers/net/bnx2x/bnx2x_dcb.c b/trunk/drivers/net/bnx2x/bnx2x_dcb.c index a1e004a82f7a..a4ea35f6a456 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_dcb.c +++ b/trunk/drivers/net/bnx2x/bnx2x_dcb.c @@ -920,7 +920,7 @@ static void bnx2x_dcbx_admin_mib_updated_params(struct bnx2x *bp, void bnx2x_dcbx_set_state(struct bnx2x *bp, bool dcb_on, u32 dcbx_enabled) { - if (!CHIP_IS_E1x(bp) && !CHIP_IS_E3(bp)) { + if (!CHIP_IS_E1x(bp)) { bp->dcb_state = dcb_on; bp->dcbx_enabled = dcbx_enabled; } else { diff --git a/trunk/drivers/net/bnx2x/bnx2x_hsi.h b/trunk/drivers/net/bnx2x/bnx2x_hsi.h index dc24de40e336..06727f32e505 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_hsi.h +++ b/trunk/drivers/net/bnx2x/bnx2x_hsi.h @@ -1204,8 +1204,6 @@ struct drv_port_mb { #define LINK_STATUS_PFC_ENABLED 0x20000000 - #define LINK_STATUS_PHYSICAL_LINK_FLAG 0x40000000 - u32 port_stx; u32 stat_nig_timer; diff --git a/trunk/drivers/net/bnx2x/bnx2x_link.c b/trunk/drivers/net/bnx2x/bnx2x_link.c index d45b1555a602..bcd8f0038628 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_link.c +++ b/trunk/drivers/net/bnx2x/bnx2x_link.c @@ -1546,12 +1546,6 @@ static void bnx2x_umac_enable(struct link_params *params, vars->line_speed); break; } - if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)) - val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE; - - if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)) - val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE; - REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val); udelay(50); @@ -1667,20 +1661,10 @@ static void bnx2x_xmac_disable(struct link_params *params) { u8 port = params->port; struct bnx2x *bp = params->bp; - u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; + u32 xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; if (REG_RD(bp, MISC_REG_RESET_REG_2) & MISC_REGISTERS_RESET_REG_2_XMAC) { - /* - * Send an indication to change the state in the NIG back to XON - * Clearing this bit enables the next set of this bit to get - * rising edge - */ - pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI); - REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, - (pfc_ctrl & ~(1<<1))); - REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, - (pfc_ctrl | (1<<1))); DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port); REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0); usleep_range(1000, 1000); @@ -1745,10 +1729,6 @@ static int bnx2x_emac_enable(struct link_params *params, DP(NETIF_MSG_LINK, "enabling EMAC\n"); - /* Disable BMAC */ - REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - /* enable emac and not bmac */ REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); @@ -2603,6 +2583,12 @@ static int bnx2x_bmac1_enable(struct link_params *params, REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, wb_data, 2); + if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { + REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LSS_STATUS, + wb_data, 2); + if (wb_data[0] > 0) + return -ESRCH; + } return 0; } @@ -2668,6 +2654,16 @@ static int bnx2x_bmac2_enable(struct link_params *params, udelay(30); bnx2x_update_pfc_bmac2(params, vars, is_lb); + if (vars->phy_flags & PHY_TX_ERROR_CHECK_FLAG) { + REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LSS_STAT, + wb_data, 2); + if (wb_data[0] > 0) { + DP(NETIF_MSG_LINK, "Got bad LSS status 0x%x\n", + wb_data[0]); + return -ESRCH; + } + } + return 0; } @@ -2953,9 +2949,7 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, u32 val; u16 i; int rc = 0; - if (phy->flags & FLAGS_MDC_MDIO_WA_B0) - bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, - EMAC_MDIO_STATUS_10MB); + /* address */ val = ((phy->addr << 21) | (devad << 16) | reg | EMAC_MDIO_COMM_COMMAND_ADDRESS | @@ -3009,9 +3003,6 @@ static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy, } } - if (phy->flags & FLAGS_MDC_MDIO_WA_B0) - bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, - EMAC_MDIO_STATUS_10MB); return rc; } @@ -3021,9 +3012,6 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, u32 tmp; u8 i; int rc = 0; - if (phy->flags & FLAGS_MDC_MDIO_WA_B0) - bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, - EMAC_MDIO_STATUS_10MB); /* address */ @@ -3077,9 +3065,7 @@ static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val); } } - if (phy->flags & FLAGS_MDC_MDIO_WA_B0) - bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS, - EMAC_MDIO_STATUS_10MB); + return rc; } @@ -4367,9 +4353,6 @@ void bnx2x_link_status_update(struct link_params *params, vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP); vars->phy_flags = PHY_XGXS_FLAG; - if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) - vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; - if (vars->link_up) { DP(NETIF_MSG_LINK, "phy link up\n"); @@ -4461,8 +4444,6 @@ void bnx2x_link_status_update(struct link_params *params, /* indicate no mac active */ vars->mac_type = MAC_TYPE_NONE; - if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG) - vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; } /* Sync media type */ @@ -5922,30 +5903,20 @@ int bnx2x_set_led(struct link_params *params, tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED); EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE)); - /* - * return here without enabling traffic - * LED blink andsetting rate in ON mode. - * In oper mode, enabling LED blink - * and setting rate is needed. - */ - if (mode == LED_MODE_ON) - return rc; + return rc; } - } else if (SINGLE_MEDIA_DIRECT(params)) { + } else if (SINGLE_MEDIA_DIRECT(params) && + (CHIP_IS_E1x(bp) || + CHIP_IS_E2(bp))) { /* * This is a work-around for HW issue found when link * is up in CL73 */ + REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); - if (CHIP_IS_E1x(bp) || - CHIP_IS_E2(bp) || - (mode == LED_MODE_ON)) - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); - else - REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, - hw_led_mode); - } else + } else { REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode); + } REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0); /* Set blinking rate to ~15.9Hz */ @@ -6189,7 +6160,6 @@ static int bnx2x_update_link_down(struct link_params *params, /* update shared memory */ vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK | LINK_STATUS_LINK_UP | - LINK_STATUS_PHYSICAL_LINK_FLAG | LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | @@ -6227,8 +6197,7 @@ static int bnx2x_update_link_up(struct link_params *params, u8 port = params->port; int rc = 0; - vars->link_status |= (LINK_STATUS_LINK_UP | - LINK_STATUS_PHYSICAL_LINK_FLAG); + vars->link_status |= LINK_STATUS_LINK_UP; vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG; if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) @@ -8029,9 +7998,6 @@ static void bnx2x_warpcore_set_limiting_mode(struct link_params *params, bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val); - /* Restart microcode to re-read the new mode */ - bnx2x_warpcore_reset_lane(bp, phy, 1); - bnx2x_warpcore_reset_lane(bp, phy, 0); } @@ -8150,6 +8116,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) offsetof(struct shmem_region, dev_info. port_feature_config[params->port]. config)); + bnx2x_set_gpio_int(bp, gpio_num, MISC_REGISTERS_GPIO_INT_OUTPUT_SET, gpio_port); @@ -8158,9 +8125,8 @@ void bnx2x_handle_module_detect_int(struct link_params *params) * Disable transmit for this module */ phy->media_type = ETH_PHY_NOT_PRESENT; - if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == - PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) || - CHIP_IS_E3(bp)) + if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == + PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) bnx2x_sfp_set_transmitter(params, phy, 0); } } @@ -8262,6 +8228,9 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, u16 cnt, val, tmp1; struct bnx2x *bp = params->bp; + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); /* HW reset */ @@ -8445,6 +8414,9 @@ static int bnx2x_8726_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); bnx2x_wait_reset_complete(bp, phy, params); @@ -8613,6 +8585,9 @@ static int bnx2x_8727_config_init(struct bnx2x_phy *phy, struct bnx2x *bp = params->bp; /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */ + /* SPF+ PHY: Set flag to check for Tx error */ + vars->phy_flags = PHY_TX_ERROR_CHECK_FLAG; + bnx2x_wait_reset_complete(bp, phy, params); rx_alarm_ctrl_val = (1<<2) | (1<<5) ; /* Should be 0x6 to enable XS on Tx side. */ @@ -9268,13 +9243,7 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, if (phy->req_duplex == DUPLEX_FULL) autoneg_val |= (1<<8); - /* - * Always write this if this is not 84833. - * For 84833, write it only when it's a forced speed. - */ - if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) || - ((autoneg_val & (1<<12)) == 0)) - bnx2x_cl45_write(bp, phy, + bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val); @@ -9288,12 +9257,13 @@ static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x3200); - } else + } else if (phy->req_line_speed != SPEED_10 && + phy->req_line_speed != SPEED_100) { bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8481_10GBASE_T_AN_CTRL, 1); - + } /* Save spirom version */ bnx2x_save_848xx_spirom_version(phy, params); @@ -9786,9 +9756,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &val16); - bnx2x_cl45_write(bp, phy, - MDIO_PMA_DEVAD, - MDIO_PMA_REG_CTRL, 0x800); + /* Put to low power mode on newer FW */ + if ((val16 & 0x303f) > 0x1009) + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_CTRL, 0x800); } } @@ -10219,15 +10191,8 @@ static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy, u32 cfg_pin; u8 port; - /* - * In case of no EPIO routed to reset the GPHY, put it - * in low power mode. - */ - bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800); - /* - * This works with E3 only, no need to check the chip - * before determining the port. - */ + /* This works with E3 only, no need to check the chip + before determining the port. */ port = params->port; cfg_pin = (REG_RD(bp, params->shmem_base + offsetof(struct shmem_region, @@ -10638,8 +10603,7 @@ static struct bnx2x_phy phy_warpcore = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT, .addr = 0xff, .def_md_devad = 0, - .flags = (FLAGS_HW_LOCK_REQUIRED | - FLAGS_TX_ERROR_CHECK), + .flags = FLAGS_HW_LOCK_REQUIRED, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -10765,8 +10729,7 @@ static struct bnx2x_phy phy_8706 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706, .addr = 0xff, .def_md_devad = 0, - .flags = (FLAGS_INIT_XGXS_FIRST | - FLAGS_TX_ERROR_CHECK), + .flags = FLAGS_INIT_XGXS_FIRST, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -10797,8 +10760,7 @@ static struct bnx2x_phy phy_8726 = { .addr = 0xff, .def_md_devad = 0, .flags = (FLAGS_HW_LOCK_REQUIRED | - FLAGS_INIT_XGXS_FIRST | - FLAGS_TX_ERROR_CHECK), + FLAGS_INIT_XGXS_FIRST), .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -10829,8 +10791,7 @@ static struct bnx2x_phy phy_8727 = { .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, .addr = 0xff, .def_md_devad = 0, - .flags = (FLAGS_FAN_FAILURE_DET_REQ | - FLAGS_TX_ERROR_CHECK), + .flags = FLAGS_FAN_FAILURE_DET_REQ, .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff}, .mdio_ctrl = 0, @@ -11151,8 +11112,6 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, */ if (CHIP_REV(bp) == CHIP_REV_Ax) phy->flags |= FLAGS_MDC_MDIO_WA; - else - phy->flags |= FLAGS_MDC_MDIO_WA_B0; } else { switch (switch_cfg) { case SWITCH_CFG_1G: @@ -11541,12 +11500,13 @@ void bnx2x_init_xmac_loopback(struct link_params *params, * Set WC to loopback mode since link is required to provide clock * to the XMAC in 20G mode */ - bnx2x_set_aer_mmd(params, ¶ms->phy[0]); - bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); - params->phy[INT_PHY].config_loopback( + if (vars->line_speed == SPEED_20000) { + bnx2x_set_aer_mmd(params, ¶ms->phy[0]); + bnx2x_warpcore_reset_lane(bp, ¶ms->phy[0], 0); + params->phy[INT_PHY].config_loopback( ¶ms->phy[INT_PHY], params); - + } bnx2x_xmac_enable(params, vars, 1); REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0); } @@ -11724,16 +11684,12 @@ int bnx2x_link_reset(struct link_params *params, struct link_vars *vars, bnx2x_set_led(params, vars, LED_MODE_OFF, 0); if (reset_ext_phy) { - bnx2x_set_mdio_clk(bp, params->chip_id, port); for (phy_index = EXT_PHY1; phy_index < params->num_phys; phy_index++) { - if (params->phy[phy_index].link_reset) { - bnx2x_set_aer_mmd(params, - ¶ms->phy[phy_index]); + if (params->phy[phy_index].link_reset) params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); - } if (params->phy[phy_index].flags & FLAGS_REARM_LATCH_SIGNAL) clear_latch_ind = 1; @@ -12222,6 +12178,10 @@ static void bnx2x_analyze_link_error(struct link_params *params, u8 led_mode; u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0; + /*DP(NETIF_MSG_LINK, "CHECK LINK: %x half_open:%x-> lss:%x\n", + vars->link_up, + half_open_conn, lss_status);*/ + if ((lss_status ^ half_open_conn) == 0) return; @@ -12234,7 +12194,6 @@ static void bnx2x_analyze_link_error(struct link_params *params, * b. Update link_vars->link_up */ if (lss_status) { - DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n"); vars->link_status &= ~LINK_STATUS_LINK_UP; vars->link_up = 0; vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG; @@ -12244,7 +12203,6 @@ static void bnx2x_analyze_link_error(struct link_params *params, */ led_mode = LED_MODE_OFF; } else { - DP(NETIF_MSG_LINK, "Remote Fault cleared\n"); vars->link_status |= LINK_STATUS_LINK_UP; vars->link_up = 1; vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG; @@ -12261,15 +12219,6 @@ static void bnx2x_analyze_link_error(struct link_params *params, bnx2x_notify_link_changed(bp); } -/****************************************************************************** -* Description: -* This function checks for half opened connection change indication. -* When such change occurs, it calls the bnx2x_analyze_link_error -* to check if Remote Fault is set or cleared. Reception of remote fault -* status message in the MAC indicates that the peer's MAC has detected -* a fault, for example, due to break in the TX side of fiber. -* -******************************************************************************/ static void bnx2x_check_half_open_conn(struct link_params *params, struct link_vars *vars) { @@ -12280,28 +12229,9 @@ static void bnx2x_check_half_open_conn(struct link_params *params, if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0) return; - if (CHIP_IS_E3(bp) && + if (!CHIP_IS_E3(bp) && (REG_RD(bp, MISC_REG_RESET_REG_2) & - (MISC_REGISTERS_RESET_REG_2_XMAC))) { - /* Check E3 XMAC */ - /* - * Note that link speed cannot be queried here, since it may be - * zero while link is down. In case UMAC is active, LSS will - * simply not be set - */ - mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0; - - /* Clear stick bits (Requires rising edge) */ - REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0); - REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, - XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS | - XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS); - if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS)) - lss_status = 1; - - bnx2x_analyze_link_error(params, vars, lss_status); - } else if (REG_RD(bp, MISC_REG_RESET_REG_2) & - (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) { + (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))) { /* Check E1X / E2 BMAC */ u32 lss_status_reg; u32 wb_data[2]; @@ -12323,20 +12253,14 @@ static void bnx2x_check_half_open_conn(struct link_params *params, void bnx2x_period_func(struct link_params *params, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u16 phy_idx; if (!params) { - DP(NETIF_MSG_LINK, "Uninitialized params !\n"); + DP(NETIF_MSG_LINK, "Ininitliazed params !\n"); return; } - - for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) { - if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) { - bnx2x_set_aer_mmd(params, ¶ms->phy[phy_idx]); - bnx2x_check_half_open_conn(params, vars); - break; - } - } - + /* DP(NETIF_MSG_LINK, "Periodic called vars->phy_flags 0x%x speed 0x%x + RESET_REG_2 0x%x\n", vars->phy_flags, vars->line_speed, + REG_RD(bp, MISC_REG_RESET_REG_2)); */ + bnx2x_check_half_open_conn(params, vars); if (CHIP_IS_E3(bp)) bnx2x_check_over_curr(params, vars); } diff --git a/trunk/drivers/net/bnx2x/bnx2x_link.h b/trunk/drivers/net/bnx2x/bnx2x_link.h index c12db6da213e..6a7708d5da37 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_link.h +++ b/trunk/drivers/net/bnx2x/bnx2x_link.h @@ -145,8 +145,6 @@ struct bnx2x_phy { #define FLAGS_SFP_NOT_APPROVED (1<<7) #define FLAGS_MDC_MDIO_WA (1<<8) #define FLAGS_DUMMY_READ (1<<9) -#define FLAGS_MDC_MDIO_WA_B0 (1<<10) -#define FLAGS_TX_ERROR_CHECK (1<<12) /* preemphasis values for the rx side */ u16 rx_preemphasis[4]; @@ -278,6 +276,7 @@ struct link_vars { #define PHY_PHYSICAL_LINK_FLAG (1<<2) #define PHY_HALF_OPEN_CONN_FLAG (1<<3) #define PHY_OVER_CURRENT_FLAG (1<<4) +#define PHY_TX_ERROR_CHECK_FLAG (1<<5) u8 mac_type; #define MAC_TYPE_NONE 0 diff --git a/trunk/drivers/net/bnx2x/bnx2x_main.c b/trunk/drivers/net/bnx2x/bnx2x_main.c index f74582a22c68..150709111548 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_main.c +++ b/trunk/drivers/net/bnx2x/bnx2x_main.c @@ -5798,12 +5798,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) DP(BNX2X_MSG_MCP, "starting common init func %d\n", BP_ABS_FUNC(bp)); - /* - * take the UNDI lock to protect undi_unload flow from accessing - * registers while we're resetting the chip - */ - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - bnx2x_reset_common(bp); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET, 0xffffffff); @@ -5814,8 +5808,6 @@ static int bnx2x_init_hw_common(struct bnx2x *bp) } REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, val); - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_UNDI); - bnx2x_init_block(bp, BLOCK_MISC, PHASE_COMMON); if (!CHIP_IS_E1x(bp)) { @@ -10259,17 +10251,10 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, /* clean indirect addresses */ pci_write_config_dword(bp->pdev, PCICFG_GRC_ADDRESS, PCICFG_VENDOR_ID_OFFSET); - /* Clean the following indirect addresses for all functions since it - * is not used by the driver. - */ - REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_88_F1, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F1, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_90_F1, 0); - REG_WR(bp, PXP2_REG_PGL_ADDR_94_F1, 0); + REG_WR(bp, PXP2_REG_PGL_ADDR_88_F0 + BP_PORT(bp)*16, 0); + REG_WR(bp, PXP2_REG_PGL_ADDR_8C_F0 + BP_PORT(bp)*16, 0); + REG_WR(bp, PXP2_REG_PGL_ADDR_90_F0 + BP_PORT(bp)*16, 0); + REG_WR(bp, PXP2_REG_PGL_ADDR_94_F0 + BP_PORT(bp)*16, 0); /* * Enable internal target-read (in case we are probed after PF FLR). diff --git a/trunk/drivers/net/bnx2x/bnx2x_reg.h b/trunk/drivers/net/bnx2x/bnx2x_reg.h index 40266c14e6dc..02461fef8751 100644 --- a/trunk/drivers/net/bnx2x/bnx2x_reg.h +++ b/trunk/drivers/net/bnx2x/bnx2x_reg.h @@ -3007,27 +3007,11 @@ /* [R 6] Debug only: Number of used entries in the data FIFO */ #define PXP2_REG_HST_DATA_FIFO_STATUS 0x12047c /* [R 7] Debug only: Number of used entries in the header FIFO */ -#define PXP2_REG_HST_HEADER_FIFO_STATUS 0x120478 -#define PXP2_REG_PGL_ADDR_88_F0 0x120534 -/* [R 32] GRC address for configuration access to PCIE config address 0x88. - * any write to this PCIE address will cause a GRC write access to the - * address that's in t this register */ -#define PXP2_REG_PGL_ADDR_88_F1 0x120544 -#define PXP2_REG_PGL_ADDR_8C_F0 0x120538 -/* [R 32] GRC address for configuration access to PCIE config address 0x8c. - * any write to this PCIE address will cause a GRC write access to the - * address that's in t this register */ -#define PXP2_REG_PGL_ADDR_8C_F1 0x120548 -#define PXP2_REG_PGL_ADDR_90_F0 0x12053c -/* [R 32] GRC address for configuration access to PCIE config address 0x90. - * any write to this PCIE address will cause a GRC write access to the - * address that's in t this register */ -#define PXP2_REG_PGL_ADDR_90_F1 0x12054c -#define PXP2_REG_PGL_ADDR_94_F0 0x120540 -/* [R 32] GRC address for configuration access to PCIE config address 0x94. - * any write to this PCIE address will cause a GRC write access to the - * address that's in t this register */ -#define PXP2_REG_PGL_ADDR_94_F1 0x120550 +#define PXP2_REG_HST_HEADER_FIFO_STATUS 0x120478 +#define PXP2_REG_PGL_ADDR_88_F0 0x120534 +#define PXP2_REG_PGL_ADDR_8C_F0 0x120538 +#define PXP2_REG_PGL_ADDR_90_F0 0x12053c +#define PXP2_REG_PGL_ADDR_94_F0 0x120540 #define PXP2_REG_PGL_CONTROL0 0x120490 #define PXP2_REG_PGL_CONTROL1 0x120514 #define PXP2_REG_PGL_DEBUG 0x120520 @@ -4787,11 +4771,9 @@ The fields are: [4:0] - tail pointer; 10:5] - Link List size; 15:11] - header pointer. */ #define UCM_REG_XX_TABLE 0xe0300 -#define UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE (0x1<<28) #define UMAC_COMMAND_CONFIG_REG_LOOP_ENA (0x1<<15) #define UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK (0x1<<24) #define UMAC_COMMAND_CONFIG_REG_PAD_EN (0x1<<5) -#define UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE (0x1<<8) #define UMAC_COMMAND_CONFIG_REG_PROMIS_EN (0x1<<4) #define UMAC_COMMAND_CONFIG_REG_RX_ENA (0x1<<1) #define UMAC_COMMAND_CONFIG_REG_SW_RESET (0x1<<13) @@ -5640,9 +5622,8 @@ #define EMAC_MDIO_COMM_START_BUSY (1L<<29) #define EMAC_MDIO_MODE_AUTO_POLL (1L<<4) #define EMAC_MDIO_MODE_CLAUSE_45 (1L<<31) -#define EMAC_MDIO_MODE_CLOCK_CNT (0x3ffL<<16) +#define EMAC_MDIO_MODE_CLOCK_CNT (0x3fL<<16) #define EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT 16 -#define EMAC_MDIO_STATUS_10MB (1L<<1) #define EMAC_MODE_25G_MODE (1L<<5) #define EMAC_MODE_HALF_DUPLEX (1L<<1) #define EMAC_MODE_PORT_GMII (2L<<2) @@ -5653,7 +5634,6 @@ #define EMAC_REG_EMAC_MAC_MATCH 0x10 #define EMAC_REG_EMAC_MDIO_COMM 0xac #define EMAC_REG_EMAC_MDIO_MODE 0xb4 -#define EMAC_REG_EMAC_MDIO_STATUS 0xb0 #define EMAC_REG_EMAC_MODE 0x0 #define EMAC_REG_EMAC_RX_MODE 0xc8 #define EMAC_REG_EMAC_RX_MTU_SIZE 0x9c diff --git a/trunk/drivers/net/can/slcan.c b/trunk/drivers/net/can/slcan.c index 4b70b7e8bdeb..f523f1cc5142 100644 --- a/trunk/drivers/net/can/slcan.c +++ b/trunk/drivers/net/can/slcan.c @@ -197,7 +197,7 @@ static void slc_bump(struct slcan *sl) skb->ip_summed = CHECKSUM_UNNECESSARY; memcpy(skb_put(skb, sizeof(struct can_frame)), &cf, sizeof(struct can_frame)); - netif_rx_ni(skb); + netif_rx(skb); sl->dev->stats.rx_packets++; sl->dev->stats.rx_bytes += cf.can_dlc; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index 5548d464261a..c5f0f04219f3 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -838,7 +838,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - E1000_WRITE_FLUSH(); msleep(10); /* Test each interrupt */ @@ -857,7 +856,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, mask); ew32(ICS, mask); - E1000_WRITE_FLUSH(); msleep(10); if (adapter->test_icr & mask) { @@ -875,7 +873,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMS, mask); ew32(ICS, mask); - E1000_WRITE_FLUSH(); msleep(10); if (!(adapter->test_icr & mask)) { @@ -893,7 +890,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, ~mask & 0x00007FFF); ew32(ICS, ~mask & 0x00007FFF); - E1000_WRITE_FLUSH(); msleep(10); if (adapter->test_icr) { @@ -905,7 +901,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - E1000_WRITE_FLUSH(); msleep(10); /* Unhook test interrupt handler */ @@ -1399,7 +1394,6 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) if (unlikely(++k == txdr->count)) k = 0; } ew32(TDT, k); - E1000_WRITE_FLUSH(); msleep(200); time = jiffies; /* set the start time for the receive */ good_cnt = 0; diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 8545c7aa93eb..1698622af434 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -446,7 +446,6 @@ s32 e1000_reset_hw(struct e1000_hw *hw) /* Must reset the PHY before resetting the MAC */ if ((hw->mac_type == e1000_82541) || (hw->mac_type == e1000_82547)) { ew32(CTRL, (ctrl | E1000_CTRL_PHY_RST)); - E1000_WRITE_FLUSH(); msleep(5); } @@ -3753,7 +3752,6 @@ static s32 e1000_acquire_eeprom(struct e1000_hw *hw) /* Clear SK and CS */ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); ew32(EECD, eecd); - E1000_WRITE_FLUSH(); udelay(1); } @@ -3826,7 +3824,6 @@ static void e1000_release_eeprom(struct e1000_hw *hw) eecd &= ~E1000_EECD_SK; /* Lower SCK */ ew32(EECD, eecd); - E1000_WRITE_FLUSH(); udelay(hw->eeprom.delay_usec); } else if (hw->eeprom.type == e1000_eeprom_microwire) { diff --git a/trunk/drivers/net/e1000e/82571.c b/trunk/drivers/net/e1000e/82571.c index 536b3a55c45f..480f2592f8a5 100644 --- a/trunk/drivers/net/e1000e/82571.c +++ b/trunk/drivers/net/e1000e/82571.c @@ -2085,8 +2085,7 @@ struct e1000_info e1000_82574_info = { | FLAG_HAS_AMT | FLAG_HAS_CTRLEXT_ON_LOAD, .flags2 = FLAG2_CHECK_PHY_HANG - | FLAG2_DISABLE_ASPM_L0S - | FLAG2_NO_DISABLE_RX, + | FLAG2_DISABLE_ASPM_L0S, .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, @@ -2105,8 +2104,7 @@ struct e1000_info e1000_82583_info = { | FLAG_HAS_AMT | FLAG_HAS_JUMBO_FRAMES | FLAG_HAS_CTRLEXT_ON_LOAD, - .flags2 = FLAG2_DISABLE_ASPM_L0S - | FLAG2_NO_DISABLE_RX, + .flags2 = FLAG2_DISABLE_ASPM_L0S, .pba = 32, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_82571, diff --git a/trunk/drivers/net/e1000e/e1000.h b/trunk/drivers/net/e1000e/e1000.h index 35916f485028..638d175792cf 100644 --- a/trunk/drivers/net/e1000e/e1000.h +++ b/trunk/drivers/net/e1000e/e1000.h @@ -453,7 +453,6 @@ struct e1000_info { #define FLAG2_DISABLE_ASPM_L0S (1 << 7) #define FLAG2_DISABLE_AIM (1 << 8) #define FLAG2_CHECK_PHY_HANG (1 << 9) -#define FLAG2_NO_DISABLE_RX (1 << 10) #define E1000_RX_DESC_PS(R, i) \ (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) diff --git a/trunk/drivers/net/e1000e/es2lan.c b/trunk/drivers/net/e1000e/es2lan.c index e4f42257c24c..c0ecb2d9fdb7 100644 --- a/trunk/drivers/net/e1000e/es2lan.c +++ b/trunk/drivers/net/e1000e/es2lan.c @@ -1313,7 +1313,6 @@ static s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; ew32(KMRNCTRLSTA, kmrnctrlsta); - e1e_flush(); udelay(2); @@ -1348,7 +1347,6 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | data; ew32(KMRNCTRLSTA, kmrnctrlsta); - e1e_flush(); udelay(2); diff --git a/trunk/drivers/net/e1000e/ethtool.c b/trunk/drivers/net/e1000e/ethtool.c index 6a0526a59a8a..cb1a3623253e 100644 --- a/trunk/drivers/net/e1000e/ethtool.c +++ b/trunk/drivers/net/e1000e/ethtool.c @@ -28,8 +28,8 @@ /* ethtool support for e1000 */ -#include #include +#include #include #include #include @@ -964,7 +964,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - e1e_flush(); usleep_range(10000, 20000); /* Test each interrupt */ @@ -997,7 +996,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, mask); ew32(ICS, mask); - e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr & mask) { @@ -1016,7 +1014,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMS, mask); ew32(ICS, mask); - e1e_flush(); usleep_range(10000, 20000); if (!(adapter->test_icr & mask)) { @@ -1035,7 +1032,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) adapter->test_icr = 0; ew32(IMC, ~mask & 0x00007FFF); ew32(ICS, ~mask & 0x00007FFF); - e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr) { @@ -1047,7 +1043,6 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); - e1e_flush(); usleep_range(10000, 20000); /* Unhook test interrupt handler */ @@ -1206,8 +1201,7 @@ static int e1000_setup_desc_rings(struct e1000_adapter *adapter) rx_ring->next_to_clean = 0; rctl = er32(RCTL); - if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) - ew32(RCTL, rctl & ~E1000_RCTL_EN); + ew32(RCTL, rctl & ~E1000_RCTL_EN); ew32(RDBAL, ((u64) rx_ring->dma & 0xFFFFFFFF)); ew32(RDBAH, ((u64) rx_ring->dma >> 32)); ew32(RDLEN, rx_ring->size); @@ -1282,7 +1276,6 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter) E1000_CTRL_FD); /* Force Duplex to FULL */ ew32(CTRL, ctrl_reg); - e1e_flush(); udelay(500); return 0; @@ -1425,7 +1418,6 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter) */ #define E1000_SERDES_LB_ON 0x410 ew32(SCTL, E1000_SERDES_LB_ON); - e1e_flush(); usleep_range(10000, 20000); return 0; @@ -1521,7 +1513,6 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter) hw->phy.media_type == e1000_media_type_internal_serdes) { #define E1000_SERDES_LB_OFF 0x400 ew32(SCTL, E1000_SERDES_LB_OFF); - e1e_flush(); usleep_range(10000, 20000); break; } @@ -1601,7 +1592,6 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter) k = 0; } ew32(TDT, k); - e1e_flush(); msleep(200); time = jiffies; /* set the start time for the receive */ good_cnt = 0; diff --git a/trunk/drivers/net/e1000e/ich8lan.c b/trunk/drivers/net/e1000e/ich8lan.c index 4e36978b8fd8..c1752124f3cd 100644 --- a/trunk/drivers/net/e1000e/ich8lan.c +++ b/trunk/drivers/net/e1000e/ich8lan.c @@ -283,7 +283,6 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) ctrl |= E1000_CTRL_LANPHYPC_OVERRIDE; ctrl &= ~E1000_CTRL_LANPHYPC_VALUE; ew32(CTRL, ctrl); - e1e_flush(); udelay(10); ctrl &= ~E1000_CTRL_LANPHYPC_OVERRIDE; ew32(CTRL, ctrl); @@ -1231,11 +1230,9 @@ s32 e1000_configure_k1_ich8lan(struct e1000_hw *hw, bool k1_enable) ew32(CTRL, reg); ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_SPD_BYPS); - e1e_flush(); udelay(20); ew32(CTRL, ctrl_reg); ew32(CTRL_EXT, ctrl_ext); - e1e_flush(); udelay(20); out: @@ -2137,7 +2134,8 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words, ret_val = 0; for (i = 0; i < words; i++) { - if (dev_spec->shadow_ram[offset+i].modified) { + if ((dev_spec->shadow_ram) && + (dev_spec->shadow_ram[offset+i].modified)) { data[i] = dev_spec->shadow_ram[offset+i].value; } else { ret_val = e1000_read_flash_word_ich8lan(hw, @@ -3092,7 +3090,6 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw) ret_val = e1000_acquire_swflag_ich8lan(hw); e_dbg("Issuing a global reset to ich8lan\n"); ew32(CTRL, (ctrl | E1000_CTRL_RST)); - /* cannot issue a flush here because it hangs the hardware */ msleep(20); if (!ret_val) diff --git a/trunk/drivers/net/e1000e/lib.c b/trunk/drivers/net/e1000e/lib.c index 0893ab107adf..65580b405942 100644 --- a/trunk/drivers/net/e1000e/lib.c +++ b/trunk/drivers/net/e1000e/lib.c @@ -190,8 +190,7 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ if (!((nvm_data & NVM_COMPAT_LOM) || (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) + (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD))) goto out; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, @@ -201,10 +200,10 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) goto out; } - if ((nvm_alt_mac_addr_offset == 0xFFFF) || - (nvm_alt_mac_addr_offset == 0x0000)) + if (nvm_alt_mac_addr_offset == 0xFFFF) { /* There is no Alternate MAC Address */ goto out; + } if (hw->bus.func == E1000_FUNC_1) nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; @@ -1987,7 +1986,6 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) /* Clear SK and CS */ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); ew32(EECD, eecd); - e1e_flush(); udelay(1); /* diff --git a/trunk/drivers/net/e1000e/netdev.c b/trunk/drivers/net/e1000e/netdev.c index 362f70382cdd..4353ad56cf16 100644 --- a/trunk/drivers/net/e1000e/netdev.c +++ b/trunk/drivers/net/e1000e/netdev.c @@ -31,12 +31,12 @@ #include #include #include +#include #include #include #include #include #include -#include #include #include #include @@ -56,7 +56,7 @@ #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.4.4" DRV_EXTRAVERSION +#define DRV_VERSION "1.3.16" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; @@ -2915,8 +2915,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* disable receives while setting up the descriptors */ rctl = er32(RCTL); - if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) - ew32(RCTL, rctl & ~E1000_RCTL_EN); + ew32(RCTL, rctl & ~E1000_RCTL_EN); e1e_flush(); usleep_range(10000, 20000); @@ -3395,8 +3394,7 @@ void e1000e_down(struct e1000_adapter *adapter) /* disable receives in the hardware */ rctl = er32(RCTL); - if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX)) - ew32(RCTL, rctl & ~E1000_RCTL_EN); + ew32(RCTL, rctl & ~E1000_RCTL_EN); /* flush and sleep below */ netif_stop_queue(netdev); @@ -3405,7 +3403,6 @@ void e1000e_down(struct e1000_adapter *adapter) tctl = er32(TCTL); tctl &= ~E1000_TCTL_EN; ew32(TCTL, tctl); - /* flush both disables and wait for them to finish */ e1e_flush(); usleep_range(10000, 20000); diff --git a/trunk/drivers/net/e1000e/phy.c b/trunk/drivers/net/e1000e/phy.c index 8666476cb9be..2a6ee13285b1 100644 --- a/trunk/drivers/net/e1000e/phy.c +++ b/trunk/drivers/net/e1000e/phy.c @@ -537,7 +537,6 @@ static s32 __e1000_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data, kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN; ew32(KMRNCTRLSTA, kmrnctrlsta); - e1e_flush(); udelay(2); @@ -610,7 +609,6 @@ static s32 __e1000_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data, kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) & E1000_KMRNCTRLSTA_OFFSET) | data; ew32(KMRNCTRLSTA, kmrnctrlsta); - e1e_flush(); udelay(2); diff --git a/trunk/drivers/net/gianfar_ptp.c b/trunk/drivers/net/gianfar_ptp.c index f67b8aebc89c..1c97861596f0 100644 --- a/trunk/drivers/net/gianfar_ptp.c +++ b/trunk/drivers/net/gianfar_ptp.c @@ -193,9 +193,14 @@ static void set_alarm(struct etsects *etsects) /* Caller must hold etsects->lock. */ static void set_fipers(struct etsects *etsects) { - set_alarm(etsects); + u32 tmr_ctrl = gfar_read(&etsects->regs->tmr_ctrl); + + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl & (~TE)); + gfar_write(&etsects->regs->tmr_prsc, etsects->tmr_prsc); gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); + set_alarm(etsects); + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|TE); } /* @@ -506,7 +511,7 @@ static int gianfar_ptp_probe(struct platform_device *dev) gfar_write(&etsects->regs->tmr_fiper1, etsects->tmr_fiper1); gfar_write(&etsects->regs->tmr_fiper2, etsects->tmr_fiper2); set_alarm(etsects); - gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE|FRD); + gfar_write(&etsects->regs->tmr_ctrl, tmr_ctrl|FS|RTPE|TE); spin_unlock_irqrestore(&etsects->lock, flags); diff --git a/trunk/drivers/net/igb/e1000_nvm.c b/trunk/drivers/net/igb/e1000_nvm.c index 40407124e722..7dcd65cede56 100644 --- a/trunk/drivers/net/igb/e1000_nvm.c +++ b/trunk/drivers/net/igb/e1000_nvm.c @@ -285,7 +285,6 @@ static s32 igb_ready_nvm_eeprom(struct e1000_hw *hw) /* Clear SK and CS */ eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); wr32(E1000_EECD, eecd); - wrfl(); udelay(1); timeout = NVM_MAX_RETRY_SPI; diff --git a/trunk/drivers/net/igb/igb_ethtool.c b/trunk/drivers/net/igb/igb_ethtool.c index 414b0225be89..ff244ce803ce 100644 --- a/trunk/drivers/net/igb/igb_ethtool.c +++ b/trunk/drivers/net/igb/igb_ethtool.c @@ -1225,7 +1225,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) /* Disable all the interrupts */ wr32(E1000_IMC, ~0); - wrfl(); msleep(10); /* Define all writable bits for ICS */ @@ -1269,7 +1268,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMC, mask); wr32(E1000_ICS, mask); - wrfl(); msleep(10); if (adapter->test_icr & mask) { @@ -1291,7 +1289,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMS, mask); wr32(E1000_ICS, mask); - wrfl(); msleep(10); if (!(adapter->test_icr & mask)) { @@ -1313,7 +1310,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) wr32(E1000_IMC, ~mask); wr32(E1000_ICS, ~mask); - wrfl(); msleep(10); if (adapter->test_icr & mask) { @@ -1325,7 +1321,6 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data) /* Disable all the interrupts */ wr32(E1000_IMC, ~0); - wrfl(); msleep(10); /* Unhook test interrupt handler */ diff --git a/trunk/drivers/net/igb/igb_main.c b/trunk/drivers/net/igb/igb_main.c index 40d4c405fd7e..dc599059512a 100644 --- a/trunk/drivers/net/igb/igb_main.c +++ b/trunk/drivers/net/igb/igb_main.c @@ -1052,7 +1052,6 @@ static int igb_set_interrupt_capability(struct igb_adapter *adapter) kfree(adapter->vf_data); adapter->vf_data = NULL; wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); - wrfl(); msleep(100); dev_info(&adapter->pdev->dev, "IOV Disabled\n"); } @@ -2023,7 +2022,7 @@ static int __devinit igb_probe(struct pci_dev *pdev, if (hw->bus.func == 0) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A, 1, &eeprom_data); - else if (hw->mac.type >= e1000_82580) + else if (hw->mac.type == e1000_82580) hw->nvm.ops.read(hw, NVM_INIT_CONTROL3_PORT_A + NVM_82580_LAN_FUNC_OFFSET(hw->bus.func), 1, &eeprom_data); @@ -2199,7 +2198,6 @@ static void __devexit igb_remove(struct pci_dev *pdev) kfree(adapter->vf_data); adapter->vf_data = NULL; wr32(E1000_IOVCTL, E1000_IOVCTL_REUSE_VFQ); - wrfl(); msleep(100); dev_info(&pdev->dev, "IOV Disabled\n"); } diff --git a/trunk/drivers/net/igbvf/netdev.c b/trunk/drivers/net/igbvf/netdev.c index 40ed066e3ef4..1330c8e932da 100644 --- a/trunk/drivers/net/igbvf/netdev.c +++ b/trunk/drivers/net/igbvf/netdev.c @@ -1226,7 +1226,6 @@ static void igbvf_configure_tx(struct igbvf_adapter *adapter) /* disable transmits */ txdctl = er32(TXDCTL(0)); ew32(TXDCTL(0), txdctl & ~E1000_TXDCTL_QUEUE_ENABLE); - e1e_flush(); msleep(10); /* Setup the HW Tx Head and Tail descriptor pointers */ @@ -1307,7 +1306,6 @@ static void igbvf_configure_rx(struct igbvf_adapter *adapter) /* disable receives */ rxdctl = er32(RXDCTL(0)); ew32(RXDCTL(0), rxdctl & ~E1000_RXDCTL_QUEUE_ENABLE); - e1e_flush(); msleep(10); rdlen = rx_ring->count * sizeof(union e1000_adv_rx_desc); diff --git a/trunk/drivers/net/irda/sh_irda.c b/trunk/drivers/net/irda/sh_irda.c index 82660672dcd9..4488bd581eca 100644 --- a/trunk/drivers/net/irda/sh_irda.c +++ b/trunk/drivers/net/irda/sh_irda.c @@ -22,8 +22,6 @@ * - DMA transfer support * - FIFO mode support */ -#include -#include #include #include #include diff --git a/trunk/drivers/net/irda/sh_sir.c b/trunk/drivers/net/irda/sh_sir.c index ed7d7d62bf68..52a7c86af663 100644 --- a/trunk/drivers/net/irda/sh_sir.c +++ b/trunk/drivers/net/irda/sh_sir.c @@ -12,8 +12,6 @@ * published by the Free Software Foundation. */ -#include -#include #include #include #include @@ -513,7 +511,7 @@ static void sh_sir_tx(struct sh_sir_self *self, int phase) static int sh_sir_read_data(struct sh_sir_self *self) { - u16 val = 0; + u16 val; int timeout = 1024; while (timeout--) { diff --git a/trunk/drivers/net/irda/smsc-ircc2.c b/trunk/drivers/net/irda/smsc-ircc2.c index 8b1c3484d271..954f6e938fb7 100644 --- a/trunk/drivers/net/irda/smsc-ircc2.c +++ b/trunk/drivers/net/irda/smsc-ircc2.c @@ -2405,6 +2405,8 @@ static int __init smsc_superio_lpc(unsigned short cfg_base) * addresses making a subsystem device table necessary. */ #ifdef CONFIG_PCI +#define PCIID_VENDOR_INTEL 0x8086 +#define PCIID_VENDOR_ALI 0x10b9 static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __initdata = { /* * Subsystems needing entries: @@ -2414,7 +2416,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini */ { /* Guessed entry */ - .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x08bc, @@ -2427,7 +2429,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nx5000 family", }, { - .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x088c, @@ -2441,7 +2443,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nc8000 family", }, { - .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x103c, .subdevice = 0x0890, @@ -2454,7 +2456,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "HP nc6000 family", }, { - .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801DBM LPC bridge */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801DBM LPC bridge */ .device = 0x24cc, .subvendor = 0x0e11, .subdevice = 0x0860, @@ -2469,7 +2471,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* Intel 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge */ - .vendor = PCI_VENDOR_ID_INTEL, + .vendor = PCIID_VENDOR_INTEL, .device = 0x24c0, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2482,7 +2484,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini .name = "Toshiba laptop with Intel 82801DB/DBL LPC bridge", }, { - .vendor = PCI_VENDOR_ID_INTEL, /* Intel 82801CAM ISA bridge */ + .vendor = PCIID_VENDOR_INTEL, /* Intel 82801CAM ISA bridge */ .device = 0x248c, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2496,7 +2498,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* 82801DBM (ICH4-M) LPC Interface Bridge */ - .vendor = PCI_VENDOR_ID_INTEL, + .vendor = PCIID_VENDOR_INTEL, .device = 0x24cc, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ @@ -2510,7 +2512,7 @@ static struct smsc_ircc_subsystem_configuration subsystem_configurations[] __ini }, { /* ALi M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] */ - .vendor = PCI_VENDOR_ID_AL, + .vendor = PCIID_VENDOR_ALI, .device = 0x1533, .subvendor = 0x1179, .subdevice = 0xffff, /* 0xffff is "any" */ diff --git a/trunk/drivers/net/ixgb/ixgb_ee.c b/trunk/drivers/net/ixgb/ixgb_ee.c index 38b362b67857..c982ab9f9005 100644 --- a/trunk/drivers/net/ixgb/ixgb_ee.c +++ b/trunk/drivers/net/ixgb/ixgb_ee.c @@ -57,7 +57,6 @@ ixgb_raise_clock(struct ixgb_hw *hw, */ *eecd_reg = *eecd_reg | IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, *eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); } @@ -76,7 +75,6 @@ ixgb_lower_clock(struct ixgb_hw *hw, */ *eecd_reg = *eecd_reg & ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, *eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); } @@ -114,7 +112,6 @@ ixgb_shift_out_bits(struct ixgb_hw *hw, eecd_reg |= IXGB_EECD_DI; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); @@ -209,25 +206,21 @@ ixgb_standby_eeprom(struct ixgb_hw *hw) /* Deselect EEPROM */ eecd_reg &= ~(IXGB_EECD_CS | IXGB_EECD_SK); IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); /* Clock high */ eecd_reg |= IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); /* Select EEPROM */ eecd_reg |= IXGB_EECD_CS; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); /* Clock low */ eecd_reg &= ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); } @@ -246,13 +239,11 @@ ixgb_clock_eeprom(struct ixgb_hw *hw) /* Rising edge of clock */ eecd_reg |= IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); /* Falling edge of clock */ eecd_reg &= ~IXGB_EECD_SK; IXGB_WRITE_REG(hw, EECD, eecd_reg); - IXGB_WRITE_FLUSH(hw); udelay(50); } diff --git a/trunk/drivers/net/ixgb/ixgb_hw.c b/trunk/drivers/net/ixgb/ixgb_hw.c index 3d61a9e4faf7..6cb2e42ff4c1 100644 --- a/trunk/drivers/net/ixgb/ixgb_hw.c +++ b/trunk/drivers/net/ixgb/ixgb_hw.c @@ -149,7 +149,6 @@ ixgb_adapter_stop(struct ixgb_hw *hw) */ IXGB_WRITE_REG(hw, RCTL, IXGB_READ_REG(hw, RCTL) & ~IXGB_RCTL_RXEN); IXGB_WRITE_REG(hw, TCTL, IXGB_READ_REG(hw, TCTL) & ~IXGB_TCTL_TXEN); - IXGB_WRITE_FLUSH(hw); msleep(IXGB_DELAY_BEFORE_RESET); /* Issue a global reset to the MAC. This will reset the chip's @@ -1221,7 +1220,6 @@ ixgb_optics_reset_bcm(struct ixgb_hw *hw) ctrl &= ~IXGB_CTRL0_SDP2; ctrl |= IXGB_CTRL0_SDP3; IXGB_WRITE_REG(hw, CTRL0, ctrl); - IXGB_WRITE_FLUSH(hw); /* SerDes needs extra delay */ msleep(IXGB_SUN_PHY_RESET_DELAY); diff --git a/trunk/drivers/net/ixgbe/ixgbe_82599.c b/trunk/drivers/net/ixgbe/ixgbe_82599.c index 34f30ec79c2e..3b3dd4df4c5c 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_82599.c +++ b/trunk/drivers/net/ixgbe/ixgbe_82599.c @@ -213,7 +213,6 @@ static s32 ixgbe_init_phy_ops_82599(struct ixgbe_hw *hw) switch (hw->phy.type) { case ixgbe_phy_tn: phy->ops.check_link = &ixgbe_check_phy_link_tnx; - phy->ops.setup_link = &ixgbe_setup_phy_link_tnx; phy->ops.get_firmware_version = &ixgbe_get_phy_firmware_version_tnx; break; diff --git a/trunk/drivers/net/ixgbe/ixgbe_common.c b/trunk/drivers/net/ixgbe/ixgbe_common.c index fc1375f26fe5..777051f54e53 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_common.c +++ b/trunk/drivers/net/ixgbe/ixgbe_common.c @@ -2632,7 +2632,6 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_FLU; IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); - IXGBE_WRITE_FLUSH(hw); usleep_range(10000, 20000); } diff --git a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c index 82d4244c6e10..dc649553a0a6 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/trunk/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1378,7 +1378,6 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) /* Disable all the interrupts */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - IXGBE_WRITE_FLUSH(&adapter->hw); usleep_range(10000, 20000); /* Test each interrupt */ @@ -1399,7 +1398,6 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) ~mask & 0x00007FFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, ~mask & 0x00007FFF); - IXGBE_WRITE_FLUSH(&adapter->hw); usleep_range(10000, 20000); if (adapter->test_icr & mask) { @@ -1417,7 +1415,6 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) adapter->test_icr = 0; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, mask); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, mask); - IXGBE_WRITE_FLUSH(&adapter->hw); usleep_range(10000, 20000); if (!(adapter->test_icr &mask)) { @@ -1438,7 +1435,6 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) ~mask & 0x00007FFF); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, ~mask & 0x00007FFF); - IXGBE_WRITE_FLUSH(&adapter->hw); usleep_range(10000, 20000); if (adapter->test_icr) { @@ -1450,7 +1446,6 @@ static int ixgbe_intr_test(struct ixgbe_adapter *adapter, u64 *data) /* Disable all the interrupts */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, 0xFFFFFFFF); - IXGBE_WRITE_FLUSH(&adapter->hw); usleep_range(10000, 20000); /* Unhook test interrupt handler */ diff --git a/trunk/drivers/net/ixgbe/ixgbe_main.c b/trunk/drivers/net/ixgbe/ixgbe_main.c index e86297b32733..1be617545dc9 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_main.c +++ b/trunk/drivers/net/ixgbe/ixgbe_main.c @@ -184,7 +184,6 @@ static inline void ixgbe_disable_sriov(struct ixgbe_adapter *adapter) vmdctl = IXGBE_READ_REG(hw, IXGBE_VT_CTL); vmdctl &= ~IXGBE_VT_CTL_POOL_MASK; IXGBE_WRITE_REG(hw, IXGBE_VT_CTL, vmdctl); - IXGBE_WRITE_FLUSH(hw); /* take a breather then clean up driver data */ msleep(100); @@ -1006,7 +1005,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) struct ixgbe_adapter *adapter = dev_get_drvdata(dev); unsigned long event = *(unsigned long *)data; - if (!(adapter->flags & IXGBE_FLAG_DCA_CAPABLE)) + if (!(adapter->flags & IXGBE_FLAG_DCA_ENABLED)) return 0; switch (event) { diff --git a/trunk/drivers/net/ixgbe/ixgbe_phy.c b/trunk/drivers/net/ixgbe/ixgbe_phy.c index f7ca3511b9fe..735f686c3b36 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_phy.c +++ b/trunk/drivers/net/ixgbe/ixgbe_phy.c @@ -1585,7 +1585,6 @@ static s32 ixgbe_raise_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) *i2cctl |= IXGBE_I2C_CLK_OUT; IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); - IXGBE_WRITE_FLUSH(hw); /* SCL rise time (1000ns) */ udelay(IXGBE_I2C_T_RISE); @@ -1606,7 +1605,6 @@ static void ixgbe_lower_i2c_clk(struct ixgbe_hw *hw, u32 *i2cctl) *i2cctl &= ~IXGBE_I2C_CLK_OUT; IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); - IXGBE_WRITE_FLUSH(hw); /* SCL fall time (300ns) */ udelay(IXGBE_I2C_T_FALL); @@ -1630,7 +1628,6 @@ static s32 ixgbe_set_i2c_data(struct ixgbe_hw *hw, u32 *i2cctl, bool data) *i2cctl &= ~IXGBE_I2C_DATA_OUT; IXGBE_WRITE_REG(hw, IXGBE_I2CCTL, *i2cctl); - IXGBE_WRITE_FLUSH(hw); /* Data rise/fall (1000ns/300ns) and set-up time (250ns) */ udelay(IXGBE_I2C_T_RISE + IXGBE_I2C_T_FALL + IXGBE_I2C_T_SU_DATA); diff --git a/trunk/drivers/net/ixgbe/ixgbe_x540.c b/trunk/drivers/net/ixgbe/ixgbe_x540.c index 2696c78e9f46..bec30ed91adc 100644 --- a/trunk/drivers/net/ixgbe/ixgbe_x540.c +++ b/trunk/drivers/net/ixgbe/ixgbe_x540.c @@ -162,7 +162,6 @@ static s32 ixgbe_reset_hw_X540(struct ixgbe_hw *hw) ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); ctrl_ext |= IXGBE_CTRL_EXT_PFRSTD; IXGBE_WRITE_REG(hw, IXGBE_CTRL_EXT, ctrl_ext); - IXGBE_WRITE_FLUSH(hw); msleep(50); diff --git a/trunk/drivers/net/macb.c b/trunk/drivers/net/macb.c index dc4e305a1087..0fcdc25699d8 100644 --- a/trunk/drivers/net/macb.c +++ b/trunk/drivers/net/macb.c @@ -322,9 +322,6 @@ static void macb_tx(struct macb *bp) for (i = 0; i < TX_RING_SIZE; i++) bp->tx_ring[i].ctrl = MACB_BIT(TX_USED); - /* Add wrap bit */ - bp->tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); - /* free transmit buffer in upper layer*/ for (tail = bp->tx_tail; tail != head; tail = NEXT_TX(tail)) { struct ring_info *rp = &bp->tx_skb[tail]; diff --git a/trunk/drivers/net/mlx4/en_port.c b/trunk/drivers/net/mlx4/en_port.c index 5ada5b469112..5e7109178061 100644 --- a/trunk/drivers/net/mlx4/en_port.c +++ b/trunk/drivers/net/mlx4/en_port.c @@ -128,7 +128,7 @@ int mlx4_SET_PORT_qpn_calc(struct mlx4_dev *dev, u8 port, u32 base_qpn, memset(context, 0, sizeof *context); context->base_qpn = cpu_to_be32(base_qpn); - context->n_mac = 0x2; + context->n_mac = 0x7; context->promisc = cpu_to_be32(promisc << SET_PORT_PROMISC_SHIFT | base_qpn); context->mcast = cpu_to_be32(m_promisc << SET_PORT_MC_PROMISC_SHIFT | diff --git a/trunk/drivers/net/mlx4/main.c b/trunk/drivers/net/mlx4/main.c index f0ee35df4dd7..c94b3426d355 100644 --- a/trunk/drivers/net/mlx4/main.c +++ b/trunk/drivers/net/mlx4/main.c @@ -1117,8 +1117,6 @@ static int mlx4_init_port_info(struct mlx4_dev *dev, int port) info->port = port; mlx4_init_mac_table(dev, &info->mac_table); mlx4_init_vlan_table(dev, &info->vlan_table); - info->base_qpn = dev->caps.reserved_qps_base[MLX4_QP_REGION_ETH_ADDR] + - (port - 1) * (1 << log_num_mac); sprintf(info->dev_name, "mlx4_port%d", port); info->port_attr.attr.name = info->dev_name; diff --git a/trunk/drivers/net/mlx4/port.c b/trunk/drivers/net/mlx4/port.c index 609e0ec14cee..1f95afda6841 100644 --- a/trunk/drivers/net/mlx4/port.c +++ b/trunk/drivers/net/mlx4/port.c @@ -258,12 +258,9 @@ void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, int qpn) if (validate_index(dev, table, index)) goto out; - /* Check whether this address has reference count */ - if (!(--table->refs[index])) { - table->entries[index] = 0; - mlx4_set_port_mac_table(dev, port, table->entries); - --table->total; - } + table->entries[index] = 0; + mlx4_set_port_mac_table(dev, port, table->entries); + --table->total; out: mutex_unlock(&table->mutex); } diff --git a/trunk/drivers/net/niu.c b/trunk/drivers/net/niu.c index ed47585a6862..cd6c2317e29e 100644 --- a/trunk/drivers/net/niu.c +++ b/trunk/drivers/net/niu.c @@ -9201,7 +9201,7 @@ static int __devinit niu_ldg_init(struct niu *np) first_chan = 0; for (i = 0; i < port; i++) - first_chan += parent->rxchan_per_port[i]; + first_chan += parent->rxchan_per_port[port]; num_chan = parent->rxchan_per_port[port]; for (i = first_chan; i < (first_chan + num_chan); i++) { @@ -9217,7 +9217,7 @@ static int __devinit niu_ldg_init(struct niu *np) first_chan = 0; for (i = 0; i < port; i++) - first_chan += parent->txchan_per_port[i]; + first_chan += parent->txchan_per_port[port]; num_chan = parent->txchan_per_port[port]; for (i = first_chan; i < (first_chan + num_chan); i++) { err = niu_ldg_assign_ldn(np, parent, diff --git a/trunk/drivers/net/pcnet32.c b/trunk/drivers/net/pcnet32.c index 80b6f36a8074..8b3090dc4bcd 100644 --- a/trunk/drivers/net/pcnet32.c +++ b/trunk/drivers/net/pcnet32.c @@ -82,7 +82,7 @@ static int cards_found; /* * VLB I/O addresses */ -static unsigned int pcnet32_portlist[] = +static unsigned int pcnet32_portlist[] __initdata = { 0x300, 0x320, 0x340, 0x360, 0 }; static int pcnet32_debug; diff --git a/trunk/drivers/net/phy/dp83640.c b/trunk/drivers/net/phy/dp83640.c index cb6e0b486b1e..2cd8dc5847b4 100644 --- a/trunk/drivers/net/phy/dp83640.c +++ b/trunk/drivers/net/phy/dp83640.c @@ -34,7 +34,8 @@ #define PAGESEL 0x13 #define LAYER4 0x02 #define LAYER2 0x01 -#define MAX_RXTS 64 +#define MAX_RXTS 4 +#define MAX_TXTS 4 #define N_EXT_TS 1 #define PSF_PTPVER 2 #define PSF_EVNT 0x4000 @@ -217,7 +218,7 @@ static void phy2rxts(struct phy_rxts *p, struct rxts *rxts) rxts->seqid = p->seqid; rxts->msgtype = (p->msgtype >> 12) & 0xf; rxts->hash = p->msgtype & 0x0fff; - rxts->tmo = jiffies + 2; + rxts->tmo = jiffies + HZ; } static u64 phy2txts(struct phy_txts *p) diff --git a/trunk/drivers/net/r8169.c b/trunk/drivers/net/r8169.c index 02339b3352e7..7d9c650f395e 100644 --- a/trunk/drivers/net/r8169.c +++ b/trunk/drivers/net/r8169.c @@ -239,7 +239,6 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), 0, 0, RTL_CFG_1 }, { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), 0, 0, RTL_CFG_0 }, - { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4302), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(PCI_VENDOR_ID_AT, 0xc107), 0, 0, RTL_CFG_0 }, { PCI_DEVICE(0x16ec, 0x0116), 0, 0, RTL_CFG_0 }, { PCI_VENDOR_ID_LINKSYS, 0x1032, @@ -1092,21 +1091,6 @@ rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); } -struct exgmac_reg { - u16 addr; - u16 mask; - u32 val; -}; - -static void rtl_write_exgmac_batch(void __iomem *ioaddr, - const struct exgmac_reg *r, int len) -{ - while (len-- > 0) { - rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC); - r++; - } -} - static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) { u8 value = 0xff; @@ -3132,18 +3116,6 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) RTL_W32(MAC0, low); RTL_R32(MAC0); - if (tp->mac_version == RTL_GIGA_MAC_VER_34) { - const struct exgmac_reg e[] = { - { .addr = 0xe0, ERIAR_MASK_1111, .val = low }, - { .addr = 0xe4, ERIAR_MASK_1111, .val = high }, - { .addr = 0xf0, ERIAR_MASK_1111, .val = low << 16 }, - { .addr = 0xf4, ERIAR_MASK_1111, .val = high << 16 | - low >> 16 }, - }; - - rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e)); - } - RTL_W8(Cfg9346, Cfg9346_Lock); spin_unlock_irq(&tp->lock); diff --git a/trunk/drivers/net/sis190.c b/trunk/drivers/net/sis190.c index 3c0f1312b391..8ad7bfbaa3af 100644 --- a/trunk/drivers/net/sis190.c +++ b/trunk/drivers/net/sis190.c @@ -1825,16 +1825,6 @@ static int sis190_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL); } -static int sis190_mac_addr(struct net_device *dev, void *p) -{ - int rc; - - rc = eth_mac_addr(dev, p); - if (!rc) - sis190_init_rxfilter(dev); - return rc; -} - static const struct net_device_ops sis190_netdev_ops = { .ndo_open = sis190_open, .ndo_stop = sis190_close, @@ -1843,7 +1833,7 @@ static const struct net_device_ops sis190_netdev_ops = { .ndo_tx_timeout = sis190_tx_timeout, .ndo_set_multicast_list = sis190_set_rx_mode, .ndo_change_mtu = eth_change_mtu, - .ndo_set_mac_address = sis190_mac_addr, + .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sis190_netpoll, diff --git a/trunk/drivers/net/slip.c b/trunk/drivers/net/slip.c index 4c617534f937..f11b3f3df24f 100644 --- a/trunk/drivers/net/slip.c +++ b/trunk/drivers/net/slip.c @@ -367,7 +367,7 @@ static void sl_bump(struct slip *sl) memcpy(skb_put(skb, count), sl->rbuff, count); skb_reset_mac_header(skb); skb->protocol = htons(ETH_P_IP); - netif_rx_ni(skb); + netif_rx(skb); dev->stats.rx_packets++; } diff --git a/trunk/drivers/net/usb/cdc_ncm.c b/trunk/drivers/net/usb/cdc_ncm.c index a03336e086d5..fd622a66ebbf 100644 --- a/trunk/drivers/net/usb/cdc_ncm.c +++ b/trunk/drivers/net/usb/cdc_ncm.c @@ -53,7 +53,7 @@ #include #include -#define DRIVER_VERSION "04-Aug-2011" +#define DRIVER_VERSION "01-June-2011" /* CDC NCM subclass 3.2.1 */ #define USB_CDC_NCM_NDP16_LENGTH_MIN 0x10 @@ -163,8 +163,35 @@ cdc_ncm_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *info) usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info)); } +static int +cdc_ncm_do_request(struct cdc_ncm_ctx *ctx, struct usb_cdc_notification *req, + void *data, u16 flags, u16 *actlen, u16 timeout) +{ + int err; + + err = usb_control_msg(ctx->udev, (req->bmRequestType & USB_DIR_IN) ? + usb_rcvctrlpipe(ctx->udev, 0) : + usb_sndctrlpipe(ctx->udev, 0), + req->bNotificationType, req->bmRequestType, + req->wValue, + req->wIndex, data, + req->wLength, timeout); + + if (err < 0) { + if (actlen) + *actlen = 0; + return err; + } + + if (actlen) + *actlen = err; + + return 0; +} + static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) { + struct usb_cdc_notification req; u32 val; u8 flags; u8 iface_no; @@ -173,14 +200,14 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) iface_no = ctx->control->cur_altsetting->desc.bInterfaceNumber; - err = usb_control_msg(ctx->udev, - usb_rcvctrlpipe(ctx->udev, 0), - USB_CDC_GET_NTB_PARAMETERS, - USB_TYPE_CLASS | USB_DIR_IN - | USB_RECIP_INTERFACE, - 0, iface_no, &ctx->ncm_parm, - sizeof(ctx->ncm_parm), 10000); - if (err < 0) { + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_NTB_PARAMETERS; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(sizeof(ctx->ncm_parm)); + + err = cdc_ncm_do_request(ctx, &req, &ctx->ncm_parm, 0, NULL, 1000); + if (err) { pr_debug("failed GET_NTB_PARAMETERS\n"); return 1; } @@ -226,26 +253,31 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) /* inform device about NTB input size changes */ if (ctx->rx_max != le32_to_cpu(ctx->ncm_parm.dwNtbInMaxSize)) { + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_NTB_INPUT_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); if (flags & USB_CDC_NCM_NCAP_NTB_INPUT_SIZE) { struct usb_cdc_ncm_ndp_input_size ndp_in_sz; - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_INPUT_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, iface_no, &ndp_in_sz, 8, 1000); + + req.wLength = 8; + ndp_in_sz.dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); + ndp_in_sz.wNtbInMaxDatagrams = + cpu_to_le16(CDC_NCM_DPT_DATAGRAMS_MAX); + ndp_in_sz.wReserved = 0; + err = cdc_ncm_do_request(ctx, &req, &ndp_in_sz, 0, NULL, + 1000); } else { __le32 dwNtbInMaxSize = cpu_to_le32(ctx->rx_max); - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_INPUT_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, iface_no, &dwNtbInMaxSize, 4, 1000); + + req.wLength = 4; + err = cdc_ncm_do_request(ctx, &req, &dwNtbInMaxSize, 0, + NULL, 1000); } - if (err < 0) + if (err) pr_debug("Setting NTB Input Size failed\n"); } @@ -300,24 +332,29 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) /* set CRC Mode */ if (flags & USB_CDC_NCM_NCAP_CRC_MODE) { - err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_CRC_MODE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - USB_CDC_NCM_CRC_NOT_APPENDED, - iface_no, NULL, 0, 1000); - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_CRC_MODE; + req.wValue = cpu_to_le16(USB_CDC_NCM_CRC_NOT_APPENDED); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) pr_debug("Setting CRC mode off failed\n"); } /* set NTB format, if both formats are supported */ if (ntb_fmt_supported & USB_CDC_NCM_NTH32_SIGN) { - err = usb_control_msg(ctx->udev, usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_NTB_FORMAT, USB_TYPE_CLASS - | USB_DIR_OUT | USB_RECIP_INTERFACE, - USB_CDC_NCM_NTB16_FORMAT, - iface_no, NULL, 0, 1000); - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_NTB_FORMAT; + req.wValue = cpu_to_le16(USB_CDC_NCM_NTB16_FORMAT); + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 0; + + err = cdc_ncm_do_request(ctx, &req, NULL, 0, NULL, 1000); + if (err) pr_debug("Setting NTB format to 16-bit failed\n"); } @@ -327,13 +364,17 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) if (flags & USB_CDC_NCM_NCAP_MAX_DATAGRAM_SIZE) { __le16 max_datagram_size; u16 eth_max_sz = le16_to_cpu(ctx->ether_desc->wMaxSegmentSize); - err = usb_control_msg(ctx->udev, usb_rcvctrlpipe(ctx->udev, 0), - USB_CDC_GET_MAX_DATAGRAM_SIZE, - USB_TYPE_CLASS | USB_DIR_IN - | USB_RECIP_INTERFACE, - 0, iface_no, &max_datagram_size, - 2, 1000); - if (err < 0) { + + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_IN | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_GET_MAX_DATAGRAM_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = cpu_to_le16(2); + + err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, 0, NULL, + 1000); + if (err) { pr_debug("GET_MAX_DATAGRAM_SIZE failed, use size=%u\n", CDC_NCM_MIN_DATAGRAM_SIZE); } else { @@ -354,15 +395,17 @@ static u8 cdc_ncm_setup(struct cdc_ncm_ctx *ctx) CDC_NCM_MIN_DATAGRAM_SIZE; /* if value changed, update device */ - err = usb_control_msg(ctx->udev, - usb_sndctrlpipe(ctx->udev, 0), - USB_CDC_SET_MAX_DATAGRAM_SIZE, - USB_TYPE_CLASS | USB_DIR_OUT - | USB_RECIP_INTERFACE, - 0, - iface_no, &max_datagram_size, - 2, 1000); - if (err < 0) + req.bmRequestType = USB_TYPE_CLASS | USB_DIR_OUT | + USB_RECIP_INTERFACE; + req.bNotificationType = USB_CDC_SET_MAX_DATAGRAM_SIZE; + req.wValue = 0; + req.wIndex = cpu_to_le16(iface_no); + req.wLength = 2; + max_datagram_size = cpu_to_le16(ctx->max_datagram_size); + + err = cdc_ncm_do_request(ctx, &req, &max_datagram_size, + 0, NULL, 1000); + if (err) pr_debug("SET_MAX_DATAGRAM_SIZE failed\n"); } @@ -628,7 +671,7 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) u32 rem; u32 offset; u32 last_offset; - u16 n = 0, index; + u16 n = 0; u8 ready2send = 0; /* if there is a remaining skb, it gets priority */ @@ -816,8 +859,8 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) cpu_to_le16(sizeof(ctx->tx_ncm.nth16)); ctx->tx_ncm.nth16.wSequence = cpu_to_le16(ctx->tx_seq); ctx->tx_ncm.nth16.wBlockLength = cpu_to_le16(last_offset); - index = ALIGN(sizeof(struct usb_cdc_ncm_nth16), ctx->tx_ndp_modulus); - ctx->tx_ncm.nth16.wNdpIndex = cpu_to_le16(index); + ctx->tx_ncm.nth16.wNdpIndex = ALIGN(sizeof(struct usb_cdc_ncm_nth16), + ctx->tx_ndp_modulus); memcpy(skb_out->data, &(ctx->tx_ncm.nth16), sizeof(ctx->tx_ncm.nth16)); ctx->tx_seq++; @@ -830,11 +873,12 @@ cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb) ctx->tx_ncm.ndp16.wLength = cpu_to_le16(rem); ctx->tx_ncm.ndp16.wNextNdpIndex = 0; /* reserved */ - memcpy(((u8 *)skb_out->data) + index, + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex, &(ctx->tx_ncm.ndp16), sizeof(ctx->tx_ncm.ndp16)); - memcpy(((u8 *)skb_out->data) + index + sizeof(ctx->tx_ncm.ndp16), + memcpy(((u8 *)skb_out->data) + ctx->tx_ncm.nth16.wNdpIndex + + sizeof(ctx->tx_ncm.ndp16), &(ctx->tx_ncm.dpe16), (ctx->tx_curr_frame_num + 1) * sizeof(struct usb_cdc_ncm_dpe16)); diff --git a/trunk/drivers/net/usb/rtl8150.c b/trunk/drivers/net/usb/rtl8150.c index ef3b236b5145..041fb7d43c4f 100644 --- a/trunk/drivers/net/usb/rtl8150.c +++ b/trunk/drivers/net/usb/rtl8150.c @@ -977,6 +977,7 @@ static void rtl8150_disconnect(struct usb_interface *intf) usb_set_intfdata(intf, NULL); if (dev) { set_bit(RTL8150_UNPLUG, &dev->flags); + tasklet_disable(&dev->tl); tasklet_kill(&dev->tl); unregister_netdev(dev->netdev); unlink_all_urbs(dev); diff --git a/trunk/drivers/net/wireless/ath/ath5k/base.c b/trunk/drivers/net/wireless/ath/ath5k/base.c index c3119a6caace..f54dff44ed50 100644 --- a/trunk/drivers/net/wireless/ath/ath5k/base.c +++ b/trunk/drivers/net/wireless/ath/ath5k/base.c @@ -1735,8 +1735,6 @@ ath5k_beacon_setup(struct ath5k_hw *ah, struct ath5k_buf *bf) if (dma_mapping_error(ah->dev, bf->skbaddr)) { ATH5K_ERR(ah, "beacon DMA mapping failed\n"); - dev_kfree_skb_any(skb); - bf->skb = NULL; return -EIO; } @@ -1821,6 +1819,8 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif) ath5k_txbuf_free_skb(ah, avf->bbuf); avf->bbuf->skb = skb; ret = ath5k_beacon_setup(ah, avf->bbuf); + if (ret) + avf->bbuf->skb = NULL; out: return ret; } @@ -1840,7 +1840,6 @@ ath5k_beacon_send(struct ath5k_hw *ah) struct ath5k_vif *avf; struct ath5k_buf *bf; struct sk_buff *skb; - int err; ATH5K_DBG_UNLIMIT(ah, ATH5K_DEBUG_BEACON, "in beacon_send\n"); @@ -1889,6 +1888,11 @@ ath5k_beacon_send(struct ath5k_hw *ah) avf = (void *)vif->drv_priv; bf = avf->bbuf; + if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || + ah->opmode == NL80211_IFTYPE_MONITOR)) { + ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); + return; + } /* * Stop any current dma and put the new frame on the queue. @@ -1902,17 +1906,8 @@ ath5k_beacon_send(struct ath5k_hw *ah) /* refresh the beacon for AP or MESH mode */ if (ah->opmode == NL80211_IFTYPE_AP || - ah->opmode == NL80211_IFTYPE_MESH_POINT) { - err = ath5k_beacon_update(ah->hw, vif); - if (err) - return; - } - - if (unlikely(bf->skb == NULL || ah->opmode == NL80211_IFTYPE_STATION || - ah->opmode == NL80211_IFTYPE_MONITOR)) { - ATH5K_WARN(ah, "bf=%p bf_skb=%p\n", bf, bf->skb); - return; - } + ah->opmode == NL80211_IFTYPE_MESH_POINT) + ath5k_beacon_update(ah->hw, vif); trace_ath5k_tx(ah, bf->skb, &ah->txqs[ah->bhalq]); diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c index 44d9d8d56490..9ff7c30573b8 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9002_hw.c @@ -309,7 +309,11 @@ static void ar9002_hw_configpcipowersave(struct ath_hw *ah, u8 i; u32 val; - if (ah->is_pciexpress != true || ah->aspm_enabled != true) + if (ah->is_pciexpress != true) + return; + + /* Do not touch SerDes registers */ + if (ah->config.pcie_powersave_enable == 2) return; /* Nothing to do on restore for 11N */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c34bef1bf2b0..d109c25417f4 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -307,7 +307,7 @@ static const struct ar9300_eeprom ar9300_default = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -884,7 +884,7 @@ static const struct ar9300_eeprom ar9300_x113 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -2040,7 +2040,7 @@ static const struct ar9300_eeprom ar9300_x112 = { { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, - { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0) } }, + { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, @@ -3734,7 +3734,7 @@ static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) } } else { reg_pmu_set = (5 << 1) | (7 << 4) | - (2 << 8) | (2 << 14) | + (1 << 8) | (2 << 14) | (6 << 17) | (1 << 20) | (3 << 24) | (1 << 28); } diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c index ad2bb2bf4e8a..8efdec247c02 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -519,7 +519,11 @@ static void ar9003_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) { - if (ah->is_pciexpress != true || ah->aspm_enabled != true) + if (ah->is_pciexpress != true) + return; + + /* Do not touch SerDes registers */ + if (ah->config.pcie_powersave_enable == 2) return; /* Nothing to do on restore for 11N */ diff --git a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 5c590429f120..6de3f0bc18e6 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/trunk/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -850,7 +850,7 @@ #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) -#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) +#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM_BASE + 0x450 + ((_i) << 2)) /* * Channel 2 Register Map diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.c b/trunk/drivers/net/wireless/ath/ath9k/hw.c index 8dcefe74f4c3..8006ce0c7357 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.c +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.c @@ -318,14 +318,6 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); } -static void ath9k_hw_aspm_init(struct ath_hw *ah) -{ - struct ath_common *common = ath9k_hw_common(ah); - - if (common->bus_ops->aspm_init) - common->bus_ops->aspm_init(common); -} - /* This should work for all families including legacy */ static bool ath9k_hw_chip_test(struct ath_hw *ah) { @@ -386,6 +378,7 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.additional_swba_backoff = 0; ah->config.ack_6mb = 0x0; ah->config.cwm_ignore_extcca = 0; + ah->config.pcie_powersave_enable = 0; ah->config.pcie_clock_req = 0; ah->config.pcie_waen = 0; ah->config.analog_shiftreg = 1; @@ -605,7 +598,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (ah->is_pciexpress) - ath9k_hw_aspm_init(ah); + ath9k_hw_configpcipowersave(ah, 0, 0); else ath9k_hw_disablepcie(ah); diff --git a/trunk/drivers/net/wireless/ath/ath9k/hw.h b/trunk/drivers/net/wireless/ath/ath9k/hw.h index c79889036ec4..6acd0f975ae1 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/hw.h +++ b/trunk/drivers/net/wireless/ath/ath9k/hw.h @@ -219,6 +219,7 @@ struct ath9k_ops_config { int additional_swba_backoff; int ack_6mb; u32 cwm_ignore_extcca; + u8 pcie_powersave_enable; bool pcieSerDesWrite; u8 pcie_clock_req; u32 pcie_waen; @@ -672,7 +673,6 @@ struct ath_hw { bool sw_mgmt_crypto; bool is_pciexpress; - bool aspm_enabled; bool is_monitoring; bool need_an_top2_fixup; u16 tx_trig_level; @@ -874,7 +874,6 @@ struct ath_bus_ops { bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); void (*bt_coex_prep)(struct ath_common *common); void (*extn_synch_en)(struct ath_common *common); - void (*aspm_init)(struct ath_common *common); }; static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) diff --git a/trunk/drivers/net/wireless/ath/ath9k/init.c b/trunk/drivers/net/wireless/ath/ath9k/init.c index aa0ff7e2c922..ac5107172f94 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/init.c +++ b/trunk/drivers/net/wireless/ath/ath9k/init.c @@ -670,10 +670,8 @@ static void ath9k_init_band_txpower(struct ath_softc *sc, int band) static void ath9k_init_txpower_limits(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; - struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath9k_channel *curchan = ah->curchan; - ah->txchainmask = common->tx_chainmask; if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) ath9k_init_band_txpower(sc, IEEE80211_BAND_2GHZ); if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) diff --git a/trunk/drivers/net/wireless/ath/ath9k/pci.c b/trunk/drivers/net/wireless/ath/ath9k/pci.c index be4ea1329813..3bad0b2cf9a3 100644 --- a/trunk/drivers/net/wireless/ath/ath9k/pci.c +++ b/trunk/drivers/net/wireless/ath/ath9k/pci.c @@ -16,7 +16,6 @@ #include #include -#include #include #include "ath9k.h" @@ -116,38 +115,12 @@ static void ath_pci_extn_synch_enable(struct ath_common *common) pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl); } -static void ath_pci_aspm_init(struct ath_common *common) -{ - struct ath_softc *sc = (struct ath_softc *) common->priv; - struct ath_hw *ah = sc->sc_ah; - struct pci_dev *pdev = to_pci_dev(sc->dev); - struct pci_dev *parent; - int pos; - u8 aspm; - - if (!pci_is_pcie(pdev)) - return; - - parent = pdev->bus->self; - if (WARN_ON(!parent)) - return; - - pos = pci_pcie_cap(parent); - pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); - if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { - ah->aspm_enabled = true; - /* Initialize PCIe PM and SERDES registers. */ - ath9k_hw_configpcipowersave(ah, 0, 0); - } -} - static const struct ath_bus_ops ath_pci_bus_ops = { .ath_bus_type = ATH_PCI, .read_cachesize = ath_pci_read_cachesize, .eeprom_read = ath_pci_eeprom_read, .bt_coex_prep = ath_pci_bt_coex_prep, .extn_synch_en = ath_pci_extn_synch_enable, - .aspm_init = ath_pci_aspm_init, }; static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) diff --git a/trunk/drivers/net/wireless/b43/dma.c b/trunk/drivers/net/wireless/b43/dma.c index 481e534534eb..83cba22ac6e8 100644 --- a/trunk/drivers/net/wireless/b43/dma.c +++ b/trunk/drivers/net/wireless/b43/dma.c @@ -795,23 +795,9 @@ static u64 supported_dma_mask(struct b43_wldev *dev) u32 tmp; u16 mmio_base; - switch (dev->dev->bus_type) { -#ifdef CONFIG_B43_BCMA - case B43_BUS_BCMA: - tmp = bcma_aread32(dev->dev->bdev, BCMA_IOST); - if (tmp & BCMA_IOST_DMA64) - return DMA_BIT_MASK(64); - break; -#endif -#ifdef CONFIG_B43_SSB - case B43_BUS_SSB: - tmp = ssb_read32(dev->dev->sdev, SSB_TMSHIGH); - if (tmp & SSB_TMSHIGH_DMA64) - return DMA_BIT_MASK(64); - break; -#endif - } - + tmp = b43_read32(dev, SSB_TMSHIGH); + if (tmp & SSB_TMSHIGH_DMA64) + return DMA_BIT_MASK(64); mmio_base = b43_dmacontroller_base(0, 0); b43_write32(dev, mmio_base + B43_DMA32_TXCTL, B43_DMA32_TXADDREXT_MASK); tmp = b43_read32(dev, mmio_base + B43_DMA32_TXCTL); diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c b/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c index 73fe3cdf796b..dab67a12d73b 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-3945.c @@ -1746,11 +1746,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) } memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); - /* - * We do not commit tx power settings while channel changing, - * do it now if tx power changed. - */ - iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); + return 0; } diff --git a/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c b/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c index ecdc6e557428..bd4b000733f7 100644 --- a/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c +++ b/trunk/drivers/net/wireless/iwlegacy/iwl-4965.c @@ -1235,12 +1235,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon)); iwl_legacy_print_rx_config_cmd(priv, ctx); - /* - * We do not commit tx power settings while channel changing, - * do it now if tx power changed. - */ - iwl_legacy_set_tx_power(priv, priv->tx_power_next, false); - return 0; + goto set_tx_power; } /* If we are currently associated and the new config requires @@ -1320,6 +1315,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c iwl4965_init_sensitivity(priv); +set_tx_power: /* If we issue a new RXON command which required a tune then we must * send a new TXPOWER command or we won't be able to Tx any frames */ ret = iwl_legacy_set_tx_power(priv, priv->tx_power_next, true); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c index c95cefd529dc..3eeb12ebe6e9 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -365,7 +365,6 @@ static struct iwl_base_params iwl5000_base_params = { .chain_noise_scale = 1000, .wd_timeout = IWL_LONG_WD_TIMEOUT, .max_event_log_size = 512, - .no_idle_support = true, }; static struct iwl_ht_params iwl5000_ht_params = { .ht_greenfield_support = true, diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h index 02817a438550..3e6bb734dcb7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-core.h @@ -135,7 +135,6 @@ struct iwl_mod_params { * @temperature_kelvin: temperature report by uCode in kelvin * @max_event_log_size: size of event log buffer size for ucode event logging * @shadow_reg_enable: HW shadhow register bit - * @no_idle_support: do not support idle mode */ struct iwl_base_params { int eeprom_size; @@ -157,7 +156,6 @@ struct iwl_base_params { bool temperature_kelvin; u32 max_event_log_size; const bool shadow_reg_enable; - const bool no_idle_support; }; /* * @advanced_bt_coexist: support advanced bt coexist diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c b/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c index 69d4ec467dca..fb7e436b40c7 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -134,7 +134,6 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) static void iwl_pci_set_drv_data(struct iwl_bus *bus, void *drv_data) { bus->drv_data = drv_data; - pci_set_drvdata(IWL_BUS_GET_PCI_DEV(bus), drv_data); } static void iwl_pci_get_hw_id(struct iwl_bus *bus, char buf[], @@ -455,6 +454,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); } + pci_set_drvdata(pdev, bus); + bus->dev = &pdev->dev; bus->irq = pdev->irq; bus->ops = &pci_ops; @@ -493,12 +494,11 @@ static void iwl_pci_down(struct iwl_bus *bus) static void __devexit iwl_pci_remove(struct pci_dev *pdev) { - struct iwl_priv *priv = pci_get_drvdata(pdev); - void *bus_specific = priv->bus->bus_specific; + struct iwl_bus *bus = pci_get_drvdata(pdev); - iwl_remove(priv); + iwl_remove(bus->drv_data); - iwl_pci_down(bus_specific); + iwl_pci_down(bus); } #ifdef CONFIG_PM @@ -506,20 +506,20 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) static int iwl_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if * WoWLAN is enabled - don't kill the NIC, someone may need it in Sx. */ - return iwl_suspend(priv); + return iwl_suspend(bus->drv_data); } static int iwl_pci_resume(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); - struct iwl_priv *priv = pci_get_drvdata(pdev); + struct iwl_bus *bus = pci_get_drvdata(pdev); /* Before you put code here, think about WoWLAN. You cannot check here * whether WoWLAN is enabled or not, and your code will run even if @@ -532,7 +532,7 @@ static int iwl_pci_resume(struct device *device) */ pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - return iwl_resume(priv); + return iwl_resume(bus->drv_data); } static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume); diff --git a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c index cd64df05f9ed..3ec619c6881c 100644 --- a/trunk/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/trunk/drivers/net/wireless/iwlwifi/iwl-power.c @@ -349,8 +349,7 @@ static void iwl_power_build_cmd(struct iwl_priv *priv, if (priv->wowlan) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, dtimper); - else if (!priv->cfg->base_params->no_idle_support && - priv->hw->conf.flags & IEEE80211_CONF_IDLE) + else if (priv->hw->conf.flags & IEEE80211_CONF_IDLE) iwl_static_sleep_cmd(priv, cmd, IWL_POWER_INDEX_5, 20); else if (iwl_tt_is_low_power_state(priv)) { /* in thermal throttling low power state */ diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c index ef67f6786a84..84ab7d1acb6a 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800lib.c @@ -703,7 +703,8 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) /* * Add space for the TXWI in front of the skb. */ - memset(skb_push(entry->skb, TXWI_DESC_SIZE), 0, TXWI_DESC_SIZE); + skb_push(entry->skb, TXWI_DESC_SIZE); + memset(entry->skb, 0, TXWI_DESC_SIZE); /* * Register descriptor details in skb frame descriptor. diff --git a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c index 939563162fb3..507559361d87 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2800usb.c @@ -921,8 +921,6 @@ static struct usb_device_id rt2800usb_device_table[] = { { USB_DEVICE(0x07d1, 0x3c16) }, /* Draytek */ { USB_DEVICE(0x07fa, 0x7712) }, - /* DVICO */ - { USB_DEVICE(0x0fe9, 0xb307) }, /* Edimax */ { USB_DEVICE(0x7392, 0x7711) }, { USB_DEVICE(0x7392, 0x7717) }, diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h b/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h index 4cdf247a870d..15cdc7e57fc4 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00lib.h @@ -355,8 +355,7 @@ static inline enum cipher rt2x00crypto_key_to_cipher(struct ieee80211_key_conf * return CIPHER_NONE; } -static inline void rt2x00crypto_create_tx_descriptor(struct rt2x00_dev *rt2x00dev, - struct sk_buff *skb, +static inline void rt2x00crypto_create_tx_descriptor(struct queue_entry *entry, struct txentry_desc *txdesc) { } diff --git a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c index 4ccf23805973..8efab3983528 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/trunk/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -113,7 +113,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) * due to possible race conditions in mac80211. */ if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) - goto exit_free_skb; + goto exit_fail; /* * Use the ATIM queue if appropriate and present. @@ -127,7 +127,7 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) ERROR(rt2x00dev, "Attempt to send packet over invalid queue %d.\n" "Please file bug report to %s.\n", qid, DRV_PROJECT); - goto exit_free_skb; + goto exit_fail; } /* @@ -159,7 +159,6 @@ void rt2x00mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb) exit_fail: rt2x00queue_pause_queue(queue); - exit_free_skb: dev_kfree_skb_any(skb); } EXPORT_SYMBOL_GPL(rt2x00mac_tx); diff --git a/trunk/drivers/net/wireless/rt2x00/rt73usb.c b/trunk/drivers/net/wireless/rt2x00/rt73usb.c index 0baeb894f093..6a93939f44e8 100644 --- a/trunk/drivers/net/wireless/rt2x00/rt73usb.c +++ b/trunk/drivers/net/wireless/rt2x00/rt73usb.c @@ -2420,7 +2420,6 @@ static struct usb_device_id rt73usb_device_table[] = { /* Buffalo */ { USB_DEVICE(0x0411, 0x00d8) }, { USB_DEVICE(0x0411, 0x00d9) }, - { USB_DEVICE(0x0411, 0x00e6) }, { USB_DEVICE(0x0411, 0x00f4) }, { USB_DEVICE(0x0411, 0x0116) }, { USB_DEVICE(0x0411, 0x0119) }, diff --git a/trunk/drivers/net/wireless/rtlwifi/pci.c b/trunk/drivers/net/wireless/rtlwifi/pci.c index 56f12358389d..5efd57833489 100644 --- a/trunk/drivers/net/wireless/rtlwifi/pci.c +++ b/trunk/drivers/net/wireless/rtlwifi/pci.c @@ -1696,17 +1696,15 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, pcipriv->ndis_adapter.devnumber = PCI_SLOT(pdev->devfn); pcipriv->ndis_adapter.funcnumber = PCI_FUNC(pdev->devfn); - if (bridge_pdev) { - /*find bridge info if available */ - pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; - for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { - if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { - pcipriv->ndis_adapter.pcibridge_vendor = tmp; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index:" - " %d\n", tmp)); - break; - } + /*find bridge info */ + pcipriv->ndis_adapter.pcibridge_vendorid = bridge_pdev->vendor; + for (tmp = 0; tmp < PCI_BRIDGE_VENDOR_MAX; tmp++) { + if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { + pcipriv->ndis_adapter.pcibridge_vendor = tmp; + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, + ("Pci Bridge Vendor is found index: %d\n", + tmp)); + break; } } diff --git a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index ef63c0df006a..942f7a3969a7 100644 --- a/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/trunk/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -281,8 +281,6 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817d, rtl92cu_hal_cfg)}, /* 8188CE-VAU USB minCard (b/g mode only) */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817e, rtl92cu_hal_cfg)}, - /* 8188RU in Alfa AWUS036NHR */ - {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x817f, rtl92cu_hal_cfg)}, /* 8188 Combo for BC4 */ {RTL_USB_DEVICE(USB_VENDER_ID_REALTEK, 0x8754, rtl92cu_hal_cfg)}, @@ -305,23 +303,20 @@ static struct usb_device_id rtl8192c_usb_ids[] = { {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ /* HP - Lite-On ,8188CUS Slim Combo */ {RTL_USB_DEVICE(0x103c, 0x1629, rtl92cu_hal_cfg)}, - {RTL_USB_DEVICE(0x13d3, 0x3357, rtl92cu_hal_cfg)}, /* AzureWave */ {RTL_USB_DEVICE(0x2001, 0x3308, rtl92cu_hal_cfg)}, /*D-Link - Alpha*/ {RTL_USB_DEVICE(0x2019, 0xab2a, rtl92cu_hal_cfg)}, /*Planex - Abocom*/ {RTL_USB_DEVICE(0x2019, 0xed17, rtl92cu_hal_cfg)}, /*PCI - Edimax*/ {RTL_USB_DEVICE(0x20f4, 0x648b, rtl92cu_hal_cfg)}, /*TRENDnet - Cameo*/ {RTL_USB_DEVICE(0x7392, 0x7811, rtl92cu_hal_cfg)}, /*Edimax - Edimax*/ - {RTL_USB_DEVICE(0x13d3, 0x3358, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ + {RTL_USB_DEVICE(0x3358, 0x13d3, rtl92cu_hal_cfg)}, /*Azwave 8188CE-VAU*/ /* Russian customer -Azwave (8188CE-VAU b/g mode only) */ - {RTL_USB_DEVICE(0x13d3, 0x3359, rtl92cu_hal_cfg)}, - {RTL_USB_DEVICE(0x4855, 0x0090, rtl92cu_hal_cfg)}, /* Feixun */ - {RTL_USB_DEVICE(0x4855, 0x0091, rtl92cu_hal_cfg)}, /* NetweeN-Feixun */ - {RTL_USB_DEVICE(0x9846, 0x9041, rtl92cu_hal_cfg)}, /* Netgear Cameo */ + {RTL_USB_DEVICE(0x3359, 0x13d3, rtl92cu_hal_cfg)}, /****** 8192CU ********/ {RTL_USB_DEVICE(0x0586, 0x341f, rtl92cu_hal_cfg)}, /*Zyxel -Abocom*/ {RTL_USB_DEVICE(0x07aa, 0x0056, rtl92cu_hal_cfg)}, /*ATKK-Gemtek*/ {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Funai -Abocom*/ + {RTL_USB_DEVICE(0x07b8, 0x8178, rtl92cu_hal_cfg)}, /*Abocom -Abocom*/ {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ diff --git a/trunk/drivers/net/wireless/wl1251/acx.c b/trunk/drivers/net/wireless/wl1251/acx.c index ad87a1ac6462..ef8370edace7 100644 --- a/trunk/drivers/net/wireless/wl1251/acx.c +++ b/trunk/drivers/net/wireless/wl1251/acx.c @@ -140,6 +140,8 @@ int wl1251_acx_sleep_auth(struct wl1251 *wl, u8 sleep_auth) auth->sleep_auth = sleep_auth; ret = wl1251_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth)); + if (ret < 0) + return ret; out: kfree(auth); @@ -679,8 +681,10 @@ int wl1251_acx_cca_threshold(struct wl1251 *wl) ret = wl1251_cmd_configure(wl, ACX_CCA_THRESHOLD, detection, sizeof(*detection)); - if (ret < 0) + if (ret < 0) { wl1251_warning("failed to set cca threshold: %d", ret); + return ret; + } out: kfree(detection); diff --git a/trunk/drivers/net/wireless/wl1251/cmd.c b/trunk/drivers/net/wireless/wl1251/cmd.c index d14d69d733a0..81f164bc4888 100644 --- a/trunk/drivers/net/wireless/wl1251/cmd.c +++ b/trunk/drivers/net/wireless/wl1251/cmd.c @@ -241,7 +241,7 @@ int wl1251_cmd_data_path(struct wl1251 *wl, u8 channel, bool enable) if (ret < 0) { wl1251_error("tx %s cmd for channel %d failed", enable ? "start" : "stop", channel); - goto out; + return ret; } wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", diff --git a/trunk/drivers/of/address.c b/trunk/drivers/of/address.c index 72c33fbe451d..da1f4b9605df 100644 --- a/trunk/drivers/of/address.c +++ b/trunk/drivers/of/address.c @@ -610,6 +610,6 @@ void __iomem *of_iomap(struct device_node *np, int index) if (of_address_to_resource(np, index, &res)) return NULL; - return ioremap(res.start, resource_size(&res)); + return ioremap(res.start, 1 + res.end - res.start); } EXPORT_SYMBOL(of_iomap); diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index 3ff22e32b602..02ed36719def 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -610,9 +610,8 @@ EXPORT_SYMBOL(of_find_node_by_phandle); * * The out_value is modified only if a valid u32 value can be decoded. */ -int of_property_read_u32_array(const struct device_node *np, - const char *propname, u32 *out_values, - size_t sz) +int of_property_read_u32_array(const struct device_node *np, char *propname, + u32 *out_values, size_t sz) { struct property *prop = of_find_property(np, propname, NULL); const __be32 *val; @@ -646,7 +645,7 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_array); * * The out_string pointer is modified only if a valid string can be decoded. */ -int of_property_read_string(struct device_node *np, const char *propname, +int of_property_read_string(struct device_node *np, char *propname, const char **out_string) { struct property *prop = of_find_property(np, propname, NULL); diff --git a/trunk/drivers/pci/hotplug/acpiphp_glue.c b/trunk/drivers/pci/hotplug/acpiphp_glue.c index 220285760b68..a70fa89f76fd 100644 --- a/trunk/drivers/pci/hotplug/acpiphp_glue.c +++ b/trunk/drivers/pci/hotplug/acpiphp_glue.c @@ -110,7 +110,7 @@ static int post_dock_fixups(struct notifier_block *nb, unsigned long val, } -static const struct acpi_dock_ops acpiphp_dock_ops = { +static struct acpi_dock_ops acpiphp_dock_ops = { .handler = handle_hotplug_event_func, }; diff --git a/trunk/drivers/platform/x86/Kconfig b/trunk/drivers/platform/x86/Kconfig index 1e88d4785321..45e0191c35dd 100644 --- a/trunk/drivers/platform/x86/Kconfig +++ b/trunk/drivers/platform/x86/Kconfig @@ -769,12 +769,4 @@ config INTEL_OAKTRAIL enable/disable the Camera, WiFi, BT etc. devices. If in doubt, say Y here; it will only load on supported platforms. -config SAMSUNG_Q10 - tristate "Samsung Q10 Extras" - depends on SERIO_I8042 - select BACKLIGHT_CLASS_DEVICE - ---help--- - This driver provides support for backlight control on Samsung Q10 - and related laptops, including Dell Latitude X200. - endif # X86_PLATFORM_DEVICES diff --git a/trunk/drivers/platform/x86/Makefile b/trunk/drivers/platform/x86/Makefile index 293a320d9faa..afc1f832aa67 100644 --- a/trunk/drivers/platform/x86/Makefile +++ b/trunk/drivers/platform/x86/Makefile @@ -44,4 +44,3 @@ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o obj-$(CONFIG_MXM_WMI) += mxm-wmi.o obj-$(CONFIG_INTEL_MID_POWER_BUTTON) += intel_mid_powerbtn.o obj-$(CONFIG_INTEL_OAKTRAIL) += intel_oaktrail.o -obj-$(CONFIG_SAMSUNG_Q10) += samsung-q10.o diff --git a/trunk/drivers/platform/x86/acer-wmi.c b/trunk/drivers/platform/x86/acer-wmi.c index af2bb20cb2fb..e1c4938b301b 100644 --- a/trunk/drivers/platform/x86/acer-wmi.c +++ b/trunk/drivers/platform/x86/acer-wmi.c @@ -99,7 +99,6 @@ enum acer_wmi_event_ids { static const struct key_entry acer_wmi_keymap[] = { {KE_KEY, 0x01, {KEY_WLAN} }, /* WiFi */ {KE_KEY, 0x03, {KEY_WLAN} }, /* WiFi */ - {KE_KEY, 0x04, {KEY_WLAN} }, /* WiFi */ {KE_KEY, 0x12, {KEY_BLUETOOTH} }, /* BT */ {KE_KEY, 0x21, {KEY_PROG1} }, /* Backup */ {KE_KEY, 0x22, {KEY_PROG2} }, /* Arcade */ @@ -305,10 +304,6 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = { .wireless = 2, }; -static struct quirk_entry quirk_lenovo_ideapad_s205 = { - .wireless = 3, -}; - /* The Aspire One has a dummy ACPI-WMI interface - disable it */ static struct dmi_system_id __devinitdata acer_blacklist[] = { { @@ -455,15 +450,6 @@ static struct dmi_system_id acer_quirks[] = { }, .driver_data = &quirk_medion_md_98300, }, - { - .callback = dmi_matched, - .ident = "Lenovo Ideapad S205", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), - DMI_MATCH(DMI_PRODUCT_NAME, "10382LG"), - }, - .driver_data = &quirk_lenovo_ideapad_s205, - }, {} }; @@ -556,12 +542,6 @@ struct wmi_interface *iface) return AE_ERROR; *value = result & 0x1; return AE_OK; - case 3: - err = ec_read(0x78, &result); - if (err) - return AE_ERROR; - *value = result & 0x1; - return AE_OK; default: err = ec_read(0xA, &result); if (err) @@ -1286,13 +1266,8 @@ static void acer_rfkill_update(struct work_struct *ignored) acpi_status status; status = get_u32(&state, ACER_CAP_WIRELESS); - if (ACPI_SUCCESS(status)) { - if (quirks->wireless == 3) { - rfkill_set_hw_state(wireless_rfkill, !state); - } else { - rfkill_set_sw_state(wireless_rfkill, !state); - } - } + if (ACPI_SUCCESS(status)) + rfkill_set_sw_state(wireless_rfkill, !state); if (has_cap(ACER_CAP_BLUETOOTH)) { status = get_u32(&state, ACER_CAP_BLUETOOTH); @@ -1425,9 +1400,6 @@ static ssize_t show_bool_threeg(struct device *dev, { u32 result; \ acpi_status status; - - pr_info("This threeg sysfs will be removed in 2012" - " - used by: %s\n", current->comm); if (wmi_has_guid(WMID_GUID3)) status = wmid3_get_device_status(&result, ACER_WMID3_GDS_THREEG); @@ -1443,10 +1415,8 @@ static ssize_t set_bool_threeg(struct device *dev, { u32 tmp = simple_strtoul(buf, NULL, 10); acpi_status status = set_u32(tmp, ACER_CAP_THREEG); - pr_info("This threeg sysfs will be removed in 2012" - " - used by: %s\n", current->comm); - if (ACPI_FAILURE(status)) - return -EINVAL; + if (ACPI_FAILURE(status)) + return -EINVAL; return count; } static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, @@ -1455,8 +1425,6 @@ static DEVICE_ATTR(threeg, S_IRUGO | S_IWUSR, show_bool_threeg, static ssize_t show_interface(struct device *dev, struct device_attribute *attr, char *buf) { - pr_info("This interface sysfs will be removed in 2012" - " - used by: %s\n", current->comm); switch (interface->type) { case ACER_AMW0: return sprintf(buf, "AMW0\n"); diff --git a/trunk/drivers/platform/x86/acerhdf.c b/trunk/drivers/platform/x86/acerhdf.c index 760c6d7624fe..fca3489218b7 100644 --- a/trunk/drivers/platform/x86/acerhdf.c +++ b/trunk/drivers/platform/x86/acerhdf.c @@ -182,7 +182,6 @@ static const struct bios_settings_t bios_tbl[] = { {"Acer", "Aspire 1810T", "v1.3308", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810TZ", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, {"Acer", "Aspire 1810T", "v1.3310", 0x55, 0x58, {0x9e, 0x00} }, - {"Acer", "Aspire 1810TZ", "v1.3314", 0x55, 0x58, {0x9e, 0x00} }, /* Acer 531 */ {"Acer", "AO531h", "v0.3201", 0x55, 0x58, {0x20, 0x00} }, /* Gateway */ @@ -704,15 +703,15 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Peter Feuerer"); MODULE_DESCRIPTION("Aspire One temperature and fan driver"); MODULE_ALIAS("dmi:*:*Acer*:pnAOA*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1410*:"); -MODULE_ALIAS("dmi:*:*Acer*:pnAspire*1810*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1410*:"); +MODULE_ALIAS("dmi:*:*Acer*:pnAspire 1810*:"); MODULE_ALIAS("dmi:*:*Acer*:pnAO531*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnAOA*:"); MODULE_ALIAS("dmi:*:*Gateway*:pnLT31*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnAOA*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOA*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMU*:"); -MODULE_ALIAS("dmi:*:*Packard*Bell*:pnDOTMA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnAOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOA*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMU*:"); +MODULE_ALIAS("dmi:*:*Packard Bell*:pnDOTMA*:"); module_init(acerhdf_init); module_exit(acerhdf_exit); diff --git a/trunk/drivers/platform/x86/asus-laptop.c b/trunk/drivers/platform/x86/asus-laptop.c index fa6d7ec68b26..d65df92e2acc 100644 --- a/trunk/drivers/platform/x86/asus-laptop.c +++ b/trunk/drivers/platform/x86/asus-laptop.c @@ -70,10 +70,11 @@ MODULE_LICENSE("GPL"); * WAPF defines the behavior of the Fn+Fx wlan key * The significance of values is yet to be found, but * most of the time: - * Bit | Bluetooth | WLAN - * 0 | Hardware | Hardware - * 1 | Hardware | Software - * 4 | Software | Software + * 0x0 will do nothing + * 0x1 will allow to control the device with Fn+Fx key. + * 0x4 will send an ACPI event (0x88) while pressing the Fn+Fx key + * 0x5 like 0x1 or 0x4 + * So, if something doesn't work as you want, just try other values =) */ static uint wapf = 1; module_param(wapf, uint, 0444); diff --git a/trunk/drivers/platform/x86/asus-nb-wmi.c b/trunk/drivers/platform/x86/asus-nb-wmi.c index b0859d4183e8..0580d99b0798 100644 --- a/trunk/drivers/platform/x86/asus-nb-wmi.c +++ b/trunk/drivers/platform/x86/asus-nb-wmi.c @@ -38,24 +38,6 @@ MODULE_LICENSE("GPL"); MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID); -/* - * WAPF defines the behavior of the Fn+Fx wlan key - * The significance of values is yet to be found, but - * most of the time: - * Bit | Bluetooth | WLAN - * 0 | Hardware | Hardware - * 1 | Hardware | Software - * 4 | Software | Software - */ -static uint wapf; -module_param(wapf, uint, 0444); -MODULE_PARM_DESC(wapf, "WAPF value"); - -static void asus_nb_wmi_quirks(struct asus_wmi_driver *driver) -{ - driver->wapf = wapf; -} - static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0x30, { KEY_VOLUMEUP } }, { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, @@ -71,16 +53,16 @@ static const struct key_entry asus_nb_wmi_keymap[] = { { KE_KEY, 0x51, { KEY_WWW } }, { KE_KEY, 0x55, { KEY_CALC } }, { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */ - { KE_KEY, 0x5D, { KEY_WLAN } }, /* Wireless console Toggle */ - { KE_KEY, 0x5E, { KEY_WLAN } }, /* Wireless console Enable */ - { KE_KEY, 0x5F, { KEY_WLAN } }, /* Wireless console Disable */ + { KE_KEY, 0x5D, { KEY_WLAN } }, + { KE_KEY, 0x5E, { KEY_WLAN } }, + { KE_KEY, 0x5F, { KEY_WLAN } }, { KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } }, - { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, { KE_KEY, 0x7E, { KEY_BLUETOOTH } }, + { KE_KEY, 0x7D, { KEY_BLUETOOTH } }, { KE_KEY, 0x82, { KEY_CAMERA } }, { KE_KEY, 0x88, { KEY_RFKILL } }, { KE_KEY, 0x8A, { KEY_PROG1 } }, @@ -99,7 +81,6 @@ static struct asus_wmi_driver asus_nb_wmi_driver = { .keymap = asus_nb_wmi_keymap, .input_name = "Asus WMI hotkeys", .input_phys = ASUS_NB_WMI_FILE "/input0", - .quirks = asus_nb_wmi_quirks, }; diff --git a/trunk/drivers/platform/x86/asus-wmi.c b/trunk/drivers/platform/x86/asus-wmi.c index 95cba9ebf6c0..65b66aa44c78 100644 --- a/trunk/drivers/platform/x86/asus-wmi.c +++ b/trunk/drivers/platform/x86/asus-wmi.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -67,8 +66,6 @@ MODULE_LICENSE("GPL"); #define NOTIFY_BRNUP_MAX 0x1f #define NOTIFY_BRNDOWN_MIN 0x20 #define NOTIFY_BRNDOWN_MAX 0x2e -#define NOTIFY_KBD_BRTUP 0xc4 -#define NOTIFY_KBD_BRTDWN 0xc5 /* WMI Methods */ #define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */ @@ -96,7 +93,6 @@ MODULE_LICENSE("GPL"); /* Wireless */ #define ASUS_WMI_DEVID_HW_SWITCH 0x00010001 #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 -#define ASUS_WMI_DEVID_CWAP 0x00010003 #define ASUS_WMI_DEVID_WLAN 0x00010011 #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 #define ASUS_WMI_DEVID_GPS 0x00010015 @@ -106,12 +102,6 @@ MODULE_LICENSE("GPL"); /* Leds */ /* 0x000200XX and 0x000400XX */ -#define ASUS_WMI_DEVID_LED1 0x00020011 -#define ASUS_WMI_DEVID_LED2 0x00020012 -#define ASUS_WMI_DEVID_LED3 0x00020013 -#define ASUS_WMI_DEVID_LED4 0x00020014 -#define ASUS_WMI_DEVID_LED5 0x00020015 -#define ASUS_WMI_DEVID_LED6 0x00020016 /* Backlight and Brightness */ #define ASUS_WMI_DEVID_BACKLIGHT 0x00050011 @@ -184,18 +174,13 @@ struct asus_wmi { struct led_classdev tpd_led; int tpd_led_wk; - struct led_classdev kbd_led; - int kbd_led_wk; struct workqueue_struct *led_workqueue; struct work_struct tpd_led_work; - struct work_struct kbd_led_work; struct asus_rfkill wlan; struct asus_rfkill bluetooth; struct asus_rfkill wimax; struct asus_rfkill wwan3g; - struct asus_rfkill gps; - struct asus_rfkill uwb; struct hotplug_slot *hotplug_slot; struct mutex hotplug_lock; @@ -220,7 +205,6 @@ static int asus_wmi_input_init(struct asus_wmi *asus) asus->inputdev->phys = asus->driver->input_phys; asus->inputdev->id.bustype = BUS_HOST; asus->inputdev->dev.parent = &asus->platform_device->dev; - set_bit(EV_REP, asus->inputdev->evbit); err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL); if (err) @@ -375,80 +359,30 @@ static enum led_brightness tpd_led_get(struct led_classdev *led_cdev) return read_tpd_led_state(asus); } -static void kbd_led_update(struct work_struct *work) +static int asus_wmi_led_init(struct asus_wmi *asus) { - int ctrl_param = 0; - struct asus_wmi *asus; - - asus = container_of(work, struct asus_wmi, kbd_led_work); + int rv; - /* - * bits 0-2: level - * bit 7: light on/off - */ - if (asus->kbd_led_wk > 0) - ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F); + if (read_tpd_led_state(asus) < 0) + return 0; - asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL); -} + asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); + if (!asus->led_workqueue) + return -ENOMEM; + INIT_WORK(&asus->tpd_led_work, tpd_led_update); -static int kbd_led_read(struct asus_wmi *asus, int *level, int *env) -{ - int retval; + asus->tpd_led.name = "asus::touchpad"; + asus->tpd_led.brightness_set = tpd_led_set; + asus->tpd_led.brightness_get = tpd_led_get; + asus->tpd_led.max_brightness = 1; - /* - * bits 0-2: level - * bit 7: light on/off - * bit 8-10: environment (0: dark, 1: normal, 2: light) - * bit 17: status unknown - */ - retval = asus_wmi_get_devstate_bits(asus, ASUS_WMI_DEVID_KBD_BACKLIGHT, - 0xFFFF); - - /* Unknown status is considered as off */ - if (retval == 0x8000) - retval = 0; - - if (retval >= 0) { - if (level) - *level = retval & 0x80 ? retval & 0x7F : 0; - if (env) - *env = (retval >> 8) & 0x7F; - retval = 0; + rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led); + if (rv) { + destroy_workqueue(asus->led_workqueue); + return rv; } - return retval; -} - -static void kbd_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct asus_wmi *asus; - - asus = container_of(led_cdev, struct asus_wmi, kbd_led); - - if (value > asus->kbd_led.max_brightness) - value = asus->kbd_led.max_brightness; - else if (value < 0) - value = 0; - - asus->kbd_led_wk = value; - queue_work(asus->led_workqueue, &asus->kbd_led_work); -} - -static enum led_brightness kbd_led_get(struct led_classdev *led_cdev) -{ - struct asus_wmi *asus; - int retval, value; - - asus = container_of(led_cdev, struct asus_wmi, kbd_led); - - retval = kbd_led_read(asus, &value, NULL); - - if (retval < 0) - return retval; - - return value; + return 0; } static void asus_wmi_led_exit(struct asus_wmi *asus) @@ -459,48 +393,6 @@ static void asus_wmi_led_exit(struct asus_wmi *asus) destroy_workqueue(asus->led_workqueue); } -static int asus_wmi_led_init(struct asus_wmi *asus) -{ - int rv = 0; - - asus->led_workqueue = create_singlethread_workqueue("led_workqueue"); - if (!asus->led_workqueue) - return -ENOMEM; - - if (read_tpd_led_state(asus) >= 0) { - INIT_WORK(&asus->tpd_led_work, tpd_led_update); - - asus->tpd_led.name = "asus::touchpad"; - asus->tpd_led.brightness_set = tpd_led_set; - asus->tpd_led.brightness_get = tpd_led_get; - asus->tpd_led.max_brightness = 1; - - rv = led_classdev_register(&asus->platform_device->dev, - &asus->tpd_led); - if (rv) - goto error; - } - - if (kbd_led_read(asus, NULL, NULL) >= 0) { - INIT_WORK(&asus->kbd_led_work, kbd_led_update); - - asus->kbd_led.name = "asus::kbd_backlight"; - asus->kbd_led.brightness_set = kbd_led_set; - asus->kbd_led.brightness_get = kbd_led_get; - asus->kbd_led.max_brightness = 3; - - rv = led_classdev_register(&asus->platform_device->dev, - &asus->kbd_led); - } - -error: - if (rv) - asus_wmi_led_exit(asus); - - return rv; -} - - /* * PCI hotplug (for wlan rfkill) */ @@ -837,16 +729,6 @@ static void asus_wmi_rfkill_exit(struct asus_wmi *asus) rfkill_destroy(asus->wwan3g.rfkill); asus->wwan3g.rfkill = NULL; } - if (asus->gps.rfkill) { - rfkill_unregister(asus->gps.rfkill); - rfkill_destroy(asus->gps.rfkill); - asus->gps.rfkill = NULL; - } - if (asus->uwb.rfkill) { - rfkill_unregister(asus->uwb.rfkill); - rfkill_destroy(asus->uwb.rfkill); - asus->uwb.rfkill = NULL; - } } static int asus_wmi_rfkill_init(struct asus_wmi *asus) @@ -881,18 +763,6 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) if (result && result != -ENODEV) goto exit; - result = asus_new_rfkill(asus, &asus->gps, "asus-gps", - RFKILL_TYPE_GPS, ASUS_WMI_DEVID_GPS); - - if (result && result != -ENODEV) - goto exit; - - result = asus_new_rfkill(asus, &asus->uwb, "asus-uwb", - RFKILL_TYPE_UWB, ASUS_WMI_DEVID_UWB); - - if (result && result != -ENODEV) - goto exit; - if (!asus->driver->hotplug_wireless) goto exit; @@ -927,8 +797,8 @@ static int asus_wmi_rfkill_init(struct asus_wmi *asus) * Hwmon device */ static ssize_t asus_hwmon_pwm1(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct asus_wmi *asus = dev_get_drvdata(dev); u32 value; @@ -939,7 +809,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, if (err < 0) return err; - value &= 0xFF; + value |= 0xFF; if (value == 1) /* Low Speed */ value = 85; @@ -955,26 +825,7 @@ static ssize_t asus_hwmon_pwm1(struct device *dev, return sprintf(buf, "%d\n", value); } -static ssize_t asus_hwmon_temp1(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct asus_wmi *asus = dev_get_drvdata(dev); - u32 value; - int err; - - err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_THERMAL_CTRL, &value); - - if (err < 0) - return err; - - value = KELVIN_TO_CELSIUS((value & 0xFFFF)) * 1000; - - return sprintf(buf, "%d\n", value); -} - static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0); -static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, asus_hwmon_temp1, NULL, 0); static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf) @@ -985,13 +836,12 @@ static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0); static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_pwm1.dev_attr.attr, - &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_name.dev_attr.attr, NULL }; static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, - struct attribute *attr, int idx) + struct attribute *attr, int idx) { struct device *dev = container_of(kobj, struct device, kobj); struct platform_device *pdev = to_platform_device(dev->parent); @@ -1002,8 +852,6 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, if (attr == &sensor_dev_attr_pwm1.dev_attr.attr) dev_id = ASUS_WMI_DEVID_FAN_CTRL; - else if (attr == &sensor_dev_attr_temp1_input.dev_attr.attr) - dev_id = ASUS_WMI_DEVID_THERMAL_CTRL; if (dev_id != -1) { int err = asus_wmi_get_devstate(asus, dev_id, &value); @@ -1021,13 +869,9 @@ static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj, * - reverved bits are non-zero * - sfun and presence bit are not set */ - if (value == ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 + if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000 || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT))) ok = false; - } else if (dev_id == ASUS_WMI_DEVID_THERMAL_CTRL) { - /* If value is zero, something is clearly wrong */ - if (value == 0) - ok = false; } return ok ? attr->mode : 0; @@ -1060,7 +904,6 @@ static int asus_wmi_hwmon_init(struct asus_wmi *asus) pr_err("Could not register asus hwmon device\n"); return PTR_ERR(hwmon); } - dev_set_drvdata(hwmon, asus); asus->hwmon_device = hwmon; result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group); if (result) @@ -1217,8 +1060,6 @@ static void asus_wmi_notify(u32 value, void *context) acpi_status status; int code; int orig_code; - unsigned int key_value = 1; - bool autorelease = 1; status = wmi_get_event_data(value, &response); if (status != AE_OK) { @@ -1234,13 +1075,6 @@ static void asus_wmi_notify(u32 value, void *context) code = obj->integer.value; orig_code = code; - if (asus->driver->key_filter) { - asus->driver->key_filter(asus->driver, &code, &key_value, - &autorelease); - if (code == ASUS_WMI_KEY_IGNORE) - goto exit; - } - if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX) code = NOTIFY_BRNUP_MIN; else if (code >= NOTIFY_BRNDOWN_MIN && @@ -1250,8 +1084,7 @@ static void asus_wmi_notify(u32 value, void *context) if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) { if (!acpi_video_backlight_support()) asus_wmi_backlight_notify(asus, orig_code); - } else if (!sparse_keymap_report_event(asus->inputdev, code, - key_value, autorelease)) + } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true)) pr_info("Unknown key %x pressed\n", code); exit: @@ -1331,18 +1164,14 @@ ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER); static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - int value, rv; + int value; if (!count || sscanf(buf, "%i", &value) != 1) return -EINVAL; if (value < 0 || value > 2) return -EINVAL; - rv = asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); - if (rv < 0) - return rv; - - return count; + return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL); } static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv); @@ -1405,7 +1234,7 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) /* We don't know yet what to do with this version... */ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) { - pr_info("BIOS WMI version: %d.%d", rv >> 16, rv & 0xFF); + pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF); asus->spec = rv; } @@ -1437,12 +1266,6 @@ static int asus_wmi_platform_init(struct asus_wmi *asus) return -ENODEV; } - /* CWAP allow to define the behavior of the Fn+F2 key, - * this method doesn't seems to be present on Eee PCs */ - if (asus->driver->wapf >= 0) - asus_wmi_set_devstate(ASUS_WMI_DEVID_CWAP, - asus->driver->wapf, NULL); - return asus_wmi_sysfs_init(asus->platform_device); } @@ -1745,14 +1568,6 @@ static int asus_hotk_restore(struct device *device) bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G); rfkill_set_sw_state(asus->wwan3g.rfkill, bl); } - if (asus->gps.rfkill) { - bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_GPS); - rfkill_set_sw_state(asus->gps.rfkill, bl); - } - if (asus->uwb.rfkill) { - bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_UWB); - rfkill_set_sw_state(asus->uwb.rfkill, bl); - } return 0; } @@ -1789,7 +1604,7 @@ static int asus_wmi_probe(struct platform_device *pdev) static bool used; -int __init_or_module asus_wmi_register_driver(struct asus_wmi_driver *driver) +int asus_wmi_register_driver(struct asus_wmi_driver *driver) { struct platform_driver *platform_driver; struct platform_device *platform_device; diff --git a/trunk/drivers/platform/x86/asus-wmi.h b/trunk/drivers/platform/x86/asus-wmi.h index 8147c10161cc..c044522c8766 100644 --- a/trunk/drivers/platform/x86/asus-wmi.h +++ b/trunk/drivers/platform/x86/asus-wmi.h @@ -29,15 +29,12 @@ #include -#define ASUS_WMI_KEY_IGNORE (-1) - struct module; struct key_entry; struct asus_wmi; struct asus_wmi_driver { bool hotplug_wireless; - int wapf; const char *name; struct module *owner; @@ -47,10 +44,6 @@ struct asus_wmi_driver { const struct key_entry *keymap; const char *input_name; const char *input_phys; - /* Returns new code, value, and autorelease values in arguments. - * Return ASUS_WMI_KEY_IGNORE in code if event should be ignored. */ - void (*key_filter) (struct asus_wmi_driver *driver, int *code, - unsigned int *value, bool *autorelease); int (*probe) (struct platform_device *device); void (*quirks) (struct asus_wmi_driver *driver); diff --git a/trunk/drivers/platform/x86/dell-laptop.c b/trunk/drivers/platform/x86/dell-laptop.c index f31fa4efa725..e39ab1d3ed87 100644 --- a/trunk/drivers/platform/x86/dell-laptop.c +++ b/trunk/drivers/platform/x86/dell-laptop.c @@ -612,6 +612,7 @@ static int __init dell_init(void) if (!bufferpage) goto fail_buffer; buffer = page_address(bufferpage); + mutex_init(&buffer_mutex); ret = dell_setup_rfkill(); diff --git a/trunk/drivers/platform/x86/dell-wmi.c b/trunk/drivers/platform/x86/dell-wmi.c index fa9a2171cc13..ce790827e199 100644 --- a/trunk/drivers/platform/x86/dell-wmi.c +++ b/trunk/drivers/platform/x86/dell-wmi.c @@ -54,8 +54,6 @@ MODULE_ALIAS("wmi:"DELL_EVENT_GUID); */ static const struct key_entry dell_wmi_legacy_keymap[] __initconst = { - { KE_IGNORE, 0x003a, { KEY_CAPSLOCK } }, - { KE_KEY, 0xe045, { KEY_PROG1 } }, { KE_KEY, 0xe009, { KEY_EJECTCD } }, @@ -87,11 +85,6 @@ static const struct key_entry dell_wmi_legacy_keymap[] __initconst = { { KE_IGNORE, 0xe013, { KEY_RESERVED } }, { KE_IGNORE, 0xe020, { KEY_MUTE } }, - - /* Shortcut and audio panel keys */ - { KE_IGNORE, 0xe025, { KEY_RESERVED } }, - { KE_IGNORE, 0xe026, { KEY_RESERVED } }, - { KE_IGNORE, 0xe02e, { KEY_VOLUMEDOWN } }, { KE_IGNORE, 0xe030, { KEY_VOLUMEUP } }, { KE_IGNORE, 0xe033, { KEY_KBDILLUMUP } }, @@ -99,9 +92,6 @@ static const struct key_entry dell_wmi_legacy_keymap[] __initconst = { { KE_IGNORE, 0xe03a, { KEY_CAPSLOCK } }, { KE_IGNORE, 0xe045, { KEY_NUMLOCK } }, { KE_IGNORE, 0xe046, { KEY_SCROLLLOCK } }, - { KE_IGNORE, 0xe0f7, { KEY_MUTE } }, - { KE_IGNORE, 0xe0f8, { KEY_VOLUMEDOWN } }, - { KE_IGNORE, 0xe0f9, { KEY_VOLUMEUP } }, { KE_END, 0 } }; diff --git a/trunk/drivers/platform/x86/eeepc-wmi.c b/trunk/drivers/platform/x86/eeepc-wmi.c index 9f6e64302b45..4aa867a9b88b 100644 --- a/trunk/drivers/platform/x86/eeepc-wmi.c +++ b/trunk/drivers/platform/x86/eeepc-wmi.c @@ -56,11 +56,6 @@ MODULE_PARM_DESC(hotplug_wireless, "If your laptop needs that, please report to " "acpi4asus-user@lists.sourceforge.net."); -/* Values for T101MT "Home" key */ -#define HOME_PRESS 0xe4 -#define HOME_HOLD 0xea -#define HOME_RELEASE 0xe5 - static const struct key_entry eeepc_wmi_keymap[] = { /* Sleep already handled via generic ACPI code */ { KE_KEY, 0x30, { KEY_VOLUMEUP } }, @@ -76,7 +71,6 @@ static const struct key_entry eeepc_wmi_keymap[] = { { KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } }, { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */ { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */ - { KE_KEY, HOME_PRESS, { KEY_CONFIG } }, /* Home/Express gate key */ { KE_KEY, 0xe8, { KEY_SCREENLOCK } }, { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } }, { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } }, @@ -87,25 +81,6 @@ static const struct key_entry eeepc_wmi_keymap[] = { { KE_END, 0}, }; -static void eeepc_wmi_key_filter(struct asus_wmi_driver *asus_wmi, int *code, - unsigned int *value, bool *autorelease) -{ - switch (*code) { - case HOME_PRESS: - *value = 1; - *autorelease = 0; - break; - case HOME_HOLD: - *code = ASUS_WMI_KEY_IGNORE; - break; - case HOME_RELEASE: - *code = HOME_PRESS; - *value = 0; - *autorelease = 0; - break; - } -} - static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level, void *context, void **retval) { @@ -166,7 +141,6 @@ static void eeepc_dmi_check(struct asus_wmi_driver *driver) static void eeepc_wmi_quirks(struct asus_wmi_driver *driver) { driver->hotplug_wireless = hotplug_wireless; - driver->wapf = -1; eeepc_dmi_check(driver); } @@ -177,7 +151,6 @@ static struct asus_wmi_driver asus_wmi_driver = { .keymap = eeepc_wmi_keymap, .input_name = "Eee PC WMI hotkeys", .input_phys = EEEPC_WMI_FILE "/input0", - .key_filter = eeepc_wmi_key_filter, .probe = eeepc_wmi_probe, .quirks = eeepc_wmi_quirks, }; diff --git a/trunk/drivers/platform/x86/ideapad-laptop.c b/trunk/drivers/platform/x86/ideapad-laptop.c index 0c595410e788..bfdda33feb26 100644 --- a/trunk/drivers/platform/x86/ideapad-laptop.c +++ b/trunk/drivers/platform/x86/ideapad-laptop.c @@ -32,22 +32,13 @@ #include #include #include -#include -#include #define IDEAPAD_RFKILL_DEV_NUM (3) -#define CFG_BT_BIT (16) -#define CFG_3G_BIT (17) -#define CFG_WIFI_BIT (18) -#define CFG_CAMERA_BIT (19) - struct ideapad_private { struct rfkill *rfk[IDEAPAD_RFKILL_DEV_NUM]; struct platform_device *platform_device; struct input_dev *inputdev; - struct backlight_device *blightdev; - unsigned long cfg; }; static acpi_handle ideapad_handle; @@ -164,7 +155,7 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) } /* - * sysfs + * camera power */ static ssize_t show_ideapad_cam(struct device *dev, struct device_attribute *attr, @@ -195,44 +186,6 @@ static ssize_t store_ideapad_cam(struct device *dev, static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); -static ssize_t show_ideapad_cfg(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct ideapad_private *priv = dev_get_drvdata(dev); - - return sprintf(buf, "0x%.8lX\n", priv->cfg); -} - -static DEVICE_ATTR(cfg, 0444, show_ideapad_cfg, NULL); - -static struct attribute *ideapad_attributes[] = { - &dev_attr_camera_power.attr, - &dev_attr_cfg.attr, - NULL -}; - -static mode_t ideapad_is_visible(struct kobject *kobj, - struct attribute *attr, - int idx) -{ - struct device *dev = container_of(kobj, struct device, kobj); - struct ideapad_private *priv = dev_get_drvdata(dev); - bool supported; - - if (attr == &dev_attr_camera_power.attr) - supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); - else - supported = true; - - return supported ? attr->mode : 0; -} - -static struct attribute_group ideapad_attribute_group = { - .is_visible = ideapad_is_visible, - .attrs = ideapad_attributes -}; - /* * Rfkill */ @@ -244,9 +197,9 @@ struct ideapad_rfk_data { }; const struct ideapad_rfk_data ideapad_rfk_data[] = { - { "ideapad_wlan", CFG_WIFI_BIT, 0x15, RFKILL_TYPE_WLAN }, - { "ideapad_bluetooth", CFG_BT_BIT, 0x17, RFKILL_TYPE_BLUETOOTH }, - { "ideapad_3g", CFG_3G_BIT, 0x20, RFKILL_TYPE_WWAN }, + { "ideapad_wlan", 18, 0x15, RFKILL_TYPE_WLAN }, + { "ideapad_bluetooth", 16, 0x17, RFKILL_TYPE_BLUETOOTH }, + { "ideapad_3g", 17, 0x20, RFKILL_TYPE_WWAN }, }; static int ideapad_rfk_set(void *data, bool blocked) @@ -312,7 +265,8 @@ static int __devinit ideapad_register_rfkill(struct acpi_device *adevice, return 0; } -static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) +static void __devexit ideapad_unregister_rfkill(struct acpi_device *adevice, + int dev) { struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); @@ -326,6 +280,15 @@ static void ideapad_unregister_rfkill(struct acpi_device *adevice, int dev) /* * Platform device */ +static struct attribute *ideapad_attributes[] = { + &dev_attr_camera_power.attr, + NULL +}; + +static struct attribute_group ideapad_attribute_group = { + .attrs = ideapad_attributes +}; + static int __devinit ideapad_platform_init(struct ideapad_private *priv) { int result; @@ -406,7 +369,7 @@ static int __devinit ideapad_input_init(struct ideapad_private *priv) return error; } -static void ideapad_input_exit(struct ideapad_private *priv) +static void __devexit ideapad_input_exit(struct ideapad_private *priv) { sparse_keymap_free(priv->inputdev); input_unregister_device(priv->inputdev); @@ -419,98 +382,6 @@ static void ideapad_input_report(struct ideapad_private *priv, sparse_keymap_report_event(priv->inputdev, scancode, 1, true); } -/* - * backlight - */ -static int ideapad_backlight_get_brightness(struct backlight_device *blightdev) -{ - unsigned long now; - - if (read_ec_data(ideapad_handle, 0x12, &now)) - return -EIO; - return now; -} - -static int ideapad_backlight_update_status(struct backlight_device *blightdev) -{ - if (write_ec_cmd(ideapad_handle, 0x13, blightdev->props.brightness)) - return -EIO; - if (write_ec_cmd(ideapad_handle, 0x33, - blightdev->props.power == FB_BLANK_POWERDOWN ? 0 : 1)) - return -EIO; - - return 0; -} - -static const struct backlight_ops ideapad_backlight_ops = { - .get_brightness = ideapad_backlight_get_brightness, - .update_status = ideapad_backlight_update_status, -}; - -static int ideapad_backlight_init(struct ideapad_private *priv) -{ - struct backlight_device *blightdev; - struct backlight_properties props; - unsigned long max, now, power; - - if (read_ec_data(ideapad_handle, 0x11, &max)) - return -EIO; - if (read_ec_data(ideapad_handle, 0x12, &now)) - return -EIO; - if (read_ec_data(ideapad_handle, 0x18, &power)) - return -EIO; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.max_brightness = max; - props.type = BACKLIGHT_PLATFORM; - blightdev = backlight_device_register("ideapad", - &priv->platform_device->dev, - priv, - &ideapad_backlight_ops, - &props); - if (IS_ERR(blightdev)) { - pr_err("Could not register backlight device\n"); - return PTR_ERR(blightdev); - } - - priv->blightdev = blightdev; - blightdev->props.brightness = now; - blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; - backlight_update_status(blightdev); - - return 0; -} - -static void ideapad_backlight_exit(struct ideapad_private *priv) -{ - if (priv->blightdev) - backlight_device_unregister(priv->blightdev); - priv->blightdev = NULL; -} - -static void ideapad_backlight_notify_power(struct ideapad_private *priv) -{ - unsigned long power; - struct backlight_device *blightdev = priv->blightdev; - - if (read_ec_data(ideapad_handle, 0x18, &power)) - return; - blightdev->props.power = power ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; -} - -static void ideapad_backlight_notify_brightness(struct ideapad_private *priv) -{ - unsigned long now; - - /* if we control brightness via acpi video driver */ - if (priv->blightdev == NULL) { - read_ec_data(ideapad_handle, 0x12, &now); - return; - } - - backlight_force_update(priv->blightdev, BACKLIGHT_UPDATE_HOTKEY); -} - /* * module init/exit */ @@ -522,11 +393,10 @@ MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); static int __devinit ideapad_acpi_add(struct acpi_device *adevice) { - int ret, i; - unsigned long cfg; + int ret, i, cfg; struct ideapad_private *priv; - if (read_method_int(adevice->handle, "_CFG", (int *)&cfg)) + if (read_method_int(adevice->handle, "_CFG", &cfg)) return -ENODEV; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -534,7 +404,6 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) return -ENOMEM; dev_set_drvdata(&adevice->dev, priv); ideapad_handle = adevice->handle; - priv->cfg = cfg; ret = ideapad_platform_init(priv); if (ret) @@ -545,25 +414,15 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) goto input_failed; for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { - if (test_bit(ideapad_rfk_data[i].cfgbit, &cfg)) + if (test_bit(ideapad_rfk_data[i].cfgbit, (unsigned long *)&cfg)) ideapad_register_rfkill(adevice, i); else priv->rfk[i] = NULL; } ideapad_sync_rfk_state(adevice); - if (!acpi_video_backlight_support()) { - ret = ideapad_backlight_init(priv); - if (ret && ret != -ENODEV) - goto backlight_failed; - } - return 0; -backlight_failed: - for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) - ideapad_unregister_rfkill(adevice, i); - ideapad_input_exit(priv); input_failed: ideapad_platform_exit(priv); platform_failed: @@ -576,7 +435,6 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type) struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); int i; - ideapad_backlight_exit(priv); for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) ideapad_unregister_rfkill(adevice, i); ideapad_input_exit(priv); @@ -601,19 +459,12 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) vpc1 = (vpc2 << 8) | vpc1; for (vpc_bit = 0; vpc_bit < 16; vpc_bit++) { if (test_bit(vpc_bit, &vpc1)) { - switch (vpc_bit) { - case 9: + if (vpc_bit == 9) ideapad_sync_rfk_state(adevice); - break; - case 4: - ideapad_backlight_notify_brightness(priv); - break; - case 2: - ideapad_backlight_notify_power(priv); - break; - default: + else if (vpc_bit == 4) + read_ec_data(handle, 0x12, &vpc2); + else ideapad_input_report(priv, vpc_bit); - } } } } diff --git a/trunk/drivers/platform/x86/intel_ips.c b/trunk/drivers/platform/x86/intel_ips.c index 809a3ae943c6..5ffe7c398148 100644 --- a/trunk/drivers/platform/x86/intel_ips.c +++ b/trunk/drivers/platform/x86/intel_ips.c @@ -403,7 +403,7 @@ static void ips_cpu_raise(struct ips_driver *ips) thm_writew(THM_MPCPC, (new_tdp_limit * 10) / 8); - turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDP_OVR_EN; + turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDC_OVR_EN; wrmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_override); turbo_override &= ~TURBO_TDP_MASK; @@ -438,7 +438,7 @@ static void ips_cpu_lower(struct ips_driver *ips) thm_writew(THM_MPCPC, (new_limit * 10) / 8); - turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDP_OVR_EN; + turbo_override |= TURBO_TDC_OVR_EN | TURBO_TDC_OVR_EN; wrmsrl(TURBO_POWER_CURRENT_LIMIT, turbo_override); turbo_override &= ~TURBO_TDP_MASK; diff --git a/trunk/drivers/platform/x86/intel_menlow.c b/trunk/drivers/platform/x86/intel_menlow.c index abddc83e9fd7..809adea4965f 100644 --- a/trunk/drivers/platform/x86/intel_menlow.c +++ b/trunk/drivers/platform/x86/intel_menlow.c @@ -477,8 +477,6 @@ static acpi_status intel_menlow_register_sensor(acpi_handle handle, u32 lvl, return AE_ERROR; } - return AE_OK; - aux1_not_found: if (status == AE_NOT_FOUND) return AE_OK; diff --git a/trunk/drivers/platform/x86/intel_mid_thermal.c b/trunk/drivers/platform/x86/intel_mid_thermal.c index ccd7b1f83519..3a578323122b 100644 --- a/trunk/drivers/platform/x86/intel_mid_thermal.c +++ b/trunk/drivers/platform/x86/intel_mid_thermal.c @@ -493,30 +493,20 @@ static int mid_thermal_probe(struct platform_device *pdev) /* Register each sensor with the generic thermal framework*/ for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { - struct thermal_device_info *td_info = initialize_sensor(i); - - if (!td_info) { - ret = -ENOMEM; - goto err; - } pinfo->tzd[i] = thermal_zone_device_register(name[i], - 0, td_info, &tzd_ops, 0, 0, 0, 0); - if (IS_ERR(pinfo->tzd[i])) { - kfree(td_info); - ret = PTR_ERR(pinfo->tzd[i]); - goto err; - } + 0, initialize_sensor(i), &tzd_ops, 0, 0, 0, 0); + if (IS_ERR(pinfo->tzd[i])) + goto reg_fail; } pinfo->pdev = pdev; platform_set_drvdata(pdev, pinfo); return 0; -err: - while (--i >= 0) { - kfree(pinfo->tzd[i]->devdata); +reg_fail: + ret = PTR_ERR(pinfo->tzd[i]); + while (--i >= 0) thermal_zone_device_unregister(pinfo->tzd[i]); - } configure_adc(0); kfree(pinfo); return ret; @@ -534,10 +524,8 @@ static int mid_thermal_remove(struct platform_device *pdev) int i; struct platform_info *pinfo = platform_get_drvdata(pdev); - for (i = 0; i < MSIC_THERMAL_SENSORS; i++) { - kfree(pinfo->tzd[i]->devdata); + for (i = 0; i < MSIC_THERMAL_SENSORS; i++) thermal_zone_device_unregister(pinfo->tzd[i]); - } kfree(pinfo); platform_set_drvdata(pdev, NULL); diff --git a/trunk/drivers/platform/x86/intel_rar_register.c b/trunk/drivers/platform/x86/intel_rar_register.c index c8a6aed45277..bde47e9080cd 100644 --- a/trunk/drivers/platform/x86/intel_rar_register.c +++ b/trunk/drivers/platform/x86/intel_rar_register.c @@ -637,13 +637,15 @@ static int rar_probe(struct pci_dev *dev, const struct pci_device_id *id) return error; } -static DEFINE_PCI_DEVICE_TABLE(rar_pci_id_tbl) = { +const struct pci_device_id rar_pci_id_tbl[] = { { PCI_VDEVICE(INTEL, 0x4110) }, { 0 } }; MODULE_DEVICE_TABLE(pci, rar_pci_id_tbl); +const struct pci_device_id *my_id_table = rar_pci_id_tbl; + /* field for registering driver to PCI device */ static struct pci_driver rar_pci_driver = { .name = "rar_register_driver", diff --git a/trunk/drivers/platform/x86/intel_scu_ipc.c b/trunk/drivers/platform/x86/intel_scu_ipc.c index c86665369a22..940accbe28d3 100644 --- a/trunk/drivers/platform/x86/intel_scu_ipc.c +++ b/trunk/drivers/platform/x86/intel_scu_ipc.c @@ -725,7 +725,7 @@ static void ipc_remove(struct pci_dev *pdev) intel_scu_devices_destroy(); } -static DEFINE_PCI_DEVICE_TABLE(pci_ids) = { +static const struct pci_device_id pci_ids[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x080e)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x082a)}, { 0,} diff --git a/trunk/drivers/platform/x86/msi-laptop.c b/trunk/drivers/platform/x86/msi-laptop.c index f204643c5052..3ff629df9f01 100644 --- a/trunk/drivers/platform/x86/msi-laptop.c +++ b/trunk/drivers/platform/x86/msi-laptop.c @@ -538,15 +538,6 @@ static struct dmi_system_id __initdata msi_load_scm_models_dmi_table[] = { }, .callback = dmi_check_cb }, - { - .ident = "MSI U270", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "Micro-Star International Co., Ltd."), - DMI_MATCH(DMI_PRODUCT_NAME, "U270 series"), - }, - .callback = dmi_check_cb - }, { } }; @@ -1005,4 +996,3 @@ MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N034:*"); MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N051:*"); MODULE_ALIAS("dmi:*:svnMICRO-STARINTERNATIONAL*:pnMS-N014:*"); MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnCR620:*"); -MODULE_ALIAS("dmi:*:svnMicro-StarInternational*:pnU270series:*"); diff --git a/trunk/drivers/platform/x86/msi-wmi.c b/trunk/drivers/platform/x86/msi-wmi.c index 6f40bf202dc7..c832e3356cd6 100644 --- a/trunk/drivers/platform/x86/msi-wmi.c +++ b/trunk/drivers/platform/x86/msi-wmi.c @@ -272,7 +272,6 @@ static int __init msi_wmi_init(void) err_free_backlight: backlight_device_unregister(backlight); err_free_input: - sparse_keymap_free(msi_wmi_input_dev); input_unregister_device(msi_wmi_input_dev); err_uninstall_notifier: wmi_remove_notify_handler(MSIWMI_EVENT_GUID); diff --git a/trunk/drivers/platform/x86/samsung-laptop.c b/trunk/drivers/platform/x86/samsung-laptop.c index 359163011044..d347116d150e 100644 --- a/trunk/drivers/platform/x86/samsung-laptop.c +++ b/trunk/drivers/platform/x86/samsung-laptop.c @@ -520,16 +520,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, - { - .ident = "N510", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N510"), - DMI_MATCH(DMI_BOARD_NAME, "N510"), - }, - .callback = dmi_check_cb, - }, { .ident = "X125", .matches = { @@ -610,16 +600,6 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, .callback = dmi_check_cb, }, - { - .ident = "N150/N210/N220", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, - "SAMSUNG ELECTRONICS CO., LTD."), - DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"), - DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"), - }, - .callback = dmi_check_cb, - }, { .ident = "N150/N210/N220/N230", .matches = { diff --git a/trunk/drivers/platform/x86/samsung-q10.c b/trunk/drivers/platform/x86/samsung-q10.c deleted file mode 100644 index 1e54ae74274c..000000000000 --- a/trunk/drivers/platform/x86/samsung-q10.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * Driver for Samsung Q10 and related laptops: controls the backlight - * - * Copyright (c) 2011 Frederick van der Wyck - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#define SAMSUNGQ10_BL_MAX_INTENSITY 255 -#define SAMSUNGQ10_BL_DEFAULT_INTENSITY 185 - -#define SAMSUNGQ10_BL_8042_CMD 0xbe -#define SAMSUNGQ10_BL_8042_DATA { 0x89, 0x91 } - -static int samsungq10_bl_brightness; - -static bool force; -module_param(force, bool, 0); -MODULE_PARM_DESC(force, - "Disable the DMI check and force the driver to be loaded"); - -static int samsungq10_bl_set_intensity(struct backlight_device *bd) -{ - - int brightness = bd->props.brightness; - unsigned char c[3] = SAMSUNGQ10_BL_8042_DATA; - - c[2] = (unsigned char)brightness; - i8042_lock_chip(); - i8042_command(c, (0x30 << 8) | SAMSUNGQ10_BL_8042_CMD); - i8042_unlock_chip(); - samsungq10_bl_brightness = brightness; - - return 0; -} - -static int samsungq10_bl_get_intensity(struct backlight_device *bd) -{ - return samsungq10_bl_brightness; -} - -static const struct backlight_ops samsungq10_bl_ops = { - .get_brightness = samsungq10_bl_get_intensity, - .update_status = samsungq10_bl_set_intensity, -}; - -#ifdef CONFIG_PM_SLEEP -static int samsungq10_suspend(struct device *dev) -{ - return 0; -} - -static int samsungq10_resume(struct device *dev) -{ - - struct backlight_device *bd = dev_get_drvdata(dev); - - samsungq10_bl_set_intensity(bd); - return 0; -} -#else -#define samsungq10_suspend NULL -#define samsungq10_resume NULL -#endif - -static SIMPLE_DEV_PM_OPS(samsungq10_pm_ops, - samsungq10_suspend, samsungq10_resume); - -static int __devinit samsungq10_probe(struct platform_device *pdev) -{ - - struct backlight_properties props; - struct backlight_device *bd; - - memset(&props, 0, sizeof(struct backlight_properties)); - props.type = BACKLIGHT_PLATFORM; - props.max_brightness = SAMSUNGQ10_BL_MAX_INTENSITY; - bd = backlight_device_register("samsung", &pdev->dev, NULL, - &samsungq10_bl_ops, &props); - if (IS_ERR(bd)) - return PTR_ERR(bd); - - platform_set_drvdata(pdev, bd); - - bd->props.brightness = SAMSUNGQ10_BL_DEFAULT_INTENSITY; - samsungq10_bl_set_intensity(bd); - - return 0; -} - -static int __devexit samsungq10_remove(struct platform_device *pdev) -{ - - struct backlight_device *bd = platform_get_drvdata(pdev); - - bd->props.brightness = SAMSUNGQ10_BL_DEFAULT_INTENSITY; - samsungq10_bl_set_intensity(bd); - - backlight_device_unregister(bd); - - return 0; -} - -static struct platform_driver samsungq10_driver = { - .driver = { - .name = KBUILD_MODNAME, - .owner = THIS_MODULE, - .pm = &samsungq10_pm_ops, - }, - .probe = samsungq10_probe, - .remove = __devexit_p(samsungq10_remove), -}; - -static struct platform_device *samsungq10_device; - -static int __init dmi_check_callback(const struct dmi_system_id *id) -{ - printk(KERN_INFO KBUILD_MODNAME ": found model '%s'\n", id->ident); - return 1; -} - -static struct dmi_system_id __initdata samsungq10_dmi_table[] = { - { - .ident = "Samsung Q10", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Samsung"), - DMI_MATCH(DMI_PRODUCT_NAME, "SQ10"), - }, - .callback = dmi_check_callback, - }, - { - .ident = "Samsung Q20", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"), - DMI_MATCH(DMI_PRODUCT_NAME, "SENS Q20"), - }, - .callback = dmi_check_callback, - }, - { - .ident = "Samsung Q25", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG Electronics"), - DMI_MATCH(DMI_PRODUCT_NAME, "NQ25"), - }, - .callback = dmi_check_callback, - }, - { - .ident = "Dell Latitude X200", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "X200"), - }, - .callback = dmi_check_callback, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, samsungq10_dmi_table); - -static int __init samsungq10_init(void) -{ - if (!force && !dmi_check_system(samsungq10_dmi_table)) - return -ENODEV; - - samsungq10_device = platform_create_bundle(&samsungq10_driver, - samsungq10_probe, - NULL, 0, NULL, 0); - - if (IS_ERR(samsungq10_device)) - return PTR_ERR(samsungq10_device); - - return 0; -} - -static void __exit samsungq10_exit(void) -{ - platform_device_unregister(samsungq10_device); - platform_driver_unregister(&samsungq10_driver); -} - -module_init(samsungq10_init); -module_exit(samsungq10_exit); - -MODULE_AUTHOR("Frederick van der Wyck "); -MODULE_DESCRIPTION("Samsung Q10 Driver"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/platform/x86/thinkpad_acpi.c b/trunk/drivers/platform/x86/thinkpad_acpi.c index 7bd829f247eb..26c5b117df22 100644 --- a/trunk/drivers/platform/x86/thinkpad_acpi.c +++ b/trunk/drivers/platform/x86/thinkpad_acpi.c @@ -3186,17 +3186,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) KEY_VENDOR, /* 0x17: Thinkpad/AccessIBM/Lenovo */ /* (assignments unknown, please report if found) */ - KEY_UNKNOWN, KEY_UNKNOWN, - - /* - * The mic mute button only sends 0x1a. It does not - * automatically mute the mic or change the mute light. - */ - KEY_MICMUTE, /* 0x1a: Mic mute (since ?400 or so) */ - - /* (assignments unknown, please report if found) */ KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - KEY_UNKNOWN, + KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, }, }; diff --git a/trunk/drivers/rtc/rtc-omap.c b/trunk/drivers/rtc/rtc-omap.c index 7789002bdd5c..bcae8dd41496 100644 --- a/trunk/drivers/rtc/rtc-omap.c +++ b/trunk/drivers/rtc/rtc-omap.c @@ -368,7 +368,7 @@ static int __init omap_rtc_probe(struct platform_device *pdev) pr_info("%s: already running\n", pdev->name); /* force to 24 hour mode */ - new_ctrl = reg & (OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP); + new_ctrl = reg & ~(OMAP_RTC_CTRL_SPLIT|OMAP_RTC_CTRL_AUTO_COMP); new_ctrl |= OMAP_RTC_CTRL_STOP; /* BOARD-SPECIFIC CUSTOMIZATION CAN GO HERE: diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index a1d3ddba99cc..432444af7ee4 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include @@ -889,11 +888,11 @@ char *dasd_get_user_string(const char __user *user_buf, size_t user_len) { char *buffer; - buffer = vmalloc(user_len + 1); + buffer = kmalloc(user_len + 1, GFP_KERNEL); if (buffer == NULL) return ERR_PTR(-ENOMEM); if (copy_from_user(buffer, user_buf, user_len) != 0) { - vfree(buffer); + kfree(buffer); return ERR_PTR(-EFAULT); } /* got the string, now strip linefeed. */ @@ -931,7 +930,7 @@ static ssize_t dasd_stats_write(struct file *file, dasd_profile_off(prof); } else rc = -EINVAL; - vfree(buffer); + kfree(buffer); return rc; } @@ -1043,7 +1042,7 @@ static ssize_t dasd_stats_global_write(struct file *file, dasd_global_profile_level = DASD_PROFILE_OFF; } else rc = -EINVAL; - vfree(buffer); + kfree(buffer); return rc; } diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 6e835c9fdfcb..30fb979d684d 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1461,15 +1461,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) "Read device characteristic failed, rc=%d", rc); goto out_err3; } - - if ((device->features & DASD_FEATURE_USERAW) && - !(private->rdc_data.facilities.RT_in_LR)) { - dev_err(&device->cdev->dev, "The storage server does not " - "support raw-track access\n"); - rc = -EINVAL; - goto out_err3; - } - /* find the valid cylinder size */ if (private->rdc_data.no_cyl == LV_COMPAT_CYL && private->rdc_data.long_no_cyl) diff --git a/trunk/drivers/s390/block/dasd_proc.c b/trunk/drivers/s390/block/dasd_proc.c index e12989fff4ff..6c3c5364d082 100644 --- a/trunk/drivers/s390/block/dasd_proc.c +++ b/trunk/drivers/s390/block/dasd_proc.c @@ -312,14 +312,14 @@ static ssize_t dasd_stats_proc_write(struct file *file, pr_info("The statistics have been reset\n"); } else goto out_parse_error; - vfree(buffer); + kfree(buffer); return user_len; out_parse_error: rc = -EINVAL; pr_warning("%s is not a supported value for /proc/dasd/statistics\n", str); out_error: - vfree(buffer); + kfree(buffer); return rc; #else pr_warning("/proc/dasd/statistics: is not activated in this kernel\n"); diff --git a/trunk/drivers/s390/char/sclp_async.c b/trunk/drivers/s390/char/sclp_async.c index 5f9f929e891c..7ad30e72f868 100644 --- a/trunk/drivers/s390/char/sclp_async.c +++ b/trunk/drivers/s390/char/sclp_async.c @@ -82,9 +82,12 @@ static int proc_handler_callhome(struct ctl_table *ctl, int write, return -EFAULT; } else { len = *count; - rc = kstrtoul_from_user(buffer, len, 0, &val); - if (rc) - return rc; + rc = copy_from_user(buf, buffer, sizeof(buf)); + if (rc != 0) + return -EFAULT; + buf[sizeof(buf) - 1] = '\0'; + if (strict_strtoul(buf, 0, &val) != 0) + return -EINVAL; if (val != 0 && val != 1) return -EINVAL; callhome_enabled = val; diff --git a/trunk/drivers/s390/cio/qdio.h b/trunk/drivers/s390/cio/qdio.h index e5c966462c5a..7bc643f3f5ab 100644 --- a/trunk/drivers/s390/cio/qdio.h +++ b/trunk/drivers/s390/cio/qdio.h @@ -14,8 +14,6 @@ #include "chsc.h" #define QDIO_BUSY_BIT_PATIENCE (100 << 12) /* 100 microseconds */ -#define QDIO_BUSY_BIT_RETRY_DELAY 10 /* 10 milliseconds */ -#define QDIO_BUSY_BIT_RETRIES 1000 /* = 10s retry time */ #define QDIO_INPUT_THRESHOLD (500 << 12) /* 500 microseconds */ /* diff --git a/trunk/drivers/s390/cio/qdio_debug.c b/trunk/drivers/s390/cio/qdio_debug.c index 0e615cb912d0..f8b03a636e49 100644 --- a/trunk/drivers/s390/cio/qdio_debug.c +++ b/trunk/drivers/s390/cio/qdio_debug.c @@ -188,13 +188,19 @@ static ssize_t qperf_seq_write(struct file *file, const char __user *ubuf, struct qdio_irq *irq_ptr = seq->private; struct qdio_q *q; unsigned long val; + char buf[8]; int ret, i; if (!irq_ptr) return 0; - - ret = kstrtoul_from_user(ubuf, count, 10, &val); - if (ret) + if (count >= sizeof(buf)) + return -EINVAL; + if (copy_from_user(&buf, ubuf, count)) + return -EFAULT; + buf[count] = 0; + + ret = strict_strtoul(buf, 10, &val); + if (ret < 0) return ret; switch (val) { diff --git a/trunk/drivers/s390/cio/qdio_main.c b/trunk/drivers/s390/cio/qdio_main.c index 288c9140290e..e58169c32474 100644 --- a/trunk/drivers/s390/cio/qdio_main.c +++ b/trunk/drivers/s390/cio/qdio_main.c @@ -313,7 +313,7 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit) unsigned long schid = *((u32 *) &q->irq_ptr->schid); unsigned int fc = QDIO_SIGA_WRITE; u64 start_time = 0; - int retries = 0, cc; + int cc; if (is_qebsm(q)) { schid = q->irq_ptr->sch_token; @@ -325,7 +325,6 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit) /* hipersocket busy condition */ if (unlikely(*busy_bit)) { WARN_ON(queue_type(q) != QDIO_IQDIO_QFMT || cc != 2); - retries++; if (!start_time) { start_time = get_clock(); @@ -334,11 +333,6 @@ static int qdio_siga_output(struct qdio_q *q, unsigned int *busy_bit) if ((get_clock() - start_time) < QDIO_BUSY_BIT_PATIENCE) goto again; } - if (retries) { - DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, - "%4x cc2 BB1:%1d", SCH_NO(q), q->nr); - DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "count:%u", retries); - } return cc; } @@ -734,14 +728,13 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q) static int qdio_kick_outbound_q(struct qdio_q *q) { - int retries = 0, cc; unsigned int busy_bit; + int cc; if (!need_siga_out(q)) return 0; DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w:%1d", q->nr); -retry: qperf_inc(q, siga_write); cc = qdio_siga_output(q, &busy_bit); @@ -750,11 +743,7 @@ static int qdio_kick_outbound_q(struct qdio_q *q) break; case 2: if (busy_bit) { - while (++retries < QDIO_BUSY_BIT_RETRIES) { - mdelay(QDIO_BUSY_BIT_RETRY_DELAY); - goto retry; - } - DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); + DBF_ERROR("%4x cc2 REP:%1d", SCH_NO(q), q->nr); cc |= QDIO_ERROR_SIGA_BUSY; } else DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); @@ -764,10 +753,6 @@ static int qdio_kick_outbound_q(struct qdio_q *q) DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); break; } - if (retries) { - DBF_ERROR("%4x cc2 BB2:%1d", SCH_NO(q), q->nr); - DBF_ERROR("count:%u", retries); - } return cc; } diff --git a/trunk/drivers/spi/spi-pl022.c b/trunk/drivers/spi/spi-pl022.c index 730b4a37b823..eba88c749fb1 100644 --- a/trunk/drivers/spi/spi-pl022.c +++ b/trunk/drivers/spi/spi-pl022.c @@ -2267,13 +2267,17 @@ static int __devexit pl022_remove(struct amba_device *adev) { struct pl022 *pl022 = amba_get_drvdata(adev); - + int status = 0; if (!pl022) return 0; /* Remove the queue */ - if (destroy_queue(pl022) != 0) - dev_err(&adev->dev, "queue remove failed\n"); + status = destroy_queue(pl022); + if (status != 0) { + dev_err(&adev->dev, + "queue remove failed (%d)\n", status); + return status; + } load_ssp_default_config(pl022); pl022_dma_remove(pl022); free_irq(adev->irq[0], pl022); @@ -2285,6 +2289,7 @@ pl022_remove(struct amba_device *adev) spi_unregister_master(pl022->master); spi_master_put(pl022->master); amba_set_drvdata(adev, NULL); + dev_dbg(&adev->dev, "remove succeeded\n"); return 0; } diff --git a/trunk/drivers/staging/gma500/gem_glue.c b/trunk/drivers/staging/gma500/gem_glue.c index daac12120653..779ac1a12d24 100644 --- a/trunk/drivers/staging/gma500/gem_glue.c +++ b/trunk/drivers/staging/gma500/gem_glue.c @@ -20,6 +20,26 @@ #include #include +/** + * Initialize an already allocated GEM object of the specified size with + * no GEM provided backing store. Instead the caller is responsible for + * backing the object and handling it. + */ +int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size) +{ + BUG_ON((size & (PAGE_SIZE - 1)) != 0); + + obj->dev = dev; + obj->filp = NULL; + + kref_init(&obj->refcount); + atomic_set(&obj->handle_count, 0); + obj->size = size; + + return 0; +} + void drm_gem_object_release_wrap(struct drm_gem_object *obj) { /* Remove the list map if one is present */ @@ -31,7 +51,8 @@ void drm_gem_object_release_wrap(struct drm_gem_object *obj) kfree(list->map); list->map = NULL; } - drm_gem_object_release(obj); + if (obj->filp) + drm_gem_object_release(obj); } /** diff --git a/trunk/drivers/staging/gma500/gem_glue.h b/trunk/drivers/staging/gma500/gem_glue.h index ce5ce30f74db..a0f2bc4e4ae7 100644 --- a/trunk/drivers/staging/gma500/gem_glue.h +++ b/trunk/drivers/staging/gma500/gem_glue.h @@ -1,2 +1,4 @@ extern void drm_gem_object_release_wrap(struct drm_gem_object *obj); +extern int drm_gem_private_object_init(struct drm_device *dev, + struct drm_gem_object *obj, size_t size); extern int gem_create_mmap_offset(struct drm_gem_object *obj); diff --git a/trunk/drivers/staging/zcache/Makefile b/trunk/drivers/staging/zcache/Makefile index f5ec64f94470..60daa272c204 100644 --- a/trunk/drivers/staging/zcache/Makefile +++ b/trunk/drivers/staging/zcache/Makefile @@ -1,3 +1,3 @@ -zcache-y := tmem.o +zcache-y := zcache-main.o tmem.o obj-$(CONFIG_ZCACHE) += zcache.o diff --git a/trunk/drivers/staging/zcache/zcache.c b/trunk/drivers/staging/zcache/zcache-main.c similarity index 100% rename from trunk/drivers/staging/zcache/zcache.c rename to trunk/drivers/staging/zcache/zcache-main.c diff --git a/trunk/drivers/target/iscsi/Kconfig b/trunk/drivers/target/iscsi/Kconfig index 8345fb457a40..564ff4e0dbc4 100644 --- a/trunk/drivers/target/iscsi/Kconfig +++ b/trunk/drivers/target/iscsi/Kconfig @@ -1,6 +1,5 @@ config ISCSI_TARGET tristate "Linux-iSCSI.org iSCSI Target Mode Stack" - depends on NET select CRYPTO select CRYPTO_CRC32C select CRYPTO_CRC32C_INTEL if X86 diff --git a/trunk/drivers/target/iscsi/iscsi_target.c b/trunk/drivers/target/iscsi/iscsi_target.c index c24fb10de60b..14c81c4265bd 100644 --- a/trunk/drivers/target/iscsi/iscsi_target.c +++ b/trunk/drivers/target/iscsi/iscsi_target.c @@ -120,7 +120,7 @@ struct iscsi_tiqn *iscsit_add_tiqn(unsigned char *buf) struct iscsi_tiqn *tiqn = NULL; int ret; - if (strlen(buf) >= ISCSI_IQN_LEN) { + if (strlen(buf) > ISCSI_IQN_LEN) { pr_err("Target IQN exceeds %d bytes\n", ISCSI_IQN_LEN); return ERR_PTR(-EINVAL); @@ -1857,7 +1857,7 @@ static int iscsit_handle_text_cmd( char *text_ptr, *text_in; int cmdsn_ret, niov = 0, rx_got, rx_size; u32 checksum = 0, data_crc = 0, payload_length; - u32 padding = 0, pad_bytes = 0, text_length = 0; + u32 padding = 0, text_length = 0; struct iscsi_cmd *cmd; struct kvec iov[3]; struct iscsi_text *hdr; @@ -1896,7 +1896,7 @@ static int iscsit_handle_text_cmd( padding = ((-payload_length) & 3); if (padding != 0) { - iov[niov].iov_base = &pad_bytes; + iov[niov].iov_base = cmd->pad_bytes; iov[niov++].iov_len = padding; rx_size += padding; pr_debug("Receiving %u additional bytes" @@ -1917,7 +1917,7 @@ static int iscsit_handle_text_cmd( if (conn->conn_ops->DataDigest) { iscsit_do_crypto_hash_buf(&conn->conn_rx_hash, text_in, text_length, - padding, (u8 *)&pad_bytes, + padding, cmd->pad_bytes, (u8 *)&data_crc); if (checksum != data_crc) { @@ -3468,12 +3468,7 @@ static inline void iscsit_thread_check_cpumask( } #else - -void iscsit_thread_get_cpumask(struct iscsi_conn *conn) -{ - return; -} - +#define iscsit_thread_get_cpumask(X) ({}) #define iscsit_thread_check_cpumask(X, Y, Z) ({}) #endif /* CONFIG_SMP */ diff --git a/trunk/drivers/target/iscsi/iscsi_target_configfs.c b/trunk/drivers/target/iscsi/iscsi_target_configfs.c index f095e65b1ccf..32bb92c44450 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_configfs.c +++ b/trunk/drivers/target/iscsi/iscsi_target_configfs.c @@ -181,7 +181,7 @@ struct se_tpg_np *lio_target_call_addnptotpg( return ERR_PTR(-EOVERFLOW); } memset(buf, 0, MAX_PORTAL_LEN + 1); - snprintf(buf, MAX_PORTAL_LEN + 1, "%s", name); + snprintf(buf, MAX_PORTAL_LEN, "%s", name); memset(&sockaddr, 0, sizeof(struct __kernel_sockaddr_storage)); diff --git a/trunk/drivers/target/iscsi/iscsi_target_nego.c b/trunk/drivers/target/iscsi/iscsi_target_nego.c index 4d087ac11067..713a4d23557a 100644 --- a/trunk/drivers/target/iscsi/iscsi_target_nego.c +++ b/trunk/drivers/target/iscsi/iscsi_target_nego.c @@ -978,7 +978,7 @@ struct iscsi_login *iscsi_target_init_negotiation( pr_err("Unable to allocate memory for struct iscsi_login.\n"); iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR, ISCSI_LOGIN_STATUS_NO_RESOURCES); - return NULL; + goto out; } login->req = kzalloc(ISCSI_HDR_LEN, GFP_KERNEL); diff --git a/trunk/drivers/target/target_core_transport.c b/trunk/drivers/target/target_core_transport.c index 89760329d5d0..c75a01a1c475 100644 --- a/trunk/drivers/target/target_core_transport.c +++ b/trunk/drivers/target/target_core_transport.c @@ -1747,8 +1747,6 @@ int transport_generic_handle_cdb( } EXPORT_SYMBOL(transport_generic_handle_cdb); -static void transport_generic_request_failure(struct se_cmd *, - struct se_device *, int, int); /* * Used by fabric module frontends to queue tasks directly. * Many only be used from process context only @@ -1756,8 +1754,6 @@ static void transport_generic_request_failure(struct se_cmd *, int transport_handle_cdb_direct( struct se_cmd *cmd) { - int ret; - if (!cmd->se_lun) { dump_stack(); pr_err("cmd->se_lun is NULL\n"); @@ -1769,31 +1765,8 @@ int transport_handle_cdb_direct( " from interrupt context\n"); return -EINVAL; } - /* - * Set TRANSPORT_NEW_CMD state and cmd->t_transport_active=1 following - * transport_generic_handle_cdb*() -> transport_add_cmd_to_queue() - * in existing usage to ensure that outstanding descriptors are handled - * correctly during shutdown via transport_generic_wait_for_tasks() - * - * Also, we don't take cmd->t_state_lock here as we only expect - * this to be called for initial descriptor submission. - */ - cmd->t_state = TRANSPORT_NEW_CMD; - atomic_set(&cmd->t_transport_active, 1); - /* - * transport_generic_new_cmd() is already handling QUEUE_FULL, - * so follow TRANSPORT_NEW_CMD processing thread context usage - * and call transport_generic_request_failure() if necessary.. - */ - ret = transport_generic_new_cmd(cmd); - if (ret == -EAGAIN) - return 0; - else if (ret < 0) { - cmd->transport_error_status = ret; - transport_generic_request_failure(cmd, NULL, 0, - (cmd->data_direction != DMA_TO_DEVICE)); - } - return 0; + + return transport_generic_new_cmd(cmd); } EXPORT_SYMBOL(transport_handle_cdb_direct); @@ -3351,7 +3324,7 @@ static int transport_generic_cmd_sequencer( goto out_invalid_cdb_field; } - cmd->t_task_lba = get_unaligned_be64(&cdb[2]); + cmd->t_task_lba = get_unaligned_be16(&cdb[2]); passthrough = (dev->transport->transport_type == TRANSPORT_PLUGIN_PHBA_PDEV); /* diff --git a/trunk/drivers/target/tcm_fc/tcm_fc.h b/trunk/drivers/target/tcm_fc/tcm_fc.h index bd4fe21a23b8..f7fff7ed63c3 100644 --- a/trunk/drivers/target/tcm_fc/tcm_fc.h +++ b/trunk/drivers/target/tcm_fc/tcm_fc.h @@ -187,9 +187,4 @@ void ft_dump_cmd(struct ft_cmd *, const char *caller); ssize_t ft_format_wwn(char *, size_t, u64); -/* - * Underlying HW specific helper function - */ -void ft_invl_hw_context(struct ft_cmd *); - #endif /* __TCM_FC_H__ */ diff --git a/trunk/drivers/target/tcm_fc/tfc_cmd.c b/trunk/drivers/target/tcm_fc/tfc_cmd.c index 5654dc22f7ae..09df38b4610c 100644 --- a/trunk/drivers/target/tcm_fc/tfc_cmd.c +++ b/trunk/drivers/target/tcm_fc/tfc_cmd.c @@ -320,7 +320,6 @@ static void ft_recv_seq(struct fc_seq *sp, struct fc_frame *fp, void *arg) default: pr_debug("%s: unhandled frame r_ctl %x\n", __func__, fh->fh_r_ctl); - ft_invl_hw_context(cmd); fc_frame_free(fp); transport_generic_free_cmd(&cmd->se_cmd, 0, 0); break; diff --git a/trunk/drivers/target/tcm_fc/tfc_io.c b/trunk/drivers/target/tcm_fc/tfc_io.c index c37f4cd96452..8e2a46ddcccb 100644 --- a/trunk/drivers/target/tcm_fc/tfc_io.c +++ b/trunk/drivers/target/tcm_fc/tfc_io.c @@ -213,49 +213,62 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp) if (!(ntoh24(fh->fh_f_ctl) & FC_FC_REL_OFF)) goto drop; - f_ctl = ntoh24(fh->fh_f_ctl); - ep = fc_seq_exch(seq); - lport = ep->lp; - if (cmd->was_ddp_setup) { - BUG_ON(!ep); - BUG_ON(!lport); - } - /* - * Doesn't expect payload if DDP is setup. Payload + * Doesn't expect even single byte of payload. Payload * is expected to be copied directly to user buffers - * due to DDP (Large Rx offload), + * due to DDP (Large Rx offload) feature, hence + * BUG_ON if BUF is non-NULL */ buf = fc_frame_payload_get(fp, 1); - if (buf) - pr_err("%s: xid 0x%x, f_ctl 0x%x, cmd->sg %p, " - "cmd->sg_cnt 0x%x. DDP was setup" - " hence not expected to receive frame with " - "payload, Frame will be dropped if " - "'Sequence Initiative' bit in f_ctl is " - "not set\n", __func__, ep->xid, f_ctl, - cmd->sg, cmd->sg_cnt); - /* - * Invalidate HW DDP context if it was setup for respective - * command. Invalidation of HW DDP context is requited in both - * situation (success and error). - */ - ft_invl_hw_context(cmd); + if (cmd->was_ddp_setup && buf) { + pr_debug("%s: When DDP was setup, not expected to" + "receive frame with payload, Payload shall be" + "copied directly to buffer instead of coming " + "via. legacy receive queues\n", __func__); + BUG_ON(buf); + } /* - * If "Sequence Initiative (TSI)" bit set in f_ctl, means last - * write data frame is received successfully where payload is - * posted directly to user buffer and only the last frame's - * header is posted in receive queue. - * - * If "Sequence Initiative (TSI)" bit is not set, means error - * condition w.r.t. DDP, hence drop the packet and let explict - * ABORTS from other end of exchange timer trigger the recovery. + * If ft_cmd indicated 'ddp_setup', in that case only the last frame + * should come with 'TSI bit being set'. If 'TSI bit is not set and if + * data frame appears here, means error condition. In both the cases + * release the DDP context (ddp_put) and in error case, as well + * initiate error recovery mechanism. */ - if (f_ctl & FC_FC_SEQ_INIT) - goto last_frame; - else - goto drop; + ep = fc_seq_exch(seq); + if (cmd->was_ddp_setup) { + BUG_ON(!ep); + lport = ep->lp; + BUG_ON(!lport); + } + if (cmd->was_ddp_setup && ep->xid != FC_XID_UNKNOWN) { + f_ctl = ntoh24(fh->fh_f_ctl); + /* + * If TSI bit set in f_ctl, means last write data frame is + * received successfully where payload is posted directly + * to user buffer and only the last frame's header is posted + * in legacy receive queue + */ + if (f_ctl & FC_FC_SEQ_INIT) { /* TSI bit set in FC frame */ + cmd->write_data_len = lport->tt.ddp_done(lport, + ep->xid); + goto last_frame; + } else { + /* + * Updating the write_data_len may be meaningless at + * this point, but just in case if required in future + * for debugging or any other purpose + */ + pr_err("%s: Received frame with TSI bit not" + " being SET, dropping the frame, " + "cmd->sg <%p>, cmd->sg_cnt <0x%x>\n", + __func__, cmd->sg, cmd->sg_cnt); + cmd->write_data_len = lport->tt.ddp_done(lport, + ep->xid); + lport->tt.seq_exch_abort(cmd->seq, 0); + goto drop; + } + } rel_off = ntohl(fh->fh_parm_offset); frame_len = fr_len(fp); @@ -318,39 +331,3 @@ void ft_recv_write_data(struct ft_cmd *cmd, struct fc_frame *fp) drop: fc_frame_free(fp); } - -/* - * Handle and cleanup any HW specific resources if - * received ABORTS, errors, timeouts. - */ -void ft_invl_hw_context(struct ft_cmd *cmd) -{ - struct fc_seq *seq = cmd->seq; - struct fc_exch *ep = NULL; - struct fc_lport *lport = NULL; - - BUG_ON(!cmd); - - /* Cleanup the DDP context in HW if DDP was setup */ - if (cmd->was_ddp_setup && seq) { - ep = fc_seq_exch(seq); - if (ep) { - lport = ep->lp; - if (lport && (ep->xid <= lport->lro_xid)) - /* - * "ddp_done" trigger invalidation of HW - * specific DDP context - */ - cmd->write_data_len = lport->tt.ddp_done(lport, - ep->xid); - - /* - * Resetting same variable to indicate HW's - * DDP context has been invalidated to avoid - * re_invalidation of same context (context is - * identified using ep->xid) - */ - cmd->was_ddp_setup = 0; - } - } -} diff --git a/trunk/drivers/thermal/Kconfig b/trunk/drivers/thermal/Kconfig index f7f71b2d3101..bf7c687519ef 100644 --- a/trunk/drivers/thermal/Kconfig +++ b/trunk/drivers/thermal/Kconfig @@ -14,7 +14,11 @@ menuconfig THERMAL If you want this support, you should say Y or M here. config THERMAL_HWMON - bool + bool "Hardware monitoring support" depends on THERMAL depends on HWMON=y || HWMON=THERMAL - default y + help + The generic thermal sysfs driver's hardware monitoring support + requires a 2.10.7/3.0.2 or later lm-sensors userspace. + + Say Y if your user-space is new enough. diff --git a/trunk/drivers/thermal/thermal_sys.c b/trunk/drivers/thermal/thermal_sys.c index 708f8e92771a..0b1c82ad6805 100644 --- a/trunk/drivers/thermal/thermal_sys.c +++ b/trunk/drivers/thermal/thermal_sys.c @@ -420,29 +420,6 @@ thermal_cooling_device_trip_point_show(struct device *dev, /* hwmon sys I/F */ #include - -/* thermal zone devices with the same type share one hwmon device */ -struct thermal_hwmon_device { - char type[THERMAL_NAME_LENGTH]; - struct device *device; - int count; - struct list_head tz_list; - struct list_head node; -}; - -struct thermal_hwmon_attr { - struct device_attribute attr; - char name[16]; -}; - -/* one temperature input for each thermal zone */ -struct thermal_hwmon_temp { - struct list_head hwmon_node; - struct thermal_zone_device *tz; - struct thermal_hwmon_attr temp_input; /* hwmon sys attr */ - struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */ -}; - static LIST_HEAD(thermal_hwmon_list); static ssize_t @@ -460,10 +437,9 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) int ret; struct thermal_hwmon_attr *hwmon_attr = container_of(attr, struct thermal_hwmon_attr, attr); - struct thermal_hwmon_temp *temp - = container_of(hwmon_attr, struct thermal_hwmon_temp, + struct thermal_zone_device *tz + = container_of(hwmon_attr, struct thermal_zone_device, temp_input); - struct thermal_zone_device *tz = temp->tz; ret = tz->ops->get_temp(tz, &temperature); @@ -479,10 +455,9 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, { struct thermal_hwmon_attr *hwmon_attr = container_of(attr, struct thermal_hwmon_attr, attr); - struct thermal_hwmon_temp *temp - = container_of(hwmon_attr, struct thermal_hwmon_temp, + struct thermal_zone_device *tz + = container_of(hwmon_attr, struct thermal_zone_device, temp_crit); - struct thermal_zone_device *tz = temp->tz; long temperature; int ret; @@ -494,54 +469,22 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, } -static struct thermal_hwmon_device * -thermal_hwmon_lookup_by_type(const struct thermal_zone_device *tz) +static int +thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) { struct thermal_hwmon_device *hwmon; + int new_hwmon_device = 1; + int result; mutex_lock(&thermal_list_lock); list_for_each_entry(hwmon, &thermal_hwmon_list, node) if (!strcmp(hwmon->type, tz->type)) { + new_hwmon_device = 0; mutex_unlock(&thermal_list_lock); - return hwmon; - } - mutex_unlock(&thermal_list_lock); - - return NULL; -} - -/* Find the temperature input matching a given thermal zone */ -static struct thermal_hwmon_temp * -thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon, - const struct thermal_zone_device *tz) -{ - struct thermal_hwmon_temp *temp; - - mutex_lock(&thermal_list_lock); - list_for_each_entry(temp, &hwmon->tz_list, hwmon_node) - if (temp->tz == tz) { - mutex_unlock(&thermal_list_lock); - return temp; + goto register_sys_interface; } mutex_unlock(&thermal_list_lock); - return NULL; -} - -static int -thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) -{ - struct thermal_hwmon_device *hwmon; - struct thermal_hwmon_temp *temp; - int new_hwmon_device = 1; - int result; - - hwmon = thermal_hwmon_lookup_by_type(tz); - if (hwmon) { - new_hwmon_device = 0; - goto register_sys_interface; - } - hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL); if (!hwmon) return -ENOMEM; @@ -559,36 +502,30 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) goto free_mem; register_sys_interface: - temp = kzalloc(sizeof(struct thermal_hwmon_temp), GFP_KERNEL); - if (!temp) { - result = -ENOMEM; - goto unregister_name; - } - - temp->tz = tz; + tz->hwmon = hwmon; hwmon->count++; - snprintf(temp->temp_input.name, THERMAL_NAME_LENGTH, + snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH, "temp%d_input", hwmon->count); - temp->temp_input.attr.attr.name = temp->temp_input.name; - temp->temp_input.attr.attr.mode = 0444; - temp->temp_input.attr.show = temp_input_show; - sysfs_attr_init(&temp->temp_input.attr.attr); - result = device_create_file(hwmon->device, &temp->temp_input.attr); + tz->temp_input.attr.attr.name = tz->temp_input.name; + tz->temp_input.attr.attr.mode = 0444; + tz->temp_input.attr.show = temp_input_show; + sysfs_attr_init(&tz->temp_input.attr.attr); + result = device_create_file(hwmon->device, &tz->temp_input.attr); if (result) - goto free_temp_mem; + goto unregister_name; if (tz->ops->get_crit_temp) { unsigned long temperature; if (!tz->ops->get_crit_temp(tz, &temperature)) { - snprintf(temp->temp_crit.name, THERMAL_NAME_LENGTH, + snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH, "temp%d_crit", hwmon->count); - temp->temp_crit.attr.attr.name = temp->temp_crit.name; - temp->temp_crit.attr.attr.mode = 0444; - temp->temp_crit.attr.show = temp_crit_show; - sysfs_attr_init(&temp->temp_crit.attr.attr); + tz->temp_crit.attr.attr.name = tz->temp_crit.name; + tz->temp_crit.attr.attr.mode = 0444; + tz->temp_crit.attr.show = temp_crit_show; + sysfs_attr_init(&tz->temp_crit.attr.attr); result = device_create_file(hwmon->device, - &temp->temp_crit.attr); + &tz->temp_crit.attr); if (result) goto unregister_input; } @@ -597,15 +534,13 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) mutex_lock(&thermal_list_lock); if (new_hwmon_device) list_add_tail(&hwmon->node, &thermal_hwmon_list); - list_add_tail(&temp->hwmon_node, &hwmon->tz_list); + list_add_tail(&tz->hwmon_node, &hwmon->tz_list); mutex_unlock(&thermal_list_lock); return 0; unregister_input: - device_remove_file(hwmon->device, &temp->temp_input.attr); - free_temp_mem: - kfree(temp); + device_remove_file(hwmon->device, &tz->temp_input.attr); unregister_name: if (new_hwmon_device) { device_remove_file(hwmon->device, &dev_attr_name); @@ -621,30 +556,15 @@ thermal_add_hwmon_sysfs(struct thermal_zone_device *tz) static void thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz) { - struct thermal_hwmon_device *hwmon; - struct thermal_hwmon_temp *temp; - - hwmon = thermal_hwmon_lookup_by_type(tz); - if (unlikely(!hwmon)) { - /* Should never happen... */ - dev_dbg(&tz->device, "hwmon device lookup failed!\n"); - return; - } - - temp = thermal_hwmon_lookup_temp(hwmon, tz); - if (unlikely(!temp)) { - /* Should never happen... */ - dev_dbg(&tz->device, "temperature input lookup failed!\n"); - return; - } + struct thermal_hwmon_device *hwmon = tz->hwmon; - device_remove_file(hwmon->device, &temp->temp_input.attr); + tz->hwmon = NULL; + device_remove_file(hwmon->device, &tz->temp_input.attr); if (tz->ops->get_crit_temp) - device_remove_file(hwmon->device, &temp->temp_crit.attr); + device_remove_file(hwmon->device, &tz->temp_crit.attr); mutex_lock(&thermal_list_lock); - list_del(&temp->hwmon_node); - kfree(temp); + list_del(&tz->hwmon_node); if (!list_empty(&hwmon->tz_list)) { mutex_unlock(&thermal_list_lock); return; diff --git a/trunk/drivers/tty/serial/imx.c b/trunk/drivers/tty/serial/imx.c index 7e91b3d368cd..827db7654594 100644 --- a/trunk/drivers/tty/serial/imx.c +++ b/trunk/drivers/tty/serial/imx.c @@ -1286,17 +1286,22 @@ static int serial_imx_resume(struct platform_device *dev) static int serial_imx_probe_dt(struct imx_port *sport, struct platform_device *pdev) { - static int portnum = 0; struct device_node *np = pdev->dev.of_node; const struct of_device_id *of_id = of_match_device(imx_uart_dt_ids, &pdev->dev); + int ret; if (!np) return -ENODEV; - sport->port.line = portnum++; - if (sport->port.line >= UART_NR) - return -EINVAL; + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + pr_err("%s: failed to get alias id, errno %d\n", + __func__, ret); + return -ENODEV; + } else { + sport->port.line = ret; + } if (of_get_property(np, "fsl,uart-has-rtscts", NULL)) sport->have_rtscts = 1; diff --git a/trunk/drivers/tty/serial/sh-sci.c b/trunk/drivers/tty/serial/sh-sci.c index 2ec57b2fb278..d0a56235c50e 100644 --- a/trunk/drivers/tty/serial/sh-sci.c +++ b/trunk/drivers/tty/serial/sh-sci.c @@ -1889,7 +1889,7 @@ static int __devinit sci_init_single(struct platform_device *dev, if (p->regtype == SCIx_PROBE_REGTYPE) { ret = sci_probe_regmap(p); - if (unlikely(ret)) + if (unlikely(!ret)) return ret; } diff --git a/trunk/drivers/video/backlight/Kconfig b/trunk/drivers/video/backlight/Kconfig index 278aeaa92505..69407e72aac1 100644 --- a/trunk/drivers/video/backlight/Kconfig +++ b/trunk/drivers/video/backlight/Kconfig @@ -336,7 +336,7 @@ config BACKLIGHT_PCF50633 enable its driver. config BACKLIGHT_AAT2870 - tristate "AnalogicTech AAT2870 Backlight" + bool "AnalogicTech AAT2870 Backlight" depends on BACKLIGHT_CLASS_DEVICE && MFD_AAT2870_CORE help If you have a AnalogicTech AAT2870 say Y to enable the diff --git a/trunk/drivers/video/backlight/aat2870_bl.c b/trunk/drivers/video/backlight/aat2870_bl.c index 331f1ef1dad5..4952a617563d 100644 --- a/trunk/drivers/video/backlight/aat2870_bl.c +++ b/trunk/drivers/video/backlight/aat2870_bl.c @@ -44,7 +44,7 @@ static inline int aat2870_brightness(struct aat2870_bl_driver_data *aat2870_bl, struct backlight_device *bd = aat2870_bl->bd; int val; - val = brightness * (aat2870_bl->max_current - 1); + val = brightness * aat2870_bl->max_current; val /= bd->props.max_brightness; return val; @@ -158,10 +158,10 @@ static int aat2870_bl_probe(struct platform_device *pdev) props.type = BACKLIGHT_RAW; bd = backlight_device_register("aat2870-backlight", &pdev->dev, aat2870_bl, &aat2870_bl_ops, &props); - if (IS_ERR(bd)) { + if (!bd) { dev_err(&pdev->dev, "Failed allocate memory for backlight device\n"); - ret = PTR_ERR(bd); + ret = -ENOMEM; goto out_kfree; } @@ -175,7 +175,7 @@ static int aat2870_bl_probe(struct platform_device *pdev) else aat2870_bl->channels = AAT2870_BL_CH_ALL; - if (pdata->max_current > 0) + if (pdata->max_brightness > 0) aat2870_bl->max_current = pdata->max_current; else aat2870_bl->max_current = AAT2870_CURRENT_27_9; diff --git a/trunk/drivers/video/savage/savagefb.h b/trunk/drivers/video/savage/savagefb.h index dcaab9012ca2..32549d177b19 100644 --- a/trunk/drivers/video/savage/savagefb.h +++ b/trunk/drivers/video/savage/savagefb.h @@ -55,7 +55,7 @@ #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) -#define S3_SAVAGE4_SERIES(chip) ((chip>=S3_SAVAGE4) && (chip<=S3_PROSAVAGEDDR)) +#define S3_SAVAGE4_SERIES(chip) ((chip>=S3_SAVAGE4) || (chip<=S3_PROSAVAGEDDR)) #define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) diff --git a/trunk/drivers/watchdog/Kconfig b/trunk/drivers/watchdog/Kconfig index 86b0735e6aa0..f441726ddf2b 100644 --- a/trunk/drivers/watchdog/Kconfig +++ b/trunk/drivers/watchdog/Kconfig @@ -36,6 +36,9 @@ config WATCHDOG_CORE and gives them the /dev/watchdog interface (and later also the sysfs interface). + To compile this driver as a module, choose M here: the module will + be called watchdog. + config WATCHDOG_NOWAYOUT bool "Disable watchdog shutdown on close" help diff --git a/trunk/drivers/watchdog/nv_tco.c b/trunk/drivers/watchdog/nv_tco.c index 809f41c30c44..afa78a54711e 100644 --- a/trunk/drivers/watchdog/nv_tco.c +++ b/trunk/drivers/watchdog/nv_tco.c @@ -458,15 +458,7 @@ static int __devexit nv_tco_remove(struct platform_device *dev) static void nv_tco_shutdown(struct platform_device *dev) { - u32 val; - tco_timer_stop(); - - /* Some BIOSes fail the POST (once) if the NO_REBOOT flag is not - * unset during shutdown. */ - pci_read_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, &val); - val &= ~MCP51_SMBUS_SETUP_B_TCO_REBOOT; - pci_write_config_dword(tco_pci, MCP51_SMBUS_SETUP_B, val); } static struct platform_driver nv_tco_driver = { diff --git a/trunk/drivers/watchdog/shwdt.c b/trunk/drivers/watchdog/shwdt.c index a267dc078daf..db84f2322d1a 100644 --- a/trunk/drivers/watchdog/shwdt.c +++ b/trunk/drivers/watchdog/shwdt.c @@ -64,7 +64,7 @@ * misses its deadline, the kernel timer will allow the WDT to overflow. */ static int clock_division_ratio = WTCSR_CKS_4096; -#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) +#define next_ping_period(cks) msecs_to_jiffies(cks - 4) static const struct watchdog_info sh_wdt_info; static struct platform_device *sh_wdt_dev; diff --git a/trunk/drivers/xen/Kconfig b/trunk/drivers/xen/Kconfig index 5f7ff8e2fc14..f815283667af 100644 --- a/trunk/drivers/xen/Kconfig +++ b/trunk/drivers/xen/Kconfig @@ -11,7 +11,7 @@ config XEN_BALLOON config XEN_SELFBALLOONING bool "Dynamically self-balloon kernel memory to target" - depends on XEN && XEN_BALLOON && CLEANCACHE && SWAP && XEN_TMEM + depends on XEN && XEN_BALLOON && CLEANCACHE && SWAP default n help Self-ballooning dynamically balloons available kernel memory driven diff --git a/trunk/fs/Kconfig b/trunk/fs/Kconfig index 9fe0b349f4cd..19891aab9c6e 100644 --- a/trunk/fs/Kconfig +++ b/trunk/fs/Kconfig @@ -127,21 +127,14 @@ config TMPFS_POSIX_ACL select TMPFS_XATTR select GENERIC_ACL help - POSIX Access Control Lists (ACLs) support additional access rights - for users and groups beyond the standard owner/group/world scheme, - and this option selects support for ACLs specifically for tmpfs - filesystems. - - If you've selected TMPFS, it's possible that you'll also need - this option as there are a number of Linux distros that require - POSIX ACL support under /dev for certain features to work properly. - For example, some distros need this feature for ALSA-related /dev - files for sound to work properly. In short, if you're not sure, - say Y. + POSIX Access Control Lists (ACLs) support permissions for users and + groups beyond the owner/group/world scheme. To learn more about Access Control Lists, visit the POSIX ACLs for Linux website . + If you don't know what Access Control Lists are, say N. + config TMPFS_XATTR bool "Tmpfs extended attributes" depends on TMPFS diff --git a/trunk/fs/autofs4/autofs_i.h b/trunk/fs/autofs4/autofs_i.h index 326dc08d3e3f..475f9c597cb7 100644 --- a/trunk/fs/autofs4/autofs_i.h +++ b/trunk/fs/autofs4/autofs_i.h @@ -39,17 +39,27 @@ /* #define DEBUG */ -#define DPRINTK(fmt, ...) \ - pr_debug("pid %d: %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) - -#define AUTOFS_WARN(fmt, ...) \ +#ifdef DEBUG +#define DPRINTK(fmt, args...) \ +do { \ + printk(KERN_DEBUG "pid %d: %s: " fmt "\n", \ + current->pid, __func__, ##args); \ +} while (0) +#else +#define DPRINTK(fmt, args...) do {} while (0) +#endif + +#define AUTOFS_WARN(fmt, args...) \ +do { \ printk(KERN_WARNING "pid %d: %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) + current->pid, __func__, ##args); \ +} while (0) -#define AUTOFS_ERROR(fmt, ...) \ +#define AUTOFS_ERROR(fmt, args...) \ +do { \ printk(KERN_ERR "pid %d: %s: " fmt "\n", \ - current->pid, __func__, ##__VA_ARGS__) + current->pid, __func__, ##args); \ +} while (0) /* Unified info structure. This is pointed to by both the dentry and inode structures. Each file in the filesystem has an instance of this diff --git a/trunk/fs/autofs4/waitq.c b/trunk/fs/autofs4/waitq.c index e1fbdeef85db..25435987d6ae 100644 --- a/trunk/fs/autofs4/waitq.c +++ b/trunk/fs/autofs4/waitq.c @@ -104,7 +104,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, size_t pktsz; DPRINTK("wait id = 0x%08lx, name = %.*s, type=%d", - (unsigned long) wq->wait_queue_token, wq->name.len, wq->name.name, type); + wq->wait_queue_token, wq->name.len, wq->name.name, type); memset(&pkt,0,sizeof pkt); /* For security reasons */ diff --git a/trunk/fs/block_dev.c b/trunk/fs/block_dev.c index ff77262e887c..f28680553288 100644 --- a/trunk/fs/block_dev.c +++ b/trunk/fs/block_dev.c @@ -387,10 +387,6 @@ int blkdev_fsync(struct file *filp, loff_t start, loff_t end, int datasync) struct inode *bd_inode = filp->f_mapping->host; struct block_device *bdev = I_BDEV(bd_inode); int error; - - error = filemap_write_and_wait_range(filp->f_mapping, start, end); - if (error) - return error; /* * There is no need to serialise calls to blkdev_issue_flush with diff --git a/trunk/fs/btrfs/Makefile b/trunk/fs/btrfs/Makefile index 40e6ac08c21f..9b72dcf1cd25 100644 --- a/trunk/fs/btrfs/Makefile +++ b/trunk/fs/btrfs/Makefile @@ -6,7 +6,5 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ transaction.o inode.o file.o tree-defrag.o \ extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \ extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ - export.o tree-log.o free-space-cache.o zlib.o lzo.o \ + export.o tree-log.o acl.o free-space-cache.o zlib.o lzo.o \ compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o - -btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o diff --git a/trunk/fs/btrfs/acl.c b/trunk/fs/btrfs/acl.c index eb159aaa5a11..4cc5c0164ed6 100644 --- a/trunk/fs/btrfs/acl.c +++ b/trunk/fs/btrfs/acl.c @@ -28,6 +28,8 @@ #include "btrfs_inode.h" #include "xattr.h" +#ifdef CONFIG_BTRFS_FS_POSIX_ACL + struct posix_acl *btrfs_get_acl(struct inode *inode, int type) { int size; @@ -274,3 +276,18 @@ const struct xattr_handler btrfs_xattr_acl_access_handler = { .get = btrfs_xattr_acl_get, .set = btrfs_xattr_acl_set, }; + +#else /* CONFIG_BTRFS_FS_POSIX_ACL */ + +int btrfs_acl_chmod(struct inode *inode) +{ + return 0; +} + +int btrfs_init_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir) +{ + return 0; +} + +#endif /* CONFIG_BTRFS_FS_POSIX_ACL */ diff --git a/trunk/fs/btrfs/compression.c b/trunk/fs/btrfs/compression.c index 8ec5d86f1734..bfe42b03eaf9 100644 --- a/trunk/fs/btrfs/compression.c +++ b/trunk/fs/btrfs/compression.c @@ -338,7 +338,6 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, u64 first_byte = disk_start; struct block_device *bdev; int ret; - int skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; WARN_ON(start & ((u64)PAGE_CACHE_SIZE - 1)); cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); @@ -393,11 +392,8 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); BUG_ON(ret); - if (!skip_sum) { - ret = btrfs_csum_one_bio(root, inode, bio, - start, 1); - BUG_ON(ret); - } + ret = btrfs_csum_one_bio(root, inode, bio, start, 1); + BUG_ON(ret); ret = btrfs_map_bio(root, WRITE, bio, 0, 1); BUG_ON(ret); @@ -422,10 +418,8 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); BUG_ON(ret); - if (!skip_sum) { - ret = btrfs_csum_one_bio(root, inode, bio, start, 1); - BUG_ON(ret); - } + ret = btrfs_csum_one_bio(root, inode, bio, start, 1); + BUG_ON(ret); ret = btrfs_map_bio(root, WRITE, bio, 0, 1); BUG_ON(ret); diff --git a/trunk/fs/btrfs/ctree.h b/trunk/fs/btrfs/ctree.h index 0469263e327e..365c4e1dde04 100644 --- a/trunk/fs/btrfs/ctree.h +++ b/trunk/fs/btrfs/ctree.h @@ -2406,8 +2406,8 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, struct btrfs_root_item *item, struct btrfs_key *key); int btrfs_find_dead_roots(struct btrfs_root *root, u64 objectid); int btrfs_find_orphan_roots(struct btrfs_root *tree_root); -void btrfs_set_root_node(struct btrfs_root_item *item, - struct extent_buffer *node); +int btrfs_set_root_node(struct btrfs_root_item *item, + struct extent_buffer *node); void btrfs_check_and_init_root_item(struct btrfs_root_item *item); /* dir-item.c */ @@ -2523,14 +2523,6 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag #define PageChecked PageFsMisc #endif -/* This forces readahead on a given range of bytes in an inode */ -static inline void btrfs_force_ra(struct address_space *mapping, - struct file_ra_state *ra, struct file *file, - pgoff_t offset, unsigned long req_size) -{ - page_cache_sync_readahead(mapping, ra, file, offset, req_size); -} - struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry); int btrfs_set_inode_index(struct inode *dir, u64 *index); int btrfs_unlink_inode(struct btrfs_trans_handle *trans, @@ -2559,6 +2551,9 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, int btrfs_merge_bio_hook(struct page *page, unsigned long offset, size_t size, struct bio *bio, unsigned long bio_flags); +unsigned long btrfs_force_ra(struct address_space *mapping, + struct file_ra_state *ra, struct file *file, + pgoff_t offset, pgoff_t last_index); int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf); int btrfs_readpage(struct file *file, struct page *page); void btrfs_evict_inode(struct inode *inode); @@ -2653,21 +2648,12 @@ do { \ /* acl.c */ #ifdef CONFIG_BTRFS_FS_POSIX_ACL struct posix_acl *btrfs_get_acl(struct inode *inode, int type); -int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir); -int btrfs_acl_chmod(struct inode *inode); #else #define btrfs_get_acl NULL -static inline int btrfs_init_acl(struct btrfs_trans_handle *trans, - struct inode *inode, struct inode *dir) -{ - return 0; -} -static inline int btrfs_acl_chmod(struct inode *inode) -{ - return 0; -} #endif +int btrfs_init_acl(struct btrfs_trans_handle *trans, + struct inode *inode, struct inode *dir); +int btrfs_acl_chmod(struct inode *inode); /* relocation.c */ int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start); diff --git a/trunk/fs/btrfs/dir-item.c b/trunk/fs/btrfs/dir-item.c index 31d84e78129b..c360a848d97f 100644 --- a/trunk/fs/btrfs/dir-item.c +++ b/trunk/fs/btrfs/dir-item.c @@ -198,6 +198,8 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_key key; int ins_len = mod < 0 ? -1 : 0; int cow = mod != 0; + struct btrfs_key found_key; + struct extent_buffer *leaf; key.objectid = dir; btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); @@ -207,7 +209,18 @@ struct btrfs_dir_item *btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); if (ret < 0) return ERR_PTR(ret); - if (ret > 0) + if (ret > 0) { + if (path->slots[0] == 0) + return NULL; + path->slots[0]--; + } + + leaf = path->nodes[0]; + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); + + if (found_key.objectid != dir || + btrfs_key_type(&found_key) != BTRFS_DIR_ITEM_KEY || + found_key.offset != key.offset) return NULL; return btrfs_match_dir_item_name(root, path, name, name_len); @@ -302,6 +315,8 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, struct btrfs_key key; int ins_len = mod < 0 ? -1 : 0; int cow = mod != 0; + struct btrfs_key found_key; + struct extent_buffer *leaf; key.objectid = dir; btrfs_set_key_type(&key, BTRFS_XATTR_ITEM_KEY); @@ -309,7 +324,18 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); if (ret < 0) return ERR_PTR(ret); - if (ret > 0) + if (ret > 0) { + if (path->slots[0] == 0) + return NULL; + path->slots[0]--; + } + + leaf = path->nodes[0]; + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); + + if (found_key.objectid != dir || + btrfs_key_type(&found_key) != BTRFS_XATTR_ITEM_KEY || + found_key.offset != key.offset) return NULL; return btrfs_match_dir_item_name(root, path, name, name_len); diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index 66bac226944e..4d08ed79405d 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -663,9 +663,7 @@ int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len) struct btrfs_path *path; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - + BUG_ON(!path); key.objectid = start; key.offset = len; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); @@ -3274,9 +3272,6 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, } ret = btrfs_alloc_chunk(trans, extent_root, flags); - if (ret < 0 && ret != -ENOSPC) - goto out; - spin_lock(&space_info->lock); if (ret) space_info->full = 1; @@ -3286,7 +3281,6 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, space_info->force_alloc = CHUNK_ALLOC_NO_FORCE; space_info->chunk_alloc = 0; spin_unlock(&space_info->lock); -out: mutex_unlock(&extent_root->fs_info->chunk_mutex); return ret; } @@ -4462,9 +4456,7 @@ static int __btrfs_free_extent(struct btrfs_trans_handle *trans, printk(KERN_ERR "umm, got %d back from search" ", was looking for %llu\n", ret, (unsigned long long)bytenr); - if (ret > 0) - btrfs_print_leaf(extent_root, - path->nodes[0]); + btrfs_print_leaf(extent_root, path->nodes[0]); } BUG_ON(ret); extent_slot = path->slots[0]; @@ -5081,9 +5073,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, * group is does point to and try again */ if (!last_ptr_loop && last_ptr->block_group && - last_ptr->block_group != block_group && - index <= - get_block_group_index(last_ptr->block_group)) { + last_ptr->block_group != block_group) { btrfs_put_block_group(block_group); block_group = last_ptr->block_group; @@ -5511,8 +5501,7 @@ static int alloc_reserved_tree_block(struct btrfs_trans_handle *trans, u32 size = sizeof(*extent_item) + sizeof(*block_info) + sizeof(*iref); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); path->leave_spinning = 1; ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path, @@ -6283,14 +6272,10 @@ int btrfs_drop_snapshot(struct btrfs_root *root, int level; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); wc = kzalloc(sizeof(*wc), GFP_NOFS); - if (!wc) { - btrfs_free_path(path); - return -ENOMEM; - } + BUG_ON(!wc); trans = btrfs_start_transaction(tree_root, 0); BUG_ON(IS_ERR(trans)); @@ -6553,6 +6538,8 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache, int force) u64 min_allocable_bytes; int ret = -ENOSPC; + if (cache->ro) + return 0; /* * We need some metadata space and system metadata space for @@ -6568,12 +6555,6 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache, int force) spin_lock(&sinfo->lock); spin_lock(&cache->lock); - - if (cache->ro) { - ret = 0; - goto out; - } - num_bytes = cache->key.offset - cache->reserved - cache->pinned - cache->bytes_super - btrfs_block_group_used(&cache->item); @@ -6587,7 +6568,7 @@ static int set_block_group_ro(struct btrfs_block_group_cache *cache, int force) cache->ro = 1; ret = 0; } -out: + spin_unlock(&cache->lock); spin_unlock(&sinfo->lock); return ret; @@ -7202,15 +7183,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, spin_unlock(&cluster->refill_lock); path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto out; - } + BUG_ON(!path); inode = lookup_free_space_inode(root, block_group, path); if (!IS_ERR(inode)) { - ret = btrfs_orphan_add(trans, inode); - BUG_ON(ret); + btrfs_orphan_add(trans, inode); clear_nlink(inode); /* One for the block groups ref */ spin_lock(&block_group->lock); diff --git a/trunk/fs/btrfs/extent_io.c b/trunk/fs/btrfs/extent_io.c index d418164a35f1..067b1747421b 100644 --- a/trunk/fs/btrfs/extent_io.c +++ b/trunk/fs/btrfs/extent_io.c @@ -254,14 +254,14 @@ static void merge_cb(struct extent_io_tree *tree, struct extent_state *new, * * This should be called with the tree lock held. */ -static void merge_state(struct extent_io_tree *tree, - struct extent_state *state) +static int merge_state(struct extent_io_tree *tree, + struct extent_state *state) { struct extent_state *other; struct rb_node *other_node; if (state->state & (EXTENT_IOBITS | EXTENT_BOUNDARY)) - return; + return 0; other_node = rb_prev(&state->rb_node); if (other_node) { @@ -287,13 +287,19 @@ static void merge_state(struct extent_io_tree *tree, free_extent_state(other); } } + + return 0; } -static void set_state_cb(struct extent_io_tree *tree, +static int set_state_cb(struct extent_io_tree *tree, struct extent_state *state, int *bits) { - if (tree->ops && tree->ops->set_bit_hook) - tree->ops->set_bit_hook(tree->mapping->host, state, bits); + if (tree->ops && tree->ops->set_bit_hook) { + return tree->ops->set_bit_hook(tree->mapping->host, + state, bits); + } + + return 0; } static void clear_state_cb(struct extent_io_tree *tree, @@ -303,9 +309,6 @@ static void clear_state_cb(struct extent_io_tree *tree, tree->ops->clear_bit_hook(tree->mapping->host, state, bits); } -static void set_state_bits(struct extent_io_tree *tree, - struct extent_state *state, int *bits); - /* * insert an extent_state struct into the tree. 'bits' are set on the * struct before it is inserted. @@ -321,6 +324,8 @@ static int insert_state(struct extent_io_tree *tree, int *bits) { struct rb_node *node; + int bits_to_set = *bits & ~EXTENT_CTLBITS; + int ret; if (end < start) { printk(KERN_ERR "btrfs end < start %llu %llu\n", @@ -330,9 +335,13 @@ static int insert_state(struct extent_io_tree *tree, } state->start = start; state->end = end; + ret = set_state_cb(tree, state, bits); + if (ret) + return ret; - set_state_bits(tree, state, bits); - + if (bits_to_set & EXTENT_DIRTY) + tree->dirty_bytes += end - start + 1; + state->state |= bits_to_set; node = tree_insert(&tree->state, end, &state->rb_node); if (node) { struct extent_state *found; @@ -348,11 +357,13 @@ static int insert_state(struct extent_io_tree *tree, return 0; } -static void split_cb(struct extent_io_tree *tree, struct extent_state *orig, +static int split_cb(struct extent_io_tree *tree, struct extent_state *orig, u64 split) { if (tree->ops && tree->ops->split_extent_hook) - tree->ops->split_extent_hook(tree->mapping->host, orig, split); + return tree->ops->split_extent_hook(tree->mapping->host, + orig, split); + return 0; } /* @@ -648,25 +659,34 @@ int wait_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, int bits) if (start > end) break; - cond_resched_lock(&tree->lock); + if (need_resched()) { + spin_unlock(&tree->lock); + cond_resched(); + spin_lock(&tree->lock); + } } out: spin_unlock(&tree->lock); return 0; } -static void set_state_bits(struct extent_io_tree *tree, +static int set_state_bits(struct extent_io_tree *tree, struct extent_state *state, int *bits) { + int ret; int bits_to_set = *bits & ~EXTENT_CTLBITS; - set_state_cb(tree, state, bits); + ret = set_state_cb(tree, state, bits); + if (ret) + return ret; if ((bits_to_set & EXTENT_DIRTY) && !(state->state & EXTENT_DIRTY)) { u64 range = state->end - state->start + 1; tree->dirty_bytes += range; } state->state |= bits_to_set; + + return 0; } static void cache_state(struct extent_state *state, @@ -759,7 +779,9 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, goto out; } - set_state_bits(tree, state, &bits); + err = set_state_bits(tree, state, &bits); + if (err) + goto out; cache_state(state, cached_state); merge_state(tree, state); @@ -808,7 +830,9 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, if (err) goto out; if (state->end <= end) { - set_state_bits(tree, state, &bits); + err = set_state_bits(tree, state, &bits); + if (err) + goto out; cache_state(state, cached_state); merge_state(tree, state); if (last_end == (u64)-1) @@ -869,7 +893,11 @@ int set_extent_bit(struct extent_io_tree *tree, u64 start, u64 end, err = split_state(tree, state, prealloc, end + 1); BUG_ON(err == -EEXIST); - set_state_bits(tree, prealloc, &bits); + err = set_state_bits(tree, prealloc, &bits); + if (err) { + prealloc = NULL; + goto out; + } cache_state(prealloc, cached_state); merge_state(tree, prealloc); prealloc = NULL; @@ -1031,6 +1059,46 @@ static int set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end) return 0; } +/* + * find the first offset in the io tree with 'bits' set. zero is + * returned if we find something, and *start_ret and *end_ret are + * set to reflect the state struct that was found. + * + * If nothing was found, 1 is returned, < 0 on error + */ +int find_first_extent_bit(struct extent_io_tree *tree, u64 start, + u64 *start_ret, u64 *end_ret, int bits) +{ + struct rb_node *node; + struct extent_state *state; + int ret = 1; + + spin_lock(&tree->lock); + /* + * this search will find all the extents that end after + * our range starts. + */ + node = tree_search(tree, start); + if (!node) + goto out; + + while (1) { + state = rb_entry(node, struct extent_state, rb_node); + if (state->end >= start && (state->state & bits)) { + *start_ret = state->start; + *end_ret = state->end; + ret = 0; + break; + } + node = rb_next(node); + if (!node) + break; + } +out: + spin_unlock(&tree->lock); + return ret; +} + /* find the first state struct with 'bits' set after 'start', and * return it. tree->lock must be held. NULL will returned if * nothing was found after 'start' @@ -1062,30 +1130,6 @@ struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree, return NULL; } -/* - * find the first offset in the io tree with 'bits' set. zero is - * returned if we find something, and *start_ret and *end_ret are - * set to reflect the state struct that was found. - * - * If nothing was found, 1 is returned, < 0 on error - */ -int find_first_extent_bit(struct extent_io_tree *tree, u64 start, - u64 *start_ret, u64 *end_ret, int bits) -{ - struct extent_state *state; - int ret = 1; - - spin_lock(&tree->lock); - state = find_first_extent_bit_state(tree, start, bits); - if (state) { - *start_ret = state->start; - *end_ret = state->end; - ret = 0; - } - spin_unlock(&tree->lock); - return ret; -} - /* * find a contiguous range of bytes in the file marked as delalloc, not * more than 'max_bytes'. start and end are used to return the range, @@ -2502,6 +2546,7 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page, struct writeback_control *wbc) { int ret; + struct address_space *mapping = page->mapping; struct extent_page_data epd = { .bio = NULL, .tree = tree, @@ -2509,9 +2554,17 @@ int extent_write_full_page(struct extent_io_tree *tree, struct page *page, .extent_locked = 0, .sync_io = wbc->sync_mode == WB_SYNC_ALL, }; + struct writeback_control wbc_writepages = { + .sync_mode = wbc->sync_mode, + .nr_to_write = 64, + .range_start = page_offset(page) + PAGE_CACHE_SIZE, + .range_end = (loff_t)-1, + }; ret = __extent_writepage(page, wbc, &epd); + extent_write_cache_pages(tree, mapping, &wbc_writepages, + __extent_writepage, &epd, flush_write_bio); flush_epd_write_bio(&epd); return ret; } diff --git a/trunk/fs/btrfs/extent_io.h b/trunk/fs/btrfs/extent_io.h index 7b2f0c3e7929..21a7ca9e7282 100644 --- a/trunk/fs/btrfs/extent_io.h +++ b/trunk/fs/btrfs/extent_io.h @@ -76,15 +76,15 @@ struct extent_io_ops { struct extent_state *state); int (*writepage_end_io_hook)(struct page *page, u64 start, u64 end, struct extent_state *state, int uptodate); - void (*set_bit_hook)(struct inode *inode, struct extent_state *state, - int *bits); - void (*clear_bit_hook)(struct inode *inode, struct extent_state *state, - int *bits); - void (*merge_extent_hook)(struct inode *inode, - struct extent_state *new, - struct extent_state *other); - void (*split_extent_hook)(struct inode *inode, - struct extent_state *orig, u64 split); + int (*set_bit_hook)(struct inode *inode, struct extent_state *state, + int *bits); + int (*clear_bit_hook)(struct inode *inode, struct extent_state *state, + int *bits); + int (*merge_extent_hook)(struct inode *inode, + struct extent_state *new, + struct extent_state *other); + int (*split_extent_hook)(struct inode *inode, + struct extent_state *orig, u64 split); int (*write_cache_pages_lock_hook)(struct page *page); }; @@ -108,6 +108,8 @@ struct extent_state { wait_queue_head_t wq; atomic_t refs; unsigned long state; + u64 split_start; + u64 split_end; /* for use by the FS */ u64 private; diff --git a/trunk/fs/btrfs/extent_map.c b/trunk/fs/btrfs/extent_map.c index 7c97b3301459..2d0410344ea3 100644 --- a/trunk/fs/btrfs/extent_map.c +++ b/trunk/fs/btrfs/extent_map.c @@ -183,10 +183,22 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next) return 0; } -static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em) +int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) { + int ret = 0; struct extent_map *merge = NULL; struct rb_node *rb; + struct extent_map *em; + + write_lock(&tree->lock); + em = lookup_extent_mapping(tree, start, len); + + WARN_ON(!em || em->start != start); + + if (!em) + goto out; + + clear_bit(EXTENT_FLAG_PINNED, &em->flags); if (em->start != 0) { rb = rb_prev(&em->rb_node); @@ -213,24 +225,6 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em) merge->in_tree = 0; free_extent_map(merge); } -} - -int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len) -{ - int ret = 0; - struct extent_map *em; - - write_lock(&tree->lock); - em = lookup_extent_mapping(tree, start, len); - - WARN_ON(!em || em->start != start); - - if (!em) - goto out; - - clear_bit(EXTENT_FLAG_PINNED, &em->flags); - - try_merge_map(tree, em); free_extent_map(em); out: @@ -253,6 +247,7 @@ int add_extent_mapping(struct extent_map_tree *tree, struct extent_map *em) { int ret = 0; + struct extent_map *merge = NULL; struct rb_node *rb; struct extent_map *exist; @@ -268,8 +263,30 @@ int add_extent_mapping(struct extent_map_tree *tree, goto out; } atomic_inc(&em->refs); - - try_merge_map(tree, em); + if (em->start != 0) { + rb = rb_prev(&em->rb_node); + if (rb) + merge = rb_entry(rb, struct extent_map, rb_node); + if (rb && mergable_maps(merge, em)) { + em->start = merge->start; + em->len += merge->len; + em->block_len += merge->block_len; + em->block_start = merge->block_start; + merge->in_tree = 0; + rb_erase(&merge->rb_node, &tree->map); + free_extent_map(merge); + } + } + rb = rb_next(&em->rb_node); + if (rb) + merge = rb_entry(rb, struct extent_map, rb_node); + if (rb && mergable_maps(em, merge)) { + em->len += merge->len; + em->block_len += merge->len; + rb_erase(&merge->rb_node, &tree->map); + merge->in_tree = 0; + free_extent_map(merge); + } out: return ret; } @@ -282,8 +299,19 @@ static u64 range_end(u64 start, u64 len) return start + len; } -struct extent_map *__lookup_extent_mapping(struct extent_map_tree *tree, - u64 start, u64 len, int strict) +/** + * lookup_extent_mapping - lookup extent_map + * @tree: tree to lookup in + * @start: byte offset to start the search + * @len: length of the lookup range + * + * Find and return the first extent_map struct in @tree that intersects the + * [start, len] range. There may be additional objects in the tree that + * intersect, so check the object returned carefully to make sure that no + * additional lookups are needed. + */ +struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, + u64 start, u64 len) { struct extent_map *em; struct rb_node *rb_node; @@ -292,41 +320,37 @@ struct extent_map *__lookup_extent_mapping(struct extent_map_tree *tree, u64 end = range_end(start, len); rb_node = __tree_search(&tree->map, start, &prev, &next); + if (!rb_node && prev) { + em = rb_entry(prev, struct extent_map, rb_node); + if (end > em->start && start < extent_map_end(em)) + goto found; + } + if (!rb_node && next) { + em = rb_entry(next, struct extent_map, rb_node); + if (end > em->start && start < extent_map_end(em)) + goto found; + } if (!rb_node) { - if (prev) - rb_node = prev; - else if (next) - rb_node = next; - else - return NULL; + em = NULL; + goto out; + } + if (IS_ERR(rb_node)) { + em = ERR_CAST(rb_node); + goto out; } - em = rb_entry(rb_node, struct extent_map, rb_node); + if (end > em->start && start < extent_map_end(em)) + goto found; - if (strict && !(end > em->start && start < extent_map_end(em))) - return NULL; + em = NULL; + goto out; +found: atomic_inc(&em->refs); +out: return em; } -/** - * lookup_extent_mapping - lookup extent_map - * @tree: tree to lookup in - * @start: byte offset to start the search - * @len: length of the lookup range - * - * Find and return the first extent_map struct in @tree that intersects the - * [start, len] range. There may be additional objects in the tree that - * intersect, so check the object returned carefully to make sure that no - * additional lookups are needed. - */ -struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, - u64 start, u64 len) -{ - return __lookup_extent_mapping(tree, start, len, 1); -} - /** * search_extent_mapping - find a nearby extent map * @tree: tree to lookup in @@ -341,7 +365,38 @@ struct extent_map *lookup_extent_mapping(struct extent_map_tree *tree, struct extent_map *search_extent_mapping(struct extent_map_tree *tree, u64 start, u64 len) { - return __lookup_extent_mapping(tree, start, len, 0); + struct extent_map *em; + struct rb_node *rb_node; + struct rb_node *prev = NULL; + struct rb_node *next = NULL; + + rb_node = __tree_search(&tree->map, start, &prev, &next); + if (!rb_node && prev) { + em = rb_entry(prev, struct extent_map, rb_node); + goto found; + } + if (!rb_node && next) { + em = rb_entry(next, struct extent_map, rb_node); + goto found; + } + if (!rb_node) { + em = NULL; + goto out; + } + if (IS_ERR(rb_node)) { + em = ERR_CAST(rb_node); + goto out; + } + em = rb_entry(rb_node, struct extent_map, rb_node); + goto found; + + em = NULL; + goto out; + +found: + atomic_inc(&em->refs); +out: + return em; } /** diff --git a/trunk/fs/btrfs/file-item.c b/trunk/fs/btrfs/file-item.c index b910694f61ed..08bcfa92a222 100644 --- a/trunk/fs/btrfs/file-item.c +++ b/trunk/fs/btrfs/file-item.c @@ -291,8 +291,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); if (search_commit) { path->skip_locking = 1; @@ -678,9 +677,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, btrfs_super_csum_size(&root->fs_info->super_copy); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - + BUG_ON(!path); sector_sum = sums->sums; again: next_offset = (u64)-1; diff --git a/trunk/fs/btrfs/file.c b/trunk/fs/btrfs/file.c index 658d66959abe..a35e51c9f235 100644 --- a/trunk/fs/btrfs/file.c +++ b/trunk/fs/btrfs/file.c @@ -74,7 +74,7 @@ struct inode_defrag { * If an existing record is found the defrag item you * pass in is freed */ -static void __btrfs_add_inode_defrag(struct inode *inode, +static int __btrfs_add_inode_defrag(struct inode *inode, struct inode_defrag *defrag) { struct btrfs_root *root = BTRFS_I(inode)->root; @@ -106,11 +106,11 @@ static void __btrfs_add_inode_defrag(struct inode *inode, BTRFS_I(inode)->in_defrag = 1; rb_link_node(&defrag->rb_node, parent, p); rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes); - return; + return 0; exists: kfree(defrag); - return; + return 0; } @@ -123,6 +123,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, { struct btrfs_root *root = BTRFS_I(inode)->root; struct inode_defrag *defrag; + int ret = 0; u64 transid; if (!btrfs_test_opt(root, AUTO_DEFRAG)) @@ -149,9 +150,9 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, spin_lock(&root->fs_info->defrag_inodes_lock); if (!BTRFS_I(inode)->in_defrag) - __btrfs_add_inode_defrag(inode, defrag); + ret = __btrfs_add_inode_defrag(inode, defrag); spin_unlock(&root->fs_info->defrag_inodes_lock); - return 0; + return ret; } /* @@ -854,8 +855,7 @@ int btrfs_mark_extent_written(struct btrfs_trans_handle *trans, btrfs_drop_extent_cache(inode, start, end - 1, 0); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); again: recow = 0; split = start; @@ -1059,7 +1059,7 @@ static int prepare_uptodate_page(struct page *page, u64 pos) static noinline int prepare_pages(struct btrfs_root *root, struct file *file, struct page **pages, size_t num_pages, loff_t pos, unsigned long first_index, - size_t write_bytes) + unsigned long last_index, size_t write_bytes) { struct extent_state *cached_state = NULL; int i; @@ -1159,6 +1159,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, struct btrfs_root *root = BTRFS_I(inode)->root; struct page **pages = NULL; unsigned long first_index; + unsigned long last_index; size_t num_written = 0; int nrptrs; int ret = 0; @@ -1171,6 +1172,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, return -ENOMEM; first_index = pos >> PAGE_CACHE_SHIFT; + last_index = (pos + iov_iter_count(i)) >> PAGE_CACHE_SHIFT; while (iov_iter_count(i) > 0) { size_t offset = pos & (PAGE_CACHE_SIZE - 1); @@ -1204,7 +1206,8 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, * contents of pages from loop to loop */ ret = prepare_pages(root, file, pages, num_pages, - pos, first_index, write_bytes); + pos, first_index, last_index, + write_bytes); if (ret) { btrfs_delalloc_release_space(inode, num_pages << PAGE_CACHE_SHIFT); diff --git a/trunk/fs/btrfs/inode.c b/trunk/fs/btrfs/inode.c index 15fceefbca0a..ae762dab37f8 100644 --- a/trunk/fs/btrfs/inode.c +++ b/trunk/fs/btrfs/inode.c @@ -1061,8 +1061,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, u64 ino = btrfs_ino(inode); path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); nolock = btrfs_is_free_space_inode(root, inode); @@ -1283,16 +1282,17 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page, return ret; } -static void btrfs_split_extent_hook(struct inode *inode, - struct extent_state *orig, u64 split) +static int btrfs_split_extent_hook(struct inode *inode, + struct extent_state *orig, u64 split) { /* not delalloc, ignore it */ if (!(orig->state & EXTENT_DELALLOC)) - return; + return 0; spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents++; spin_unlock(&BTRFS_I(inode)->lock); + return 0; } /* @@ -1301,17 +1301,18 @@ static void btrfs_split_extent_hook(struct inode *inode, * extents, such as when we are doing sequential writes, so we can properly * account for the metadata space we'll need. */ -static void btrfs_merge_extent_hook(struct inode *inode, - struct extent_state *new, - struct extent_state *other) +static int btrfs_merge_extent_hook(struct inode *inode, + struct extent_state *new, + struct extent_state *other) { /* not delalloc, ignore it */ if (!(other->state & EXTENT_DELALLOC)) - return; + return 0; spin_lock(&BTRFS_I(inode)->lock); BTRFS_I(inode)->outstanding_extents--; spin_unlock(&BTRFS_I(inode)->lock); + return 0; } /* @@ -1319,8 +1320,8 @@ static void btrfs_merge_extent_hook(struct inode *inode, * bytes in this file, and to maintain the list of inodes that * have pending delalloc work to be done. */ -static void btrfs_set_bit_hook(struct inode *inode, - struct extent_state *state, int *bits) +static int btrfs_set_bit_hook(struct inode *inode, + struct extent_state *state, int *bits) { /* @@ -1350,13 +1351,14 @@ static void btrfs_set_bit_hook(struct inode *inode, } spin_unlock(&root->fs_info->delalloc_lock); } + return 0; } /* * extent_io.c clear_bit_hook, see set_bit_hook for why */ -static void btrfs_clear_bit_hook(struct inode *inode, - struct extent_state *state, int *bits) +static int btrfs_clear_bit_hook(struct inode *inode, + struct extent_state *state, int *bits) { /* * set_bit and clear bit hooks normally require _irqsave/restore @@ -1393,6 +1395,7 @@ static void btrfs_clear_bit_hook(struct inode *inode, } spin_unlock(&root->fs_info->delalloc_lock); } + return 0; } /* @@ -1642,8 +1645,7 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, int ret; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); path->leave_spinning = 1; @@ -2213,8 +2215,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) if (!root->orphan_block_rsv) { block_rsv = btrfs_alloc_block_rsv(root); - if (!block_rsv) - return -ENOMEM; + BUG_ON(!block_rsv); } spin_lock(&root->orphan_lock); @@ -2516,9 +2517,7 @@ static void btrfs_read_locked_inode(struct inode *inode) filled = true; path = btrfs_alloc_path(); - if (!path) - goto make_bad; - + BUG_ON(!path); path->leave_spinning = 1; memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); @@ -2999,16 +2998,13 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) ret = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, dentry->d_name.name, dentry->d_name.len); - if (ret) - goto out; + BUG_ON(ret); if (inode->i_nlink == 0) { ret = btrfs_orphan_add(trans, inode); - if (ret) - goto out; + BUG_ON(ret); } -out: nr = trans->blocks_used; __unlink_end_trans(trans, root); btrfs_btree_balance_dirty(root, nr); @@ -3151,11 +3147,6 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, BUG_ON(new_size > 0 && min_type != BTRFS_EXTENT_DATA_KEY); - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; - path->reada = -1; - if (root->ref_cows || root == root->fs_info->tree_root) btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0); @@ -3168,6 +3159,10 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans, if (min_type == 0 && root == BTRFS_I(inode)->root) btrfs_kill_delayed_inode_items(inode); + path = btrfs_alloc_path(); + BUG_ON(!path); + path->reada = -1; + key.objectid = ino; key.offset = (u64)-1; key.type = (u8)-1; @@ -3695,8 +3690,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, int ret = 0; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); di = btrfs_lookup_dir_item(NULL, root, path, btrfs_ino(dir), name, namelen, 0); @@ -3952,7 +3946,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, struct btrfs_root *root, int *new) { struct inode *inode; - int bad_inode = 0; inode = btrfs_iget_locked(s, location->objectid, root); if (!inode) @@ -3962,19 +3955,10 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, BTRFS_I(inode)->root = root; memcpy(&BTRFS_I(inode)->location, location, sizeof(*location)); btrfs_read_locked_inode(inode); - if (!is_bad_inode(inode)) { - inode_tree_add(inode); - unlock_new_inode(inode); - if (new) - *new = 1; - } else { - bad_inode = 1; - } - } - - if (bad_inode) { - iput(inode); - inode = ERR_PTR(-ESTALE); + inode_tree_add(inode); + unlock_new_inode(inode); + if (new) + *new = 1; } return inode; @@ -4467,8 +4451,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, int owner; path = btrfs_alloc_path(); - if (!path) - return ERR_PTR(-ENOMEM); + BUG_ON(!path); inode = new_inode(root->fs_info->sb); if (!inode) { @@ -6728,6 +6711,19 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, return 0; } +/* helper function for file defrag and space balancing. This + * forces readahead on a given range of bytes in an inode + */ +unsigned long btrfs_force_ra(struct address_space *mapping, + struct file_ra_state *ra, struct file *file, + pgoff_t offset, pgoff_t last_index) +{ + pgoff_t req_size = last_index - offset + 1; + + page_cache_sync_readahead(mapping, ra, file, offset, req_size); + return offset + req_size; +} + struct inode *btrfs_alloc_inode(struct super_block *sb) { struct btrfs_inode *ei; @@ -7210,11 +7206,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, goto out_unlock; path = btrfs_alloc_path(); - if (!path) { - err = -ENOMEM; - drop_inode = 1; - goto out_unlock; - } + BUG_ON(!path); key.objectid = btrfs_ino(inode); key.offset = 0; btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY); diff --git a/trunk/fs/btrfs/ioctl.c b/trunk/fs/btrfs/ioctl.c index 7cf013349941..0b980afc5edd 100644 --- a/trunk/fs/btrfs/ioctl.c +++ b/trunk/fs/btrfs/ioctl.c @@ -1749,10 +1749,11 @@ static noinline int btrfs_search_path_in_tree(struct btrfs_fs_info *info, key.objectid = key.offset; key.offset = (u64)-1; dirid = key.objectid; + } if (ptr < name) goto out; - memmove(name, ptr, total_len); + memcpy(name, ptr, total_len); name[total_len]='\0'; ret = 0; out: diff --git a/trunk/fs/btrfs/ref-cache.c b/trunk/fs/btrfs/ref-cache.c new file mode 100644 index 000000000000..82d569cb6267 --- /dev/null +++ b/trunk/fs/btrfs/ref-cache.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2008 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include "ctree.h" +#include "ref-cache.h" +#include "transaction.h" + +static struct rb_node *tree_insert(struct rb_root *root, u64 bytenr, + struct rb_node *node) +{ + struct rb_node **p = &root->rb_node; + struct rb_node *parent = NULL; + struct btrfs_leaf_ref *entry; + + while (*p) { + parent = *p; + entry = rb_entry(parent, struct btrfs_leaf_ref, rb_node); + + if (bytenr < entry->bytenr) + p = &(*p)->rb_left; + else if (bytenr > entry->bytenr) + p = &(*p)->rb_right; + else + return parent; + } + + entry = rb_entry(node, struct btrfs_leaf_ref, rb_node); + rb_link_node(node, parent, p); + rb_insert_color(node, root); + return NULL; +} + +static struct rb_node *tree_search(struct rb_root *root, u64 bytenr) +{ + struct rb_node *n = root->rb_node; + struct btrfs_leaf_ref *entry; + + while (n) { + entry = rb_entry(n, struct btrfs_leaf_ref, rb_node); + WARN_ON(!entry->in_tree); + + if (bytenr < entry->bytenr) + n = n->rb_left; + else if (bytenr > entry->bytenr) + n = n->rb_right; + else + return n; + } + return NULL; +} diff --git a/trunk/fs/btrfs/ref-cache.h b/trunk/fs/btrfs/ref-cache.h new file mode 100644 index 000000000000..24f7001f6387 --- /dev/null +++ b/trunk/fs/btrfs/ref-cache.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2008 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ +#ifndef __REFCACHE__ +#define __REFCACHE__ + +struct btrfs_extent_info { + /* bytenr and num_bytes find the extent in the extent allocation tree */ + u64 bytenr; + u64 num_bytes; + + /* objectid and offset find the back reference for the file */ + u64 objectid; + u64 offset; +}; + +struct btrfs_leaf_ref { + struct rb_node rb_node; + struct btrfs_leaf_ref_tree *tree; + int in_tree; + atomic_t usage; + + u64 root_gen; + u64 bytenr; + u64 owner; + u64 generation; + int nritems; + + struct list_head list; + struct btrfs_extent_info extents[]; +}; + +static inline size_t btrfs_leaf_ref_size(int nr_extents) +{ + return sizeof(struct btrfs_leaf_ref) + + sizeof(struct btrfs_extent_info) * nr_extents; +} +#endif diff --git a/trunk/fs/btrfs/root-tree.c b/trunk/fs/btrfs/root-tree.c index f4099904565a..ebe45443de06 100644 --- a/trunk/fs/btrfs/root-tree.c +++ b/trunk/fs/btrfs/root-tree.c @@ -71,12 +71,13 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid, return ret; } -void btrfs_set_root_node(struct btrfs_root_item *item, - struct extent_buffer *node) +int btrfs_set_root_node(struct btrfs_root_item *item, + struct extent_buffer *node) { btrfs_set_root_bytenr(item, node->start); btrfs_set_root_level(item, btrfs_header_level(node)); btrfs_set_root_generation(item, btrfs_header_generation(node)); + return 0; } /* diff --git a/trunk/fs/btrfs/transaction.c b/trunk/fs/btrfs/transaction.c index 7dc36fab4afc..eb55863bb4ae 100644 --- a/trunk/fs/btrfs/transaction.c +++ b/trunk/fs/btrfs/transaction.c @@ -216,11 +216,17 @@ static void wait_current_trans(struct btrfs_root *root) spin_lock(&root->fs_info->trans_lock); cur_trans = root->fs_info->running_transaction; if (cur_trans && cur_trans->blocked) { + DEFINE_WAIT(wait); atomic_inc(&cur_trans->use_count); spin_unlock(&root->fs_info->trans_lock); - - wait_event(root->fs_info->transaction_wait, - !cur_trans->blocked); + while (1) { + prepare_to_wait(&root->fs_info->transaction_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (!cur_trans->blocked) + break; + schedule(); + } + finish_wait(&root->fs_info->transaction_wait, &wait); put_transaction(cur_trans); } else { spin_unlock(&root->fs_info->trans_lock); @@ -351,10 +357,19 @@ struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root } /* wait for a transaction commit to be fully complete */ -static noinline void wait_for_commit(struct btrfs_root *root, +static noinline int wait_for_commit(struct btrfs_root *root, struct btrfs_transaction *commit) { - wait_event(commit->commit_wait, commit->commit_done); + DEFINE_WAIT(wait); + while (!commit->commit_done) { + prepare_to_wait(&commit->commit_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (commit->commit_done) + break; + schedule(); + } + finish_wait(&commit->commit_wait, &wait); + return 0; } int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) @@ -1070,7 +1085,22 @@ int btrfs_transaction_blocked(struct btrfs_fs_info *info) static void wait_current_trans_commit_start(struct btrfs_root *root, struct btrfs_transaction *trans) { - wait_event(root->fs_info->transaction_blocked_wait, trans->in_commit); + DEFINE_WAIT(wait); + + if (trans->in_commit) + return; + + while (1) { + prepare_to_wait(&root->fs_info->transaction_blocked_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (trans->in_commit) { + finish_wait(&root->fs_info->transaction_blocked_wait, + &wait); + break; + } + schedule(); + finish_wait(&root->fs_info->transaction_blocked_wait, &wait); + } } /* @@ -1080,8 +1110,24 @@ static void wait_current_trans_commit_start(struct btrfs_root *root, static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root, struct btrfs_transaction *trans) { - wait_event(root->fs_info->transaction_wait, - trans->commit_done || (trans->in_commit && !trans->blocked)); + DEFINE_WAIT(wait); + + if (trans->commit_done || (trans->in_commit && !trans->blocked)) + return; + + while (1) { + prepare_to_wait(&root->fs_info->transaction_wait, &wait, + TASK_UNINTERRUPTIBLE); + if (trans->commit_done || + (trans->in_commit && !trans->blocked)) { + finish_wait(&root->fs_info->transaction_wait, + &wait); + break; + } + schedule(); + finish_wait(&root->fs_info->transaction_wait, + &wait); + } } /* @@ -1188,7 +1234,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, atomic_inc(&cur_trans->use_count); btrfs_end_transaction(trans, root); - wait_for_commit(root, cur_trans); + ret = wait_for_commit(root, cur_trans); + BUG_ON(ret); put_transaction(cur_trans); diff --git a/trunk/fs/btrfs/tree-log.c b/trunk/fs/btrfs/tree-log.c index babee65f8eda..ac278dd83175 100644 --- a/trunk/fs/btrfs/tree-log.c +++ b/trunk/fs/btrfs/tree-log.c @@ -1617,8 +1617,7 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb, return 0; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); nritems = btrfs_header_nritems(eb); for (i = 0; i < nritems; i++) { @@ -1724,9 +1723,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, return -ENOMEM; if (*level == 1) { - ret = wc->process_func(root, next, wc, ptr_gen); - if (ret) - return ret; + wc->process_func(root, next, wc, ptr_gen); path->slots[*level]++; if (wc->free) { @@ -1791,11 +1788,8 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, parent = path->nodes[*level + 1]; root_owner = btrfs_header_owner(parent); - ret = wc->process_func(root, path->nodes[*level], wc, + wc->process_func(root, path->nodes[*level], wc, btrfs_header_generation(path->nodes[*level])); - if (ret) - return ret; - if (wc->free) { struct extent_buffer *next; diff --git a/trunk/fs/btrfs/volumes.c b/trunk/fs/btrfs/volumes.c index 53875ae73ad4..b89e372c7544 100644 --- a/trunk/fs/btrfs/volumes.c +++ b/trunk/fs/btrfs/volumes.c @@ -1037,8 +1037,7 @@ static noinline int find_next_chunk(struct btrfs_root *root, struct btrfs_key found_key; path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; + BUG_ON(!path); key.objectid = objectid; key.offset = (u64)-1; @@ -2062,10 +2061,8 @@ int btrfs_balance(struct btrfs_root *dev_root) /* step two, relocate all the chunks */ path = btrfs_alloc_path(); - if (!path) { - ret = -ENOMEM; - goto error; - } + BUG_ON(!path); + key.objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID; key.offset = (u64)-1; key.type = BTRFS_CHUNK_ITEM_KEY; @@ -2664,8 +2661,7 @@ static noinline int init_first_rw_device(struct btrfs_trans_handle *trans, ret = find_next_chunk(fs_info->chunk_root, BTRFS_FIRST_CHUNK_TREE_OBJECTID, &chunk_offset); - if (ret) - return ret; + BUG_ON(ret); alloc_profile = BTRFS_BLOCK_GROUP_METADATA | (fs_info->metadata_alloc_profile & diff --git a/trunk/fs/cifs/cifs_dfs_ref.c b/trunk/fs/cifs/cifs_dfs_ref.c index 6873bb634a97..8d8f28c94c0f 100644 --- a/trunk/fs/cifs/cifs_dfs_ref.c +++ b/trunk/fs/cifs/cifs_dfs_ref.c @@ -141,11 +141,10 @@ char *cifs_compose_mount_options(const char *sb_mountdata, rc = dns_resolve_server_name_to_ip(*devname, &srvIP); if (rc < 0) { - cFYI(1, "%s: Failed to resolve server part of %s to IP: %d", - __func__, *devname, rc); + cERROR(1, "%s: Failed to resolve server part of %s to IP: %d", + __func__, *devname, rc); goto compose_mount_options_err; } - /* md_len = strlen(...) + 12 for 'sep+prefixpath=' * assuming that we have 'unc=' and 'ip=' in * the original sb_mountdata diff --git a/trunk/fs/cifs/cifsfs.c b/trunk/fs/cifs/cifsfs.c index f93eb948d071..212e5629cc1d 100644 --- a/trunk/fs/cifs/cifsfs.c +++ b/trunk/fs/cifs/cifsfs.c @@ -563,10 +563,6 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) mutex_unlock(&dir->i_mutex); dput(dentry); dentry = child; - if (!dentry->d_inode) { - dput(dentry); - dentry = ERR_PTR(-ENOENT); - } } while (!IS_ERR(dentry)); _FreeXid(xid); kfree(full_path); diff --git a/trunk/fs/cifs/dns_resolve.c b/trunk/fs/cifs/dns_resolve.c index 1d2d91d9bf65..548f06230a6d 100644 --- a/trunk/fs/cifs/dns_resolve.c +++ b/trunk/fs/cifs/dns_resolve.c @@ -79,8 +79,8 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr) /* Perform the upcall */ rc = dns_query(NULL, hostname, len, NULL, ip_addr, NULL); if (rc < 0) - cFYI(1, "%s: unable to resolve: %*.*s", - __func__, len, len, hostname); + cERROR(1, "%s: unable to resolve: %*.*s", + __func__, len, len, hostname); else cFYI(1, "%s: resolved: %*.*s to %s", __func__, len, len, hostname, *ip_addr); diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index a7b2dcd4a53e..9b018c8334fa 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -764,10 +764,20 @@ char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, if (full_path == NULL) return full_path; - if (dfsplen) + if (dfsplen) { strncpy(full_path, tcon->treeName, dfsplen); + /* switch slash direction in prepath depending on whether + * windows or posix style path names + */ + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) { + int i; + for (i = 0; i < dfsplen; i++) { + if (full_path[i] == '\\') + full_path[i] = '/'; + } + } + } strncpy(full_path + dfsplen, vol->prepath, pplen); - convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); full_path[dfsplen + pplen] = 0; /* add trailing null */ return full_path; } diff --git a/trunk/fs/cifs/sess.c b/trunk/fs/cifs/sess.c index d3e619692ee0..243d58720513 100644 --- a/trunk/fs/cifs/sess.c +++ b/trunk/fs/cifs/sess.c @@ -124,7 +124,8 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB) /* that we use in next few lines */ /* Note that header is initialized to zero in header_assemble */ pSMB->req.AndXCommand = 0xFF; - pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); + pSMB->req.MaxBufferSize = cpu_to_le16(min_t(u32, CIFSMaxBufSize - 4, + USHRT_MAX)); pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); pSMB->req.VcNumber = get_next_vcnum(ses); diff --git a/trunk/fs/cifs/transport.c b/trunk/fs/cifs/transport.c index c1b9c4b10739..147aa22c3c3a 100644 --- a/trunk/fs/cifs/transport.c +++ b/trunk/fs/cifs/transport.c @@ -362,8 +362,6 @@ cifs_call_async(struct TCP_Server_Info *server, struct kvec *iov, mid = AllocMidQEntry(hdr, server); if (mid == NULL) { mutex_unlock(&server->srv_mutex); - atomic_dec(&server->inFlight); - wake_up(&server->request_q); return -ENOMEM; } diff --git a/trunk/fs/compat_ioctl.c b/trunk/fs/compat_ioctl.c index 51352de88ef1..8be086e9abe4 100644 --- a/trunk/fs/compat_ioctl.c +++ b/trunk/fs/compat_ioctl.c @@ -1003,7 +1003,6 @@ COMPATIBLE_IOCTL(PPPIOCCONNECT) COMPATIBLE_IOCTL(PPPIOCDISCONN) COMPATIBLE_IOCTL(PPPIOCATTCHAN) COMPATIBLE_IOCTL(PPPIOCGCHAN) -COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS) /* PPPOX */ COMPATIBLE_IOCTL(PPPOEIOCSFWD) COMPATIBLE_IOCTL(PPPOEIOCDFWD) diff --git a/trunk/fs/dcache.c b/trunk/fs/dcache.c index a88948b8bd17..2347cdb15abb 100644 --- a/trunk/fs/dcache.c +++ b/trunk/fs/dcache.c @@ -795,7 +795,6 @@ static void __shrink_dcache_sb(struct super_block *sb, int count, int flags) /** * prune_dcache_sb - shrink the dcache - * @sb: superblock * @nr_to_scan: number of entries to try to free * * Attempt to shrink the superblock dcache LRU by @nr_to_scan entries. This is @@ -1729,7 +1728,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name, */ if (read_seqcount_retry(&dentry->d_seq, *seq)) goto seqretry; - if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) { + if (parent->d_flags & DCACHE_OP_COMPARE) { if (parent->d_op->d_compare(parent, *inode, dentry, i, tlen, tname, name)) diff --git a/trunk/fs/ecryptfs/Kconfig b/trunk/fs/ecryptfs/Kconfig index cc16562654de..1cd6d9d3e29a 100644 --- a/trunk/fs/ecryptfs/Kconfig +++ b/trunk/fs/ecryptfs/Kconfig @@ -1,6 +1,6 @@ config ECRYPT_FS tristate "eCrypt filesystem layer support (EXPERIMENTAL)" - depends on EXPERIMENTAL && KEYS && CRYPTO && (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n) + depends on EXPERIMENTAL && KEYS && CRYPTO select CRYPTO_ECB select CRYPTO_CBC select CRYPTO_MD5 diff --git a/trunk/fs/ecryptfs/keystore.c b/trunk/fs/ecryptfs/keystore.c index ac1ad48c2376..08a2b52bf565 100644 --- a/trunk/fs/ecryptfs/keystore.c +++ b/trunk/fs/ecryptfs/keystore.c @@ -1973,7 +1973,7 @@ pki_encrypt_session_key(struct key *auth_tok_key, { struct ecryptfs_msg_ctx *msg_ctx = NULL; char *payload = NULL; - size_t payload_len = 0; + size_t payload_len; struct ecryptfs_message *msg; int rc; diff --git a/trunk/fs/ecryptfs/main.c b/trunk/fs/ecryptfs/main.c index b4a6befb1216..9f1bb747d77d 100644 --- a/trunk/fs/ecryptfs/main.c +++ b/trunk/fs/ecryptfs/main.c @@ -175,7 +175,6 @@ enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_encrypted_view, ecryptfs_opt_fnek_sig, ecryptfs_opt_fn_cipher, ecryptfs_opt_fn_cipher_key_bytes, ecryptfs_opt_unlink_sigs, ecryptfs_opt_mount_auth_tok_only, - ecryptfs_opt_check_dev_ruid, ecryptfs_opt_err }; static const match_table_t tokens = { @@ -192,7 +191,6 @@ static const match_table_t tokens = { {ecryptfs_opt_fn_cipher_key_bytes, "ecryptfs_fn_key_bytes=%u"}, {ecryptfs_opt_unlink_sigs, "ecryptfs_unlink_sigs"}, {ecryptfs_opt_mount_auth_tok_only, "ecryptfs_mount_auth_tok_only"}, - {ecryptfs_opt_check_dev_ruid, "ecryptfs_check_dev_ruid"}, {ecryptfs_opt_err, NULL} }; @@ -238,7 +236,6 @@ static void ecryptfs_init_mount_crypt_stat( * ecryptfs_parse_options * @sb: The ecryptfs super block * @options: The options passed to the kernel - * @check_ruid: set to 1 if device uid should be checked against the ruid * * Parse mount options: * debug=N - ecryptfs_verbosity level for debug output @@ -254,8 +251,7 @@ static void ecryptfs_init_mount_crypt_stat( * * Returns zero on success; non-zero on error */ -static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, - uid_t *check_ruid) +static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) { char *p; int rc = 0; @@ -280,8 +276,6 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, char *cipher_key_bytes_src; char *fn_cipher_key_bytes_src; - *check_ruid = 0; - if (!options) { rc = -EINVAL; goto out; @@ -386,9 +380,6 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, mount_crypt_stat->flags |= ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY; break; - case ecryptfs_opt_check_dev_ruid: - *check_ruid = 1; - break; case ecryptfs_opt_err: default: printk(KERN_WARNING @@ -484,7 +475,6 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags const char *err = "Getting sb failed"; struct inode *inode; struct path path; - uid_t check_ruid; int rc; sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); @@ -493,7 +483,7 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags goto out; } - rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); + rc = ecryptfs_parse_options(sbi, raw_data); if (rc) { err = "Error parsing options"; goto out; @@ -531,15 +521,6 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags "known incompatibilities\n"); goto out_free; } - - if (check_ruid && path.dentry->d_inode->i_uid != current_uid()) { - rc = -EPERM; - printk(KERN_ERR "Mount of device (uid: %d) not owned by " - "requested user (uid: %d)\n", - path.dentry->d_inode->i_uid, current_uid()); - goto out_free; - } - ecryptfs_set_superblock_lower(s, path.dentry->d_sb); s->s_maxbytes = path.dentry->d_sb->s_maxbytes; s->s_blocksize = path.dentry->d_sb->s_blocksize; diff --git a/trunk/fs/ecryptfs/read_write.c b/trunk/fs/ecryptfs/read_write.c index 3745f7c2b9c2..85d430963116 100644 --- a/trunk/fs/ecryptfs/read_write.c +++ b/trunk/fs/ecryptfs/read_write.c @@ -39,16 +39,15 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, loff_t offset, size_t size) { - struct file *lower_file; + struct ecryptfs_inode_info *inode_info; mm_segment_t fs_save; ssize_t rc; - lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; - if (!lower_file) - return -EIO; + inode_info = ecryptfs_inode_to_private(ecryptfs_inode); + BUG_ON(!inode_info->lower_file); fs_save = get_fs(); set_fs(get_ds()); - rc = vfs_write(lower_file, data, size, &offset); + rc = vfs_write(inode_info->lower_file, data, size, &offset); set_fs(fs_save); mark_inode_dirty_sync(ecryptfs_inode); return rc; @@ -226,16 +225,15 @@ int ecryptfs_write(struct inode *ecryptfs_inode, char *data, loff_t offset, int ecryptfs_read_lower(char *data, loff_t offset, size_t size, struct inode *ecryptfs_inode) { - struct file *lower_file; + struct ecryptfs_inode_info *inode_info = + ecryptfs_inode_to_private(ecryptfs_inode); mm_segment_t fs_save; ssize_t rc; - lower_file = ecryptfs_inode_to_private(ecryptfs_inode)->lower_file; - if (!lower_file) - return -EIO; + BUG_ON(!inode_info->lower_file); fs_save = get_fs(); set_fs(get_ds()); - rc = vfs_read(lower_file, data, size, &offset); + rc = vfs_read(inode_info->lower_file, data, size, &offset); set_fs(fs_save); return rc; } diff --git a/trunk/fs/exec.c b/trunk/fs/exec.c index 25dcbe5fc356..da80612a35f4 100644 --- a/trunk/fs/exec.c +++ b/trunk/fs/exec.c @@ -1459,23 +1459,6 @@ static int do_execve_common(const char *filename, struct files_struct *displaced; bool clear_in_exec; int retval; - const struct cred *cred = current_cred(); - - /* - * We move the actual failure in case of RLIMIT_NPROC excess from - * set*uid() to execve() because too many poorly written programs - * don't check setuid() return code. Here we additionally recheck - * whether NPROC limit is still exceeded. - */ - if ((current->flags & PF_NPROC_EXCEEDED) && - atomic_read(&cred->user->processes) > rlimit(RLIMIT_NPROC)) { - retval = -EAGAIN; - goto out_ret; - } - - /* We're below the limit (still or again), so we don't want to make - * further execve() calls fail. */ - current->flags &= ~PF_NPROC_EXCEEDED; retval = unshare_files(&displaced); if (retval) diff --git a/trunk/fs/exofs/Kbuild b/trunk/fs/exofs/Kbuild index c5a5855a6c44..2d0f757fda3e 100644 --- a/trunk/fs/exofs/Kbuild +++ b/trunk/fs/exofs/Kbuild @@ -12,8 +12,5 @@ # Kbuild - Gets included from the Kernels Makefile and build system # -# ore module library -obj-$(CONFIG_ORE) += ore.o - -exofs-y := inode.o file.o symlink.o namei.o dir.o super.o +exofs-y := ios.o inode.o file.o symlink.o namei.o dir.o super.o obj-$(CONFIG_EXOFS_FS) += exofs.o diff --git a/trunk/fs/exofs/Kconfig b/trunk/fs/exofs/Kconfig index 70bae4149291..86194b2f799d 100644 --- a/trunk/fs/exofs/Kconfig +++ b/trunk/fs/exofs/Kconfig @@ -1,10 +1,6 @@ -config ORE - tristate - config EXOFS_FS tristate "exofs: OSD based file system support" depends on SCSI_OSD_ULD - select ORE help EXOFS is a file system that uses an OSD storage device, as its backing storage. diff --git a/trunk/fs/exofs/exofs.h b/trunk/fs/exofs/exofs.h index f4e442ec7445..c965806c2821 100644 --- a/trunk/fs/exofs/exofs.h +++ b/trunk/fs/exofs/exofs.h @@ -36,10 +36,13 @@ #include #include #include -#include - #include "common.h" +/* FIXME: Remove once pnfs hits mainline + * #include + */ +#include "pnfs.h" + #define EXOFS_ERR(fmt, a...) printk(KERN_ERR "exofs: " fmt, ##a) #ifdef CONFIG_EXOFS_DEBUG @@ -53,11 +56,27 @@ /* u64 has problems with printk this will cast it to unsigned long long */ #define _LLU(x) (unsigned long long)(x) +struct exofs_layout { + osd_id s_pid; /* partition ID of file system*/ + + /* Our way of looking at the data_map */ + unsigned stripe_unit; + unsigned mirrors_p1; + + unsigned group_width; + u64 group_depth; + unsigned group_count; + + enum exofs_inode_layout_gen_functions lay_func; + + unsigned s_numdevs; /* Num of devices in array */ + struct osd_dev *s_ods[0]; /* Variable length */ +}; + /* * our extension to the in-memory superblock */ struct exofs_sb_info { - struct backing_dev_info bdi; /* register our bdi with VFS */ struct exofs_sb_stats s_ess; /* Written often, pre-allocate*/ int s_timeout; /* timeout for OSD operations */ uint64_t s_nextid; /* highest object ID used */ @@ -65,13 +84,16 @@ struct exofs_sb_info { spinlock_t s_next_gen_lock; /* spinlock for gen # update */ u32 s_next_generation; /* next gen # to use */ atomic_t s_curr_pending; /* number of pending commands */ + uint8_t s_cred[OSD_CAP_LEN]; /* credential for the fscb */ + struct backing_dev_info bdi; /* register our bdi with VFS */ struct pnfs_osd_data_map data_map; /* Default raid to use * FIXME: Needed ? */ - struct ore_layout layout; /* Default files layout */ - struct ore_comp one_comp; /* id & cred of partition id=0*/ - struct ore_components comps; /* comps for the partition */ +/* struct exofs_layout dir_layout;*/ /* Default dir layout */ + struct exofs_layout layout; /* Default files layout, + * contains the variable osd_dev + * array. Keep last */ struct osd_dev *_min_one_dev[1]; /* Place holder for one dev */ }; @@ -85,8 +107,7 @@ struct exofs_i_info { uint32_t i_data[EXOFS_IDATA];/*short symlink names and device #s*/ uint32_t i_dir_start_lookup; /* which page to start lookup */ uint64_t i_commit_size; /* the object's written length */ - struct ore_comp one_comp; /* same component for all devices */ - struct ore_components comps; /* inode view of the device table */ + uint8_t i_cred[OSD_CAP_LEN];/* all-powerful credential */ }; static inline osd_id exofs_oi_objno(struct exofs_i_info *oi) @@ -94,6 +115,52 @@ static inline osd_id exofs_oi_objno(struct exofs_i_info *oi) return oi->vfs_inode.i_ino + EXOFS_OBJ_OFF; } +struct exofs_io_state; +typedef void (*exofs_io_done_fn)(struct exofs_io_state *or, void *private); + +struct exofs_io_state { + struct kref kref; + + void *private; + exofs_io_done_fn done; + + struct exofs_layout *layout; + struct osd_obj_id obj; + u8 *cred; + + /* Global read/write IO*/ + loff_t offset; + unsigned long length; + void *kern_buff; + + struct page **pages; + unsigned nr_pages; + unsigned pgbase; + unsigned pages_consumed; + + /* Attributes */ + unsigned in_attr_len; + struct osd_attr *in_attr; + unsigned out_attr_len; + struct osd_attr *out_attr; + + /* Variable array of size numdevs */ + unsigned numdevs; + struct exofs_per_dev_state { + struct osd_request *or; + struct bio *bio; + loff_t offset; + unsigned length; + unsigned dev; + } per_dev[]; +}; + +static inline unsigned exofs_io_state_size(unsigned numdevs) +{ + return sizeof(struct exofs_io_state) + + sizeof(struct exofs_per_dev_state) * numdevs; +} + /* * our inode flags */ @@ -137,6 +204,12 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode) return container_of(inode, struct exofs_i_info, vfs_inode); } +/* + * Given a layout, object_number and stripe_index return the associated global + * dev_index + */ +unsigned exofs_layout_od_id(struct exofs_layout *layout, + osd_id obj_no, unsigned layout_index); /* * Maximum count of links to a file */ @@ -146,8 +219,44 @@ static inline struct exofs_i_info *exofs_i(struct inode *inode) * function declarations * *************************/ +/* ios.c */ +void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], + const struct osd_obj_id *obj); +int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, + u64 offset, void *p, unsigned length); + +int exofs_get_io_state(struct exofs_layout *layout, + struct exofs_io_state **ios); +void exofs_put_io_state(struct exofs_io_state *ios); + +int exofs_check_io(struct exofs_io_state *ios, u64 *resid); + +int exofs_sbi_create(struct exofs_io_state *ios); +int exofs_sbi_remove(struct exofs_io_state *ios); +int exofs_sbi_write(struct exofs_io_state *ios); +int exofs_sbi_read(struct exofs_io_state *ios); + +int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr); + +int exofs_oi_truncate(struct exofs_i_info *oi, u64 new_len); +static inline int exofs_oi_write(struct exofs_i_info *oi, + struct exofs_io_state *ios) +{ + ios->obj.id = exofs_oi_objno(oi); + ios->cred = oi->i_cred; + return exofs_sbi_write(ios); +} + +static inline int exofs_oi_read(struct exofs_i_info *oi, + struct exofs_io_state *ios) +{ + ios->obj.id = exofs_oi_objno(oi); + ios->cred = oi->i_cred; + return exofs_sbi_read(ios); +} + /* inode.c */ -unsigned exofs_max_io_pages(struct ore_layout *layout, +unsigned exofs_max_io_pages(struct exofs_layout *layout, unsigned expected_pages); int exofs_setattr(struct dentry *, struct iattr *); int exofs_write_begin(struct file *file, struct address_space *mapping, @@ -172,8 +281,6 @@ int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *, struct inode *); /* super.c */ -void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], - const struct osd_obj_id *obj); int exofs_sbi_write_stats(struct exofs_sb_info *sbi); /********************* @@ -188,6 +295,7 @@ extern const struct file_operations exofs_file_operations; /* inode.c */ extern const struct address_space_operations exofs_aops; +extern const struct osd_attr g_attr_logical_length; /* namei.c */ extern const struct inode_operations exofs_dir_inode_operations; @@ -197,33 +305,4 @@ extern const struct inode_operations exofs_special_inode_operations; extern const struct inode_operations exofs_symlink_inode_operations; extern const struct inode_operations exofs_fast_symlink_inode_operations; -/* exofs_init_comps will initialize an ore_components device array - * pointing to a single ore_comp struct, and a round-robin view - * of the device table. - * The first device of each inode is the [inode->ino % num_devices] - * and the rest of the devices sequentially following where the - * first device is after the last device. - * It is assumed that the global device array at @sbi is twice - * bigger and that the device table repeats twice. - * See: exofs_read_lookup_dev_table() - */ -static inline void exofs_init_comps(struct ore_components *comps, - struct ore_comp *one_comp, - struct exofs_sb_info *sbi, osd_id oid) -{ - unsigned dev_mod = (unsigned)oid, first_dev; - - one_comp->obj.partition = sbi->one_comp.obj.partition; - one_comp->obj.id = oid; - exofs_make_credential(one_comp->cred, &one_comp->obj); - - comps->numdevs = sbi->comps.numdevs; - comps->single_comp = EC_SINGLE_COMP; - comps->comps = one_comp; - - /* Round robin device view of the table */ - first_dev = (dev_mod * sbi->layout.mirrors_p1) % sbi->comps.numdevs; - comps->ods = sbi->comps.ods + first_dev; -} - #endif diff --git a/trunk/fs/exofs/inode.c b/trunk/fs/exofs/inode.c index f39a38fc2349..8472c098445d 100644 --- a/trunk/fs/exofs/inode.c +++ b/trunk/fs/exofs/inode.c @@ -43,7 +43,7 @@ enum { BIO_MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), }; -unsigned exofs_max_io_pages(struct ore_layout *layout, +unsigned exofs_max_io_pages(struct exofs_layout *layout, unsigned expected_pages) { unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); @@ -58,7 +58,7 @@ struct page_collect { struct exofs_sb_info *sbi; struct inode *inode; unsigned expected_pages; - struct ore_io_state *ios; + struct exofs_io_state *ios; struct page **pages; unsigned alloc_pages; @@ -110,6 +110,13 @@ static int pcol_try_alloc(struct page_collect *pcol) { unsigned pages; + if (!pcol->ios) { /* First time allocate io_state */ + int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); + + if (ret) + return ret; + } + /* TODO: easily support bio chaining */ pages = exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages); @@ -133,7 +140,7 @@ static void pcol_free(struct page_collect *pcol) pcol->pages = NULL; if (pcol->ios) { - ore_put_io_state(pcol->ios); + exofs_put_io_state(pcol->ios); pcol->ios = NULL; } } @@ -193,7 +200,7 @@ static int __readpages_done(struct page_collect *pcol) u64 resid; u64 good_bytes; u64 length = 0; - int ret = ore_check_io(pcol->ios, &resid); + int ret = exofs_check_io(pcol->ios, &resid); if (likely(!ret)) good_bytes = pcol->length; @@ -234,7 +241,7 @@ static int __readpages_done(struct page_collect *pcol) } /* callback of async reads */ -static void readpages_done(struct ore_io_state *ios, void *p) +static void readpages_done(struct exofs_io_state *ios, void *p) { struct page_collect *pcol = p; @@ -262,28 +269,20 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw) static int read_exec(struct page_collect *pcol) { struct exofs_i_info *oi = exofs_i(pcol->inode); - struct ore_io_state *ios; + struct exofs_io_state *ios = pcol->ios; struct page_collect *pcol_copy = NULL; int ret; if (!pcol->pages) return 0; - if (!pcol->ios) { - int ret = ore_get_rw_state(&pcol->sbi->layout, &oi->comps, true, - pcol->pg_first << PAGE_CACHE_SHIFT, - pcol->length, &pcol->ios); - - if (ret) - return ret; - } - - ios = pcol->ios; ios->pages = pcol->pages; ios->nr_pages = pcol->nr_pages; + ios->length = pcol->length; + ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT; if (pcol->read_4_write) { - ore_read(pcol->ios); + exofs_oi_read(oi, pcol->ios); return __readpages_done(pcol); } @@ -296,14 +295,14 @@ static int read_exec(struct page_collect *pcol) *pcol_copy = *pcol; ios->done = readpages_done; ios->private = pcol_copy; - ret = ore_read(ios); + ret = exofs_oi_read(oi, ios); if (unlikely(ret)) goto err; atomic_inc(&pcol->sbi->s_curr_pending); EXOFS_DBGMSG2("read_exec obj=0x%llx start=0x%llx length=0x%lx\n", - oi->one_comp.obj.id, _LLU(ios->offset), pcol->length); + ios->obj.id, _LLU(ios->offset), pcol->length); /* pages ownership was passed to pcol_copy */ _pcol_reset(pcol); @@ -458,14 +457,14 @@ static int exofs_readpage(struct file *file, struct page *page) } /* Callback for osd_write. All writes are asynchronous */ -static void writepages_done(struct ore_io_state *ios, void *p) +static void writepages_done(struct exofs_io_state *ios, void *p) { struct page_collect *pcol = p; int i; u64 resid; u64 good_bytes; u64 length = 0; - int ret = ore_check_io(ios, &resid); + int ret = exofs_check_io(ios, &resid); atomic_dec(&pcol->sbi->s_curr_pending); @@ -508,21 +507,13 @@ static void writepages_done(struct ore_io_state *ios, void *p) static int write_exec(struct page_collect *pcol) { struct exofs_i_info *oi = exofs_i(pcol->inode); - struct ore_io_state *ios; + struct exofs_io_state *ios = pcol->ios; struct page_collect *pcol_copy = NULL; int ret; if (!pcol->pages) return 0; - BUG_ON(pcol->ios); - ret = ore_get_rw_state(&pcol->sbi->layout, &oi->comps, false, - pcol->pg_first << PAGE_CACHE_SHIFT, - pcol->length, &pcol->ios); - - if (unlikely(ret)) - goto err; - pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL); if (!pcol_copy) { EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n"); @@ -532,15 +523,16 @@ static int write_exec(struct page_collect *pcol) *pcol_copy = *pcol; - ios = pcol->ios; ios->pages = pcol_copy->pages; ios->nr_pages = pcol_copy->nr_pages; + ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT; + ios->length = pcol_copy->length; ios->done = writepages_done; ios->private = pcol_copy; - ret = ore_write(ios); + ret = exofs_oi_write(oi, ios); if (unlikely(ret)) { - EXOFS_ERR("write_exec: ore_write() Failed\n"); + EXOFS_ERR("write_exec: exofs_oi_write() Failed\n"); goto err; } @@ -852,15 +844,17 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode) return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0); } +const struct osd_attr g_attr_logical_length = ATTR_DEF( + OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); + static int _do_truncate(struct inode *inode, loff_t newsize) { struct exofs_i_info *oi = exofs_i(inode); - struct exofs_sb_info *sbi = inode->i_sb->s_fs_info; int ret; inode->i_mtime = inode->i_ctime = CURRENT_TIME; - ret = ore_truncate(&sbi->layout, &oi->comps, (u64)newsize); + ret = exofs_oi_truncate(oi, (u64)newsize); if (likely(!ret)) truncate_setsize(inode, newsize); @@ -923,26 +917,30 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi, [1] = g_attr_inode_file_layout, [2] = g_attr_inode_dir_layout, }; - struct ore_io_state *ios; + struct exofs_io_state *ios; struct exofs_on_disk_inode_layout *layout; int ret; - ret = ore_get_io_state(&sbi->layout, &oi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__); + EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); return ret; } - attrs[1].len = exofs_on_disk_inode_layout_size(sbi->comps.numdevs); - attrs[2].len = exofs_on_disk_inode_layout_size(sbi->comps.numdevs); + ios->obj.id = exofs_oi_objno(oi); + exofs_make_credential(oi->i_cred, &ios->obj); + ios->cred = oi->i_cred; + + attrs[1].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs); + attrs[2].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs); ios->in_attr = attrs; ios->in_attr_len = ARRAY_SIZE(attrs); - ret = ore_read(ios); + ret = exofs_sbi_read(ios); if (unlikely(ret)) { EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n", - _LLU(oi->one_comp.obj.id), ret); + _LLU(ios->obj.id), ret); memset(inode, 0, sizeof(*inode)); inode->i_mode = 0040000 | (0777 & ~022); /* If object is lost on target we might as well enable it's @@ -992,7 +990,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi, } out: - ore_put_io_state(ios); + exofs_put_io_state(ios); return ret; } @@ -1018,8 +1016,6 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino) return inode; oi = exofs_i(inode); __oi_init(oi); - exofs_init_comps(&oi->comps, &oi->one_comp, sb->s_fs_info, - exofs_oi_objno(oi)); /* read the inode from the osd */ ret = exofs_get_inode(sb, oi, &fcb); @@ -1111,22 +1107,21 @@ int __exofs_wait_obj_created(struct exofs_i_info *oi) * set the obj_created flag so that other methods know that the object exists on * the OSD. */ -static void create_done(struct ore_io_state *ios, void *p) +static void create_done(struct exofs_io_state *ios, void *p) { struct inode *inode = p; struct exofs_i_info *oi = exofs_i(inode); struct exofs_sb_info *sbi = inode->i_sb->s_fs_info; int ret; - ret = ore_check_io(ios, NULL); - ore_put_io_state(ios); + ret = exofs_check_io(ios, NULL); + exofs_put_io_state(ios); atomic_dec(&sbi->s_curr_pending); if (unlikely(ret)) { EXOFS_ERR("object=0x%llx creation failed in pid=0x%llx", - _LLU(exofs_oi_objno(oi)), - _LLU(oi->one_comp.obj.partition)); + _LLU(exofs_oi_objno(oi)), _LLU(sbi->layout.s_pid)); /*TODO: When FS is corrupted creation can fail, object already * exist. Get rid of this asynchronous creation, if exist * increment the obj counter and try the next object. Until we @@ -1145,13 +1140,14 @@ static void create_done(struct ore_io_state *ios, void *p) */ struct inode *exofs_new_inode(struct inode *dir, int mode) { - struct super_block *sb = dir->i_sb; - struct exofs_sb_info *sbi = sb->s_fs_info; + struct super_block *sb; struct inode *inode; struct exofs_i_info *oi; - struct ore_io_state *ios; + struct exofs_sb_info *sbi; + struct exofs_io_state *ios; int ret; + sb = dir->i_sb; inode = new_inode(sb); if (!inode) return ERR_PTR(-ENOMEM); @@ -1161,6 +1157,8 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) set_obj_2bcreated(oi); + sbi = sb->s_fs_info; + inode->i_mapping->backing_dev_info = sb->s_bdi; inode_init_owner(inode, dir, mode); inode->i_ino = sbi->s_nextid++; @@ -1172,24 +1170,25 @@ struct inode *exofs_new_inode(struct inode *dir, int mode) spin_unlock(&sbi->s_next_gen_lock); insert_inode_hash(inode); - exofs_init_comps(&oi->comps, &oi->one_comp, sb->s_fs_info, - exofs_oi_objno(oi)); exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */ mark_inode_dirty(inode); - ret = ore_get_io_state(&sbi->layout, &oi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("exofs_new_inode: ore_get_io_state failed\n"); + EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n"); return ERR_PTR(ret); } + ios->obj.id = exofs_oi_objno(oi); + exofs_make_credential(oi->i_cred, &ios->obj); + ios->done = create_done; ios->private = inode; - - ret = ore_create(ios); + ios->cred = oi->i_cred; + ret = exofs_sbi_create(ios); if (ret) { - ore_put_io_state(ios); + exofs_put_io_state(ios); return ERR_PTR(ret); } atomic_inc(&sbi->s_curr_pending); @@ -1208,11 +1207,11 @@ struct updatei_args { /* * Callback function from exofs_update_inode(). */ -static void updatei_done(struct ore_io_state *ios, void *p) +static void updatei_done(struct exofs_io_state *ios, void *p) { struct updatei_args *args = p; - ore_put_io_state(ios); + exofs_put_io_state(ios); atomic_dec(&args->sbi->s_curr_pending); @@ -1228,7 +1227,7 @@ static int exofs_update_inode(struct inode *inode, int do_sync) struct exofs_i_info *oi = exofs_i(inode); struct super_block *sb = inode->i_sb; struct exofs_sb_info *sbi = sb->s_fs_info; - struct ore_io_state *ios; + struct exofs_io_state *ios; struct osd_attr attr; struct exofs_fcb *fcb; struct updatei_args *args; @@ -1267,9 +1266,9 @@ static int exofs_update_inode(struct inode *inode, int do_sync) } else memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data)); - ret = ore_get_io_state(&sbi->layout, &oi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__); + EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); goto free_args; } @@ -1286,13 +1285,13 @@ static int exofs_update_inode(struct inode *inode, int do_sync) ios->private = args; } - ret = ore_write(ios); + ret = exofs_oi_write(oi, ios); if (!do_sync && !ret) { atomic_inc(&sbi->s_curr_pending); goto out; /* deallocation in updatei_done */ } - ore_put_io_state(ios); + exofs_put_io_state(ios); free_args: kfree(args); out: @@ -1311,11 +1310,11 @@ int exofs_write_inode(struct inode *inode, struct writeback_control *wbc) * Callback function from exofs_delete_inode() - don't have much cleaning up to * do. */ -static void delete_done(struct ore_io_state *ios, void *p) +static void delete_done(struct exofs_io_state *ios, void *p) { struct exofs_sb_info *sbi = p; - ore_put_io_state(ios); + exofs_put_io_state(ios); atomic_dec(&sbi->s_curr_pending); } @@ -1330,7 +1329,7 @@ void exofs_evict_inode(struct inode *inode) struct exofs_i_info *oi = exofs_i(inode); struct super_block *sb = inode->i_sb; struct exofs_sb_info *sbi = sb->s_fs_info; - struct ore_io_state *ios; + struct exofs_io_state *ios; int ret; truncate_inode_pages(&inode->i_data, 0); @@ -1350,19 +1349,20 @@ void exofs_evict_inode(struct inode *inode) /* ignore the error, attempt a remove anyway */ /* Now Remove the OSD objects */ - ret = ore_get_io_state(&sbi->layout, &oi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_get_io_state failed\n", __func__); + EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); return; } + ios->obj.id = exofs_oi_objno(oi); ios->done = delete_done; ios->private = sbi; - - ret = ore_remove(ios); + ios->cred = oi->i_cred; + ret = exofs_sbi_remove(ios); if (ret) { - EXOFS_ERR("%s: ore_remove failed\n", __func__); - ore_put_io_state(ios); + EXOFS_ERR("%s: exofs_sbi_remove failed\n", __func__); + exofs_put_io_state(ios); return; } atomic_inc(&sbi->s_curr_pending); diff --git a/trunk/fs/exofs/ore.c b/trunk/fs/exofs/ios.c similarity index 61% rename from trunk/fs/exofs/ore.c rename to trunk/fs/exofs/ios.c index 25305af88198..f74a2ec027a6 100644 --- a/trunk/fs/exofs/ore.c +++ b/trunk/fs/exofs/ios.c @@ -23,87 +23,81 @@ */ #include +#include #include -#include +#include "exofs.h" -#define ORE_ERR(fmt, a...) printk(KERN_ERR "ore: " fmt, ##a) +#define EXOFS_DBGMSG2(M...) do {} while (0) +/* #define EXOFS_DBGMSG2 EXOFS_DBGMSG */ -#ifdef CONFIG_EXOFS_DEBUG -#define ORE_DBGMSG(fmt, a...) \ - printk(KERN_NOTICE "ore @%s:%d: " fmt, __func__, __LINE__, ##a) -#else -#define ORE_DBGMSG(fmt, a...) \ - do { if (0) printk(fmt, ##a); } while (0) -#endif - -/* u64 has problems with printk this will cast it to unsigned long long */ -#define _LLU(x) (unsigned long long)(x) - -#define ORE_DBGMSG2(M...) do {} while (0) -/* #define ORE_DBGMSG2 ORE_DBGMSG */ - -MODULE_AUTHOR("Boaz Harrosh "); -MODULE_DESCRIPTION("Objects Raid Engine ore.ko"); -MODULE_LICENSE("GPL"); - -static u8 *_ios_cred(struct ore_io_state *ios, unsigned index) +void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj) { - return ios->comps->comps[index & ios->comps->single_comp].cred; + osd_sec_init_nosec_doall_caps(cred_a, obj, false, true); } -static struct osd_obj_id *_ios_obj(struct ore_io_state *ios, unsigned index) +int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, + u64 offset, void *p, unsigned length) { - return &ios->comps->comps[index & ios->comps->single_comp].obj; -} + struct osd_request *or = osd_start_request(od, GFP_KERNEL); +/* struct osd_sense_info osi = {.key = 0};*/ + int ret; -static struct osd_dev *_ios_od(struct ore_io_state *ios, unsigned index) -{ - return ios->comps->ods[index]; + if (unlikely(!or)) { + EXOFS_DBGMSG("%s: osd_start_request failed.\n", __func__); + return -ENOMEM; + } + ret = osd_req_read_kern(or, obj, offset, p, length); + if (unlikely(ret)) { + EXOFS_DBGMSG("%s: osd_req_read_kern failed.\n", __func__); + goto out; + } + + ret = osd_finalize_request(or, 0, cred, NULL); + if (unlikely(ret)) { + EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", ret); + goto out; + } + + ret = osd_execute_request(or); + if (unlikely(ret)) + EXOFS_DBGMSG("osd_execute_request() => %d\n", ret); + /* osd_req_decode_sense(or, ret); */ + +out: + osd_end_request(or); + return ret; } -int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, - bool is_reading, u64 offset, u64 length, - struct ore_io_state **pios) +int exofs_get_io_state(struct exofs_layout *layout, + struct exofs_io_state **pios) { - struct ore_io_state *ios; + struct exofs_io_state *ios; /*TODO: Maybe use kmem_cach per sbi of size * exofs_io_state_size(layout->s_numdevs) */ - ios = kzalloc(ore_io_state_size(comps->numdevs), GFP_KERNEL); + ios = kzalloc(exofs_io_state_size(layout->s_numdevs), GFP_KERNEL); if (unlikely(!ios)) { - ORE_DBGMSG("Failed kzalloc bytes=%d\n", - ore_io_state_size(comps->numdevs)); + EXOFS_DBGMSG("Failed kzalloc bytes=%d\n", + exofs_io_state_size(layout->s_numdevs)); *pios = NULL; return -ENOMEM; } ios->layout = layout; - ios->comps = comps; - ios->offset = offset; - ios->length = length; - ios->reading = is_reading; - + ios->obj.partition = layout->s_pid; *pios = ios; return 0; } -EXPORT_SYMBOL(ore_get_rw_state); - -int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps, - struct ore_io_state **ios) -{ - return ore_get_rw_state(layout, comps, true, 0, 0, ios); -} -EXPORT_SYMBOL(ore_get_io_state); -void ore_put_io_state(struct ore_io_state *ios) +void exofs_put_io_state(struct exofs_io_state *ios) { if (ios) { unsigned i; for (i = 0; i < ios->numdevs; i++) { - struct ore_per_dev_state *per_dev = &ios->per_dev[i]; + struct exofs_per_dev_state *per_dev = &ios->per_dev[i]; if (per_dev->or) osd_end_request(per_dev->or); @@ -114,9 +108,31 @@ void ore_put_io_state(struct ore_io_state *ios) kfree(ios); } } -EXPORT_SYMBOL(ore_put_io_state); -static void _sync_done(struct ore_io_state *ios, void *p) +unsigned exofs_layout_od_id(struct exofs_layout *layout, + osd_id obj_no, unsigned layout_index) +{ +/* switch (layout->lay_func) { + case LAYOUT_MOVING_WINDOW: + {*/ + unsigned dev_mod = obj_no; + + return (layout_index + dev_mod * layout->mirrors_p1) % + layout->s_numdevs; +/* } + case LAYOUT_FUNC_IMPLICT: + return layout->devs[layout_index]; + }*/ +} + +static inline struct osd_dev *exofs_ios_od(struct exofs_io_state *ios, + unsigned layout_index) +{ + return ios->layout->s_ods[ + exofs_layout_od_id(ios->layout, ios->obj.id, layout_index)]; +} + +static void _sync_done(struct exofs_io_state *ios, void *p) { struct completion *waiting = p; @@ -125,20 +141,20 @@ static void _sync_done(struct ore_io_state *ios, void *p) static void _last_io(struct kref *kref) { - struct ore_io_state *ios = container_of( - kref, struct ore_io_state, kref); + struct exofs_io_state *ios = container_of( + kref, struct exofs_io_state, kref); ios->done(ios, ios->private); } static void _done_io(struct osd_request *or, void *p) { - struct ore_io_state *ios = p; + struct exofs_io_state *ios = p; kref_put(&ios->kref, _last_io); } -static int ore_io_execute(struct ore_io_state *ios) +static int exofs_io_execute(struct exofs_io_state *ios) { DECLARE_COMPLETION_ONSTACK(wait); bool sync = (ios->done == NULL); @@ -154,9 +170,9 @@ static int ore_io_execute(struct ore_io_state *ios) if (unlikely(!or)) continue; - ret = osd_finalize_request(or, 0, _ios_cred(ios, i), NULL); + ret = osd_finalize_request(or, 0, ios->cred, NULL); if (unlikely(ret)) { - ORE_DBGMSG("Failed to osd_finalize_request() => %d\n", + EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", ret); return ret; } @@ -178,7 +194,7 @@ static int ore_io_execute(struct ore_io_state *ios) if (sync) { wait_for_completion(&wait); - ret = ore_check_io(ios, NULL); + ret = exofs_check_io(ios, NULL); } return ret; } @@ -198,7 +214,7 @@ static void _clear_bio(struct bio *bio) } } -int ore_check_io(struct ore_io_state *ios, u64 *resid) +int exofs_check_io(struct exofs_io_state *ios, u64 *resid) { enum osd_err_priority acumulated_osd_err = 0; int acumulated_lin_err = 0; @@ -219,7 +235,7 @@ int ore_check_io(struct ore_io_state *ios, u64 *resid) if (OSD_ERR_PRI_CLEAR_PAGES == osi.osd_err_pri) { /* start read offset passed endof file */ _clear_bio(ios->per_dev[i].bio); - ORE_DBGMSG("start read offset passed end of file " + EXOFS_DBGMSG("start read offset passed end of file " "offset=0x%llx, length=0x%llx\n", _LLU(ios->per_dev[i].offset), _LLU(ios->per_dev[i].length)); @@ -243,7 +259,6 @@ int ore_check_io(struct ore_io_state *ios, u64 *resid) return acumulated_lin_err; } -EXPORT_SYMBOL(ore_check_io); /* * L - logical offset into the file @@ -290,21 +305,20 @@ EXPORT_SYMBOL(ore_check_io); struct _striping_info { u64 obj_offset; u64 group_length; - u64 M; /* for truncate */ unsigned dev; unsigned unit_off; }; -static void _calc_stripe_info(struct ore_layout *layout, u64 file_offset, +static void _calc_stripe_info(struct exofs_io_state *ios, u64 file_offset, struct _striping_info *si) { - u32 stripe_unit = layout->stripe_unit; - u32 group_width = layout->group_width; - u64 group_depth = layout->group_depth; + u32 stripe_unit = ios->layout->stripe_unit; + u32 group_width = ios->layout->group_width; + u64 group_depth = ios->layout->group_depth; u32 U = stripe_unit * group_width; u64 T = U * group_depth; - u64 S = T * layout->group_count; + u64 S = T * ios->layout->group_count; u64 M = div64_u64(file_offset, S); /* @@ -319,7 +333,7 @@ static void _calc_stripe_info(struct ore_layout *layout, u64 file_offset, /* "H - (N * U)" is just "H % U" so it's bound to u32 */ si->dev = (u32)(H - (N * U)) / stripe_unit + G * group_width; - si->dev *= layout->mirrors_p1; + si->dev *= ios->layout->mirrors_p1; div_u64_rem(file_offset, stripe_unit, &si->unit_off); @@ -327,16 +341,15 @@ static void _calc_stripe_info(struct ore_layout *layout, u64 file_offset, (M * group_depth * stripe_unit); si->group_length = T - H; - si->M = M; } -static int _add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, - unsigned pgbase, struct ore_per_dev_state *per_dev, +static int _add_stripe_unit(struct exofs_io_state *ios, unsigned *cur_pg, + unsigned pgbase, struct exofs_per_dev_state *per_dev, int cur_len) { unsigned pg = *cur_pg; struct request_queue *q = - osd_request_queue(_ios_od(ios, per_dev->dev)); + osd_request_queue(exofs_ios_od(ios, per_dev->dev)); per_dev->length += cur_len; @@ -348,7 +361,7 @@ static int _add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, per_dev->bio = bio_kmalloc(GFP_KERNEL, bio_size); if (unlikely(!per_dev->bio)) { - ORE_DBGMSG("Failed to allocate BIO size=%u\n", + EXOFS_DBGMSG("Failed to allocate BIO size=%u\n", bio_size); return -ENOMEM; } @@ -374,7 +387,7 @@ static int _add_stripe_unit(struct ore_io_state *ios, unsigned *cur_pg, return 0; } -static int _prepare_one_group(struct ore_io_state *ios, u64 length, +static int _prepare_one_group(struct exofs_io_state *ios, u64 length, struct _striping_info *si) { unsigned stripe_unit = ios->layout->stripe_unit; @@ -387,7 +400,7 @@ static int _prepare_one_group(struct ore_io_state *ios, u64 length, int ret = 0; while (length) { - struct ore_per_dev_state *per_dev = &ios->per_dev[dev]; + struct exofs_per_dev_state *per_dev = &ios->per_dev[dev]; unsigned cur_len, page_off = 0; if (!per_dev->length) { @@ -430,7 +443,7 @@ static int _prepare_one_group(struct ore_io_state *ios, u64 length, return ret; } -static int _prepare_for_striping(struct ore_io_state *ios) +static int _prepare_for_striping(struct exofs_io_state *ios) { u64 length = ios->length; u64 offset = ios->offset; @@ -439,9 +452,9 @@ static int _prepare_for_striping(struct ore_io_state *ios) if (!ios->pages) { if (ios->kern_buff) { - struct ore_per_dev_state *per_dev = &ios->per_dev[0]; + struct exofs_per_dev_state *per_dev = &ios->per_dev[0]; - _calc_stripe_info(ios->layout, ios->offset, &si); + _calc_stripe_info(ios, ios->offset, &si); per_dev->offset = si.obj_offset; per_dev->dev = si.dev; @@ -455,7 +468,7 @@ static int _prepare_for_striping(struct ore_io_state *ios) } while (length) { - _calc_stripe_info(ios->layout, offset, &si); + _calc_stripe_info(ios, offset, &si); if (length < si.group_length) si.group_length = length; @@ -472,59 +485,57 @@ static int _prepare_for_striping(struct ore_io_state *ios) return ret; } -int ore_create(struct ore_io_state *ios) +int exofs_sbi_create(struct exofs_io_state *ios) { int i, ret; - for (i = 0; i < ios->comps->numdevs; i++) { + for (i = 0; i < ios->layout->s_numdevs; i++) { struct osd_request *or; - or = osd_start_request(_ios_od(ios, i), GFP_KERNEL); + or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); if (unlikely(!or)) { - ORE_ERR("%s: osd_start_request failed\n", __func__); + EXOFS_ERR("%s: osd_start_request failed\n", __func__); ret = -ENOMEM; goto out; } ios->per_dev[i].or = or; ios->numdevs++; - osd_req_create_object(or, _ios_obj(ios, i)); + osd_req_create_object(or, &ios->obj); } - ret = ore_io_execute(ios); + ret = exofs_io_execute(ios); out: return ret; } -EXPORT_SYMBOL(ore_create); -int ore_remove(struct ore_io_state *ios) +int exofs_sbi_remove(struct exofs_io_state *ios) { int i, ret; - for (i = 0; i < ios->comps->numdevs; i++) { + for (i = 0; i < ios->layout->s_numdevs; i++) { struct osd_request *or; - or = osd_start_request(_ios_od(ios, i), GFP_KERNEL); + or = osd_start_request(exofs_ios_od(ios, i), GFP_KERNEL); if (unlikely(!or)) { - ORE_ERR("%s: osd_start_request failed\n", __func__); + EXOFS_ERR("%s: osd_start_request failed\n", __func__); ret = -ENOMEM; goto out; } ios->per_dev[i].or = or; ios->numdevs++; - osd_req_remove_object(or, _ios_obj(ios, i)); + osd_req_remove_object(or, &ios->obj); } - ret = ore_io_execute(ios); + ret = exofs_io_execute(ios); out: return ret; } -EXPORT_SYMBOL(ore_remove); -static int _write_mirror(struct ore_io_state *ios, int cur_comp) +static int _sbi_write_mirror(struct exofs_io_state *ios, int cur_comp) { - struct ore_per_dev_state *master_dev = &ios->per_dev[cur_comp]; + struct exofs_per_dev_state *master_dev = &ios->per_dev[cur_comp]; unsigned dev = ios->per_dev[cur_comp].dev; unsigned last_comp = cur_comp + ios->layout->mirrors_p1; int ret = 0; @@ -533,12 +544,12 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) return 0; /* Just an empty slot */ for (; cur_comp < last_comp; ++cur_comp, ++dev) { - struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp]; + struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; struct osd_request *or; - or = osd_start_request(_ios_od(ios, dev), GFP_KERNEL); + or = osd_start_request(exofs_ios_od(ios, dev), GFP_KERNEL); if (unlikely(!or)) { - ORE_ERR("%s: osd_start_request failed\n", __func__); + EXOFS_ERR("%s: osd_start_request failed\n", __func__); ret = -ENOMEM; goto out; } @@ -552,7 +563,7 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) bio = bio_kmalloc(GFP_KERNEL, master_dev->bio->bi_max_vecs); if (unlikely(!bio)) { - ORE_DBGMSG( + EXOFS_DBGMSG( "Failed to allocate BIO size=%u\n", master_dev->bio->bi_max_vecs); ret = -ENOMEM; @@ -571,29 +582,25 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) bio->bi_rw |= REQ_WRITE; } - osd_req_write(or, _ios_obj(ios, dev), per_dev->offset, - bio, per_dev->length); - ORE_DBGMSG("write(0x%llx) offset=0x%llx " + osd_req_write(or, &ios->obj, per_dev->offset, bio, + per_dev->length); + EXOFS_DBGMSG("write(0x%llx) offset=0x%llx " "length=0x%llx dev=%d\n", - _LLU(_ios_obj(ios, dev)->id), - _LLU(per_dev->offset), + _LLU(ios->obj.id), _LLU(per_dev->offset), _LLU(per_dev->length), dev); } else if (ios->kern_buff) { - ret = osd_req_write_kern(or, _ios_obj(ios, dev), - per_dev->offset, - ios->kern_buff, ios->length); + ret = osd_req_write_kern(or, &ios->obj, per_dev->offset, + ios->kern_buff, ios->length); if (unlikely(ret)) goto out; - ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " + EXOFS_DBGMSG2("write_kern(0x%llx) offset=0x%llx " "length=0x%llx dev=%d\n", - _LLU(_ios_obj(ios, dev)->id), - _LLU(per_dev->offset), + _LLU(ios->obj.id), _LLU(per_dev->offset), _LLU(ios->length), dev); } else { - osd_req_set_attributes(or, _ios_obj(ios, dev)); - ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", - _LLU(_ios_obj(ios, dev)->id), - ios->out_attr_len, dev); + osd_req_set_attributes(or, &ios->obj); + EXOFS_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", + _LLU(ios->obj.id), ios->out_attr_len, dev); } if (ios->out_attr) @@ -609,7 +616,7 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) return ret; } -int ore_write(struct ore_io_state *ios) +int exofs_sbi_write(struct exofs_io_state *ios) { int i; int ret; @@ -619,55 +626,52 @@ int ore_write(struct ore_io_state *ios) return ret; for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { - ret = _write_mirror(ios, i); + ret = _sbi_write_mirror(ios, i); if (unlikely(ret)) return ret; } - ret = ore_io_execute(ios); + ret = exofs_io_execute(ios); return ret; } -EXPORT_SYMBOL(ore_write); -static int _read_mirror(struct ore_io_state *ios, unsigned cur_comp) +static int _sbi_read_mirror(struct exofs_io_state *ios, unsigned cur_comp) { struct osd_request *or; - struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp]; - struct osd_obj_id *obj = _ios_obj(ios, cur_comp); - unsigned first_dev = (unsigned)obj->id; + struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; + unsigned first_dev = (unsigned)ios->obj.id; if (ios->pages && !per_dev->length) return 0; /* Just an empty slot */ first_dev = per_dev->dev + first_dev % ios->layout->mirrors_p1; - or = osd_start_request(_ios_od(ios, first_dev), GFP_KERNEL); + or = osd_start_request(exofs_ios_od(ios, first_dev), GFP_KERNEL); if (unlikely(!or)) { - ORE_ERR("%s: osd_start_request failed\n", __func__); + EXOFS_ERR("%s: osd_start_request failed\n", __func__); return -ENOMEM; } per_dev->or = or; if (ios->pages) { - osd_req_read(or, obj, per_dev->offset, + osd_req_read(or, &ios->obj, per_dev->offset, per_dev->bio, per_dev->length); - ORE_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx" - " dev=%d\n", _LLU(obj->id), + EXOFS_DBGMSG("read(0x%llx) offset=0x%llx length=0x%llx" + " dev=%d\n", _LLU(ios->obj.id), _LLU(per_dev->offset), _LLU(per_dev->length), first_dev); } else if (ios->kern_buff) { - int ret = osd_req_read_kern(or, obj, per_dev->offset, + int ret = osd_req_read_kern(or, &ios->obj, per_dev->offset, ios->kern_buff, ios->length); - ORE_DBGMSG2("read_kern(0x%llx) offset=0x%llx " + EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx " "length=0x%llx dev=%d ret=>%d\n", - _LLU(obj->id), _LLU(per_dev->offset), + _LLU(ios->obj.id), _LLU(per_dev->offset), _LLU(ios->length), first_dev, ret); if (unlikely(ret)) return ret; } else { - osd_req_get_attributes(or, obj); - ORE_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n", - _LLU(obj->id), - ios->in_attr_len, first_dev); + osd_req_get_attributes(or, &ios->obj); + EXOFS_DBGMSG2("obj(0x%llx) get_attributes=%d dev=%d\n", + _LLU(ios->obj.id), ios->in_attr_len, first_dev); } if (ios->out_attr) osd_req_add_set_attr_list(or, ios->out_attr, ios->out_attr_len); @@ -678,7 +682,7 @@ static int _read_mirror(struct ore_io_state *ios, unsigned cur_comp) return 0; } -int ore_read(struct ore_io_state *ios) +int exofs_sbi_read(struct exofs_io_state *ios) { int i; int ret; @@ -688,17 +692,16 @@ int ore_read(struct ore_io_state *ios) return ret; for (i = 0; i < ios->numdevs; i += ios->layout->mirrors_p1) { - ret = _read_mirror(ios, i); + ret = _sbi_read_mirror(ios, i); if (unlikely(ret)) return ret; } - ret = ore_io_execute(ios); + ret = exofs_io_execute(ios); return ret; } -EXPORT_SYMBOL(ore_read); -int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr) +int extract_attr_from_ios(struct exofs_io_state *ios, struct osd_attr *attr) { struct osd_attr cur_attr = {.attr_page = 0}; /* start with zeros */ void *iter = NULL; @@ -718,118 +721,83 @@ int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr) return -EIO; } -EXPORT_SYMBOL(extract_attr_from_ios); -static int _truncate_mirrors(struct ore_io_state *ios, unsigned cur_comp, +static int _truncate_mirrors(struct exofs_io_state *ios, unsigned cur_comp, struct osd_attr *attr) { int last_comp = cur_comp + ios->layout->mirrors_p1; for (; cur_comp < last_comp; ++cur_comp) { - struct ore_per_dev_state *per_dev = &ios->per_dev[cur_comp]; + struct exofs_per_dev_state *per_dev = &ios->per_dev[cur_comp]; struct osd_request *or; - or = osd_start_request(_ios_od(ios, cur_comp), GFP_KERNEL); + or = osd_start_request(exofs_ios_od(ios, cur_comp), GFP_KERNEL); if (unlikely(!or)) { - ORE_ERR("%s: osd_start_request failed\n", __func__); + EXOFS_ERR("%s: osd_start_request failed\n", __func__); return -ENOMEM; } per_dev->or = or; - osd_req_set_attributes(or, _ios_obj(ios, cur_comp)); + osd_req_set_attributes(or, &ios->obj); osd_req_add_set_attr_list(or, attr, 1); } return 0; } -struct _trunc_info { - struct _striping_info si; - u64 prev_group_obj_off; - u64 next_group_obj_off; - - unsigned first_group_dev; - unsigned nex_group_dev; - unsigned max_devs; -}; - -void _calc_trunk_info(struct ore_layout *layout, u64 file_offset, - struct _trunc_info *ti) -{ - unsigned stripe_unit = layout->stripe_unit; - - _calc_stripe_info(layout, file_offset, &ti->si); - - ti->prev_group_obj_off = ti->si.M * stripe_unit; - ti->next_group_obj_off = ti->si.M ? (ti->si.M - 1) * stripe_unit : 0; - - ti->first_group_dev = ti->si.dev - (ti->si.dev % layout->group_width); - ti->nex_group_dev = ti->first_group_dev + layout->group_width; - ti->max_devs = layout->group_width * layout->group_count; -} - -int ore_truncate(struct ore_layout *layout, struct ore_components *comps, - u64 size) +int exofs_oi_truncate(struct exofs_i_info *oi, u64 size) { - struct ore_io_state *ios; + struct exofs_sb_info *sbi = oi->vfs_inode.i_sb->s_fs_info; + struct exofs_io_state *ios; struct exofs_trunc_attr { struct osd_attr attr; __be64 newsize; } *size_attrs; - struct _trunc_info ti; + struct _striping_info si; int i, ret; - ret = ore_get_io_state(layout, comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) return ret; - _calc_trunk_info(ios->layout, size, &ti); - - size_attrs = kcalloc(ti.max_devs, sizeof(*size_attrs), + size_attrs = kcalloc(ios->layout->group_width, sizeof(*size_attrs), GFP_KERNEL); if (unlikely(!size_attrs)) { ret = -ENOMEM; goto out; } - ios->numdevs = ios->comps->numdevs; + ios->obj.id = exofs_oi_objno(oi); + ios->cred = oi->i_cred; - for (i = 0; i < ti.max_devs; ++i) { + ios->numdevs = ios->layout->s_numdevs; + _calc_stripe_info(ios, size, &si); + + for (i = 0; i < ios->layout->group_width; ++i) { struct exofs_trunc_attr *size_attr = &size_attrs[i]; u64 obj_size; - if (i < ti.first_group_dev) - obj_size = ti.prev_group_obj_off; - else if (i >= ti.nex_group_dev) - obj_size = ti.next_group_obj_off; - else if (i < ti.si.dev) /* dev within this group */ - obj_size = ti.si.obj_offset + - ios->layout->stripe_unit - ti.si.unit_off; - else if (i == ti.si.dev) - obj_size = ti.si.obj_offset; - else /* i > ti.dev */ - obj_size = ti.si.obj_offset - ti.si.unit_off; + if (i < si.dev) + obj_size = si.obj_offset + + ios->layout->stripe_unit - si.unit_off; + else if (i == si.dev) + obj_size = si.obj_offset; + else /* i > si.dev */ + obj_size = si.obj_offset - si.unit_off; size_attr->newsize = cpu_to_be64(obj_size); size_attr->attr = g_attr_logical_length; size_attr->attr.val_ptr = &size_attr->newsize; - ORE_DBGMSG("trunc(0x%llx) obj_offset=0x%llx dev=%d\n", - _LLU(comps->comps->obj.id), _LLU(obj_size), i); ret = _truncate_mirrors(ios, i * ios->layout->mirrors_p1, &size_attr->attr); if (unlikely(ret)) goto out; } - ret = ore_io_execute(ios); + ret = exofs_io_execute(ios); out: kfree(size_attrs); - ore_put_io_state(ios); + exofs_put_io_state(ios); return ret; } -EXPORT_SYMBOL(ore_truncate); - -const struct osd_attr g_attr_logical_length = ATTR_DEF( - OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); -EXPORT_SYMBOL(g_attr_logical_length); diff --git a/trunk/fs/exofs/pnfs.h b/trunk/fs/exofs/pnfs.h new file mode 100644 index 000000000000..c52e9888b8ab --- /dev/null +++ b/trunk/fs/exofs/pnfs.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008, 2009 + * Boaz Harrosh + * + * This file is part of exofs. + * + * exofs is free software; you can redistribute it and/or modify it under the + * terms of the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + */ + +/* FIXME: Remove this file once pnfs hits mainline */ + +#ifndef __EXOFS_PNFS_H__ +#define __EXOFS_PNFS_H__ + +#if ! defined(__PNFS_OSD_XDR_H__) + +enum pnfs_iomode { + IOMODE_READ = 1, + IOMODE_RW = 2, + IOMODE_ANY = 3, +}; + +/* Layout Structure */ +enum pnfs_osd_raid_algorithm4 { + PNFS_OSD_RAID_0 = 1, + PNFS_OSD_RAID_4 = 2, + PNFS_OSD_RAID_5 = 3, + PNFS_OSD_RAID_PQ = 4 /* Reed-Solomon P+Q */ +}; + +struct pnfs_osd_data_map { + u32 odm_num_comps; + u64 odm_stripe_unit; + u32 odm_group_width; + u32 odm_group_depth; + u32 odm_mirror_cnt; + u32 odm_raid_algorithm; +}; + +#endif /* ! defined(__PNFS_OSD_XDR_H__) */ + +#endif /* __EXOFS_PNFS_H__ */ diff --git a/trunk/fs/exofs/super.c b/trunk/fs/exofs/super.c index 274894053b02..c57beddcc217 100644 --- a/trunk/fs/exofs/super.c +++ b/trunk/fs/exofs/super.c @@ -40,8 +40,6 @@ #include "exofs.h" -#define EXOFS_DBGMSG2(M...) do {} while (0) - /****************************************************************************** * MOUNT OPTIONS *****************************************************************************/ @@ -210,48 +208,10 @@ static void destroy_inodecache(void) } /****************************************************************************** - * Some osd helpers + * SUPERBLOCK FUNCTIONS *****************************************************************************/ -void exofs_make_credential(u8 cred_a[OSD_CAP_LEN], const struct osd_obj_id *obj) -{ - osd_sec_init_nosec_doall_caps(cred_a, obj, false, true); -} - -static int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj, - u64 offset, void *p, unsigned length) -{ - struct osd_request *or = osd_start_request(od, GFP_KERNEL); -/* struct osd_sense_info osi = {.key = 0};*/ - int ret; - - if (unlikely(!or)) { - EXOFS_DBGMSG("%s: osd_start_request failed.\n", __func__); - return -ENOMEM; - } - ret = osd_req_read_kern(or, obj, offset, p, length); - if (unlikely(ret)) { - EXOFS_DBGMSG("%s: osd_req_read_kern failed.\n", __func__); - goto out; - } - - ret = osd_finalize_request(or, 0, cred, NULL); - if (unlikely(ret)) { - EXOFS_DBGMSG("Failed to osd_finalize_request() => %d\n", ret); - goto out; - } - - ret = osd_execute_request(or); - if (unlikely(ret)) - EXOFS_DBGMSG("osd_execute_request() => %d\n", ret); - /* osd_req_decode_sense(or, ret); */ - -out: - osd_end_request(or); - EXOFS_DBGMSG2("read_kern(0x%llx) offset=0x%llx " - "length=0x%llx dev=%p ret=>%d\n", - _LLU(obj->id), _LLU(offset), _LLU(length), od, ret); - return ret; -} +static const struct super_operations exofs_sops; +static const struct export_operations exofs_export_ops; static const struct osd_attr g_attr_sb_stats = ATTR_DEF( EXOFS_APAGE_SB_DATA, @@ -263,19 +223,21 @@ static int __sbi_read_stats(struct exofs_sb_info *sbi) struct osd_attr attrs[] = { [0] = g_attr_sb_stats, }; - struct ore_io_state *ios; + struct exofs_io_state *ios; int ret; - ret = ore_get_io_state(&sbi->layout, &sbi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__); + EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); return ret; } + ios->cred = sbi->s_cred; + ios->in_attr = attrs; ios->in_attr_len = ARRAY_SIZE(attrs); - ret = ore_read(ios); + ret = exofs_sbi_read(ios); if (unlikely(ret)) { EXOFS_ERR("Error reading super_block stats => %d\n", ret); goto out; @@ -302,13 +264,13 @@ static int __sbi_read_stats(struct exofs_sb_info *sbi) } out: - ore_put_io_state(ios); + exofs_put_io_state(ios); return ret; } -static void stats_done(struct ore_io_state *ios, void *p) +static void stats_done(struct exofs_io_state *ios, void *p) { - ore_put_io_state(ios); + exofs_put_io_state(ios); /* Good thanks nothing to do anymore */ } @@ -318,12 +280,12 @@ int exofs_sbi_write_stats(struct exofs_sb_info *sbi) struct osd_attr attrs[] = { [0] = g_attr_sb_stats, }; - struct ore_io_state *ios; + struct exofs_io_state *ios; int ret; - ret = ore_get_io_state(&sbi->layout, &sbi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__); + EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); return ret; } @@ -331,27 +293,21 @@ int exofs_sbi_write_stats(struct exofs_sb_info *sbi) sbi->s_ess.s_numfiles = cpu_to_le64(sbi->s_numfiles); attrs[0].val_ptr = &sbi->s_ess; - + ios->cred = sbi->s_cred; ios->done = stats_done; ios->private = sbi; ios->out_attr = attrs; ios->out_attr_len = ARRAY_SIZE(attrs); - ret = ore_write(ios); + ret = exofs_sbi_write(ios); if (unlikely(ret)) { - EXOFS_ERR("%s: ore_write failed.\n", __func__); - ore_put_io_state(ios); + EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__); + exofs_put_io_state(ios); } return ret; } -/****************************************************************************** - * SUPERBLOCK FUNCTIONS - *****************************************************************************/ -static const struct super_operations exofs_sops; -static const struct export_operations exofs_export_ops; - /* * Write the superblock to the OSD */ @@ -359,9 +315,7 @@ int exofs_sync_fs(struct super_block *sb, int wait) { struct exofs_sb_info *sbi; struct exofs_fscb *fscb; - struct ore_comp one_comp; - struct ore_components comps; - struct ore_io_state *ios; + struct exofs_io_state *ios; int ret = -ENOMEM; fscb = kmalloc(sizeof(*fscb), GFP_KERNEL); @@ -377,10 +331,7 @@ int exofs_sync_fs(struct super_block *sb, int wait) * version). Otherwise the exofs_fscb is read-only from mkfs time. All * the writeable info is set in exofs_sbi_write_stats() above. */ - - exofs_init_comps(&comps, &one_comp, sbi, EXOFS_SUPER_ID); - - ret = ore_get_io_state(&sbi->layout, &comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (unlikely(ret)) goto out; @@ -394,12 +345,14 @@ int exofs_sync_fs(struct super_block *sb, int wait) fscb->s_newfs = 0; fscb->s_version = EXOFS_FSCB_VER; + ios->obj.id = EXOFS_SUPER_ID; ios->offset = 0; ios->kern_buff = fscb; + ios->cred = sbi->s_cred; - ret = ore_write(ios); + ret = exofs_sbi_write(ios); if (unlikely(ret)) - EXOFS_ERR("%s: ore_write failed.\n", __func__); + EXOFS_ERR("%s: exofs_sbi_write failed.\n", __func__); else sb->s_dirt = 0; @@ -407,7 +360,7 @@ int exofs_sync_fs(struct super_block *sb, int wait) unlock_super(sb); out: EXOFS_DBGMSG("s_nextid=0x%llx ret=%d\n", _LLU(sbi->s_nextid), ret); - ore_put_io_state(ios); + exofs_put_io_state(ios); kfree(fscb); return ret; } @@ -431,17 +384,15 @@ static void _exofs_print_device(const char *msg, const char *dev_path, void exofs_free_sbi(struct exofs_sb_info *sbi) { - while (sbi->comps.numdevs) { - int i = --sbi->comps.numdevs; - struct osd_dev *od = sbi->comps.ods[i]; + while (sbi->layout.s_numdevs) { + int i = --sbi->layout.s_numdevs; + struct osd_dev *od = sbi->layout.s_ods[i]; if (od) { - sbi->comps.ods[i] = NULL; + sbi->layout.s_ods[i] = NULL; osduld_put_device(od); } } - if (sbi->comps.ods != sbi->_min_one_dev) - kfree(sbi->comps.ods); kfree(sbi); } @@ -468,8 +419,8 @@ static void exofs_put_super(struct super_block *sb) msecs_to_jiffies(100)); } - _exofs_print_device("Unmounting", NULL, sbi->comps.ods[0], - sbi->one_comp.obj.partition); + _exofs_print_device("Unmounting", NULL, sbi->layout.s_ods[0], + sbi->layout.s_pid); bdi_destroy(&sbi->bdi); exofs_free_sbi(sbi); @@ -550,19 +501,10 @@ static int _read_and_match_data_map(struct exofs_sb_info *sbi, unsigned numdevs, return -EINVAL; } - EXOFS_DBGMSG("exofs: layout: " - "num_comps=%u stripe_unit=0x%x group_width=%u " - "group_depth=0x%llx mirrors_p1=%u raid_algorithm=%u\n", - numdevs, - sbi->layout.stripe_unit, - sbi->layout.group_width, - _LLU(sbi->layout.group_depth), - sbi->layout.mirrors_p1, - sbi->data_map.odm_raid_algorithm); return 0; } -static unsigned __ra_pages(struct ore_layout *layout) +static unsigned __ra_pages(struct exofs_layout *layout) { const unsigned _MIN_RA = 32; /* min 128K read-ahead */ unsigned ra_pages = layout->group_width * layout->stripe_unit / @@ -605,11 +547,13 @@ static int exofs_devs_2_odi(struct exofs_dt_device_info *dt_dev, return !(odi->systemid_len || odi->osdname_len); } -static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, - struct osd_dev *fscb_od, +static int exofs_read_lookup_dev_table(struct exofs_sb_info **psbi, unsigned table_count) { - struct ore_comp comp; + struct exofs_sb_info *sbi = *psbi; + struct osd_dev *fscb_od; + struct osd_obj_id obj = {.partition = sbi->layout.s_pid, + .id = EXOFS_DEVTABLE_ID}; struct exofs_device_table *dt; unsigned table_bytes = table_count * sizeof(dt->dt_dev_table[0]) + sizeof(*dt); @@ -623,14 +567,10 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, return -ENOMEM; } - sbi->comps.numdevs = 0; - - comp.obj.partition = sbi->one_comp.obj.partition; - comp.obj.id = EXOFS_DEVTABLE_ID; - exofs_make_credential(comp.cred, &comp.obj); - - ret = exofs_read_kern(fscb_od, comp.cred, &comp.obj, 0, dt, - table_bytes); + fscb_od = sbi->layout.s_ods[0]; + sbi->layout.s_ods[0] = NULL; + sbi->layout.s_numdevs = 0; + ret = exofs_read_kern(fscb_od, sbi->s_cred, &obj, 0, dt, table_bytes); if (unlikely(ret)) { EXOFS_ERR("ERROR: reading device table\n"); goto out; @@ -648,18 +588,16 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, goto out; if (likely(numdevs > 1)) { - unsigned size = numdevs * sizeof(sbi->comps.ods[0]); + unsigned size = numdevs * sizeof(sbi->layout.s_ods[0]); - /* Twice bigger table: See exofs_init_comps() and below - * comment - */ - sbi->comps.ods = kzalloc(size + size - 1, GFP_KERNEL); - if (unlikely(!sbi->comps.ods)) { - EXOFS_ERR("ERROR: faild allocating Device array[%d]\n", - numdevs); + sbi = krealloc(sbi, sizeof(*sbi) + size, GFP_KERNEL); + if (unlikely(!sbi)) { ret = -ENOMEM; goto out; } + memset(&sbi->layout.s_ods[1], 0, + size - sizeof(sbi->layout.s_ods[0])); + *psbi = sbi; } for (i = 0; i < numdevs; i++) { @@ -681,8 +619,8 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, * line. We always keep them in device-table order. */ if (fscb_od && osduld_device_same(fscb_od, &odi)) { - sbi->comps.ods[i] = fscb_od; - ++sbi->comps.numdevs; + sbi->layout.s_ods[i] = fscb_od; + ++sbi->layout.s_numdevs; fscb_od = NULL; continue; } @@ -695,13 +633,13 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, goto out; } - sbi->comps.ods[i] = od; - ++sbi->comps.numdevs; + sbi->layout.s_ods[i] = od; + ++sbi->layout.s_numdevs; /* Read the fscb of the other devices to make sure the FS * partition is there. */ - ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb, + ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb)); if (unlikely(ret)) { EXOFS_ERR("ERROR: Malformed participating device " @@ -718,22 +656,13 @@ static int exofs_read_lookup_dev_table(struct exofs_sb_info *sbi, out: kfree(dt); - if (likely(!ret)) { - unsigned numdevs = sbi->comps.numdevs; - - if (unlikely(fscb_od)) { - EXOFS_ERR("ERROR: Bad device-table container device not present\n"); - osduld_put_device(fscb_od); - return -EINVAL; - } - /* exofs round-robins the device table view according to inode - * number. We hold a: twice bigger table hence inodes can point - * to any device and have a sequential view of the table - * starting at this device. See exofs_init_comps() - */ - for (i = 0; i < numdevs - 1; ++i) - sbi->comps.ods[i + numdevs] = sbi->comps.ods[i]; + if (unlikely(!ret && fscb_od)) { + EXOFS_ERR( + "ERROR: Bad device-table container device not present\n"); + osduld_put_device(fscb_od); + ret = -EINVAL; } + return ret; } @@ -747,7 +676,7 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) struct exofs_sb_info *sbi; /*extended info */ struct osd_dev *od; /* Master device */ struct exofs_fscb fscb; /*on-disk superblock info */ - struct ore_comp comp; + struct osd_obj_id obj; unsigned table_count; int ret; @@ -755,6 +684,10 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) if (!sbi) return -ENOMEM; + ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY); + if (ret) + goto free_bdi; + /* use mount options to fill superblock */ if (opts->is_osdname) { struct osd_dev_info odi = {.systemid_len = 0}; @@ -762,8 +695,6 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) odi.osdname_len = strlen(opts->dev_name); odi.osdname = (u8 *)opts->dev_name; od = osduld_info_lookup(&odi); - kfree(opts->dev_name); - opts->dev_name = NULL; } else { od = osduld_path_lookup(opts->dev_name); } @@ -778,16 +709,11 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) sbi->layout.group_width = 1; sbi->layout.group_depth = -1; sbi->layout.group_count = 1; + sbi->layout.s_ods[0] = od; + sbi->layout.s_numdevs = 1; + sbi->layout.s_pid = opts->pid; sbi->s_timeout = opts->timeout; - sbi->one_comp.obj.partition = opts->pid; - sbi->one_comp.obj.id = 0; - exofs_make_credential(sbi->one_comp.cred, &sbi->one_comp.obj); - sbi->comps.numdevs = 1; - sbi->comps.single_comp = EC_SINGLE_COMP; - sbi->comps.comps = &sbi->one_comp; - sbi->comps.ods = sbi->_min_one_dev; - /* fill in some other data by hand */ memset(sb->s_id, 0, sizeof(sb->s_id)); strcpy(sb->s_id, "exofs"); @@ -798,11 +724,11 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) sb->s_bdev = NULL; sb->s_dev = 0; - comp.obj.partition = sbi->one_comp.obj.partition; - comp.obj.id = EXOFS_SUPER_ID; - exofs_make_credential(comp.cred, &comp.obj); + obj.partition = sbi->layout.s_pid; + obj.id = EXOFS_SUPER_ID; + exofs_make_credential(sbi->s_cred, &obj); - ret = exofs_read_kern(od, comp.cred, &comp.obj, 0, &fscb, sizeof(fscb)); + ret = exofs_read_kern(od, sbi->s_cred, &obj, 0, &fscb, sizeof(fscb)); if (unlikely(ret)) goto free_sbi; @@ -831,11 +757,9 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) table_count = le64_to_cpu(fscb.s_dev_table_count); if (table_count) { - ret = exofs_read_lookup_dev_table(sbi, od, table_count); + ret = exofs_read_lookup_dev_table(&sbi, table_count); if (unlikely(ret)) goto free_sbi; - } else { - sbi->comps.ods[0] = od; } __sbi_read_stats(sbi); @@ -869,20 +793,20 @@ static int exofs_fill_super(struct super_block *sb, void *data, int silent) goto free_sbi; } - ret = bdi_setup_and_register(&sbi->bdi, "exofs", BDI_CAP_MAP_COPY); - if (ret) { - EXOFS_DBGMSG("Failed to bdi_setup_and_register\n"); - goto free_sbi; - } - - _exofs_print_device("Mounting", opts->dev_name, sbi->comps.ods[0], - sbi->one_comp.obj.partition); + _exofs_print_device("Mounting", opts->dev_name, sbi->layout.s_ods[0], + sbi->layout.s_pid); + if (opts->is_osdname) + kfree(opts->dev_name); return 0; free_sbi: + bdi_destroy(&sbi->bdi); +free_bdi: EXOFS_ERR("Unable to mount exofs on %s pid=0x%llx err=%d\n", - opts->dev_name, sbi->one_comp.obj.partition, ret); + opts->dev_name, sbi->layout.s_pid, ret); exofs_free_sbi(sbi); + if (opts->is_osdname) + kfree(opts->dev_name); return ret; } @@ -913,7 +837,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf) { struct super_block *sb = dentry->d_sb; struct exofs_sb_info *sbi = sb->s_fs_info; - struct ore_io_state *ios; + struct exofs_io_state *ios; struct osd_attr attrs[] = { ATTR_DEF(OSD_APAGE_PARTITION_QUOTAS, OSD_ATTR_PQ_CAPACITY_QUOTA, sizeof(__be64)), @@ -922,18 +846,21 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf) }; uint64_t capacity = ULLONG_MAX; uint64_t used = ULLONG_MAX; + uint8_t cred_a[OSD_CAP_LEN]; int ret; - ret = ore_get_io_state(&sbi->layout, &sbi->comps, &ios); + ret = exofs_get_io_state(&sbi->layout, &ios); if (ret) { - EXOFS_DBGMSG("ore_get_io_state failed.\n"); + EXOFS_DBGMSG("exofs_get_io_state failed.\n"); return ret; } + exofs_make_credential(cred_a, &ios->obj); + ios->cred = sbi->s_cred; ios->in_attr = attrs; ios->in_attr_len = ARRAY_SIZE(attrs); - ret = ore_read(ios); + ret = exofs_sbi_read(ios); if (unlikely(ret)) goto out; @@ -962,7 +889,7 @@ static int exofs_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_namelen = EXOFS_NAME_LEN; out: - ore_put_io_state(ios); + exofs_put_io_state(ios); return ret; } diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index 5571708b6a58..6e18a0b7750d 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -2209,11 +2209,9 @@ static int ext3_symlink (struct inode * dir, /* * For non-fast symlinks, we just allocate inode and put it on * orphan list in the first transaction => we need bitmap, - * group descriptor, sb, inode block, quota blocks, and - * possibly selinux xattr blocks. + * group descriptor, sb, inode block, quota blocks. */ - credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + - EXT3_XATTR_TRANS_BLOCKS; + credits = 4 + EXT3_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); } else { /* * Fast symlink. We have to add entry to directory diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index f8068c7bae9f..565a154e22d4 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -2253,11 +2253,9 @@ static int ext4_symlink(struct inode *dir, /* * For non-fast symlinks, we just allocate inode and put it on * orphan list in the first transaction => we need bitmap, - * group descriptor, sb, inode block, quota blocks, and - * possibly selinux xattr blocks. + * group descriptor, sb, inode block, quota blocks. */ - credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb) + - EXT4_XATTR_TRANS_BLOCKS; + credits = 4 + EXT4_MAXQUOTAS_INIT_BLOCKS(dir->i_sb); } else { /* * Fast symlink. We have to add entry to directory diff --git a/trunk/fs/ext4/super.c b/trunk/fs/ext4/super.c index 4687fea0c00f..e2d88baf91d3 100644 --- a/trunk/fs/ext4/super.c +++ b/trunk/fs/ext4/super.c @@ -124,7 +124,7 @@ void *ext4_kvzalloc(size_t size, gfp_t flags) { void *ret; - ret = kzalloc(size, flags); + ret = kmalloc(size, flags); if (!ret) ret = __vmalloc(size, flags | __GFP_ZERO, PAGE_KERNEL); return ret; diff --git a/trunk/fs/inode.c b/trunk/fs/inode.c index 73920d555c88..5aab80dc008c 100644 --- a/trunk/fs/inode.c +++ b/trunk/fs/inode.c @@ -143,7 +143,6 @@ int inode_init_always(struct super_block *sb, struct inode *inode) inode->i_op = &empty_iops; inode->i_fop = &empty_fops; inode->i_nlink = 1; - inode->i_opflags = 0; inode->i_uid = 0; inode->i_gid = 0; atomic_set(&inode->i_writecount, 0); diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index 2826db35dc25..445fd5da11fa 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -179,14 +179,19 @@ static int check_acl(struct inode *inode, int mask) #ifdef CONFIG_FS_POSIX_ACL struct posix_acl *acl; + /* + * Under RCU walk, we cannot even do a "get_cached_acl()", + * because that involves locking and getting a refcount on + * a cached ACL. + * + * So the only case we handle during RCU walking is the + * case of a cached "no ACL at all", which needs no locks + * or refcounts. + */ if (mask & MAY_NOT_BLOCK) { - acl = get_cached_acl_rcu(inode, ACL_TYPE_ACCESS); - if (!acl) + if (negative_cached_acl(inode, ACL_TYPE_ACCESS)) return -EAGAIN; - /* no ->get_acl() calls in RCU mode... */ - if (acl == ACL_NOT_CACHED) - return -ECHILD; - return posix_acl_permission(inode, acl, mask & ~MAY_NOT_BLOCK); + return -ECHILD; } acl = get_cached_acl(inode, ACL_TYPE_ACCESS); @@ -308,26 +313,6 @@ int generic_permission(struct inode *inode, int mask) return -EACCES; } -/* - * We _really_ want to just do "generic_permission()" without - * even looking at the inode->i_op values. So we keep a cache - * flag in inode->i_opflags, that says "this has not special - * permission function, use the fast case". - */ -static inline int do_inode_permission(struct inode *inode, int mask) -{ - if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) { - if (likely(inode->i_op->permission)) - return inode->i_op->permission(inode, mask); - - /* This gets set once for the inode lifetime */ - spin_lock(&inode->i_lock); - inode->i_opflags |= IOP_FASTPERM; - spin_unlock(&inode->i_lock); - } - return generic_permission(inode, mask); -} - /** * inode_permission - check for access rights to a given inode * @inode: inode to check permission on @@ -342,7 +327,7 @@ int inode_permission(struct inode *inode, int mask) { int retval; - if (unlikely(mask & MAY_WRITE)) { + if (mask & MAY_WRITE) { umode_t mode = inode->i_mode; /* @@ -359,7 +344,11 @@ int inode_permission(struct inode *inode, int mask) return -EACCES; } - retval = do_inode_permission(inode, mask); + if (inode->i_op->permission) + retval = inode->i_op->permission(inode, mask); + else + retval = generic_permission(inode, mask); + if (retval) return retval; @@ -1261,26 +1250,6 @@ static void terminate_walk(struct nameidata *nd) } } -/* - * Do we need to follow links? We _really_ want to be able - * to do this check without having to look at inode->i_op, - * so we keep a cache of "no, this doesn't need follow_link" - * for the common case. - */ -static inline int should_follow_link(struct inode *inode, int follow) -{ - if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) { - if (likely(inode->i_op->follow_link)) - return follow; - - /* This gets set once for the inode lifetime */ - spin_lock(&inode->i_lock); - inode->i_opflags |= IOP_NOFOLLOW; - spin_unlock(&inode->i_lock); - } - return 0; -} - static inline int walk_component(struct nameidata *nd, struct path *path, struct qstr *name, int type, int follow) { @@ -1303,7 +1272,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path, terminate_walk(nd); return -ENOENT; } - if (should_follow_link(inode, follow)) { + if (unlikely(inode->i_op->follow_link) && follow) { if (nd->flags & LOOKUP_RCU) { if (unlikely(unlazy_walk(nd, path->dentry))) { terminate_walk(nd); @@ -1355,26 +1324,6 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd) return res; } -/* - * We really don't want to look at inode->i_op->lookup - * when we don't have to. So we keep a cache bit in - * the inode ->i_opflags field that says "yes, we can - * do lookup on this inode". - */ -static inline int can_lookup(struct inode *inode) -{ - if (likely(inode->i_opflags & IOP_LOOKUP)) - return 1; - if (likely(!inode->i_op->lookup)) - return 0; - - /* We do this once for the lifetime of the inode */ - spin_lock(&inode->i_lock); - inode->i_opflags |= IOP_LOOKUP; - spin_unlock(&inode->i_lock); - return 1; -} - /* * Name resolution. * This is the basic name resolution function, turning a pathname into @@ -1454,10 +1403,10 @@ static int link_path_walk(const char *name, struct nameidata *nd) if (err) return err; } - if (can_lookup(nd->inode)) - continue; err = -ENOTDIR; - break; + if (!nd->inode->i_op->lookup) + break; + continue; /* here ends the main loop */ last_component: diff --git a/trunk/fs/nfs/Kconfig b/trunk/fs/nfs/Kconfig index dbcd82126aed..be020771c6b4 100644 --- a/trunk/fs/nfs/Kconfig +++ b/trunk/fs/nfs/Kconfig @@ -79,9 +79,12 @@ config NFS_V4_1 depends on NFS_FS && NFS_V4 && EXPERIMENTAL select SUNRPC_BACKCHANNEL select PNFS_FILE_LAYOUT + select PNFS_BLOCK + select MD + select BLK_DEV_DM help This option enables support for minor version 1 of the NFSv4 protocol - (RFC 5661) in the kernel's NFS client. + (RFC 5661 and RFC 5663) in the kernel's NFS client. If unsure, say N. @@ -90,13 +93,16 @@ config PNFS_FILE_LAYOUT config PNFS_BLOCK tristate - depends on NFS_FS && NFS_V4_1 && BLK_DEV_DM - default m config PNFS_OBJLAYOUT - tristate + tristate "Provide support for the pNFS Objects Layout Driver for NFSv4.1 pNFS (EXPERIMENTAL)" depends on NFS_FS && NFS_V4_1 && SCSI_OSD_ULD - default m + help + Say M here if you want your pNFS client to support the Objects Layout Driver. + Requires the SCSI osd initiator library (SCSI_OSD_INITIATOR) and + upper level driver (SCSI_OSD_ULD). + + If unsure, say N. config ROOT_NFS bool "Root file system on NFS" diff --git a/trunk/fs/proc/base.c b/trunk/fs/proc/base.c index 5eb02069e1b8..08e3eccf9a12 100644 --- a/trunk/fs/proc/base.c +++ b/trunk/fs/proc/base.c @@ -1118,7 +1118,7 @@ static ssize_t oom_adjust_write(struct file *file, const char __user *buf, * Warn that /proc/pid/oom_adj is deprecated, see * Documentation/feature-removal-schedule.txt. */ - printk_once(KERN_WARNING "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", + WARN_ONCE(1, "%s (%d): /proc/%d/oom_adj is deprecated, please use /proc/%d/oom_score_adj instead.\n", current->comm, task_pid_nr(current), task_pid_nr(task), task_pid_nr(task)); task->signal->oom_adj = oom_adjust; @@ -1919,14 +1919,6 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) spin_lock(&files->file_lock); file = fcheck_files(files, fd); if (file) { - unsigned int f_flags; - struct fdtable *fdt; - - fdt = files_fdtable(files); - f_flags = file->f_flags & ~O_CLOEXEC; - if (FD_ISSET(fd, fdt->close_on_exec)) - f_flags |= O_CLOEXEC; - if (path) { *path = file->f_path; path_get(&file->f_path); @@ -1936,7 +1928,7 @@ static int proc_fd_info(struct inode *inode, struct path *path, char *info) "pos:\t%lli\n" "flags:\t0%o\n", (long long) file->f_pos, - f_flags); + file->f_flags); spin_unlock(&files->file_lock); put_files_struct(files); return 0; diff --git a/trunk/fs/stack.c b/trunk/fs/stack.c index b4f2ab48a61f..4a6f7f440658 100644 --- a/trunk/fs/stack.c +++ b/trunk/fs/stack.c @@ -29,7 +29,10 @@ void fsstack_copy_inode_size(struct inode *dst, struct inode *src) * * We don't actually know what locking is used at the lower level; * but if it's a filesystem that supports quotas, it will be using - * i_lock as in inode_add_bytes(). + * i_lock as in inode_add_bytes(). tmpfs uses other locking, and + * its 32-bit is (just) able to exceed 2TB i_size with the aid of + * holes; but its i_blocks cannot carry into the upper long without + * almost 2TB swap - let's ignore that case. */ if (sizeof(i_blocks) > sizeof(long)) spin_lock(&src->i_lock); diff --git a/trunk/fs/stat.c b/trunk/fs/stat.c index ba5316ffac61..961039121cb8 100644 --- a/trunk/fs/stat.c +++ b/trunk/fs/stat.c @@ -27,12 +27,12 @@ void generic_fillattr(struct inode *inode, struct kstat *stat) stat->uid = inode->i_uid; stat->gid = inode->i_gid; stat->rdev = inode->i_rdev; - stat->size = i_size_read(inode); stat->atime = inode->i_atime; stat->mtime = inode->i_mtime; stat->ctime = inode->i_ctime; - stat->blksize = (1 << inode->i_blkbits); + stat->size = i_size_read(inode); stat->blocks = inode->i_blocks; + stat->blksize = (1 << inode->i_blkbits); } EXPORT_SYMBOL(generic_fillattr); diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.c b/trunk/fs/xfs/linux-2.6/xfs_buf.c index c57836dc778f..d1fe74506c4c 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.c +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.c @@ -596,7 +596,7 @@ _xfs_buf_read( bp->b_flags |= flags & (XBF_READ | XBF_ASYNC | XBF_READ_AHEAD); status = xfs_buf_iorequest(bp); - if (status || bp->b_error || (flags & XBF_ASYNC)) + if (status || XFS_BUF_ISERROR(bp) || (flags & XBF_ASYNC)) return status; return xfs_buf_iowait(bp); } @@ -679,6 +679,7 @@ xfs_buf_read_uncached( /* set up the buffer for a read IO */ XFS_BUF_SET_ADDR(bp, daddr); XFS_BUF_READ(bp); + XFS_BUF_BUSY(bp); xfsbdstrat(mp, bp); error = xfs_buf_iowait(bp); @@ -1068,7 +1069,7 @@ xfs_bioerror( /* * No need to wait until the buffer is unpinned, we aren't flushing it. */ - xfs_buf_ioerror(bp, EIO); + XFS_BUF_ERROR(bp, EIO); /* * We're calling xfs_buf_ioend, so delete XBF_DONE flag. @@ -1093,7 +1094,7 @@ STATIC int xfs_bioerror_relse( struct xfs_buf *bp) { - int64_t fl = bp->b_flags; + int64_t fl = XFS_BUF_BFLAGS(bp); /* * No need to wait until the buffer is unpinned. * We aren't flushing it. @@ -1114,7 +1115,7 @@ xfs_bioerror_relse( * There's no reason to mark error for * ASYNC buffers. */ - xfs_buf_ioerror(bp, EIO); + XFS_BUF_ERROR(bp, EIO); XFS_BUF_FINISH_IOWAIT(bp); } else { xfs_buf_relse(bp); @@ -1323,7 +1324,7 @@ xfs_buf_offset( struct page *page; if (bp->b_flags & XBF_MAPPED) - return bp->b_addr + offset; + return XFS_BUF_PTR(bp) + offset; offset += bp->b_offset; page = bp->b_pages[offset >> PAGE_SHIFT]; @@ -1483,7 +1484,7 @@ xfs_setsize_buftarg_flags( if (set_blocksize(btp->bt_bdev, sectorsize)) { xfs_warn(btp->bt_mount, "Cannot set_blocksize to %u on device %s\n", - sectorsize, xfs_buf_target_name(btp)); + sectorsize, XFS_BUFTARG_NAME(btp)); return EINVAL; } @@ -1680,7 +1681,7 @@ xfs_buf_delwri_split( list_for_each_entry_safe(bp, n, dwq, b_list) { ASSERT(bp->b_flags & XBF_DELWRI); - if (!xfs_buf_ispinned(bp) && xfs_buf_trylock(bp)) { + if (!XFS_BUF_ISPINNED(bp) && xfs_buf_trylock(bp)) { if (!force && time_before(jiffies, bp->b_queuetime + age)) { xfs_buf_unlock(bp); diff --git a/trunk/fs/xfs/linux-2.6/xfs_buf.h b/trunk/fs/xfs/linux-2.6/xfs_buf.h index 620972b8094d..6a83b46b4bcf 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_buf.h +++ b/trunk/fs/xfs/linux-2.6/xfs_buf.h @@ -228,15 +228,11 @@ extern void xfs_buf_delwri_promote(xfs_buf_t *); extern int xfs_buf_init(void); extern void xfs_buf_terminate(void); -static inline const char * -xfs_buf_target_name(struct xfs_buftarg *target) -{ - static char __b[BDEVNAME_SIZE]; - - return bdevname(target->bt_bdev, __b); -} +#define xfs_buf_target_name(target) \ + ({ char __b[BDEVNAME_SIZE]; bdevname((target)->bt_bdev, __b); __b; }) +#define XFS_BUF_BFLAGS(bp) ((bp)->b_flags) #define XFS_BUF_ZEROFLAGS(bp) \ ((bp)->b_flags &= ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI| \ XBF_SYNCIO|XBF_FUA|XBF_FLUSH)) @@ -255,14 +251,23 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNDELAYWRITE(bp) xfs_buf_delwri_dequeue(bp) #define XFS_BUF_ISDELAYWRITE(bp) ((bp)->b_flags & XBF_DELWRI) +#define XFS_BUF_ERROR(bp,no) xfs_buf_ioerror(bp,no) +#define XFS_BUF_GETERROR(bp) xfs_buf_geterror(bp) +#define XFS_BUF_ISERROR(bp) (xfs_buf_geterror(bp) ? 1 : 0) + #define XFS_BUF_DONE(bp) ((bp)->b_flags |= XBF_DONE) #define XFS_BUF_UNDONE(bp) ((bp)->b_flags &= ~XBF_DONE) #define XFS_BUF_ISDONE(bp) ((bp)->b_flags & XBF_DONE) +#define XFS_BUF_BUSY(bp) do { } while (0) +#define XFS_BUF_UNBUSY(bp) do { } while (0) +#define XFS_BUF_ISBUSY(bp) (1) + #define XFS_BUF_ASYNC(bp) ((bp)->b_flags |= XBF_ASYNC) #define XFS_BUF_UNASYNC(bp) ((bp)->b_flags &= ~XBF_ASYNC) #define XFS_BUF_ISASYNC(bp) ((bp)->b_flags & XBF_ASYNC) +#define XFS_BUF_HOLD(bp) xfs_buf_hold(bp) #define XFS_BUF_READ(bp) ((bp)->b_flags |= XBF_READ) #define XFS_BUF_UNREAD(bp) ((bp)->b_flags &= ~XBF_READ) #define XFS_BUF_ISREAD(bp) ((bp)->b_flags & XBF_READ) @@ -271,6 +276,10 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_UNWRITE(bp) ((bp)->b_flags &= ~XBF_WRITE) #define XFS_BUF_ISWRITE(bp) ((bp)->b_flags & XBF_WRITE) +#define XFS_BUF_SET_START(bp) do { } while (0) + +#define XFS_BUF_PTR(bp) (xfs_caddr_t)((bp)->b_addr) +#define XFS_BUF_SET_PTR(bp, val, cnt) xfs_buf_associate_memory(bp, val, cnt) #define XFS_BUF_ADDR(bp) ((bp)->b_bn) #define XFS_BUF_SET_ADDR(bp, bno) ((bp)->b_bn = (xfs_daddr_t)(bno)) #define XFS_BUF_OFFSET(bp) ((bp)->b_file_offset) @@ -290,13 +299,14 @@ xfs_buf_set_ref( #define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref) #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) -static inline int xfs_buf_ispinned(struct xfs_buf *bp) -{ - return atomic_read(&bp->b_pin_count); -} +#define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) #define XFS_BUF_FINISH_IOWAIT(bp) complete(&bp->b_iowait); +#define XFS_BUF_SET_TARGET(bp, target) ((bp)->b_target = (target)) +#define XFS_BUF_TARGET(bp) ((bp)->b_target) +#define XFS_BUFTARG_NAME(target) xfs_buf_target_name(target) + static inline void xfs_buf_relse(xfs_buf_t *bp) { xfs_buf_unlock(bp); diff --git a/trunk/fs/xfs/linux-2.6/xfs_sync.c b/trunk/fs/xfs/linux-2.6/xfs_sync.c index 4604f90f86a3..e4c938afb910 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_sync.c +++ b/trunk/fs/xfs/linux-2.6/xfs_sync.c @@ -332,7 +332,7 @@ xfs_sync_fsdata( * between there and here. */ bp = xfs_getsb(mp, 0); - if (xfs_buf_ispinned(bp)) + if (XFS_BUF_ISPINNED(bp)) xfs_log_force(mp, 0); return xfs_bwrite(mp, bp); diff --git a/trunk/fs/xfs/quota/xfs_dquot.c b/trunk/fs/xfs/quota/xfs_dquot.c index db62959bed13..837f31158d43 100644 --- a/trunk/fs/xfs/quota/xfs_dquot.c +++ b/trunk/fs/xfs/quota/xfs_dquot.c @@ -318,9 +318,10 @@ xfs_qm_init_dquot_blk( int curid, i; ASSERT(tp); + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(xfs_buf_islocked(bp)); - d = bp->b_addr; + d = (xfs_dqblk_t *)XFS_BUF_PTR(bp); /* * ID of the first dquot in the block - id's are zero based. @@ -402,7 +403,7 @@ xfs_qm_dqalloc( dqp->q_blkno, mp->m_quotainfo->qi_dqchunklen, 0); - if (!bp || (error = xfs_buf_geterror(bp))) + if (!bp || (error = XFS_BUF_GETERROR(bp))) goto error1; /* * Make a chunk of dquots out of this buffer and log @@ -533,12 +534,13 @@ xfs_qm_dqtobp( return XFS_ERROR(error); } + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(xfs_buf_islocked(bp)); /* * calculate the location of the dquot inside the buffer. */ - ddq = bp->b_addr + dqp->q_bufoffset; + ddq = (struct xfs_disk_dquot *)(XFS_BUF_PTR(bp) + dqp->q_bufoffset); /* * A simple sanity check in case we got a corrupted dquot... @@ -551,6 +553,7 @@ xfs_qm_dqtobp( xfs_trans_brelse(tp, bp); return XFS_ERROR(EIO); } + XFS_BUF_BUSY(bp); /* We dirtied this */ } *O_bpp = bp; @@ -619,6 +622,7 @@ xfs_qm_dqread( * this particular dquot was repaired. We still aren't afraid to * brelse it because we have the changes incore. */ + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(xfs_buf_islocked(bp)); xfs_trans_brelse(tp, bp); @@ -1200,7 +1204,7 @@ xfs_qm_dqflush( /* * Calculate the location of the dquot inside the buffer. */ - ddqp = bp->b_addr + dqp->q_bufoffset; + ddqp = (struct xfs_disk_dquot *)(XFS_BUF_PTR(bp) + dqp->q_bufoffset); /* * A simple sanity check in case we got a corrupted dquot.. @@ -1236,7 +1240,7 @@ xfs_qm_dqflush( * If the buffer is pinned then push on the log so we won't * get stuck waiting in the write for too long. */ - if (xfs_buf_ispinned(bp)) { + if (XFS_BUF_ISPINNED(bp)) { trace_xfs_dqflush_force(dqp); xfs_log_force(mp, 0); } @@ -1443,7 +1447,7 @@ xfs_qm_dqflock_pushbuf_wait( goto out_lock; if (XFS_BUF_ISDELAYWRITE(bp)) { - if (xfs_buf_ispinned(bp)) + if (XFS_BUF_ISPINNED(bp)) xfs_log_force(mp, 0); xfs_buf_delwri_promote(bp); wake_up_process(bp->b_target->bt_task); diff --git a/trunk/fs/xfs/quota/xfs_qm.c b/trunk/fs/xfs/quota/xfs_qm.c index 9a0aa76facdf..46e54ad9a2dc 100644 --- a/trunk/fs/xfs/quota/xfs_qm.c +++ b/trunk/fs/xfs/quota/xfs_qm.c @@ -1240,7 +1240,7 @@ xfs_qm_reset_dqcounts( do_div(j, sizeof(xfs_dqblk_t)); ASSERT(mp->m_quotainfo->qi_dqperchunk == j); #endif - ddq = bp->b_addr; + ddq = (xfs_disk_dquot_t *)XFS_BUF_PTR(bp); for (j = 0; j < mp->m_quotainfo->qi_dqperchunk; j++) { /* * Do a sanity check, and if needed, repair the dqblk. Don't diff --git a/trunk/fs/xfs/xfs_ag.h b/trunk/fs/xfs/xfs_ag.h index 4805f009f923..6530769a999b 100644 --- a/trunk/fs/xfs/xfs_ag.h +++ b/trunk/fs/xfs/xfs_ag.h @@ -103,7 +103,7 @@ typedef struct xfs_agf { /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGF_DADDR(mp) ((xfs_daddr_t)(1 << (mp)->m_sectbb_log)) #define XFS_AGF_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp)) -#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)((bp)->b_addr)) +#define XFS_BUF_TO_AGF(bp) ((xfs_agf_t *)XFS_BUF_PTR(bp)) extern int xfs_read_agf(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, int flags, struct xfs_buf **bpp); @@ -156,7 +156,7 @@ typedef struct xfs_agi { /* disk block (xfs_daddr_t) in the AG */ #define XFS_AGI_DADDR(mp) ((xfs_daddr_t)(2 << (mp)->m_sectbb_log)) #define XFS_AGI_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGI_DADDR(mp)) -#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)((bp)->b_addr)) +#define XFS_BUF_TO_AGI(bp) ((xfs_agi_t *)XFS_BUF_PTR(bp)) extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, xfs_agnumber_t agno, struct xfs_buf **bpp); @@ -168,7 +168,7 @@ extern int xfs_read_agi(struct xfs_mount *mp, struct xfs_trans *tp, #define XFS_AGFL_DADDR(mp) ((xfs_daddr_t)(3 << (mp)->m_sectbb_log)) #define XFS_AGFL_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_AGFL_DADDR(mp)) #define XFS_AGFL_SIZE(mp) ((mp)->m_sb.sb_sectsize / sizeof(xfs_agblock_t)) -#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)((bp)->b_addr)) +#define XFS_BUF_TO_AGFL(bp) ((xfs_agfl_t *)XFS_BUF_PTR(bp)) typedef struct xfs_agfl { __be32 agfl_bno[1]; /* actually XFS_AGFL_SIZE(mp) */ diff --git a/trunk/fs/xfs/xfs_alloc.c b/trunk/fs/xfs/xfs_alloc.c index bdd9cb54d63b..1e00b3ef6274 100644 --- a/trunk/fs/xfs/xfs_alloc.c +++ b/trunk/fs/xfs/xfs_alloc.c @@ -451,7 +451,8 @@ xfs_alloc_read_agfl( XFS_FSS_TO_BB(mp, 1), 0, &bp); if (error) return error; - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp); + ASSERT(!XFS_BUF_GETERROR(bp)); XFS_BUF_SET_VTYPE_REF(bp, B_FS_AGFL, XFS_AGFL_REF); *bpp = bp; return 0; @@ -2115,7 +2116,7 @@ xfs_read_agf( if (!*bpp) return 0; - ASSERT(!(*bpp)->b_error); + ASSERT(!XFS_BUF_GETERROR(*bpp)); agf = XFS_BUF_TO_AGF(*bpp); /* @@ -2167,7 +2168,7 @@ xfs_alloc_read_agf( return error; if (!*bpp) return 0; - ASSERT(!(*bpp)->b_error); + ASSERT(!XFS_BUF_GETERROR(*bpp)); agf = XFS_BUF_TO_AGF(*bpp); pag = xfs_perag_get(mp, agno); diff --git a/trunk/fs/xfs/xfs_attr.c b/trunk/fs/xfs/xfs_attr.c index 160bcdc34a6e..cbae424fe1ba 100644 --- a/trunk/fs/xfs/xfs_attr.c +++ b/trunk/fs/xfs/xfs_attr.c @@ -2121,7 +2121,8 @@ xfs_attr_rmtval_set(xfs_da_args_t *args) bp = xfs_buf_get(mp->m_ddev_targp, dblkno, blkcnt, XBF_LOCK | XBF_DONT_BLOCK); - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp); + ASSERT(!XFS_BUF_GETERROR(bp)); tmp = (valuelen < XFS_BUF_SIZE(bp)) ? valuelen : XFS_BUF_SIZE(bp); diff --git a/trunk/fs/xfs/xfs_bmap.c b/trunk/fs/xfs/xfs_bmap.c index 452a291383ab..ab3e5c6c4642 100644 --- a/trunk/fs/xfs/xfs_bmap.c +++ b/trunk/fs/xfs/xfs_bmap.c @@ -3383,7 +3383,8 @@ xfs_bmap_local_to_extents( ASSERT(args.len == 1); *firstblock = args.fsbno; bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno, 0); - memcpy(bp->b_addr, ifp->if_u1.if_data, ifp->if_bytes); + memcpy((char *)XFS_BUF_PTR(bp), ifp->if_u1.if_data, + ifp->if_bytes); xfs_trans_log_buf(tp, bp, 0, ifp->if_bytes - 1); xfs_bmap_forkoff_reset(args.mp, ip, whichfork); xfs_idata_realloc(ip, -ifp->if_bytes, whichfork); diff --git a/trunk/fs/xfs/xfs_btree.c b/trunk/fs/xfs/xfs_btree.c index 2b9fd385e27d..cabf4b5604aa 100644 --- a/trunk/fs/xfs/xfs_btree.c +++ b/trunk/fs/xfs/xfs_btree.c @@ -275,7 +275,8 @@ xfs_btree_dup_cursor( return error; } new->bc_bufs[i] = bp; - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp); + ASSERT(!XFS_BUF_GETERROR(bp)); } else new->bc_bufs[i] = NULL; } @@ -466,7 +467,8 @@ xfs_btree_get_bufl( ASSERT(fsbno != NULLFSBLOCK); d = XFS_FSB_TO_DADDR(mp, fsbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp); + ASSERT(!XFS_BUF_GETERROR(bp)); return bp; } @@ -489,7 +491,8 @@ xfs_btree_get_bufs( ASSERT(agbno != NULLAGBLOCK); d = XFS_AGB_TO_DADDR(mp, agno, agbno); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, lock); - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp); + ASSERT(!XFS_BUF_GETERROR(bp)); return bp; } @@ -629,7 +632,7 @@ xfs_btree_read_bufl( mp->m_bsize, lock, &bp))) { return error; } - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(!bp || !XFS_BUF_GETERROR(bp)); if (bp) XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); *bpp = bp; @@ -970,7 +973,8 @@ xfs_btree_get_buf_block( *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize, flags); - ASSERT(!xfs_buf_geterror(*bpp)); + ASSERT(*bpp); + ASSERT(!XFS_BUF_GETERROR(*bpp)); *block = XFS_BUF_TO_BLOCK(*bpp); return 0; @@ -1002,7 +1006,8 @@ xfs_btree_read_buf_block( if (error) return error; - ASSERT(!xfs_buf_geterror(*bpp)); + ASSERT(*bpp != NULL); + ASSERT(!XFS_BUF_GETERROR(*bpp)); xfs_btree_set_refs(cur, *bpp); *block = XFS_BUF_TO_BLOCK(*bpp); diff --git a/trunk/fs/xfs/xfs_btree.h b/trunk/fs/xfs/xfs_btree.h index 5b240de104c0..8d05a6a46ce3 100644 --- a/trunk/fs/xfs/xfs_btree.h +++ b/trunk/fs/xfs/xfs_btree.h @@ -262,7 +262,7 @@ typedef struct xfs_btree_cur /* * Convert from buffer to btree block header. */ -#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)((bp)->b_addr)) +#define XFS_BUF_TO_BLOCK(bp) ((struct xfs_btree_block *)XFS_BUF_PTR(bp)) /* diff --git a/trunk/fs/xfs/xfs_buf_item.c b/trunk/fs/xfs/xfs_buf_item.c index cac2ecfa6746..88492916c3dc 100644 --- a/trunk/fs/xfs/xfs_buf_item.c +++ b/trunk/fs/xfs/xfs_buf_item.c @@ -124,9 +124,9 @@ xfs_buf_item_log_check( bp = bip->bli_buf; ASSERT(XFS_BUF_COUNT(bp) > 0); - ASSERT(bp->b_addr != NULL); + ASSERT(XFS_BUF_PTR(bp) != NULL); orig = bip->bli_orig; - buffer = bp->b_addr; + buffer = XFS_BUF_PTR(bp); for (x = 0; x < XFS_BUF_COUNT(bp); x++) { if (orig[x] != buffer[x] && !btst(bip->bli_logged, x)) { xfs_emerg(bp->b_mount, @@ -371,6 +371,7 @@ xfs_buf_item_pin( { struct xfs_buf_log_item *bip = BUF_ITEM(lip); + ASSERT(XFS_BUF_ISBUSY(bip->bli_buf)); ASSERT(atomic_read(&bip->bli_refcount) > 0); ASSERT((bip->bli_flags & XFS_BLI_LOGGED) || (bip->bli_flags & XFS_BLI_STALE)); @@ -478,13 +479,13 @@ xfs_buf_item_trylock( struct xfs_buf_log_item *bip = BUF_ITEM(lip); struct xfs_buf *bp = bip->bli_buf; - if (xfs_buf_ispinned(bp)) + if (XFS_BUF_ISPINNED(bp)) return XFS_ITEM_PINNED; if (!xfs_buf_trylock(bp)) return XFS_ITEM_LOCKED; /* take a reference to the buffer. */ - xfs_buf_hold(bp); + XFS_BUF_HOLD(bp); ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); trace_xfs_buf_item_trylock(bip); @@ -725,7 +726,7 @@ xfs_buf_item_init( * to have logged. */ bip->bli_orig = (char *)kmem_alloc(XFS_BUF_COUNT(bp), KM_SLEEP); - memcpy(bip->bli_orig, bp->b_addr, XFS_BUF_COUNT(bp)); + memcpy(bip->bli_orig, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp)); bip->bli_logged = (char *)kmem_zalloc(XFS_BUF_COUNT(bp) / NBBY, KM_SLEEP); #endif @@ -894,6 +895,7 @@ xfs_buf_attach_iodone( { xfs_log_item_t *head_lip; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(xfs_buf_islocked(bp)); lip->li_cb = cb; @@ -958,7 +960,7 @@ xfs_buf_iodone_callbacks( static ulong lasttime; static xfs_buftarg_t *lasttarg; - if (likely(!xfs_buf_geterror(bp))) + if (likely(!XFS_BUF_GETERROR(bp))) goto do_callbacks; /* @@ -971,14 +973,14 @@ xfs_buf_iodone_callbacks( goto do_callbacks; } - if (bp->b_target != lasttarg || + if (XFS_BUF_TARGET(bp) != lasttarg || time_after(jiffies, (lasttime + 5*HZ))) { lasttime = jiffies; xfs_alert(mp, "Device %s: metadata write error block 0x%llx", - xfs_buf_target_name(bp->b_target), + XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)), (__uint64_t)XFS_BUF_ADDR(bp)); } - lasttarg = bp->b_target; + lasttarg = XFS_BUF_TARGET(bp); /* * If the write was asynchronous then no one will be looking for the @@ -989,11 +991,12 @@ xfs_buf_iodone_callbacks( * around. */ if (XFS_BUF_ISASYNC(bp)) { - xfs_buf_ioerror(bp, 0); /* errno of 0 unsets the flag */ + XFS_BUF_ERROR(bp, 0); /* errno of 0 unsets the flag */ if (!XFS_BUF_ISSTALE(bp)) { XFS_BUF_DELAYWRITE(bp); XFS_BUF_DONE(bp); + XFS_BUF_SET_START(bp); } ASSERT(bp->b_iodone != NULL); trace_xfs_buf_item_iodone_async(bp, _RET_IP_); @@ -1010,6 +1013,7 @@ xfs_buf_iodone_callbacks( XFS_BUF_UNDELAYWRITE(bp); trace_xfs_buf_error_relse(bp, _RET_IP_); + xfs_force_shutdown(mp, SHUTDOWN_META_IO_ERROR); do_callbacks: xfs_buf_do_callbacks(bp); diff --git a/trunk/fs/xfs/xfs_da_btree.c b/trunk/fs/xfs/xfs_da_btree.c index ee9d5427fcd4..5bfcb8779f9f 100644 --- a/trunk/fs/xfs/xfs_da_btree.c +++ b/trunk/fs/xfs/xfs_da_btree.c @@ -2050,7 +2050,7 @@ xfs_da_do_buf( case 0: bp = xfs_trans_get_buf(trans, mp->m_ddev_targp, mappedbno, nmapped, 0); - error = bp ? bp->b_error : XFS_ERROR(EIO); + error = bp ? XFS_BUF_GETERROR(bp) : XFS_ERROR(EIO); break; case 1: case 2: @@ -2268,7 +2268,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps) dabuf->nbuf = 1; bp = bps[0]; dabuf->bbcount = (short)BTOBB(XFS_BUF_COUNT(bp)); - dabuf->data = bp->b_addr; + dabuf->data = XFS_BUF_PTR(bp); dabuf->bps[0] = bp; } else { dabuf->nbuf = nbuf; @@ -2279,7 +2279,7 @@ xfs_da_buf_make(int nbuf, xfs_buf_t **bps) dabuf->data = kmem_alloc(BBTOB(dabuf->bbcount), KM_SLEEP); for (i = off = 0; i < nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = bps[i]; - memcpy((char *)dabuf->data + off, bp->b_addr, + memcpy((char *)dabuf->data + off, XFS_BUF_PTR(bp), XFS_BUF_COUNT(bp)); } } @@ -2302,8 +2302,8 @@ xfs_da_buf_clean(xfs_dabuf_t *dabuf) for (i = off = 0; i < dabuf->nbuf; i++, off += XFS_BUF_COUNT(bp)) { bp = dabuf->bps[i]; - memcpy(bp->b_addr, dabuf->data + off, - XFS_BUF_COUNT(bp)); + memcpy(XFS_BUF_PTR(bp), (char *)dabuf->data + off, + XFS_BUF_COUNT(bp)); } } } @@ -2340,7 +2340,7 @@ xfs_da_log_buf(xfs_trans_t *tp, xfs_dabuf_t *dabuf, uint first, uint last) ASSERT(dabuf->nbuf && dabuf->data && dabuf->bbcount && dabuf->bps[0]); if (dabuf->nbuf == 1) { - ASSERT(dabuf->data == dabuf->bps[0]->b_addr); + ASSERT(dabuf->data == (void *)XFS_BUF_PTR(dabuf->bps[0])); xfs_trans_log_buf(tp, dabuf->bps[0], first, last); return; } diff --git a/trunk/fs/xfs/xfs_dinode.h b/trunk/fs/xfs/xfs_dinode.h index a3721633abc8..dffba9ba0db6 100644 --- a/trunk/fs/xfs/xfs_dinode.h +++ b/trunk/fs/xfs/xfs_dinode.h @@ -148,7 +148,7 @@ typedef enum xfs_dinode_fmt { be32_to_cpu((dip)->di_nextents) : \ be16_to_cpu((dip)->di_anextents)) -#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)((bp)->b_addr)) +#define XFS_BUF_TO_DINODE(bp) ((xfs_dinode_t *)XFS_BUF_PTR(bp)) /* * For block and character special files the 32bit dev_t is stored at the diff --git a/trunk/fs/xfs/xfs_ialloc.c b/trunk/fs/xfs/xfs_ialloc.c index 9f24ec28283b..dd5628bd8d0b 100644 --- a/trunk/fs/xfs/xfs_ialloc.c +++ b/trunk/fs/xfs/xfs_ialloc.c @@ -202,7 +202,8 @@ xfs_ialloc_inode_init( fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize * blks_per_cluster, XBF_LOCK); - ASSERT(!xfs_buf_geterror(fbuf)); + ASSERT(fbuf); + ASSERT(!XFS_BUF_GETERROR(fbuf)); /* * Initialize all inodes in this buffer and then log them. @@ -1485,7 +1486,7 @@ xfs_read_agi( if (error) return error; - ASSERT(!xfs_buf_geterror(*bpp)); + ASSERT(*bpp && !XFS_BUF_GETERROR(*bpp)); agi = XFS_BUF_TO_AGI(*bpp); /* diff --git a/trunk/fs/xfs/xfs_inode.c b/trunk/fs/xfs/xfs_inode.c index 0239a7c7c886..2fcca4b03ed3 100644 --- a/trunk/fs/xfs/xfs_inode.c +++ b/trunk/fs/xfs/xfs_inode.c @@ -2473,7 +2473,7 @@ xfs_iflush_cluster( if (bp->b_iodone) { XFS_BUF_UNDONE(bp); XFS_BUF_STALE(bp); - xfs_buf_ioerror(bp, EIO); + XFS_BUF_ERROR(bp,EIO); xfs_buf_ioend(bp, 0); } else { XFS_BUF_STALE(bp); @@ -2585,7 +2585,7 @@ xfs_iflush( * If the buffer is pinned then push on the log now so we won't * get stuck waiting in the write for too long. */ - if (xfs_buf_ispinned(bp)) + if (XFS_BUF_ISPINNED(bp)) xfs_log_force(mp, 0); /* diff --git a/trunk/fs/xfs/xfs_log.c b/trunk/fs/xfs/xfs_log.c index 3a8d4f66d702..06ff8437ed8e 100644 --- a/trunk/fs/xfs/xfs_log.c +++ b/trunk/fs/xfs/xfs_log.c @@ -878,7 +878,7 @@ xlog_iodone(xfs_buf_t *bp) /* * Race to shutdown the filesystem if we see an error. */ - if (XFS_TEST_ERROR((xfs_buf_geterror(bp)), l->l_mp, + if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) { xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp)); XFS_BUF_STALE(bp); @@ -1051,6 +1051,7 @@ xlog_alloc_log(xfs_mount_t *mp, if (!bp) goto out_free_log; bp->b_iodone = xlog_iodone; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(xfs_buf_islocked(bp)); log->l_xbuf = bp; @@ -1107,6 +1108,7 @@ xlog_alloc_log(xfs_mount_t *mp, iclog->ic_callback_tail = &(iclog->ic_callback); iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize; + ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); ASSERT(xfs_buf_islocked(iclog->ic_bp)); init_waitqueue_head(&iclog->ic_force_wait); init_waitqueue_head(&iclog->ic_write_wait); @@ -1246,7 +1248,7 @@ xlog_bdstrat( struct xlog_in_core *iclog = bp->b_fspriv; if (iclog->ic_state & XLOG_STATE_IOERROR) { - xfs_buf_ioerror(bp, EIO); + XFS_BUF_ERROR(bp, EIO); XFS_BUF_STALE(bp); xfs_buf_ioend(bp, 0); /* @@ -1353,6 +1355,7 @@ xlog_sync(xlog_t *log, XFS_BUF_SET_COUNT(bp, count); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); + XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); bp->b_flags |= XBF_SYNCIO; @@ -1395,15 +1398,16 @@ xlog_sync(xlog_t *log, if (split) { bp = iclog->ic_log->l_xbuf; XFS_BUF_SET_ADDR(bp, 0); /* logical 0 */ - xfs_buf_associate_memory(bp, - (char *)&iclog->ic_header + count, split); + XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+ + (__psint_t)count), split); bp->b_fspriv = iclog; XFS_BUF_ZEROFLAGS(bp); + XFS_BUF_BUSY(bp); XFS_BUF_ASYNC(bp); bp->b_flags |= XBF_SYNCIO; if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) bp->b_flags |= XBF_FUA; - dptr = bp->b_addr; + dptr = XFS_BUF_PTR(bp); /* * Bump the cycle numbers at the start of each block * since this part of the buffer is at the start of diff --git a/trunk/fs/xfs/xfs_log_recover.c b/trunk/fs/xfs/xfs_log_recover.c index a199dbcee7d8..052a2c0ec5fb 100644 --- a/trunk/fs/xfs/xfs_log_recover.c +++ b/trunk/fs/xfs/xfs_log_recover.c @@ -147,7 +147,7 @@ xlog_align( xfs_daddr_t offset = blk_no & ((xfs_daddr_t)log->l_sectBBsize - 1); ASSERT(BBTOB(offset + nbblks) <= XFS_BUF_SIZE(bp)); - return bp->b_addr + BBTOB(offset); + return XFS_BUF_PTR(bp) + BBTOB(offset); } @@ -178,7 +178,9 @@ xlog_bread_noalign( XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); XFS_BUF_READ(bp); + XFS_BUF_BUSY(bp); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); + XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp); xfsbdstrat(log->l_mp, bp); error = xfs_buf_iowait(bp); @@ -218,18 +220,18 @@ xlog_bread_offset( xfs_buf_t *bp, xfs_caddr_t offset) { - xfs_caddr_t orig_offset = bp->b_addr; + xfs_caddr_t orig_offset = XFS_BUF_PTR(bp); int orig_len = bp->b_buffer_length; int error, error2; - error = xfs_buf_associate_memory(bp, offset, BBTOB(nbblks)); + error = XFS_BUF_SET_PTR(bp, offset, BBTOB(nbblks)); if (error) return error; error = xlog_bread_noalign(log, blk_no, nbblks, bp); /* must reset buffer pointer even on error */ - error2 = xfs_buf_associate_memory(bp, orig_offset, orig_len); + error2 = XFS_BUF_SET_PTR(bp, orig_offset, orig_len); if (error) return error; return error2; @@ -264,9 +266,11 @@ xlog_bwrite( XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no); XFS_BUF_ZEROFLAGS(bp); - xfs_buf_hold(bp); + XFS_BUF_BUSY(bp); + XFS_BUF_HOLD(bp); xfs_buf_lock(bp); XFS_BUF_SET_COUNT(bp, BBTOB(nbblks)); + XFS_BUF_SET_TARGET(bp, log->l_mp->m_logdev_targp); if ((error = xfs_bwrite(log->l_mp, bp))) xfs_ioerror_alert("xlog_bwrite", log->l_mp, @@ -356,7 +360,7 @@ STATIC void xlog_recover_iodone( struct xfs_buf *bp) { - if (bp->b_error) { + if (XFS_BUF_GETERROR(bp)) { /* * We're not going to bother about retrying * this during recovery. One strike! @@ -1258,7 +1262,7 @@ xlog_write_log_records( */ ealign = round_down(end_block, sectbb); if (j == 0 && (start_block + endcount > ealign)) { - offset = bp->b_addr + BBTOB(ealign - start_block); + offset = XFS_BUF_PTR(bp) + BBTOB(ealign - start_block); error = xlog_bread_offset(log, ealign, sectbb, bp, offset); if (error) @@ -2131,16 +2135,15 @@ xlog_recover_buffer_pass2( bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len, buf_flags); - if (!bp) - return XFS_ERROR(ENOMEM); - error = bp->b_error; - if (error) { + if (XFS_BUF_ISERROR(bp)) { xfs_ioerror_alert("xlog_recover_do..(read#1)", mp, bp, buf_f->blf_blkno); + error = XFS_BUF_GETERROR(bp); xfs_buf_relse(bp); return error; } + error = 0; if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); } else if (buf_f->blf_flags & @@ -2224,17 +2227,14 @@ xlog_recover_inode_pass2( bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, XBF_LOCK); - if (!bp) { - error = ENOMEM; - goto error; - } - error = bp->b_error; - if (error) { + if (XFS_BUF_ISERROR(bp)) { xfs_ioerror_alert("xlog_recover_do..(read#2)", mp, bp, in_f->ilf_blkno); + error = XFS_BUF_GETERROR(bp); xfs_buf_relse(bp); goto error; } + error = 0; ASSERT(in_f->ilf_fields & XFS_ILOG_CORE); dip = (xfs_dinode_t *)xfs_buf_offset(bp, in_f->ilf_boffset); @@ -3437,7 +3437,7 @@ xlog_do_recovery_pass( /* * Check for header wrapping around physical end-of-log */ - offset = hbp->b_addr; + offset = XFS_BUF_PTR(hbp); split_hblks = 0; wrapped_hblks = 0; if (blk_no + hblks <= log->l_logBBsize) { @@ -3497,7 +3497,7 @@ xlog_do_recovery_pass( } else { /* This log record is split across the * physical end of log */ - offset = dbp->b_addr; + offset = XFS_BUF_PTR(dbp); split_bblks = 0; if (blk_no != log->l_logBBsize) { /* some data is before the physical diff --git a/trunk/fs/xfs/xfs_mount.c b/trunk/fs/xfs/xfs_mount.c index 0081657ad985..092e16ae4d9d 100644 --- a/trunk/fs/xfs/xfs_mount.c +++ b/trunk/fs/xfs/xfs_mount.c @@ -1615,7 +1615,7 @@ xfs_unmountfs_writesb(xfs_mount_t *mp) XFS_BUF_UNDELAYWRITE(sbp); XFS_BUF_WRITE(sbp); XFS_BUF_UNASYNC(sbp); - ASSERT(sbp->b_target == mp->m_ddev_targp); + ASSERT(XFS_BUF_TARGET(sbp) == mp->m_ddev_targp); xfsbdstrat(mp, sbp); error = xfs_buf_iowait(sbp); if (error) @@ -1938,7 +1938,7 @@ xfs_getsb( xfs_buf_lock(bp); } - xfs_buf_hold(bp); + XFS_BUF_HOLD(bp); ASSERT(XFS_BUF_ISDONE(bp)); return bp; } diff --git a/trunk/fs/xfs/xfs_rtalloc.c b/trunk/fs/xfs/xfs_rtalloc.c index 35561a511b57..8f76fdff4f46 100644 --- a/trunk/fs/xfs/xfs_rtalloc.c +++ b/trunk/fs/xfs/xfs_rtalloc.c @@ -168,7 +168,7 @@ xfs_growfs_rt_alloc( xfs_trans_cancel(tp, cancelflags); goto error; } - memset(bp->b_addr, 0, mp->m_sb.sb_blocksize); + memset(XFS_BUF_PTR(bp), 0, mp->m_sb.sb_blocksize); xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1); /* * Commit the transaction. @@ -883,7 +883,7 @@ xfs_rtbuf_get( if (error) { return error; } - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp && !XFS_BUF_GETERROR(bp)); *bpp = bp; return 0; } @@ -943,7 +943,7 @@ xfs_rtcheck_range( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Compute the starting word's address, and starting bit. */ @@ -994,7 +994,7 @@ xfs_rtcheck_range( if (error) { return error; } - b = bufp = bp->b_addr; + b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1040,7 +1040,7 @@ xfs_rtcheck_range( if (error) { return error; } - b = bufp = bp->b_addr; + b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1158,7 +1158,7 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Get the first word's index & point to it. */ @@ -1210,7 +1210,7 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = XFS_BLOCKWMASK(mp); b = &bufp[word]; } else { @@ -1256,7 +1256,7 @@ xfs_rtfind_back( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = XFS_BLOCKWMASK(mp); b = &bufp[word]; } else { @@ -1333,7 +1333,7 @@ xfs_rtfind_forw( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Get the first word's index & point to it. */ @@ -1384,7 +1384,7 @@ xfs_rtfind_forw( if (error) { return error; } - b = bufp = bp->b_addr; + b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1429,7 +1429,7 @@ xfs_rtfind_forw( if (error) { return error; } - b = bufp = bp->b_addr; + b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1649,7 +1649,7 @@ xfs_rtmodify_range( if (error) { return error; } - bufp = bp->b_addr; + bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); /* * Compute the starting word's address, and starting bit. */ @@ -1694,7 +1694,7 @@ xfs_rtmodify_range( if (error) { return error; } - first = b = bufp = bp->b_addr; + first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1734,7 +1734,7 @@ xfs_rtmodify_range( if (error) { return error; } - first = b = bufp = bp->b_addr; + first = b = bufp = (xfs_rtword_t *)XFS_BUF_PTR(bp); word = 0; } else { /* @@ -1832,8 +1832,8 @@ xfs_rtmodify_summary( */ sp = XFS_SUMPTR(mp, bp, so); *sp += delta; - xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)bp->b_addr), - (uint)((char *)sp - (char *)bp->b_addr + sizeof(*sp) - 1)); + xfs_trans_log_buf(tp, bp, (uint)((char *)sp - (char *)XFS_BUF_PTR(bp)), + (uint)((char *)sp - (char *)XFS_BUF_PTR(bp) + sizeof(*sp) - 1)); return 0; } diff --git a/trunk/fs/xfs/xfs_rtalloc.h b/trunk/fs/xfs/xfs_rtalloc.h index f7f3a359c1c5..09e1f4f35e97 100644 --- a/trunk/fs/xfs/xfs_rtalloc.h +++ b/trunk/fs/xfs/xfs_rtalloc.h @@ -47,7 +47,7 @@ struct xfs_trans; #define XFS_SUMOFFSTOBLOCK(mp,s) \ (((s) * (uint)sizeof(xfs_suminfo_t)) >> (mp)->m_sb.sb_blocklog) #define XFS_SUMPTR(mp,bp,so) \ - ((xfs_suminfo_t *)((bp)->b_addr + \ + ((xfs_suminfo_t *)((char *)XFS_BUF_PTR(bp) + \ (((so) * (uint)sizeof(xfs_suminfo_t)) & XFS_BLOCKMASK(mp)))) #define XFS_BITTOBLOCK(mp,bi) ((bi) >> (mp)->m_blkbit_log) diff --git a/trunk/fs/xfs/xfs_rw.c b/trunk/fs/xfs/xfs_rw.c index c96a8a05ac03..d6d6fdfe9422 100644 --- a/trunk/fs/xfs/xfs_rw.c +++ b/trunk/fs/xfs/xfs_rw.c @@ -104,9 +104,9 @@ xfs_ioerror_alert( xfs_alert(mp, "I/O error occurred: meta-data dev %s block 0x%llx" " (\"%s\") error %d buf count %zd", - xfs_buf_target_name(bp->b_target), + XFS_BUFTARG_NAME(XFS_BUF_TARGET(bp)), (__uint64_t)blkno, func, - bp->b_error, XFS_BUF_COUNT(bp)); + XFS_BUF_GETERROR(bp), XFS_BUF_COUNT(bp)); } /* @@ -137,8 +137,8 @@ xfs_read_buf( bp = xfs_buf_read(target, blkno, len, flags); if (!bp) return XFS_ERROR(EIO); - error = bp->b_error; - if (!error && !XFS_FORCED_SHUTDOWN(mp)) { + error = XFS_BUF_GETERROR(bp); + if (bp && !error && !XFS_FORCED_SHUTDOWN(mp)) { *bpp = bp; } else { *bpp = NULL; diff --git a/trunk/fs/xfs/xfs_sb.h b/trunk/fs/xfs/xfs_sb.h index cb6ae715814a..1eb2ba586814 100644 --- a/trunk/fs/xfs/xfs_sb.h +++ b/trunk/fs/xfs/xfs_sb.h @@ -509,7 +509,7 @@ static inline int xfs_sb_version_hasprojid32bit(xfs_sb_t *sbp) #define XFS_SB_DADDR ((xfs_daddr_t)0) /* daddr in filesystem/ag */ #define XFS_SB_BLOCK(mp) XFS_HDR_BLOCK(mp, XFS_SB_DADDR) -#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)((bp)->b_addr)) +#define XFS_BUF_TO_SBP(bp) ((xfs_dsb_t *)XFS_BUF_PTR(bp)) #define XFS_HDR_BLOCK(mp,d) ((xfs_agblock_t)XFS_BB_TO_FSBT(mp,d)) #define XFS_DADDR_TO_FSB(mp,d) XFS_AGB_TO_FSB(mp, \ diff --git a/trunk/fs/xfs/xfs_trans_ail.c b/trunk/fs/xfs/xfs_trans_ail.c index c15aa29fa169..43233e92f0f6 100644 --- a/trunk/fs/xfs/xfs_trans_ail.c +++ b/trunk/fs/xfs/xfs_trans_ail.c @@ -299,7 +299,7 @@ xfs_trans_ail_cursor_last( * Splice the log item list into the AIL at the given LSN. We splice to the * tail of the given LSN to maintain insert order for push traversals. The * cursor is optional, allowing repeated updates to the same LSN to avoid - * repeated traversals. This should not be called with an empty list. + * repeated traversals. */ static void xfs_ail_splice( @@ -308,39 +308,50 @@ xfs_ail_splice( struct list_head *list, xfs_lsn_t lsn) { - struct xfs_log_item *lip; - - ASSERT(!list_empty(list)); + struct xfs_log_item *lip = cur ? cur->item : NULL; + struct xfs_log_item *next_lip; /* - * Use the cursor to determine the insertion point if one is - * provided. If not, or if the one we got is not valid, - * find the place in the AIL where the items belong. + * Get a new cursor if we don't have a placeholder or the existing one + * has been invalidated. */ - lip = cur ? cur->item : NULL; - if (!lip || (__psint_t) lip & 1) + if (!lip || (__psint_t)lip & 1) { lip = __xfs_trans_ail_cursor_last(ailp, lsn); - /* - * If a cursor is provided, we know we're processing the AIL - * in lsn order, and future items to be spliced in will - * follow the last one being inserted now. Update the - * cursor to point to that last item, now while we have a - * reliable pointer to it. - */ - if (cur) - cur->item = list_entry(list->prev, struct xfs_log_item, li_ail); + if (!lip) { + /* The list is empty, so just splice and return. */ + if (cur) + cur->item = NULL; + list_splice(list, &ailp->xa_ail); + return; + } + } /* - * Finally perform the splice. Unless the AIL was empty, - * lip points to the item in the AIL _after_ which the new - * items should go. If lip is null the AIL was empty, so - * the new items go at the head of the AIL. + * Our cursor points to the item we want to insert _after_, so we have + * to update the cursor to point to the end of the list we are splicing + * in so that it points to the correct location for the next splice. + * i.e. before the splice + * + * lsn -> lsn -> lsn + x -> lsn + x ... + * ^ + * | cursor points here + * + * After the splice we have: + * + * lsn -> lsn -> lsn -> lsn -> .... -> lsn -> lsn + x -> lsn + x ... + * ^ ^ + * | cursor points here | needs to move here + * + * So we set the cursor to the last item in the list to be spliced + * before we execute the splice, resulting in the cursor pointing to + * the correct item after the splice occurs. */ - if (lip) - list_splice(list, &lip->li_ail); - else - list_splice(list, &ailp->xa_ail); + if (cur) { + next_lip = list_entry(list->prev, struct xfs_log_item, li_ail); + cur->item = next_lip; + } + list_splice(list, &lip->li_ail); } /* @@ -671,7 +682,6 @@ xfs_trans_ail_update_bulk( int i; LIST_HEAD(tmp); - ASSERT(nr_items > 0); /* Not required, but true. */ mlip = xfs_ail_min(ailp); for (i = 0; i < nr_items; i++) { @@ -691,8 +701,7 @@ xfs_trans_ail_update_bulk( list_add(&lip->li_ail, &tmp); } - if (!list_empty(&tmp)) - xfs_ail_splice(ailp, cur, &tmp, lsn); + xfs_ail_splice(ailp, cur, &tmp, lsn); if (!mlip_changed) { spin_unlock(&ailp->xa_lock); diff --git a/trunk/fs/xfs/xfs_trans_buf.c b/trunk/fs/xfs/xfs_trans_buf.c index 137e2b9e2948..15584fc3ed7d 100644 --- a/trunk/fs/xfs/xfs_trans_buf.c +++ b/trunk/fs/xfs/xfs_trans_buf.c @@ -54,7 +54,7 @@ xfs_trans_buf_item_match( list_for_each_entry(lidp, &tp->t_items, lid_trans) { blip = (struct xfs_buf_log_item *)lidp->lid_item; if (blip->bli_item.li_type == XFS_LI_BUF && - blip->bli_buf->b_target == target && + XFS_BUF_TARGET(blip->bli_buf) == target && XFS_BUF_ADDR(blip->bli_buf) == blkno && XFS_BUF_COUNT(blip->bli_buf) == len) return blip->bli_buf; @@ -80,6 +80,7 @@ _xfs_trans_bjoin( { struct xfs_buf_log_item *bip; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == NULL); /* @@ -193,7 +194,7 @@ xfs_trans_get_buf(xfs_trans_t *tp, return NULL; } - ASSERT(!bp->b_error); + ASSERT(!XFS_BUF_GETERROR(bp)); _xfs_trans_bjoin(tp, bp, 1); trace_xfs_trans_get_buf(bp->b_fspriv); @@ -292,10 +293,10 @@ xfs_trans_read_buf( return (flags & XBF_TRYLOCK) ? EAGAIN : XFS_ERROR(ENOMEM); - if (bp->b_error) { - error = bp->b_error; + if (XFS_BUF_GETERROR(bp) != 0) { xfs_ioerror_alert("xfs_trans_read_buf", mp, bp, blkno); + error = XFS_BUF_GETERROR(bp); xfs_buf_relse(bp); return error; } @@ -329,7 +330,7 @@ xfs_trans_read_buf( ASSERT(xfs_buf_islocked(bp)); ASSERT(bp->b_transp == tp); ASSERT(bp->b_fspriv != NULL); - ASSERT(!bp->b_error); + ASSERT((XFS_BUF_ISERROR(bp)) == 0); if (!(XFS_BUF_ISDONE(bp))) { trace_xfs_trans_read_buf_io(bp, _RET_IP_); ASSERT(!XFS_BUF_ISASYNC(bp)); @@ -385,9 +386,10 @@ xfs_trans_read_buf( return (flags & XBF_TRYLOCK) ? 0 : XFS_ERROR(ENOMEM); } - if (bp->b_error) { - error = bp->b_error; - XFS_BUF_SUPER_STALE(bp); + if (XFS_BUF_GETERROR(bp) != 0) { + XFS_BUF_SUPER_STALE(bp); + error = XFS_BUF_GETERROR(bp); + xfs_ioerror_alert("xfs_trans_read_buf", mp, bp, blkno); if (tp->t_flags & XFS_TRANS_DIRTY) @@ -428,7 +430,7 @@ xfs_trans_read_buf( if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp)) xfs_notice(mp, "about to pop assert, bp == 0x%p", bp); #endif - ASSERT((bp->b_flags & (XBF_STALE|XBF_DELWRI)) != + ASSERT((XFS_BUF_BFLAGS(bp) & (XBF_STALE|XBF_DELWRI)) != (XBF_STALE|XBF_DELWRI)); trace_xfs_trans_read_buf_shut(bp, _RET_IP_); @@ -579,6 +581,7 @@ xfs_trans_bhold(xfs_trans_t *tp, { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); @@ -599,6 +602,7 @@ xfs_trans_bhold_release(xfs_trans_t *tp, { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); @@ -627,6 +631,7 @@ xfs_trans_log_buf(xfs_trans_t *tp, { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp))); @@ -697,6 +702,7 @@ xfs_trans_binval( { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); @@ -768,6 +774,7 @@ xfs_trans_inode_buf( { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); @@ -791,6 +798,7 @@ xfs_trans_stale_inode_buf( { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); @@ -815,6 +823,7 @@ xfs_trans_inode_alloc_buf( { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(atomic_read(&bip->bli_refcount) > 0); @@ -842,6 +851,7 @@ xfs_trans_dquot_buf( { xfs_buf_log_item_t *bip = bp->b_fspriv; + ASSERT(XFS_BUF_ISBUSY(bp)); ASSERT(bp->b_transp == tp); ASSERT(bip != NULL); ASSERT(type == XFS_BLF_UDQUOT_BUF || diff --git a/trunk/fs/xfs/xfs_vnodeops.c b/trunk/fs/xfs/xfs_vnodeops.c index 51fc429527bc..9322e13f0c63 100644 --- a/trunk/fs/xfs/xfs_vnodeops.c +++ b/trunk/fs/xfs/xfs_vnodeops.c @@ -83,9 +83,7 @@ xfs_readlink_bmap( bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), XBF_LOCK | XBF_MAPPED | XBF_DONT_BLOCK); - if (!bp) - return XFS_ERROR(ENOMEM); - error = bp->b_error; + error = XFS_BUF_GETERROR(bp); if (error) { xfs_ioerror_alert("xfs_readlink", ip->i_mount, bp, XFS_BUF_ADDR(bp)); @@ -96,7 +94,7 @@ xfs_readlink_bmap( byte_cnt = pathlen; pathlen -= byte_cnt; - memcpy(link, bp->b_addr, byte_cnt); + memcpy(link, XFS_BUF_PTR(bp), byte_cnt); xfs_buf_relse(bp); } @@ -1650,13 +1648,13 @@ xfs_symlink( byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount); bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d, BTOBB(byte_cnt), 0); - ASSERT(!xfs_buf_geterror(bp)); + ASSERT(bp && !XFS_BUF_GETERROR(bp)); if (pathlen < byte_cnt) { byte_cnt = pathlen; } pathlen -= byte_cnt; - memcpy(bp->b_addr, cur_chunk, byte_cnt); + memcpy(XFS_BUF_PTR(bp), cur_chunk, byte_cnt); cur_chunk += byte_cnt; xfs_trans_log_buf(tp, bp, 0, byte_cnt - 1); @@ -2001,7 +1999,7 @@ xfs_zero_remaining_bytes( mp, bp, XFS_BUF_ADDR(bp)); break; } - memset(bp->b_addr + + memset(XFS_BUF_PTR(bp) + (offset - XFS_FSB_TO_B(mp, imap.br_startoff)), 0, lastoffset - offset + 1); XFS_BUF_UNDONE(bp); diff --git a/trunk/include/acpi/acpi_drivers.h b/trunk/include/acpi/acpi_drivers.h index e49c36d38d7e..3090471b2a5e 100644 --- a/trunk/include/acpi/acpi_drivers.h +++ b/trunk/include/acpi/acpi_drivers.h @@ -128,7 +128,7 @@ extern int is_dock_device(acpi_handle handle); extern int register_dock_notifier(struct notifier_block *nb); extern void unregister_dock_notifier(struct notifier_block *nb); extern int register_hotplug_dock_device(acpi_handle handle, - const struct acpi_dock_ops *ops, + struct acpi_dock_ops *ops, void *context); extern void unregister_hotplug_dock_device(acpi_handle handle); #else diff --git a/trunk/include/acpi/acpixf.h b/trunk/include/acpi/acpixf.h index f554a9313b43..2ed0a8486c19 100644 --- a/trunk/include/acpi/acpixf.h +++ b/trunk/include/acpi/acpixf.h @@ -47,7 +47,7 @@ /* Current ACPICA subsystem version in YYYYMMDD format */ -#define ACPI_CA_VERSION 0x20110623 +#define ACPI_CA_VERSION 0x20110413 #include "actypes.h" #include "actbl.h" @@ -69,7 +69,6 @@ extern u32 acpi_gbl_trace_flags; extern u32 acpi_gbl_enable_aml_debug_object; extern u8 acpi_gbl_copy_dsdt_locally; extern u8 acpi_gbl_truncate_io_addresses; -extern u8 acpi_gbl_disable_auto_repair; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; diff --git a/trunk/include/acpi/apei.h b/trunk/include/acpi/apei.h index 51a527d24a8a..e67b523a50e1 100644 --- a/trunk/include/acpi/apei.h +++ b/trunk/include/acpi/apei.h @@ -18,11 +18,6 @@ extern int hest_disable; extern int erst_disable; -#ifdef CONFIG_ACPI_APEI_GHES -extern int ghes_disable; -#else -#define ghes_disable 1 -#endif #ifdef CONFIG_ACPI_APEI void __init acpi_hest_init(void); diff --git a/trunk/include/acpi/processor.h b/trunk/include/acpi/processor.h index 67055f180330..ba4928cae473 100644 --- a/trunk/include/acpi/processor.h +++ b/trunk/include/acpi/processor.h @@ -337,7 +337,7 @@ extern struct cpuidle_driver acpi_idle_driver; /* in processor_thermal.c */ int acpi_processor_get_limit_info(struct acpi_processor *pr); -extern const struct thermal_cooling_device_ops processor_cooling_ops; +extern struct thermal_cooling_device_ops processor_cooling_ops; #ifdef CONFIG_CPU_FREQ void acpi_thermal_cpufreq_init(void); void acpi_thermal_cpufreq_exit(void); diff --git a/trunk/include/drm/drm_crtc.h b/trunk/include/drm/drm_crtc.h index 44335e57eaaa..33d12f87f0e0 100644 --- a/trunk/include/drm/drm_crtc.h +++ b/trunk/include/drm/drm_crtc.h @@ -205,8 +205,6 @@ struct drm_display_info { enum subpixel_order subpixel_order; u32 color_formats; - u8 cea_rev; - char *raw_edid; /* if any */ }; @@ -804,7 +802,6 @@ extern struct drm_display_mode *drm_gtf_mode_complex(struct drm_device *dev, extern int drm_add_modes_noedid(struct drm_connector *connector, int hdisplay, int vdisplay); -extern int drm_edid_header_is_valid(const u8 *raw_edid); extern bool drm_edid_is_valid(struct edid *edid); struct drm_display_mode *drm_mode_find_dmt(struct drm_device *dev, int hsize, int vsize, int fresh); diff --git a/trunk/include/drm/i915_drm.h b/trunk/include/drm/i915_drm.h index 28c0d114cb52..c4d6dbfa3ff4 100644 --- a/trunk/include/drm/i915_drm.h +++ b/trunk/include/drm/i915_drm.h @@ -237,7 +237,7 @@ typedef struct _drm_i915_sarea { #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_i915_get_pipe_from_crtc_id) #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) -#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_I915_OVERLAY_PUT_IMAGE, struct drm_intel_overlay_put_image) +#define DRM_IOCTL_I915_OVERLAY_PUT_IMAGE DRM_IOW(DRM_COMMAND_BASE + DRM_IOCTL_I915_OVERLAY_ATTRS, struct drm_intel_overlay_put_image) #define DRM_IOCTL_I915_OVERLAY_ATTRS DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_OVERLAY_ATTRS, struct drm_intel_overlay_attrs) /* Allow drivers to submit batchbuffers directly to hardware, relying diff --git a/trunk/include/linux/acpi.h b/trunk/include/linux/acpi.h index 6001b4da39dd..1deb2a73c2da 100644 --- a/trunk/include/linux/acpi.h +++ b/trunk/include/linux/acpi.h @@ -238,6 +238,7 @@ extern int acpi_paddr_to_node(u64 start_addr, u64 size); extern int pnpacpi_disabled; #define PXM_INVAL (-1) +#define NID_INVAL (-1) int acpi_check_resource_conflict(const struct resource *res); @@ -279,8 +280,6 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); #define OSC_SB_CPUHP_OST_SUPPORT 8 #define OSC_SB_APEI_SUPPORT 16 -extern bool osc_sb_apei_support_acked; - /* PCI defined _OSC bits */ /* _OSC DW1 Definition (OS Support Fields) */ #define OSC_EXT_PCI_CONFIG_SUPPORT 1 diff --git a/trunk/include/linux/bitmap.h b/trunk/include/linux/bitmap.h index 7ad634501e48..3bac44cce142 100644 --- a/trunk/include/linux/bitmap.h +++ b/trunk/include/linux/bitmap.h @@ -146,7 +146,6 @@ extern int bitmap_allocate_region(unsigned long *bitmap, int pos, int order); extern void bitmap_copy_le(void *dst, const unsigned long *src, int nbits); extern int bitmap_ord_to_pos(const unsigned long *bitmap, int n, int bits); -#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) #define BITMAP_LAST_WORD_MASK(nbits) \ ( \ ((nbits) % BITS_PER_LONG) ? \ diff --git a/trunk/include/linux/cpuidle.h b/trunk/include/linux/cpuidle.h index b51629e15cfc..36719ead50e8 100644 --- a/trunk/include/linux/cpuidle.h +++ b/trunk/include/linux/cpuidle.h @@ -122,8 +122,6 @@ struct cpuidle_driver { }; #ifdef CONFIG_CPU_IDLE -extern void disable_cpuidle(void); -extern int cpuidle_idle_call(void); extern int cpuidle_register_driver(struct cpuidle_driver *drv); struct cpuidle_driver *cpuidle_get_driver(void); @@ -137,8 +135,6 @@ extern int cpuidle_enable_device(struct cpuidle_device *dev); extern void cpuidle_disable_device(struct cpuidle_device *dev); #else -static inline void disable_cpuidle(void) { } -static inline int cpuidle_idle_call(void) { return -ENODEV; } static inline int cpuidle_register_driver(struct cpuidle_driver *drv) {return -ENODEV; } diff --git a/trunk/include/linux/cred.h b/trunk/include/linux/cred.h index 40308969ed00..48e82af1159b 100644 --- a/trunk/include/linux/cred.h +++ b/trunk/include/linux/cred.h @@ -265,11 +265,10 @@ static inline void put_cred(const struct cred *_cred) /** * current_cred - Access the current task's subjective credentials * - * Access the subjective credentials of the current task. RCU-safe, - * since nobody else can modify it. + * Access the subjective credentials of the current task. */ #define current_cred() \ - rcu_dereference_protected(current->cred, 1) + (current->cred) /** * __task_cred - Access a task's objective credentials @@ -307,8 +306,8 @@ static inline void put_cred(const struct cred *_cred) #define get_current_user() \ ({ \ struct user_struct *__u; \ - const struct cred *__cred; \ - __cred = current_cred(); \ + struct cred *__cred; \ + __cred = (struct cred *) current_cred(); \ __u = get_uid(__cred->user); \ __u; \ }) @@ -322,8 +321,8 @@ static inline void put_cred(const struct cred *_cred) #define get_current_groups() \ ({ \ struct group_info *__groups; \ - const struct cred *__cred; \ - __cred = current_cred(); \ + struct cred *__cred; \ + __cred = (struct cred *) current_cred(); \ __groups = get_group_info(__cred->group_info); \ __groups; \ }) @@ -342,7 +341,7 @@ static inline void put_cred(const struct cred *_cred) #define current_cred_xxx(xxx) \ ({ \ - current_cred()->xxx; \ + current->cred->xxx; \ }) #define current_uid() (current_cred_xxx(uid)) diff --git a/trunk/include/linux/cryptohash.h b/trunk/include/linux/cryptohash.h index 2cd9f1cf9fa3..ec78a4bbe1d5 100644 --- a/trunk/include/linux/cryptohash.h +++ b/trunk/include/linux/cryptohash.h @@ -3,16 +3,11 @@ #define SHA_DIGEST_WORDS 5 #define SHA_MESSAGE_BYTES (512 /*bits*/ / 8) -#define SHA_WORKSPACE_WORDS 16 +#define SHA_WORKSPACE_WORDS 80 void sha_init(__u32 *buf); void sha_transform(__u32 *digest, const char *data, __u32 *W); -#define MD5_DIGEST_WORDS 4 -#define MD5_MESSAGE_BYTES 64 - -void md5_transform(__u32 *hash, __u32 const *in); - __u32 half_md4_transform(__u32 buf[4], __u32 const in[8]); #endif diff --git a/trunk/include/linux/dcache.h b/trunk/include/linux/dcache.h index 62157c03caf7..d37d2a793099 100644 --- a/trunk/include/linux/dcache.h +++ b/trunk/include/linux/dcache.h @@ -180,12 +180,12 @@ struct dentry_operations { */ /* d_flags entries */ -#define DCACHE_OP_HASH 0x0001 -#define DCACHE_OP_COMPARE 0x0002 -#define DCACHE_OP_REVALIDATE 0x0004 -#define DCACHE_OP_DELETE 0x0008 +#define DCACHE_AUTOFS_PENDING 0x0001 /* autofs: "under construction" */ +#define DCACHE_NFSFS_RENAMED 0x0002 + /* this dentry has been "silly renamed" and has to be deleted on the last + * dput() */ -#define DCACHE_DISCONNECTED 0x0010 +#define DCACHE_DISCONNECTED 0x0004 /* This dentry is possibly not currently connected to the dcache tree, in * which case its parent will either be itself, or will have this flag as * well. nfsd will not use a dentry with this bit set, but will first @@ -196,18 +196,22 @@ struct dentry_operations { * dentry into place and return that dentry rather than the passed one, * typically using d_splice_alias. */ -#define DCACHE_REFERENCED 0x0020 /* Recently used, don't discard. */ -#define DCACHE_RCUACCESS 0x0040 /* Entry has ever been RCU-visible */ +#define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ +#define DCACHE_RCUACCESS 0x0010 /* Entry has ever been RCU-visible */ +#define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 + /* Parent inode is watched by inotify */ + +#define DCACHE_COOKIE 0x0040 /* For use by dcookie subsystem */ +#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x0080 + /* Parent inode is watched by some fsnotify listener */ #define DCACHE_CANT_MOUNT 0x0100 #define DCACHE_GENOCIDE 0x0200 -#define DCACHE_NFSFS_RENAMED 0x1000 - /* this dentry has been "silly renamed" and has to be deleted on the last - * dput() */ -#define DCACHE_COOKIE 0x2000 /* For use by dcookie subsystem */ -#define DCACHE_FSNOTIFY_PARENT_WATCHED 0x4000 - /* Parent inode is watched by some fsnotify listener */ +#define DCACHE_OP_HASH 0x1000 +#define DCACHE_OP_COMPARE 0x2000 +#define DCACHE_OP_REVALIDATE 0x4000 +#define DCACHE_OP_DELETE 0x8000 #define DCACHE_MOUNTED 0x10000 /* is a mountpoint */ #define DCACHE_NEED_AUTOMOUNT 0x20000 /* handle automount on this dir */ diff --git a/trunk/include/linux/device-mapper.h b/trunk/include/linux/device-mapper.h index 3fa1f3d90ce0..4427e0454051 100644 --- a/trunk/include/linux/device-mapper.h +++ b/trunk/include/linux/device-mapper.h @@ -208,49 +208,6 @@ struct dm_target_callbacks { int dm_register_target(struct target_type *t); void dm_unregister_target(struct target_type *t); -/* - * Target argument parsing. - */ -struct dm_arg_set { - unsigned argc; - char **argv; -}; - -/* - * The minimum and maximum value of a numeric argument, together with - * the error message to use if the number is found to be outside that range. - */ -struct dm_arg { - unsigned min; - unsigned max; - char *error; -}; - -/* - * Validate the next argument, either returning it as *value or, if invalid, - * returning -EINVAL and setting *error. - */ -int dm_read_arg(struct dm_arg *arg, struct dm_arg_set *arg_set, - unsigned *value, char **error); - -/* - * Process the next argument as the start of a group containing between - * arg->min and arg->max further arguments. Either return the size as - * *num_args or, if invalid, return -EINVAL and set *error. - */ -int dm_read_arg_group(struct dm_arg *arg, struct dm_arg_set *arg_set, - unsigned *num_args, char **error); - -/* - * Return the current argument and shift to the next. - */ -const char *dm_shift_arg(struct dm_arg_set *as); - -/* - * Move through num_args arguments. - */ -void dm_consume_args(struct dm_arg_set *as, unsigned num_args); - /*----------------------------------------------------------------- * Functions for creating and manipulating mapped devices. * Drop the reference with dm_put when you finish with the object. diff --git a/trunk/include/linux/dm-ioctl.h b/trunk/include/linux/dm-ioctl.h index 0cb8eff76bd6..3708455ee6c3 100644 --- a/trunk/include/linux/dm-ioctl.h +++ b/trunk/include/linux/dm-ioctl.h @@ -267,9 +267,9 @@ enum { #define DM_DEV_SET_GEOMETRY _IOWR(DM_IOCTL, DM_DEV_SET_GEOMETRY_CMD, struct dm_ioctl) #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 21 +#define DM_VERSION_MINOR 20 #define DM_VERSION_PATCHLEVEL 0 -#define DM_VERSION_EXTRA "-ioctl (2011-07-06)" +#define DM_VERSION_EXTRA "-ioctl (2011-02-02)" /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ diff --git a/trunk/include/linux/dm-kcopyd.h b/trunk/include/linux/dm-kcopyd.h index 5e54458e920f..298d587e349b 100644 --- a/trunk/include/linux/dm-kcopyd.h +++ b/trunk/include/linux/dm-kcopyd.h @@ -42,20 +42,5 @@ int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, unsigned num_dests, struct dm_io_region *dests, unsigned flags, dm_kcopyd_notify_fn fn, void *context); -/* - * Prepare a callback and submit it via the kcopyd thread. - * - * dm_kcopyd_prepare_callback allocates a callback structure and returns it. - * It must not be called from interrupt context. - * The returned value should be passed into dm_kcopyd_do_callback. - * - * dm_kcopyd_do_callback submits the callback. - * It may be called from interrupt context. - * The callback is issued from the kcopyd thread. - */ -void *dm_kcopyd_prepare_callback(struct dm_kcopyd_client *kc, - dm_kcopyd_notify_fn fn, void *context); -void dm_kcopyd_do_callback(void *job, int read_err, unsigned long write_err); - #endif /* __KERNEL__ */ #endif /* _LINUX_DM_KCOPYD_H */ diff --git a/trunk/include/linux/fault-inject.h b/trunk/include/linux/fault-inject.h index c6f996f2abb6..3ff060ac7810 100644 --- a/trunk/include/linux/fault-inject.h +++ b/trunk/include/linux/fault-inject.h @@ -25,6 +25,10 @@ struct fault_attr { unsigned long reject_end; unsigned long count; + +#ifdef CONFIG_FAULT_INJECTION_DEBUG_FS + struct dentry *dir; +#endif }; #define FAULT_ATTR_INITIALIZER { \ @@ -41,15 +45,19 @@ bool should_fail(struct fault_attr *attr, ssize_t size); #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS -struct dentry *fault_create_debugfs_attr(const char *name, - struct dentry *parent, struct fault_attr *attr); +int init_fault_attr_dentries(struct fault_attr *attr, const char *name); +void cleanup_fault_attr_dentries(struct fault_attr *attr); #else /* CONFIG_FAULT_INJECTION_DEBUG_FS */ -static inline struct dentry *fault_create_debugfs_attr(const char *name, - struct dentry *parent, struct fault_attr *attr) +static inline int init_fault_attr_dentries(struct fault_attr *attr, + const char *name) +{ + return -ENODEV; +} + +static inline void cleanup_fault_attr_dentries(struct fault_attr *attr) { - return ERR_PTR(-ENODEV); } #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index 178cdb4f1d4a..786b3b1113cf 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -738,55 +738,23 @@ static inline int mapping_writably_mapped(struct address_space *mapping) struct posix_acl; #define ACL_NOT_CACHED ((void *)(-1)) -#define IOP_FASTPERM 0x0001 -#define IOP_LOOKUP 0x0002 -#define IOP_NOFOLLOW 0x0004 - -/* - * Keep mostly read-only and often accessed (especially for - * the RCU path lookup and 'stat' data) fields at the beginning - * of the 'struct inode' - */ struct inode { + /* RCU path lookup touches following: */ umode_t i_mode; - unsigned short i_opflags; uid_t i_uid; gid_t i_gid; - unsigned int i_flags; - -#ifdef CONFIG_FS_POSIX_ACL - struct posix_acl *i_acl; - struct posix_acl *i_default_acl; -#endif - const struct inode_operations *i_op; struct super_block *i_sb; - struct address_space *i_mapping; + spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ + unsigned int i_flags; + unsigned long i_state; #ifdef CONFIG_SECURITY void *i_security; #endif - - /* Stat data, not accessed from path walking */ - unsigned long i_ino; - unsigned int i_nlink; - dev_t i_rdev; - loff_t i_size; - struct timespec i_atime; - struct timespec i_mtime; - struct timespec i_ctime; - unsigned int i_blkbits; - blkcnt_t i_blocks; - -#ifdef __NEED_I_SIZE_ORDERED - seqcount_t i_size_seqcount; -#endif - - /* Misc */ - unsigned long i_state; - spinlock_t i_lock; /* i_blocks, i_bytes, maybe i_size */ struct mutex i_mutex; + unsigned long dirtied_when; /* jiffies of first dirtying */ struct hlist_node i_hash; @@ -797,12 +765,25 @@ struct inode { struct list_head i_dentry; struct rcu_head i_rcu; }; + unsigned long i_ino; atomic_t i_count; + unsigned int i_nlink; + dev_t i_rdev; + unsigned int i_blkbits; u64 i_version; + loff_t i_size; +#ifdef __NEED_I_SIZE_ORDERED + seqcount_t i_size_seqcount; +#endif + struct timespec i_atime; + struct timespec i_mtime; + struct timespec i_ctime; + blkcnt_t i_blocks; unsigned short i_bytes; atomic_t i_dio_count; const struct file_operations *i_fop; /* former ->i_op->default_file_ops */ struct file_lock *i_flock; + struct address_space *i_mapping; struct address_space i_data; #ifdef CONFIG_QUOTA struct dquot *i_dquot[MAXQUOTAS]; @@ -825,6 +806,10 @@ struct inode { atomic_t i_readcount; /* struct files open RO */ #endif atomic_t i_writecount; +#ifdef CONFIG_FS_POSIX_ACL + struct posix_acl *i_acl; + struct posix_acl *i_default_acl; +#endif void *i_private; /* fs or device private pointer */ }; diff --git a/trunk/include/linux/genalloc.h b/trunk/include/linux/genalloc.h index 5e98eeb2af3b..5bbebda78b02 100644 --- a/trunk/include/linux/genalloc.h +++ b/trunk/include/linux/genalloc.h @@ -1,26 +1,8 @@ /* - * Basic general purpose allocator for managing special purpose - * memory, for example, memory that is not managed by the regular - * kmalloc/kfree interface. Uses for this includes on-device special - * memory, uncached memory etc. - * - * It is safe to use the allocator in NMI handlers and other special - * unblockable contexts that could otherwise deadlock on locks. This - * is implemented by using atomic operations and retries on any - * conflicts. The disadvantage is that there may be livelocks in - * extreme cases. For better scalability, one allocator can be used - * for each CPU. - * - * The lockless operation only works if there is enough memory - * available. If new memory is added to the pool a lock has to be - * still taken. So any user relying on locklessness has to ensure - * that sufficient memory is preallocated. - * - * The basic atomic operation of this allocator is cmpxchg on long. - * On architectures that don't have NMI-safe cmpxchg implementation, - * the allocator can NOT be used in NMI handler. So code uses the - * allocator in NMI handler should depend on - * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. + * Basic general purpose allocator for managing special purpose memory + * not managed by the regular kmalloc/kfree interface. + * Uses for this includes on-device special memory, uncached memory + * etc. * * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. @@ -33,7 +15,7 @@ * General purpose special memory pool descriptor. */ struct gen_pool { - spinlock_t lock; + rwlock_t lock; struct list_head chunks; /* list of chunks in this pool */ int min_alloc_order; /* minimum allocation order */ }; @@ -42,8 +24,8 @@ struct gen_pool { * General purpose special memory pool chunk descriptor. */ struct gen_pool_chunk { + spinlock_t lock; struct list_head next_chunk; /* next chunk in pool */ - atomic_t avail; phys_addr_t phys_addr; /* physical starting address of memory chunk */ unsigned long start_addr; /* starting address of memory chunk */ unsigned long end_addr; /* ending address of memory chunk */ @@ -74,8 +56,4 @@ static inline int gen_pool_add(struct gen_pool *pool, unsigned long addr, extern void gen_pool_destroy(struct gen_pool *); extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); -extern void gen_pool_for_each_chunk(struct gen_pool *, - void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); -extern size_t gen_pool_avail(struct gen_pool *); -extern size_t gen_pool_size(struct gen_pool *); #endif /* __GENALLOC_H__ */ diff --git a/trunk/include/linux/gfp.h b/trunk/include/linux/gfp.h index 3a76faf6a3ee..cb4089254f01 100644 --- a/trunk/include/linux/gfp.h +++ b/trunk/include/linux/gfp.h @@ -92,7 +92,7 @@ struct vm_area_struct; */ #define __GFP_NOTRACK_FALSE_POSITIVE (__GFP_NOTRACK) -#define __GFP_BITS_SHIFT 24 /* Room for N __GFP_FOO bits */ +#define __GFP_BITS_SHIFT 23 /* Room for 23 __GFP_FOO bits */ #define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) /* This equals 0, but use constants in case they ever change */ diff --git a/trunk/include/linux/idr.h b/trunk/include/linux/idr.h index 255491cf522e..13a801f3d028 100644 --- a/trunk/include/linux/idr.h +++ b/trunk/include/linux/idr.h @@ -146,10 +146,6 @@ void ida_remove(struct ida *ida, int id); void ida_destroy(struct ida *ida); void ida_init(struct ida *ida); -int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, - gfp_t gfp_mask); -void ida_simple_remove(struct ida *ida, unsigned int id); - void __init idr_init_cache(void); #endif /* __IDR_H__ */ diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index a637e7814334..068784e17972 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -438,8 +438,6 @@ struct input_keymap_entry { #define KEY_WIMAX 246 #define KEY_RFKILL 247 /* Key that controls all radios */ -#define KEY_MICMUTE 248 /* Mute / unmute the microphone */ - /* Code 255 is reserved for special needs of AT keyboard driver */ #define BTN_MISC 0x100 diff --git a/trunk/include/linux/llist.h b/trunk/include/linux/llist.h deleted file mode 100644 index aa0c8b5b3cd0..000000000000 --- a/trunk/include/linux/llist.h +++ /dev/null @@ -1,126 +0,0 @@ -#ifndef LLIST_H -#define LLIST_H -/* - * Lock-less NULL terminated single linked list - * - * If there are multiple producers and multiple consumers, llist_add - * can be used in producers and llist_del_all can be used in - * consumers. They can work simultaneously without lock. But - * llist_del_first can not be used here. Because llist_del_first - * depends on list->first->next does not changed if list->first is not - * changed during its operation, but llist_del_first, llist_add, - * llist_add (or llist_del_all, llist_add, llist_add) sequence in - * another consumer may violate that. - * - * If there are multiple producers and one consumer, llist_add can be - * used in producers and llist_del_all or llist_del_first can be used - * in the consumer. - * - * This can be summarized as follow: - * - * | add | del_first | del_all - * add | - | - | - - * del_first | | L | L - * del_all | | | - - * - * Where "-" stands for no lock is needed, while "L" stands for lock - * is needed. - * - * The list entries deleted via llist_del_all can be traversed with - * traversing function such as llist_for_each etc. But the list - * entries can not be traversed safely before deleted from the list. - * The order of deleted entries is from the newest to the oldest added - * one. If you want to traverse from the oldest to the newest, you - * must reverse the order by yourself before traversing. - * - * The basic atomic operation of this list is cmpxchg on long. On - * architectures that don't have NMI-safe cmpxchg implementation, the - * list can NOT be used in NMI handler. So code uses the list in NMI - * handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. - */ - -struct llist_head { - struct llist_node *first; -}; - -struct llist_node { - struct llist_node *next; -}; - -#define LLIST_HEAD_INIT(name) { NULL } -#define LLIST_HEAD(name) struct llist_head name = LLIST_HEAD_INIT(name) - -/** - * init_llist_head - initialize lock-less list head - * @head: the head for your lock-less list - */ -static inline void init_llist_head(struct llist_head *list) -{ - list->first = NULL; -} - -/** - * llist_entry - get the struct of this entry - * @ptr: the &struct llist_node pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the llist_node within the struct. - */ -#define llist_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * llist_for_each - iterate over some deleted entries of a lock-less list - * @pos: the &struct llist_node to use as a loop cursor - * @node: the first entry of deleted list entries - * - * In general, some entries of the lock-less list can be traversed - * safely only after being deleted from list, so start with an entry - * instead of list head. - * - * If being used on entries deleted from lock-less list directly, the - * traverse order is from the newest to the oldest added entry. If - * you want to traverse from the oldest to the newest, you must - * reverse the order by yourself before traversing. - */ -#define llist_for_each(pos, node) \ - for ((pos) = (node); pos; (pos) = (pos)->next) - -/** - * llist_for_each_entry - iterate over some deleted entries of lock-less list of given type - * @pos: the type * to use as a loop cursor. - * @node: the fist entry of deleted list entries. - * @member: the name of the llist_node with the struct. - * - * In general, some entries of the lock-less list can be traversed - * safely only after being removed from list, so start with an entry - * instead of list head. - * - * If being used on entries deleted from lock-less list directly, the - * traverse order is from the newest to the oldest added entry. If - * you want to traverse from the oldest to the newest, you must - * reverse the order by yourself before traversing. - */ -#define llist_for_each_entry(pos, node, member) \ - for ((pos) = llist_entry((node), typeof(*(pos)), member); \ - &(pos)->member != NULL; \ - (pos) = llist_entry((pos)->member.next, typeof(*(pos)), member)) - -/** - * llist_empty - tests whether a lock-less list is empty - * @head: the list to test - * - * Not guaranteed to be accurate or up to date. Just a quick way to - * test whether the list is empty without deleting something from the - * list. - */ -static inline int llist_empty(const struct llist_head *head) -{ - return ACCESS_ONCE(head->first) == NULL; -} - -void llist_add(struct llist_node *new, struct llist_head *head); -void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, - struct llist_head *head); -struct llist_node *llist_del_first(struct llist_head *head); -struct llist_node *llist_del_all(struct llist_head *head); -#endif /* LLIST_H */ diff --git a/trunk/include/linux/memcontrol.h b/trunk/include/linux/memcontrol.h index 3b535db00a94..b96600786913 100644 --- a/trunk/include/linux/memcontrol.h +++ b/trunk/include/linux/memcontrol.h @@ -86,6 +86,8 @@ extern void mem_cgroup_uncharge_end(void); extern void mem_cgroup_uncharge_page(struct page *page); extern void mem_cgroup_uncharge_cache_page(struct page *page); +extern int mem_cgroup_shmem_charge_fallback(struct page *page, + struct mm_struct *mm, gfp_t gfp_mask); extern void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask); int task_in_mem_cgroup(struct task_struct *task, const struct mem_cgroup *mem); @@ -223,6 +225,12 @@ static inline void mem_cgroup_uncharge_cache_page(struct page *page) { } +static inline int mem_cgroup_shmem_charge_fallback(struct page *page, + struct mm_struct *mm, gfp_t gfp_mask) +{ + return 0; +} + static inline void mem_cgroup_add_lru_list(struct page *page, int lru) { } diff --git a/trunk/include/linux/mfd/aat2870.h b/trunk/include/linux/mfd/aat2870.h index f7316c29bdec..89212df05622 100644 --- a/trunk/include/linux/mfd/aat2870.h +++ b/trunk/include/linux/mfd/aat2870.h @@ -89,7 +89,7 @@ enum aat2870_id { /* Backlight current magnitude (mA) */ enum aat2870_current { - AAT2870_CURRENT_0_45 = 1, + AAT2870_CURRENT_0_45, AAT2870_CURRENT_0_90, AAT2870_CURRENT_1_80, AAT2870_CURRENT_2_70, diff --git a/trunk/include/linux/mm.h b/trunk/include/linux/mm.h index fd599f4bb846..3172a1c0f08e 100644 --- a/trunk/include/linux/mm.h +++ b/trunk/include/linux/mm.h @@ -962,8 +962,6 @@ int invalidate_inode_page(struct page *page); #ifdef CONFIG_MMU extern int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, unsigned int flags); -extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, - unsigned long address, unsigned int fault_flags); #else static inline int handle_mm_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, @@ -973,14 +971,6 @@ static inline int handle_mm_fault(struct mm_struct *mm, BUG(); return VM_FAULT_SIGBUS; } -static inline int fixup_user_fault(struct task_struct *tsk, - struct mm_struct *mm, unsigned long address, - unsigned int fault_flags) -{ - /* should never happen if there's no MMU */ - BUG(); - return -EFAULT; -} #endif extern int make_pages_present(unsigned long addr, unsigned long end); @@ -998,6 +988,8 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, int get_user_pages_fast(unsigned long start, int nr_pages, int write, struct page **pages); struct page *get_dump_page(unsigned long addr); +extern int fixup_user_fault(struct task_struct *tsk, struct mm_struct *mm, + unsigned long address, unsigned int fault_flags); extern int try_to_release_page(struct page * page, gfp_t gfp_mask); extern void do_invalidatepage(struct page *page, unsigned long offset); @@ -1608,7 +1600,6 @@ enum mf_flags { }; extern void memory_failure(unsigned long pfn, int trapno); extern int __memory_failure(unsigned long pfn, int trapno, int flags); -extern void memory_failure_queue(unsigned long pfn, int trapno, int flags); extern int unpoison_memory(unsigned long pfn); extern int sysctl_memory_failure_early_kill; extern int sysctl_memory_failure_recovery; diff --git a/trunk/include/linux/netlink.h b/trunk/include/linux/netlink.h index 180540a84d37..2e17c5dbdcb8 100644 --- a/trunk/include/linux/netlink.h +++ b/trunk/include/linux/netlink.h @@ -29,7 +29,7 @@ #define MAX_LINKS 32 struct sockaddr_nl { - __kernel_sa_family_t nl_family; /* AF_NETLINK */ + sa_family_t nl_family; /* AF_NETLINK */ unsigned short nl_pad; /* zero */ __u32 nl_pid; /* port ID */ __u32 nl_groups; /* multicast groups mask */ diff --git a/trunk/include/linux/nfs_xdr.h b/trunk/include/linux/nfs_xdr.h index abd615d74a29..569ea5b76fda 100644 --- a/trunk/include/linux/nfs_xdr.h +++ b/trunk/include/linux/nfs_xdr.h @@ -773,11 +773,6 @@ struct nfs3_getaclres { struct posix_acl * acl_default; }; -struct nfs4_string { - unsigned int len; - char *data; -}; - #ifdef CONFIG_NFS_V4 typedef u64 clientid4; @@ -968,6 +963,11 @@ struct nfs4_server_caps_res { struct nfs4_sequence_res seq_res; }; +struct nfs4_string { + unsigned int len; + char *data; +}; + #define NFS4_PATHNAME_MAXCOMPONENTS 512 struct nfs4_pathname { unsigned int ncomponents; diff --git a/trunk/include/linux/of.h b/trunk/include/linux/of.h index 0085bb01c041..bd716f8908de 100644 --- a/trunk/include/linux/of.h +++ b/trunk/include/linux/of.h @@ -196,13 +196,12 @@ extern struct property *of_find_property(const struct device_node *np, const char *name, int *lenp); extern int of_property_read_u32_array(const struct device_node *np, - const char *propname, + char *propname, u32 *out_values, size_t sz); -extern int of_property_read_string(struct device_node *np, - const char *propname, - const char **out_string); +extern int of_property_read_string(struct device_node *np, char *propname, + const char **out_string); extern int of_device_is_compatible(const struct device_node *device, const char *); extern int of_device_is_available(const struct device_node *device); @@ -243,15 +242,13 @@ static inline bool of_have_populated_dt(void) } static inline int of_property_read_u32_array(const struct device_node *np, - const char *propname, - u32 *out_values, size_t sz) + char *propname, u32 *out_values, size_t sz) { return -ENOSYS; } static inline int of_property_read_string(struct device_node *np, - const char *propname, - const char **out_string) + char *propname, const char **out_string) { return -ENOSYS; } @@ -259,7 +256,7 @@ static inline int of_property_read_string(struct device_node *np, #endif /* CONFIG_OF */ static inline int of_property_read_u32(const struct device_node *np, - const char *propname, + char *propname, u32 *out_value) { return of_property_read_u32_array(np, propname, out_value, 1); diff --git a/trunk/include/linux/pci_ids.h b/trunk/include/linux/pci_ids.h index ae96bbe54518..b00c4ec5056e 100644 --- a/trunk/include/linux/pci_ids.h +++ b/trunk/include/linux/pci_ids.h @@ -2709,16 +2709,6 @@ #define PCI_DEVICE_ID_INTEL_ICH10_5 0x3a60 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MIN 0x3b00 #define PCI_DEVICE_ID_INTEL_5_3400_SERIES_LPC_MAX 0x3b1f -#define PCI_DEVICE_ID_INTEL_IOAT_SNB0 0x3c20 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB1 0x3c21 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB2 0x3c22 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB3 0x3c23 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB4 0x3c24 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB5 0x3c25 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB6 0x3c26 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB7 0x3c27 -#define PCI_DEVICE_ID_INTEL_IOAT_SNB8 0x3c2e -#define PCI_DEVICE_ID_INTEL_IOAT_SNB9 0x3c2f #define PCI_DEVICE_ID_INTEL_IOAT_SNB 0x402f #define PCI_DEVICE_ID_INTEL_5100_16 0x65f0 #define PCI_DEVICE_ID_INTEL_5100_21 0x65f5 diff --git a/trunk/include/linux/posix_acl.h b/trunk/include/linux/posix_acl.h index b7681102a4b9..951bba82d50d 100644 --- a/trunk/include/linux/posix_acl.h +++ b/trunk/include/linux/posix_acl.h @@ -9,7 +9,6 @@ #define __LINUX_POSIX_ACL_H #include -#include #define ACL_UNDEFINED_ID (-1) @@ -39,10 +38,7 @@ struct posix_acl_entry { }; struct posix_acl { - union { - atomic_t a_refcount; - struct rcu_head a_rcu; - }; + atomic_t a_refcount; unsigned int a_count; struct posix_acl_entry a_entries[0]; }; @@ -69,7 +65,7 @@ static inline void posix_acl_release(struct posix_acl *acl) { if (acl && atomic_dec_and_test(&acl->a_refcount)) - kfree_rcu(acl, a_rcu); + kfree(acl); } @@ -88,22 +84,20 @@ extern struct posix_acl *get_posix_acl(struct inode *, int); extern int set_posix_acl(struct inode *, int, struct posix_acl *); #ifdef CONFIG_FS_POSIX_ACL -static inline struct posix_acl **acl_by_type(struct inode *inode, int type) +static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) { + struct posix_acl **p, *acl; switch (type) { case ACL_TYPE_ACCESS: - return &inode->i_acl; + p = &inode->i_acl; + break; case ACL_TYPE_DEFAULT: - return &inode->i_default_acl; + p = &inode->i_default_acl; + break; default: - BUG(); + return ERR_PTR(-EINVAL); } -} - -static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) -{ - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *acl = ACCESS_ONCE(*p); + acl = ACCESS_ONCE(*p); if (acl) { spin_lock(&inode->i_lock); acl = *p; @@ -114,20 +108,41 @@ static inline struct posix_acl *get_cached_acl(struct inode *inode, int type) return acl; } -static inline struct posix_acl *get_cached_acl_rcu(struct inode *inode, int type) +static inline int negative_cached_acl(struct inode *inode, int type) { - return rcu_dereference(*acl_by_type(inode, type)); + struct posix_acl **p, *acl; + switch (type) { + case ACL_TYPE_ACCESS: + p = &inode->i_acl; + break; + case ACL_TYPE_DEFAULT: + p = &inode->i_default_acl; + break; + default: + BUG(); + } + acl = ACCESS_ONCE(*p); + if (acl) + return 0; + return 1; } static inline void set_cached_acl(struct inode *inode, int type, struct posix_acl *acl) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct posix_acl *old = NULL; spin_lock(&inode->i_lock); - old = *p; - rcu_assign_pointer(*p, posix_acl_dup(acl)); + switch (type) { + case ACL_TYPE_ACCESS: + old = inode->i_acl; + inode->i_acl = posix_acl_dup(acl); + break; + case ACL_TYPE_DEFAULT: + old = inode->i_default_acl; + inode->i_default_acl = posix_acl_dup(acl); + break; + } spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) posix_acl_release(old); @@ -135,11 +150,18 @@ static inline void set_cached_acl(struct inode *inode, static inline void forget_cached_acl(struct inode *inode, int type) { - struct posix_acl **p = acl_by_type(inode, type); - struct posix_acl *old; + struct posix_acl *old = NULL; spin_lock(&inode->i_lock); - old = *p; - *p = ACL_NOT_CACHED; + switch (type) { + case ACL_TYPE_ACCESS: + old = inode->i_acl; + inode->i_acl = ACL_NOT_CACHED; + break; + case ACL_TYPE_DEFAULT: + old = inode->i_default_acl; + inode->i_default_acl = ACL_NOT_CACHED; + break; + } spin_unlock(&inode->i_lock); if (old != ACL_NOT_CACHED) posix_acl_release(old); diff --git a/trunk/include/linux/radix-tree.h b/trunk/include/linux/radix-tree.h index 9d4539c52e53..23241c2fecce 100644 --- a/trunk/include/linux/radix-tree.h +++ b/trunk/include/linux/radix-tree.h @@ -39,15 +39,7 @@ * when it is shrunk, before we rcu free the node. See shrink code for * details. */ -#define RADIX_TREE_INDIRECT_PTR 1 -/* - * A common use of the radix tree is to store pointers to struct pages; - * but shmem/tmpfs needs also to store swap entries in the same tree: - * those are marked as exceptional entries to distinguish them. - * EXCEPTIONAL_ENTRY tests the bit, EXCEPTIONAL_SHIFT shifts content past it. - */ -#define RADIX_TREE_EXCEPTIONAL_ENTRY 2 -#define RADIX_TREE_EXCEPTIONAL_SHIFT 2 +#define RADIX_TREE_INDIRECT_PTR 1 #define radix_tree_indirect_to_ptr(ptr) \ radix_tree_indirect_to_ptr((void __force *)(ptr)) @@ -181,28 +173,6 @@ static inline int radix_tree_deref_retry(void *arg) return unlikely((unsigned long)arg & RADIX_TREE_INDIRECT_PTR); } -/** - * radix_tree_exceptional_entry - radix_tree_deref_slot gave exceptional entry? - * @arg: value returned by radix_tree_deref_slot - * Returns: 0 if well-aligned pointer, non-0 if exceptional entry. - */ -static inline int radix_tree_exceptional_entry(void *arg) -{ - /* Not unlikely because radix_tree_exception often tested first */ - return (unsigned long)arg & RADIX_TREE_EXCEPTIONAL_ENTRY; -} - -/** - * radix_tree_exception - radix_tree_deref_slot returned either exception? - * @arg: value returned by radix_tree_deref_slot - * Returns: 0 if well-aligned pointer, non-0 if either kind of exception. - */ -static inline int radix_tree_exception(void *arg) -{ - return unlikely((unsigned long)arg & - (RADIX_TREE_INDIRECT_PTR | RADIX_TREE_EXCEPTIONAL_ENTRY)); -} - /** * radix_tree_replace_slot - replace item in a slot * @pslot: pointer to slot, returned by radix_tree_lookup_slot @@ -224,8 +194,8 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long); unsigned int radix_tree_gang_lookup(struct radix_tree_root *root, void **results, unsigned long first_index, unsigned int max_items); -unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, - void ***results, unsigned long *indices, +unsigned int +radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, unsigned long first_index, unsigned int max_items); unsigned long radix_tree_next_hole(struct radix_tree_root *root, unsigned long index, unsigned long max_scan); @@ -252,7 +222,6 @@ unsigned long radix_tree_range_tag_if_tagged(struct radix_tree_root *root, unsigned long nr_to_tag, unsigned int fromtag, unsigned int totag); int radix_tree_tagged(struct radix_tree_root *root, unsigned int tag); -unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item); static inline void radix_tree_preload_end(void) { diff --git a/trunk/include/linux/random.h b/trunk/include/linux/random.h index d13059f3ea32..ce29a040c8dc 100644 --- a/trunk/include/linux/random.h +++ b/trunk/include/linux/random.h @@ -57,6 +57,18 @@ extern void add_interrupt_randomness(int irq); extern void get_random_bytes(void *buf, int nbytes); void generate_random_uuid(unsigned char uuid_out[16]); +extern __u32 secure_ip_id(__be32 daddr); +extern __u32 secure_ipv6_id(const __be32 daddr[4]); +extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); +extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, + __be16 dport); +extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport); +extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, + __be16 sport, __be16 dport); +extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, + __be16 sport, __be16 dport); + #ifndef MODULE extern const struct file_operations random_fops, urandom_fops; #endif diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 4ac2c0578e0f..20b03bf94748 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1767,7 +1767,6 @@ extern void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t * #define PF_DUMPCORE 0x00000200 /* dumped core */ #define PF_SIGNALED 0x00000400 /* killed by a signal */ #define PF_MEMALLOC 0x00000800 /* Allocating memory */ -#define PF_NPROC_EXCEEDED 0x00001000 /* set_user noticed that RLIMIT_NPROC was exceeded */ #define PF_USED_MATH 0x00002000 /* if unset the fpu must be initialized before use */ #define PF_FREEZING 0x00004000 /* freeze in progress. do not account to load */ #define PF_NOFREEZE 0x00008000 /* this thread should not be frozen */ diff --git a/trunk/include/linux/shmem_fs.h b/trunk/include/linux/shmem_fs.h index 9291ac3cc627..aa08fa8fd79b 100644 --- a/trunk/include/linux/shmem_fs.h +++ b/trunk/include/linux/shmem_fs.h @@ -8,15 +8,22 @@ /* inode in-kernel data */ +#define SHMEM_NR_DIRECT 16 + +#define SHMEM_SYMLINK_INLINE_LEN (SHMEM_NR_DIRECT * sizeof(swp_entry_t)) + struct shmem_inode_info { spinlock_t lock; unsigned long flags; unsigned long alloced; /* data pages alloced to file */ + unsigned long swapped; /* subtotal assigned to swap */ + unsigned long next_index; /* highest alloced index + 1 */ + struct shared_policy policy; /* NUMA memory alloc policy */ + struct page *i_indirect; /* top indirect blocks page */ union { - unsigned long swapped; /* subtotal assigned to swap */ - char *symlink; /* unswappable short symlink */ + swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* first blocks */ + char inline_symlink[SHMEM_SYMLINK_INLINE_LEN]; }; - struct shared_policy policy; /* NUMA memory alloc policy */ struct list_head swaplist; /* chain of maybes on swap */ struct list_head xattr_list; /* list of shmem_xattr */ struct inode vfs_inode; @@ -42,7 +49,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) /* * Functions in mm/shmem.c called directly from elsewhere: */ -extern int shmem_init(void); +extern int init_tmpfs(void); extern int shmem_fill_super(struct super_block *sb, void *data, int silent); extern struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags); @@ -52,6 +59,8 @@ extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, pgoff_t index, gfp_t gfp_mask); extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); extern int shmem_unuse(swp_entry_t entry, struct page *page); +extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, + struct page **pagep, swp_entry_t *ent); static inline struct page *shmem_read_mapping_page( struct address_space *mapping, pgoff_t index) diff --git a/trunk/include/linux/socket.h b/trunk/include/linux/socket.h index d0e77f607a79..e17f82266639 100644 --- a/trunk/include/linux/socket.h +++ b/trunk/include/linux/socket.h @@ -8,10 +8,8 @@ #define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *)) /* Implementation specific desired alignment */ -typedef unsigned short __kernel_sa_family_t; - struct __kernel_sockaddr_storage { - __kernel_sa_family_t ss_family; /* address family */ + unsigned short ss_family; /* address family */ /* Following field(s) are implementation specific */ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)]; /* space to achieve desired size, */ @@ -37,7 +35,7 @@ struct seq_file; extern void socket_seq_show(struct seq_file *seq); #endif -typedef __kernel_sa_family_t sa_family_t; +typedef unsigned short sa_family_t; /* * 1003.1g requires sa_family_t and that sa_data is char. diff --git a/trunk/include/linux/swapops.h b/trunk/include/linux/swapops.h index 2189d3ffc85d..cd42e30b7c6e 100644 --- a/trunk/include/linux/swapops.h +++ b/trunk/include/linux/swapops.h @@ -1,8 +1,3 @@ -#ifndef _LINUX_SWAPOPS_H -#define _LINUX_SWAPOPS_H - -#include - /* * swapcache pages are stored in the swapper_space radix tree. We want to * get good packing density in that tree, so the index should be dense in @@ -81,22 +76,6 @@ static inline pte_t swp_entry_to_pte(swp_entry_t entry) return __swp_entry_to_pte(arch_entry); } -static inline swp_entry_t radix_to_swp_entry(void *arg) -{ - swp_entry_t entry; - - entry.val = (unsigned long)arg >> RADIX_TREE_EXCEPTIONAL_SHIFT; - return entry; -} - -static inline void *swp_to_radix_entry(swp_entry_t entry) -{ - unsigned long value; - - value = entry.val << RADIX_TREE_EXCEPTIONAL_SHIFT; - return (void *)(value | RADIX_TREE_EXCEPTIONAL_ENTRY); -} - #ifdef CONFIG_MIGRATION static inline swp_entry_t make_migration_entry(struct page *page, int write) { @@ -190,5 +169,3 @@ static inline int non_swap_entry(swp_entry_t entry) return 0; } #endif - -#endif /* _LINUX_SWAPOPS_H */ diff --git a/trunk/include/linux/thermal.h b/trunk/include/linux/thermal.h index 47b4a27e6e97..d3ec89fb4122 100644 --- a/trunk/include/linux/thermal.h +++ b/trunk/include/linux/thermal.h @@ -85,6 +85,22 @@ struct thermal_cooling_device { ((long)t-2732+5)/10 : ((long)t-2732-5)/10) #define CELSIUS_TO_KELVIN(t) ((t)*10+2732) +#if defined(CONFIG_THERMAL_HWMON) +/* thermal zone devices with the same type share one hwmon device */ +struct thermal_hwmon_device { + char type[THERMAL_NAME_LENGTH]; + struct device *device; + int count; + struct list_head tz_list; + struct list_head node; +}; + +struct thermal_hwmon_attr { + struct device_attribute attr; + char name[16]; +}; +#endif + struct thermal_zone_device { int id; char type[THERMAL_NAME_LENGTH]; @@ -104,6 +120,12 @@ struct thermal_zone_device { struct mutex lock; /* protect cooling devices list */ struct list_head node; struct delayed_work poll_queue; +#if defined(CONFIG_THERMAL_HWMON) + struct list_head hwmon_node; + struct thermal_hwmon_device *hwmon; + struct thermal_hwmon_attr temp_input; /* hwmon sys attr */ + struct thermal_hwmon_attr temp_crit; /* hwmon sys attr */ +#endif }; /* Adding event notification support elements */ #define THERMAL_GENL_FAMILY_NAME "thermal_event" diff --git a/trunk/include/net/cipso_ipv4.h b/trunk/include/net/cipso_ipv4.h index 9808877c2ab9..3b938743514b 100644 --- a/trunk/include/net/cipso_ipv4.h +++ b/trunk/include/net/cipso_ipv4.h @@ -8,7 +8,7 @@ * have chosen to adopt the protocol and over the years it has become a * de-facto standard for labeled networking. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/include/net/dst.h b/trunk/include/net/dst.h index 13d507d69ddb..29e255796ce1 100644 --- a/trunk/include/net/dst.h +++ b/trunk/include/net/dst.h @@ -37,7 +37,7 @@ struct dst_entry { unsigned long _metrics; unsigned long expires; struct dst_entry *path; - struct neighbour __rcu *_neighbour; + struct neighbour *_neighbour; #ifdef CONFIG_XFRM struct xfrm_state *xfrm; #else @@ -88,17 +88,12 @@ struct dst_entry { static inline struct neighbour *dst_get_neighbour(struct dst_entry *dst) { - return rcu_dereference(dst->_neighbour); -} - -static inline struct neighbour *dst_get_neighbour_raw(struct dst_entry *dst) -{ - return rcu_dereference_raw(dst->_neighbour); + return dst->_neighbour; } static inline void dst_set_neighbour(struct dst_entry *dst, struct neighbour *neigh) { - rcu_assign_pointer(dst->_neighbour, neigh); + dst->_neighbour = neigh; } extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); @@ -387,12 +382,8 @@ static inline void dst_rcu_free(struct rcu_head *head) static inline void dst_confirm(struct dst_entry *dst) { if (dst) { - struct neighbour *n; - - rcu_read_lock(); - n = dst_get_neighbour(dst); + struct neighbour *n = dst_get_neighbour(dst); neigh_confirm(n); - rcu_read_unlock(); } } diff --git a/trunk/include/net/inet_sock.h b/trunk/include/net/inet_sock.h index b897d6e6d0a5..caaff5f5f39f 100644 --- a/trunk/include/net/inet_sock.h +++ b/trunk/include/net/inet_sock.h @@ -238,7 +238,7 @@ static inline __u8 inet_sk_flowi_flags(const struct sock *sk) { __u8 flags = 0; - if (inet_sk(sk)->transparent || inet_sk(sk)->hdrincl) + if (inet_sk(sk)->transparent) flags |= FLOWI_FLAG_ANYSRC; if (sk->sk_protocol == IPPROTO_TCP) flags |= FLOWI_FLAG_PRECOW_METRICS; diff --git a/trunk/include/net/netlabel.h b/trunk/include/net/netlabel.h index f67440970d7e..f21a16ee3705 100644 --- a/trunk/include/net/netlabel.h +++ b/trunk/include/net/netlabel.h @@ -4,7 +4,7 @@ * The NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/include/net/secure_seq.h b/trunk/include/net/secure_seq.h deleted file mode 100644 index d97f6892c019..000000000000 --- a/trunk/include/net/secure_seq.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _NET_SECURE_SEQ -#define _NET_SECURE_SEQ - -#include - -extern __u32 secure_ip_id(__be32 daddr); -extern __u32 secure_ipv6_id(const __be32 daddr[4]); -extern u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); -extern u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, - __be16 dport); -extern __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport); -extern __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, - __be16 sport, __be16 dport); -extern u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport); -extern u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, - __be16 sport, __be16 dport); - -#endif /* _NET_SECURE_SEQ */ diff --git a/trunk/include/scsi/osd_ore.h b/trunk/include/scsi/osd_ore.h deleted file mode 100644 index c5c5e008e6de..000000000000 --- a/trunk/include/scsi/osd_ore.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2011 - * Boaz Harrosh - * - * Public Declarations of the ORE API - * - * This file is part of the ORE (Object Raid Engine) library. - * - * ORE is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. (GPL v2) - * - * ORE is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the ORE; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __ORE_H__ -#define __ORE_H__ - -#include -#include -#include -#include - -struct ore_comp { - struct osd_obj_id obj; - u8 cred[OSD_CAP_LEN]; -}; - -struct ore_layout { - /* Our way of looking at the data_map */ - unsigned stripe_unit; - unsigned mirrors_p1; - - unsigned group_width; - u64 group_depth; - unsigned group_count; -}; - -struct ore_components { - unsigned numdevs; /* Num of devices in array */ - /* If @single_comp == EC_SINGLE_COMP, @comps points to a single - * component. else there are @numdevs components - */ - enum EC_COMP_USAGE { - EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff - } single_comp; - struct ore_comp *comps; - struct osd_dev **ods; /* osd_dev array */ -}; - -struct ore_io_state; -typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private); - -struct ore_io_state { - struct kref kref; - - void *private; - ore_io_done_fn done; - - struct ore_layout *layout; - struct ore_components *comps; - - /* Global read/write IO*/ - loff_t offset; - unsigned long length; - void *kern_buff; - - struct page **pages; - unsigned nr_pages; - unsigned pgbase; - unsigned pages_consumed; - - /* Attributes */ - unsigned in_attr_len; - struct osd_attr *in_attr; - unsigned out_attr_len; - struct osd_attr *out_attr; - - bool reading; - - /* Variable array of size numdevs */ - unsigned numdevs; - struct ore_per_dev_state { - struct osd_request *or; - struct bio *bio; - loff_t offset; - unsigned length; - unsigned dev; - } per_dev[]; -}; - -static inline unsigned ore_io_state_size(unsigned numdevs) -{ - return sizeof(struct ore_io_state) + - sizeof(struct ore_per_dev_state) * numdevs; -} - -/* ore.c */ -int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, - bool is_reading, u64 offset, u64 length, - struct ore_io_state **ios); -int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps, - struct ore_io_state **ios); -void ore_put_io_state(struct ore_io_state *ios); - -int ore_check_io(struct ore_io_state *ios, u64 *resid); - -int ore_create(struct ore_io_state *ios); -int ore_remove(struct ore_io_state *ios); -int ore_write(struct ore_io_state *ios); -int ore_read(struct ore_io_state *ios); -int ore_truncate(struct ore_layout *layout, struct ore_components *comps, - u64 size); - -int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr); - -extern const struct osd_attr g_attr_logical_length; - -#endif diff --git a/trunk/include/sound/wm8996.h b/trunk/include/sound/wm8915.h similarity index 63% rename from trunk/include/sound/wm8996.h rename to trunk/include/sound/wm8915.h index ea4d88f43975..5817d762f6f3 100644 --- a/trunk/include/sound/wm8996.h +++ b/trunk/include/sound/wm8915.h @@ -1,5 +1,5 @@ /* - * linux/sound/wm8996.h -- Platform data for WM8996 + * linux/sound/wm8915.h -- Platform data for WM8915 * * Copyright 2011 Wolfson Microelectronics. PLC. * @@ -8,14 +8,14 @@ * published by the Free Software Foundation. */ -#ifndef __LINUX_SND_WM8996_H -#define __LINUX_SND_WM8996_H +#ifndef __LINUX_SND_WM8903_H +#define __LINUX_SND_WM8903_H -enum wm8996_inmode { - WM8996_DIFFERRENTIAL_1 = 0, /* IN1xP - IN1xN */ - WM8996_INVERTING = 1, /* IN1xN */ - WM8996_NON_INVERTING = 2, /* IN1xP */ - WM8996_DIFFERENTIAL_2 = 3, /* IN2xP - IN2xP */ +enum wm8915_inmode { + WM8915_DIFFERRENTIAL_1 = 0, /* IN1xP - IN1xN */ + WM8915_INVERTING = 1, /* IN1xN */ + WM8915_NON_INVERTING = 2, /* IN1xP */ + WM8915_DIFFERENTIAL_2 = 3, /* IN2xP - IN2xP */ }; /** @@ -25,23 +25,23 @@ enum wm8996_inmode { * Configurations are expected to be generated using the ReTune Mobile * control panel in WISCE - see http://www.wolfsonmicro.com/wisce/ */ -struct wm8996_retune_mobile_config { +struct wm8915_retune_mobile_config { const char *name; int rate; u16 regs[20]; }; -#define WM8996_SET_DEFAULT 0x10000 +#define WM8915_SET_DEFAULT 0x10000 -struct wm8996_pdata { +struct wm8915_pdata { int irq_flags; /** Set IRQ trigger flags; default active low */ int ldo_ena; /** GPIO for LDO1; -1 for none */ int micdet_def; /** Default MICDET_SRC/HP1FB_SRC/MICD_BIAS */ - enum wm8996_inmode inl_mode; - enum wm8996_inmode inr_mode; + enum wm8915_inmode inl_mode; + enum wm8915_inmode inr_mode; u32 spkmute_seq; /** Value for register 0x802 */ @@ -49,7 +49,7 @@ struct wm8996_pdata { u32 gpio_default[5]; int num_retune_mobile_cfgs; - struct wm8996_retune_mobile_config *retune_mobile_cfgs; + struct wm8915_retune_mobile_config *retune_mobile_cfgs; }; #endif diff --git a/trunk/init/main.c b/trunk/init/main.c index 9c51ee7adf3d..d7211faed2ad 100644 --- a/trunk/init/main.c +++ b/trunk/init/main.c @@ -369,12 +369,9 @@ static noinline void __init_refok rest_init(void) init_idle_bootup_task(current); preempt_enable_no_resched(); schedule(); - - /* At this point, we can enable user mode helper functionality */ - usermodehelper_enable(); + preempt_disable(); /* Call into cpu_idle with preempt disabled */ - preempt_disable(); cpu_idle(); } @@ -718,7 +715,7 @@ static void __init do_basic_setup(void) { cpuset_init_smp(); usermodehelper_init(); - shmem_init(); + init_tmpfs(); driver_init(); init_irq_proc(); do_ctors(); diff --git a/trunk/ipc/shm.c b/trunk/ipc/shm.c index 02ecf2c078fc..9fb044f3b345 100644 --- a/trunk/ipc/shm.c +++ b/trunk/ipc/shm.c @@ -105,16 +105,9 @@ void shm_exit_ns(struct ipc_namespace *ns) } #endif -static int __init ipc_ns_init(void) -{ - shm_init_ns(&init_ipc_ns); - return 0; -} - -pure_initcall(ipc_ns_init); - void __init shm_init (void) { + shm_init_ns(&init_ipc_ns); ipc_init_proc_interface("sysvipc/shm", #if BITS_PER_LONG <= 32 " key shmid perms size cpid lpid nattch uid gid cuid cgid atime dtime ctime rss swap\n", @@ -301,7 +294,7 @@ static int shm_try_destroy_orphaned(int id, void *p, void *data) void shm_destroy_orphaned(struct ipc_namespace *ns) { down_write(&shm_ids(ns).rw_mutex); - if (shm_ids(ns).in_use) + if (&shm_ids(ns).in_use) idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_orphaned, ns); up_write(&shm_ids(ns).rw_mutex); } @@ -311,12 +304,9 @@ void exit_shm(struct task_struct *task) { struct ipc_namespace *ns = task->nsproxy->ipc_ns; - if (shm_ids(ns).in_use == 0) - return; - /* Destroy all already created segments, but not mapped yet */ down_write(&shm_ids(ns).rw_mutex); - if (shm_ids(ns).in_use) + if (&shm_ids(ns).in_use) idr_for_each(&shm_ids(ns).ipcs_idr, &shm_try_destroy_current, ns); up_write(&shm_ids(ns).rw_mutex); } diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index eca595e2fd52..d06467fc8f7c 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -10,7 +10,7 @@ obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ - async.o range.o + async.o range.o jump_label.o obj-y += groups.o ifdef CONFIG_FUNCTION_TRACER @@ -107,7 +107,6 @@ obj-$(CONFIG_PERF_EVENTS) += events/ obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o obj-$(CONFIG_PADATA) += padata.o obj-$(CONFIG_CRASH_DUMP) += crash_dump.o -obj-$(CONFIG_JUMP_LABEL) += jump_label.o ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) # According to Alan Modra , the -fno-omit-frame-pointer is diff --git a/trunk/kernel/cred.c b/trunk/kernel/cred.c index 8ef31f53c44c..174fa84eca30 100644 --- a/trunk/kernel/cred.c +++ b/trunk/kernel/cred.c @@ -508,8 +508,10 @@ int commit_creds(struct cred *new) key_fsgid_changed(task); /* do it - * RLIMIT_NPROC limits on user->processes have already been checked - * in set_user(). + * - What if a process setreuid()'s and this brings the + * new uid over his NPROC rlimit? We can check this now + * cheaply with the new uid cache, so if it matters + * we should be checking for it. -DaveM */ alter_cred_subscribers(new, 2); if (new->user != old->user) diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index 8e6b6f4fb272..e7ceaca89609 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -1111,7 +1111,6 @@ static struct task_struct *copy_process(unsigned long clone_flags, p->real_cred->user != INIT_USER) goto bad_fork_free; } - current->flags &= ~PF_NPROC_EXCEEDED; retval = copy_creds(p, clone_flags); if (retval < 0) diff --git a/trunk/kernel/futex.c b/trunk/kernel/futex.c index 11cbe052b2e8..0a308970c24a 100644 --- a/trunk/kernel/futex.c +++ b/trunk/kernel/futex.c @@ -218,8 +218,6 @@ static void drop_futex_key_refs(union futex_key *key) * @uaddr: virtual address of the futex * @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED * @key: address where result is stored. - * @rw: mapping needs to be read/write (values: VERIFY_READ, - * VERIFY_WRITE) * * Returns a negative error code or 0 * The key words are stored in *key on success. @@ -231,12 +229,12 @@ static void drop_futex_key_refs(union futex_key *key) * lock_page() might sleep, the caller should not hold a spinlock. */ static int -get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) +get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key) { unsigned long address = (unsigned long)uaddr; struct mm_struct *mm = current->mm; struct page *page, *page_head; - int err, ro = 0; + int err; /* * The futex address must be "naturally" aligned. @@ -264,18 +262,8 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) again: err = get_user_pages_fast(address, 1, 1, &page); - /* - * If write access is not required (eg. FUTEX_WAIT), try - * and get read-only access. - */ - if (err == -EFAULT && rw == VERIFY_READ) { - err = get_user_pages_fast(address, 1, 0, &page); - ro = 1; - } if (err < 0) return err; - else - err = 0; #ifdef CONFIG_TRANSPARENT_HUGEPAGE page_head = page; @@ -317,13 +305,6 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) if (!page_head->mapping) { unlock_page(page_head); put_page(page_head); - /* - * ZERO_PAGE pages don't have a mapping. Avoid a busy loop - * trying to find one. RW mapping would have COW'd (and thus - * have a mapping) so this page is RO and won't ever change. - */ - if ((page_head == ZERO_PAGE(address))) - return -EFAULT; goto again; } @@ -335,15 +316,6 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) * the object not the particular process. */ if (PageAnon(page_head)) { - /* - * A RO anonymous page will never change and thus doesn't make - * sense for futex operations. - */ - if (ro) { - err = -EFAULT; - goto out; - } - key->both.offset |= FUT_OFF_MMSHARED; /* ref taken on mm */ key->private.mm = mm; key->private.address = address; @@ -355,10 +327,9 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw) get_futex_key_refs(key); -out: unlock_page(page_head); put_page(page_head); - return err; + return 0; } static inline void put_futex_key(union futex_key *key) @@ -969,7 +940,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) if (!bitset) return -EINVAL; - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ); + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); if (unlikely(ret != 0)) goto out; @@ -1015,10 +986,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, int ret, op_ret; retry: - ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); + ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); if (unlikely(ret != 0)) goto out; - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); if (unlikely(ret != 0)) goto out_put_key1; @@ -1272,11 +1243,10 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, pi_state = NULL; } - ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ); + ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1); if (unlikely(ret != 0)) goto out; - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, - requeue_pi ? VERIFY_WRITE : VERIFY_READ); + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); if (unlikely(ret != 0)) goto out_put_key1; @@ -1820,7 +1790,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, * while the syscall executes. */ retry: - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ); + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key); if (unlikely(ret != 0)) return ret; @@ -1971,7 +1941,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags, int detect, } retry: - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, VERIFY_WRITE); + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key); if (unlikely(ret != 0)) goto out; @@ -2090,7 +2060,7 @@ static int futex_unlock_pi(u32 __user *uaddr, unsigned int flags) if ((uval & FUTEX_TID_MASK) != vpid) return -EPERM; - ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE); + ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key); if (unlikely(ret != 0)) goto out; @@ -2279,7 +2249,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, debug_rt_mutex_init_waiter(&rt_waiter); rt_waiter.task = NULL; - ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE); + ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2); if (unlikely(ret != 0)) goto out; diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index ddc7644c1305..47613dfb7b28 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -274,7 +274,7 @@ static void __call_usermodehelper(struct work_struct *work) * (used for preventing user land processes from being created after the user * land has been frozen during a system-wide hibernation or suspend operation). */ -static int usermodehelper_disabled = 1; +static int usermodehelper_disabled; /* Number of helpers running */ static atomic_t running_helpers = ATOMIC_INIT(0); diff --git a/trunk/kernel/lockdep.c b/trunk/kernel/lockdep.c index 8c24294e477f..3956f5149e25 100644 --- a/trunk/kernel/lockdep.c +++ b/trunk/kernel/lockdep.c @@ -2468,7 +2468,7 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark) BUG_ON(usage_bit >= LOCK_USAGE_STATES); - if (hlock_class(hlock)->key == __lockdep_no_validate__.subkeys) + if (hlock_class(hlock)->key == &__lockdep_no_validate__) continue; if (!mark_lock(curr, hlock, usage_bit)) @@ -2485,9 +2485,23 @@ static void __trace_hardirqs_on_caller(unsigned long ip) { struct task_struct *curr = current; + if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled))) + return; + + if (unlikely(curr->hardirqs_enabled)) { + /* + * Neither irq nor preemption are disabled here + * so this is racy by nature but losing one hit + * in a stat is not a big deal. + */ + __debug_atomic_inc(redundant_hardirqs_on); + return; + } /* we'll do an OFF -> ON transition: */ curr->hardirqs_enabled = 1; + if (DEBUG_LOCKS_WARN_ON(current->hardirq_context)) + return; /* * We are going to turn hardirqs on, so set the * usage bit for all held locks: @@ -2515,25 +2529,9 @@ void trace_hardirqs_on_caller(unsigned long ip) if (unlikely(!debug_locks || current->lockdep_recursion)) return; - if (unlikely(current->hardirqs_enabled)) { - /* - * Neither irq nor preemption are disabled here - * so this is racy by nature but losing one hit - * in a stat is not a big deal. - */ - __debug_atomic_inc(redundant_hardirqs_on); - return; - } - if (DEBUG_LOCKS_WARN_ON(!irqs_disabled())) return; - if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled))) - return; - - if (DEBUG_LOCKS_WARN_ON(current->hardirq_context)) - return; - current->lockdep_recursion = 1; __trace_hardirqs_on_caller(ip); current->lockdep_recursion = 0; @@ -2874,7 +2872,10 @@ static int mark_lock(struct task_struct *curr, struct held_lock *this, void lockdep_init_map(struct lockdep_map *lock, const char *name, struct lock_class_key *key, int subclass) { - memset(lock, 0, sizeof(*lock)); + int i; + + for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++) + lock->class_cache[i] = NULL; #ifdef CONFIG_LOCK_STAT lock->cpu = raw_smp_processor_id(); diff --git a/trunk/kernel/printk.c b/trunk/kernel/printk.c index 836a2ae0ac31..37dff3429adb 100644 --- a/trunk/kernel/printk.c +++ b/trunk/kernel/printk.c @@ -318,10 +318,8 @@ static int check_syslog_permissions(int type, bool from_file) return 0; /* For historical reasons, accept CAP_SYS_ADMIN too, with a warning */ if (capable(CAP_SYS_ADMIN)) { - printk_once(KERN_WARNING "%s (%d): " - "Attempt to access syslog with CAP_SYS_ADMIN " - "but no CAP_SYSLOG (deprecated).\n", - current->comm, task_pid_nr(current)); + WARN_ONCE(1, "Attempt to access syslog with CAP_SYS_ADMIN " + "but no CAP_SYSLOG (deprecated).\n"); return 0; } return -EPERM; diff --git a/trunk/kernel/sys.c b/trunk/kernel/sys.c index dd948a1fca4c..a101ba36c444 100644 --- a/trunk/kernel/sys.c +++ b/trunk/kernel/sys.c @@ -621,18 +621,11 @@ static int set_user(struct cred *new) if (!new_user) return -EAGAIN; - /* - * We don't fail in case of NPROC limit excess here because too many - * poorly written programs don't check set*uid() return code, assuming - * it never fails if called by root. We may still enforce NPROC limit - * for programs doing set*uid()+execve() by harmlessly deferring the - * failure to the execve() stage. - */ if (atomic_read(&new_user->processes) >= rlimit(RLIMIT_NPROC) && - new_user != INIT_USER) - current->flags |= PF_NPROC_EXCEEDED; - else - current->flags &= ~PF_NPROC_EXCEEDED; + new_user != INIT_USER) { + free_uid(new_user); + return -EAGAIN; + } free_uid(new->user); new->user = new_user; diff --git a/trunk/kernel/taskstats.c b/trunk/kernel/taskstats.c index e19ce1454ee1..d1db2880d1cf 100644 --- a/trunk/kernel/taskstats.c +++ b/trunk/kernel/taskstats.c @@ -291,28 +291,30 @@ static int add_del_listener(pid_t pid, const struct cpumask *mask, int isadd) if (!cpumask_subset(mask, cpu_possible_mask)) return -EINVAL; + s = NULL; if (isadd == REGISTER) { for_each_cpu(cpu, mask) { - s = kmalloc_node(sizeof(struct listener), - GFP_KERNEL, cpu_to_node(cpu)); + if (!s) + s = kmalloc_node(sizeof(struct listener), + GFP_KERNEL, cpu_to_node(cpu)); if (!s) goto cleanup; - s->pid = pid; + INIT_LIST_HEAD(&s->list); s->valid = 1; listeners = &per_cpu(listener_array, cpu); down_write(&listeners->sem); - list_for_each_entry(s2, &listeners->list, list) { - if (s2->pid == pid && s2->valid) - goto exists; + list_for_each_entry_safe(s2, tmp, &listeners->list, list) { + if (s2->pid == pid) + goto next_cpu; } list_add(&s->list, &listeners->list); s = NULL; -exists: +next_cpu: up_write(&listeners->sem); - kfree(s); /* nop if NULL */ } + kfree(s); return 0; } diff --git a/trunk/kernel/trace/Kconfig b/trunk/kernel/trace/Kconfig index cd3134510f3d..2ad39e556cb4 100644 --- a/trunk/kernel/trace/Kconfig +++ b/trunk/kernel/trace/Kconfig @@ -82,7 +82,7 @@ config EVENT_POWER_TRACING_DEPRECATED power:power_frequency This is for userspace compatibility and will vanish after 5 kernel iterations, - namely 3.1. + namely 2.6.41. config CONTEXT_SWITCH_TRACER bool diff --git a/trunk/lib/Kconfig b/trunk/lib/Kconfig index 6c695ff9caba..32f3e5ae2be5 100644 --- a/trunk/lib/Kconfig +++ b/trunk/lib/Kconfig @@ -276,7 +276,4 @@ config CORDIC so its calculations are in fixed point. Modules can select this when they require this function. Module will be called cordic. -config LLIST - bool - endmenu diff --git a/trunk/lib/Makefile b/trunk/lib/Makefile index d5d175c8a6ca..892f4e282ea1 100644 --- a/trunk/lib/Makefile +++ b/trunk/lib/Makefile @@ -10,7 +10,7 @@ endif lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o dump_stack.o timerqueue.o\ idr.o int_sqrt.o extable.o prio_tree.o \ - sha1.o md5.o irq_regs.o reciprocal_div.o argv_split.o \ + sha1.o irq_regs.o reciprocal_div.o argv_split.o \ proportions.o prio_heap.o ratelimit.o show_mem.o \ is_single_threaded.o plist.o decompress.o find_next_bit.o @@ -115,8 +115,6 @@ obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o obj-$(CONFIG_CORDIC) += cordic.o -obj-$(CONFIG_LLIST) += llist.o - hostprogs-y := gen_crc32table clean-files := crc32table.h diff --git a/trunk/lib/bitmap.c b/trunk/lib/bitmap.c index 2f4412e4d071..37ef4b048795 100644 --- a/trunk/lib/bitmap.c +++ b/trunk/lib/bitmap.c @@ -271,6 +271,8 @@ int __bitmap_weight(const unsigned long *bitmap, int bits) } EXPORT_SYMBOL(__bitmap_weight); +#define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG)) + void bitmap_set(unsigned long *map, int start, int nr) { unsigned long *p = map + BIT_WORD(start); diff --git a/trunk/lib/fault-inject.c b/trunk/lib/fault-inject.c index f193b7796449..2577b121c7c1 100644 --- a/trunk/lib/fault-inject.c +++ b/trunk/lib/fault-inject.c @@ -197,15 +197,21 @@ static struct dentry *debugfs_create_atomic_t(const char *name, mode_t mode, return debugfs_create_file(name, mode, parent, value, &fops_atomic_t); } -struct dentry *fault_create_debugfs_attr(const char *name, - struct dentry *parent, struct fault_attr *attr) +void cleanup_fault_attr_dentries(struct fault_attr *attr) +{ + debugfs_remove_recursive(attr->dir); +} + +int init_fault_attr_dentries(struct fault_attr *attr, const char *name) { mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; struct dentry *dir; - dir = debugfs_create_dir(name, parent); + dir = debugfs_create_dir(name, NULL); if (!dir) - return ERR_PTR(-ENOMEM); + return -ENOMEM; + + attr->dir = dir; if (!debugfs_create_ul("probability", mode, dir, &attr->probability)) goto fail; @@ -237,11 +243,11 @@ struct dentry *fault_create_debugfs_attr(const char *name, #endif /* CONFIG_FAULT_INJECTION_STACKTRACE_FILTER */ - return dir; + return 0; fail: - debugfs_remove_recursive(dir); + debugfs_remove_recursive(attr->dir); - return ERR_PTR(-ENOMEM); + return -ENOMEM; } #endif /* CONFIG_FAULT_INJECTION_DEBUG_FS */ diff --git a/trunk/lib/genalloc.c b/trunk/lib/genalloc.c index f352cc42f4f8..577ddf805975 100644 --- a/trunk/lib/genalloc.c +++ b/trunk/lib/genalloc.c @@ -1,26 +1,8 @@ /* - * Basic general purpose allocator for managing special purpose - * memory, for example, memory that is not managed by the regular - * kmalloc/kfree interface. Uses for this includes on-device special - * memory, uncached memory etc. - * - * It is safe to use the allocator in NMI handlers and other special - * unblockable contexts that could otherwise deadlock on locks. This - * is implemented by using atomic operations and retries on any - * conflicts. The disadvantage is that there may be livelocks in - * extreme cases. For better scalability, one allocator can be used - * for each CPU. - * - * The lockless operation only works if there is enough memory - * available. If new memory is added to the pool a lock has to be - * still taken. So any user relying on locklessness has to ensure - * that sufficient memory is preallocated. - * - * The basic atomic operation of this allocator is cmpxchg on long. - * On architectures that don't have NMI-safe cmpxchg implementation, - * the allocator can NOT be used in NMI handler. So code uses the - * allocator in NMI handler should depend on - * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. + * Basic general purpose allocator for managing special purpose memory + * not managed by the regular kmalloc/kfree interface. + * Uses for this includes on-device special memory, uncached memory + * etc. * * Copyright 2005 (C) Jes Sorensen * @@ -31,109 +13,8 @@ #include #include #include -#include -#include #include -static int set_bits_ll(unsigned long *addr, unsigned long mask_to_set) -{ - unsigned long val, nval; - - nval = *addr; - do { - val = nval; - if (val & mask_to_set) - return -EBUSY; - cpu_relax(); - } while ((nval = cmpxchg(addr, val, val | mask_to_set)) != val); - - return 0; -} - -static int clear_bits_ll(unsigned long *addr, unsigned long mask_to_clear) -{ - unsigned long val, nval; - - nval = *addr; - do { - val = nval; - if ((val & mask_to_clear) != mask_to_clear) - return -EBUSY; - cpu_relax(); - } while ((nval = cmpxchg(addr, val, val & ~mask_to_clear)) != val); - - return 0; -} - -/* - * bitmap_set_ll - set the specified number of bits at the specified position - * @map: pointer to a bitmap - * @start: a bit position in @map - * @nr: number of bits to set - * - * Set @nr bits start from @start in @map lock-lessly. Several users - * can set/clear the same bitmap simultaneously without lock. If two - * users set the same bit, one user will return remain bits, otherwise - * return 0. - */ -static int bitmap_set_ll(unsigned long *map, int start, int nr) -{ - unsigned long *p = map + BIT_WORD(start); - const int size = start + nr; - int bits_to_set = BITS_PER_LONG - (start % BITS_PER_LONG); - unsigned long mask_to_set = BITMAP_FIRST_WORD_MASK(start); - - while (nr - bits_to_set >= 0) { - if (set_bits_ll(p, mask_to_set)) - return nr; - nr -= bits_to_set; - bits_to_set = BITS_PER_LONG; - mask_to_set = ~0UL; - p++; - } - if (nr) { - mask_to_set &= BITMAP_LAST_WORD_MASK(size); - if (set_bits_ll(p, mask_to_set)) - return nr; - } - - return 0; -} - -/* - * bitmap_clear_ll - clear the specified number of bits at the specified position - * @map: pointer to a bitmap - * @start: a bit position in @map - * @nr: number of bits to set - * - * Clear @nr bits start from @start in @map lock-lessly. Several users - * can set/clear the same bitmap simultaneously without lock. If two - * users clear the same bit, one user will return remain bits, - * otherwise return 0. - */ -static int bitmap_clear_ll(unsigned long *map, int start, int nr) -{ - unsigned long *p = map + BIT_WORD(start); - const int size = start + nr; - int bits_to_clear = BITS_PER_LONG - (start % BITS_PER_LONG); - unsigned long mask_to_clear = BITMAP_FIRST_WORD_MASK(start); - - while (nr - bits_to_clear >= 0) { - if (clear_bits_ll(p, mask_to_clear)) - return nr; - nr -= bits_to_clear; - bits_to_clear = BITS_PER_LONG; - mask_to_clear = ~0UL; - p++; - } - if (nr) { - mask_to_clear &= BITMAP_LAST_WORD_MASK(size); - if (clear_bits_ll(p, mask_to_clear)) - return nr; - } - - return 0; -} /** * gen_pool_create - create a new special memory pool @@ -149,7 +30,7 @@ struct gen_pool *gen_pool_create(int min_alloc_order, int nid) pool = kmalloc_node(sizeof(struct gen_pool), GFP_KERNEL, nid); if (pool != NULL) { - spin_lock_init(&pool->lock); + rwlock_init(&pool->lock); INIT_LIST_HEAD(&pool->chunks); pool->min_alloc_order = min_alloc_order; } @@ -182,14 +63,14 @@ int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phy if (unlikely(chunk == NULL)) return -ENOMEM; + spin_lock_init(&chunk->lock); chunk->phys_addr = phys; chunk->start_addr = virt; chunk->end_addr = virt + size; - atomic_set(&chunk->avail, size); - spin_lock(&pool->lock); - list_add_rcu(&chunk->next_chunk, &pool->chunks); - spin_unlock(&pool->lock); + write_lock(&pool->lock); + list_add(&chunk->next_chunk, &pool->chunks); + write_unlock(&pool->lock); return 0; } @@ -204,19 +85,19 @@ EXPORT_SYMBOL(gen_pool_add_virt); */ phys_addr_t gen_pool_virt_to_phys(struct gen_pool *pool, unsigned long addr) { + struct list_head *_chunk; struct gen_pool_chunk *chunk; - phys_addr_t paddr = -1; - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { - if (addr >= chunk->start_addr && addr < chunk->end_addr) { - paddr = chunk->phys_addr + (addr - chunk->start_addr); - break; - } + read_lock(&pool->lock); + list_for_each(_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); + + if (addr >= chunk->start_addr && addr < chunk->end_addr) + return chunk->phys_addr + addr - chunk->start_addr; } - rcu_read_unlock(); + read_unlock(&pool->lock); - return paddr; + return -1; } EXPORT_SYMBOL(gen_pool_virt_to_phys); @@ -234,6 +115,7 @@ void gen_pool_destroy(struct gen_pool *pool) int order = pool->min_alloc_order; int bit, end_bit; + list_for_each_safe(_chunk, _next_chunk, &pool->chunks) { chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); list_del(&chunk->next_chunk); @@ -255,50 +137,44 @@ EXPORT_SYMBOL(gen_pool_destroy); * @size: number of bytes to allocate from the pool * * Allocate the requested number of bytes from the specified pool. - * Uses a first-fit algorithm. Can not be used in NMI handler on - * architectures without NMI-safe cmpxchg implementation. + * Uses a first-fit algorithm. */ unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size) { + struct list_head *_chunk; struct gen_pool_chunk *chunk; - unsigned long addr = 0; + unsigned long addr, flags; int order = pool->min_alloc_order; - int nbits, start_bit = 0, end_bit, remain; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif + int nbits, start_bit, end_bit; if (size == 0) return 0; nbits = (size + (1UL << order) - 1) >> order; - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { - if (size > atomic_read(&chunk->avail)) - continue; + + read_lock(&pool->lock); + list_for_each(_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); end_bit = (chunk->end_addr - chunk->start_addr) >> order; -retry: - start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, - start_bit, nbits, 0); - if (start_bit >= end_bit) + + spin_lock_irqsave(&chunk->lock, flags); + start_bit = bitmap_find_next_zero_area(chunk->bits, end_bit, 0, + nbits, 0); + if (start_bit >= end_bit) { + spin_unlock_irqrestore(&chunk->lock, flags); continue; - remain = bitmap_set_ll(chunk->bits, start_bit, nbits); - if (remain) { - remain = bitmap_clear_ll(chunk->bits, start_bit, - nbits - remain); - BUG_ON(remain); - goto retry; } addr = chunk->start_addr + ((unsigned long)start_bit << order); - size = nbits << order; - atomic_sub(size, &chunk->avail); - break; + + bitmap_set(chunk->bits, start_bit, nbits); + spin_unlock_irqrestore(&chunk->lock, flags); + read_unlock(&pool->lock); + return addr; } - rcu_read_unlock(); - return addr; + read_unlock(&pool->lock); + return 0; } EXPORT_SYMBOL(gen_pool_alloc); @@ -308,95 +184,33 @@ EXPORT_SYMBOL(gen_pool_alloc); * @addr: starting address of memory to free back to pool * @size: size in bytes of memory to free * - * Free previously allocated special memory back to the specified - * pool. Can not be used in NMI handler on architectures without - * NMI-safe cmpxchg implementation. + * Free previously allocated special memory back to the specified pool. */ void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size) { + struct list_head *_chunk; struct gen_pool_chunk *chunk; + unsigned long flags; int order = pool->min_alloc_order; - int start_bit, nbits, remain; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif + int bit, nbits; nbits = (size + (1UL << order) - 1) >> order; - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) { + + read_lock(&pool->lock); + list_for_each(_chunk, &pool->chunks) { + chunk = list_entry(_chunk, struct gen_pool_chunk, next_chunk); + if (addr >= chunk->start_addr && addr < chunk->end_addr) { BUG_ON(addr + size > chunk->end_addr); - start_bit = (addr - chunk->start_addr) >> order; - remain = bitmap_clear_ll(chunk->bits, start_bit, nbits); - BUG_ON(remain); - size = nbits << order; - atomic_add(size, &chunk->avail); - rcu_read_unlock(); - return; + spin_lock_irqsave(&chunk->lock, flags); + bit = (addr - chunk->start_addr) >> order; + while (nbits--) + __clear_bit(bit++, chunk->bits); + spin_unlock_irqrestore(&chunk->lock, flags); + break; } } - rcu_read_unlock(); - BUG(); + BUG_ON(nbits > 0); + read_unlock(&pool->lock); } EXPORT_SYMBOL(gen_pool_free); - -/** - * gen_pool_for_each_chunk - call func for every chunk of generic memory pool - * @pool: the generic memory pool - * @func: func to call - * @data: additional data used by @func - * - * Call @func for every chunk of generic memory pool. The @func is - * called with rcu_read_lock held. - */ -void gen_pool_for_each_chunk(struct gen_pool *pool, - void (*func)(struct gen_pool *pool, struct gen_pool_chunk *chunk, void *data), - void *data) -{ - struct gen_pool_chunk *chunk; - - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &(pool)->chunks, next_chunk) - func(pool, chunk, data); - rcu_read_unlock(); -} -EXPORT_SYMBOL(gen_pool_for_each_chunk); - -/** - * gen_pool_avail - get available free space of the pool - * @pool: pool to get available free space - * - * Return available free space of the specified pool. - */ -size_t gen_pool_avail(struct gen_pool *pool) -{ - struct gen_pool_chunk *chunk; - size_t avail = 0; - - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) - avail += atomic_read(&chunk->avail); - rcu_read_unlock(); - return avail; -} -EXPORT_SYMBOL_GPL(gen_pool_avail); - -/** - * gen_pool_size - get size in bytes of memory managed by the pool - * @pool: pool to get size - * - * Return size in bytes of memory managed by the pool. - */ -size_t gen_pool_size(struct gen_pool *pool) -{ - struct gen_pool_chunk *chunk; - size_t size = 0; - - rcu_read_lock(); - list_for_each_entry_rcu(chunk, &pool->chunks, next_chunk) - size += chunk->end_addr - chunk->start_addr; - rcu_read_unlock(); - return size; -} -EXPORT_SYMBOL_GPL(gen_pool_size); diff --git a/trunk/lib/idr.c b/trunk/lib/idr.c index db040ce3fa73..e15502e8b21e 100644 --- a/trunk/lib/idr.c +++ b/trunk/lib/idr.c @@ -34,10 +34,8 @@ #include #include #include -#include static struct kmem_cache *idr_layer_cache; -static DEFINE_SPINLOCK(simple_ida_lock); static struct idr_layer *get_from_free_list(struct idr *idp) { @@ -927,71 +925,6 @@ void ida_destroy(struct ida *ida) } EXPORT_SYMBOL(ida_destroy); -/** - * ida_simple_get - get a new id. - * @ida: the (initialized) ida. - * @start: the minimum id (inclusive, < 0x8000000) - * @end: the maximum id (exclusive, < 0x8000000 or 0) - * @gfp_mask: memory allocation flags - * - * Allocates an id in the range start <= id < end, or returns -ENOSPC. - * On memory allocation failure, returns -ENOMEM. - * - * Use ida_simple_remove() to get rid of an id. - */ -int ida_simple_get(struct ida *ida, unsigned int start, unsigned int end, - gfp_t gfp_mask) -{ - int ret, id; - unsigned int max; - - BUG_ON((int)start < 0); - BUG_ON((int)end < 0); - - if (end == 0) - max = 0x80000000; - else { - BUG_ON(end < start); - max = end - 1; - } - -again: - if (!ida_pre_get(ida, gfp_mask)) - return -ENOMEM; - - spin_lock(&simple_ida_lock); - ret = ida_get_new_above(ida, start, &id); - if (!ret) { - if (id > max) { - ida_remove(ida, id); - ret = -ENOSPC; - } else { - ret = id; - } - } - spin_unlock(&simple_ida_lock); - - if (unlikely(ret == -EAGAIN)) - goto again; - - return ret; -} -EXPORT_SYMBOL(ida_simple_get); - -/** - * ida_simple_remove - remove an allocated id. - * @ida: the (initialized) ida. - * @id: the id returned by ida_simple_get. - */ -void ida_simple_remove(struct ida *ida, unsigned int id) -{ - BUG_ON((int)id < 0); - spin_lock(&simple_ida_lock); - ida_remove(ida, id); - spin_unlock(&simple_ida_lock); -} -EXPORT_SYMBOL(ida_simple_remove); - /** * ida_init - initialize ida handle * @ida: ida handle diff --git a/trunk/lib/llist.c b/trunk/lib/llist.c deleted file mode 100644 index da445724fa1f..000000000000 --- a/trunk/lib/llist.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Lock-less NULL terminated single linked list - * - * The basic atomic operation of this list is cmpxchg on long. On - * architectures that don't have NMI-safe cmpxchg implementation, the - * list can NOT be used in NMI handler. So code uses the list in NMI - * handler should depend on CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. - * - * Copyright 2010,2011 Intel Corp. - * Author: Huang Ying - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License version - * 2 as published by the Free Software Foundation; - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -#include -#include -#include -#include - -#include - -/** - * llist_add - add a new entry - * @new: new entry to be added - * @head: the head for your lock-less list - */ -void llist_add(struct llist_node *new, struct llist_head *head) -{ - struct llist_node *entry, *old_entry; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - entry = head->first; - do { - old_entry = entry; - new->next = entry; - cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, new)) != old_entry); -} -EXPORT_SYMBOL_GPL(llist_add); - -/** - * llist_add_batch - add several linked entries in batch - * @new_first: first entry in batch to be added - * @new_last: last entry in batch to be added - * @head: the head for your lock-less list - */ -void llist_add_batch(struct llist_node *new_first, struct llist_node *new_last, - struct llist_head *head) -{ - struct llist_node *entry, *old_entry; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - entry = head->first; - do { - old_entry = entry; - new_last->next = entry; - cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, new_first)) != old_entry); -} -EXPORT_SYMBOL_GPL(llist_add_batch); - -/** - * llist_del_first - delete the first entry of lock-less list - * @head: the head for your lock-less list - * - * If list is empty, return NULL, otherwise, return the first entry - * deleted, this is the newest added one. - * - * Only one llist_del_first user can be used simultaneously with - * multiple llist_add users without lock. Because otherwise - * llist_del_first, llist_add, llist_add (or llist_del_all, llist_add, - * llist_add) sequence in another user may change @head->first->next, - * but keep @head->first. If multiple consumers are needed, please - * use llist_del_all or use lock between consumers. - */ -struct llist_node *llist_del_first(struct llist_head *head) -{ - struct llist_node *entry, *old_entry, *next; - -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - entry = head->first; - do { - if (entry == NULL) - return NULL; - old_entry = entry; - next = entry->next; - cpu_relax(); - } while ((entry = cmpxchg(&head->first, old_entry, next)) != old_entry); - - return entry; -} -EXPORT_SYMBOL_GPL(llist_del_first); - -/** - * llist_del_all - delete all entries from lock-less list - * @head: the head of lock-less list to delete all entries - * - * If list is empty, return NULL, otherwise, delete all entries and - * return the pointer to the first entry. The order of entries - * deleted is from the newest to the oldest added one. - */ -struct llist_node *llist_del_all(struct llist_head *head) -{ -#ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG - BUG_ON(in_nmi()); -#endif - - return xchg(&head->first, NULL); -} -EXPORT_SYMBOL_GPL(llist_del_all); diff --git a/trunk/lib/md5.c b/trunk/lib/md5.c deleted file mode 100644 index c777180e1f2f..000000000000 --- a/trunk/lib/md5.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -#define MD5STEP(f, w, x, y, z, in, s) \ - (w += f(x, y, z) + in, w = (w<>(32-s)) + x) - -void md5_transform(__u32 *hash, __u32 const *in) -{ - u32 a, b, c, d; - - a = hash[0]; - b = hash[1]; - c = hash[2]; - d = hash[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - hash[0] += a; - hash[1] += b; - hash[2] += c; - hash[3] += d; -} -EXPORT_SYMBOL(md5_transform); diff --git a/trunk/lib/radix-tree.c b/trunk/lib/radix-tree.c index a2f9da59c197..7ea2e033d715 100644 --- a/trunk/lib/radix-tree.c +++ b/trunk/lib/radix-tree.c @@ -823,8 +823,8 @@ unsigned long radix_tree_prev_hole(struct radix_tree_root *root, EXPORT_SYMBOL(radix_tree_prev_hole); static unsigned int -__lookup(struct radix_tree_node *slot, void ***results, unsigned long *indices, - unsigned long index, unsigned int max_items, unsigned long *next_index) +__lookup(struct radix_tree_node *slot, void ***results, unsigned long index, + unsigned int max_items, unsigned long *next_index) { unsigned int nr_found = 0; unsigned int shift, height; @@ -857,16 +857,12 @@ __lookup(struct radix_tree_node *slot, void ***results, unsigned long *indices, /* Bottom level: grab some items */ for (i = index & RADIX_TREE_MAP_MASK; i < RADIX_TREE_MAP_SIZE; i++) { + index++; if (slot->slots[i]) { - results[nr_found] = &(slot->slots[i]); - if (indices) - indices[nr_found] = index; - if (++nr_found == max_items) { - index++; + results[nr_found++] = &(slot->slots[i]); + if (nr_found == max_items) goto out; - } } - index++; } out: *next_index = index; @@ -922,8 +918,8 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, if (cur_index > max_index) break; - slots_found = __lookup(node, (void ***)results + ret, NULL, - cur_index, max_items - ret, &next_index); + slots_found = __lookup(node, (void ***)results + ret, cur_index, + max_items - ret, &next_index); nr_found = 0; for (i = 0; i < slots_found; i++) { struct radix_tree_node *slot; @@ -948,7 +944,6 @@ EXPORT_SYMBOL(radix_tree_gang_lookup); * radix_tree_gang_lookup_slot - perform multiple slot lookup on radix tree * @root: radix tree root * @results: where the results of the lookup are placed - * @indices: where their indices should be placed (but usually NULL) * @first_index: start the lookup from this key * @max_items: place up to this many items at *results * @@ -963,8 +958,7 @@ EXPORT_SYMBOL(radix_tree_gang_lookup); * protection, radix_tree_deref_slot may fail requiring a retry. */ unsigned int -radix_tree_gang_lookup_slot(struct radix_tree_root *root, - void ***results, unsigned long *indices, +radix_tree_gang_lookup_slot(struct radix_tree_root *root, void ***results, unsigned long first_index, unsigned int max_items) { unsigned long max_index; @@ -980,8 +974,6 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, if (first_index > 0) return 0; results[0] = (void **)&root->rnode; - if (indices) - indices[0] = 0; return 1; } node = indirect_to_ptr(node); @@ -995,9 +987,8 @@ radix_tree_gang_lookup_slot(struct radix_tree_root *root, if (cur_index > max_index) break; - slots_found = __lookup(node, results + ret, - indices ? indices + ret : NULL, - cur_index, max_items - ret, &next_index); + slots_found = __lookup(node, results + ret, cur_index, + max_items - ret, &next_index); ret += slots_found; if (next_index == 0) break; @@ -1203,98 +1194,6 @@ radix_tree_gang_lookup_tag_slot(struct radix_tree_root *root, void ***results, } EXPORT_SYMBOL(radix_tree_gang_lookup_tag_slot); -#if defined(CONFIG_SHMEM) && defined(CONFIG_SWAP) -#include /* for cond_resched() */ - -/* - * This linear search is at present only useful to shmem_unuse_inode(). - */ -static unsigned long __locate(struct radix_tree_node *slot, void *item, - unsigned long index, unsigned long *found_index) -{ - unsigned int shift, height; - unsigned long i; - - height = slot->height; - shift = (height-1) * RADIX_TREE_MAP_SHIFT; - - for ( ; height > 1; height--) { - i = (index >> shift) & RADIX_TREE_MAP_MASK; - for (;;) { - if (slot->slots[i] != NULL) - break; - index &= ~((1UL << shift) - 1); - index += 1UL << shift; - if (index == 0) - goto out; /* 32-bit wraparound */ - i++; - if (i == RADIX_TREE_MAP_SIZE) - goto out; - } - - shift -= RADIX_TREE_MAP_SHIFT; - slot = rcu_dereference_raw(slot->slots[i]); - if (slot == NULL) - goto out; - } - - /* Bottom level: check items */ - for (i = 0; i < RADIX_TREE_MAP_SIZE; i++) { - if (slot->slots[i] == item) { - *found_index = index + i; - index = 0; - goto out; - } - } - index += RADIX_TREE_MAP_SIZE; -out: - return index; -} - -/** - * radix_tree_locate_item - search through radix tree for item - * @root: radix tree root - * @item: item to be found - * - * Returns index where item was found, or -1 if not found. - * Caller must hold no lock (since this time-consuming function needs - * to be preemptible), and must check afterwards if item is still there. - */ -unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item) -{ - struct radix_tree_node *node; - unsigned long max_index; - unsigned long cur_index = 0; - unsigned long found_index = -1; - - do { - rcu_read_lock(); - node = rcu_dereference_raw(root->rnode); - if (!radix_tree_is_indirect_ptr(node)) { - rcu_read_unlock(); - if (node == item) - found_index = 0; - break; - } - - node = indirect_to_ptr(node); - max_index = radix_tree_maxindex(node->height); - if (cur_index > max_index) - break; - - cur_index = __locate(node, item, cur_index, &found_index); - rcu_read_unlock(); - cond_resched(); - } while (cur_index != 0 && cur_index <= max_index); - - return found_index; -} -#else -unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item) -{ - return -1; -} -#endif /* CONFIG_SHMEM && CONFIG_SWAP */ /** * radix_tree_shrink - shrink height of a radix tree to minimal diff --git a/trunk/lib/sha1.c b/trunk/lib/sha1.c index f33271dd00cb..4c45fd50e913 100644 --- a/trunk/lib/sha1.c +++ b/trunk/lib/sha1.c @@ -1,72 +1,31 @@ /* - * SHA1 routine optimized to do word accesses rather than byte accesses, - * and to avoid unnecessary copies into the context array. - * - * This was based on the git SHA1 implementation. + * SHA transform algorithm, originally taken from code written by + * Peter Gutmann, and placed in the public domain. */ #include #include -#include -#include +#include -/* - * If you have 32 registers or more, the compiler can (and should) - * try to change the array[] accesses into registers. However, on - * machines with less than ~25 registers, that won't really work, - * and at least gcc will make an unholy mess of it. - * - * So to avoid that mess which just slows things down, we force - * the stores to memory to actually happen (we might be better off - * with a 'W(t)=(val);asm("":"+m" (W(t))' there instead, as - * suggested by Artur Skawina - that will also make gcc unable to - * try to do the silly "optimize away loads" part because it won't - * see what the value will be). - * - * Ben Herrenschmidt reports that on PPC, the C version comes close - * to the optimized asm with this (ie on PPC you don't want that - * 'volatile', since there are lots of registers). - * - * On ARM we get the best code generation by forcing a full memory barrier - * between each SHA_ROUND, otherwise gcc happily get wild with spilling and - * the stack frame size simply explode and performance goes down the drain. - */ +/* The SHA f()-functions. */ -#ifdef CONFIG_X86 - #define setW(x, val) (*(volatile __u32 *)&W(x) = (val)) -#elif defined(CONFIG_ARM) - #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0) -#else - #define setW(x, val) (W(x) = (val)) -#endif +#define f1(x,y,z) (z ^ (x & (y ^ z))) /* x ? y : z */ +#define f2(x,y,z) (x ^ y ^ z) /* XOR */ +#define f3(x,y,z) ((x & y) + (z & (x ^ y))) /* majority */ -/* This "rolls" over the 512-bit array */ -#define W(x) (array[(x)&15]) +/* The SHA Mysterious Constants */ -/* - * Where do we get the source from? The first 16 iterations get it from - * the input data, the next mix it from the 512-bit array. - */ -#define SHA_SRC(t) get_unaligned_be32((__u32 *)data + t) -#define SHA_MIX(t) rol32(W(t+13) ^ W(t+8) ^ W(t+2) ^ W(t), 1) - -#define SHA_ROUND(t, input, fn, constant, A, B, C, D, E) do { \ - __u32 TEMP = input(t); setW(t, TEMP); \ - E += TEMP + rol32(A,5) + (fn) + (constant); \ - B = ror32(B, 2); } while (0) - -#define T_0_15(t, A, B, C, D, E) SHA_ROUND(t, SHA_SRC, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_16_19(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (((C^D)&B)^D) , 0x5a827999, A, B, C, D, E ) -#define T_20_39(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0x6ed9eba1, A, B, C, D, E ) -#define T_40_59(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, ((B&C)+(D&(B^C))) , 0x8f1bbcdc, A, B, C, D, E ) -#define T_60_79(t, A, B, C, D, E) SHA_ROUND(t, SHA_MIX, (B^C^D) , 0xca62c1d6, A, B, C, D, E ) +#define K1 0x5A827999L /* Rounds 0-19: sqrt(2) * 2^30 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39: sqrt(3) * 2^30 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59: sqrt(5) * 2^30 */ +#define K4 0xCA62C1D6L /* Rounds 60-79: sqrt(10) * 2^30 */ /** * sha_transform - single block SHA1 transform * * @digest: 160 bit digest to update * @data: 512 bits of data to hash - * @array: 16 words of workspace (see note) + * @W: 80 words of workspace (see note) * * This function generates a SHA1 digest for a single 512-bit block. * Be warned, it does not handle padding and message digest, do not @@ -77,111 +36,47 @@ * to clear the workspace. This is left to the caller to avoid * unnecessary clears between chained hashing operations. */ -void sha_transform(__u32 *digest, const char *data, __u32 *array) +void sha_transform(__u32 *digest, const char *in, __u32 *W) { - __u32 A, B, C, D, E; - - A = digest[0]; - B = digest[1]; - C = digest[2]; - D = digest[3]; - E = digest[4]; - - /* Round 1 - iterations 0-16 take their input from 'data' */ - T_0_15( 0, A, B, C, D, E); - T_0_15( 1, E, A, B, C, D); - T_0_15( 2, D, E, A, B, C); - T_0_15( 3, C, D, E, A, B); - T_0_15( 4, B, C, D, E, A); - T_0_15( 5, A, B, C, D, E); - T_0_15( 6, E, A, B, C, D); - T_0_15( 7, D, E, A, B, C); - T_0_15( 8, C, D, E, A, B); - T_0_15( 9, B, C, D, E, A); - T_0_15(10, A, B, C, D, E); - T_0_15(11, E, A, B, C, D); - T_0_15(12, D, E, A, B, C); - T_0_15(13, C, D, E, A, B); - T_0_15(14, B, C, D, E, A); - T_0_15(15, A, B, C, D, E); - - /* Round 1 - tail. Input from 512-bit mixing array */ - T_16_19(16, E, A, B, C, D); - T_16_19(17, D, E, A, B, C); - T_16_19(18, C, D, E, A, B); - T_16_19(19, B, C, D, E, A); - - /* Round 2 */ - T_20_39(20, A, B, C, D, E); - T_20_39(21, E, A, B, C, D); - T_20_39(22, D, E, A, B, C); - T_20_39(23, C, D, E, A, B); - T_20_39(24, B, C, D, E, A); - T_20_39(25, A, B, C, D, E); - T_20_39(26, E, A, B, C, D); - T_20_39(27, D, E, A, B, C); - T_20_39(28, C, D, E, A, B); - T_20_39(29, B, C, D, E, A); - T_20_39(30, A, B, C, D, E); - T_20_39(31, E, A, B, C, D); - T_20_39(32, D, E, A, B, C); - T_20_39(33, C, D, E, A, B); - T_20_39(34, B, C, D, E, A); - T_20_39(35, A, B, C, D, E); - T_20_39(36, E, A, B, C, D); - T_20_39(37, D, E, A, B, C); - T_20_39(38, C, D, E, A, B); - T_20_39(39, B, C, D, E, A); - - /* Round 3 */ - T_40_59(40, A, B, C, D, E); - T_40_59(41, E, A, B, C, D); - T_40_59(42, D, E, A, B, C); - T_40_59(43, C, D, E, A, B); - T_40_59(44, B, C, D, E, A); - T_40_59(45, A, B, C, D, E); - T_40_59(46, E, A, B, C, D); - T_40_59(47, D, E, A, B, C); - T_40_59(48, C, D, E, A, B); - T_40_59(49, B, C, D, E, A); - T_40_59(50, A, B, C, D, E); - T_40_59(51, E, A, B, C, D); - T_40_59(52, D, E, A, B, C); - T_40_59(53, C, D, E, A, B); - T_40_59(54, B, C, D, E, A); - T_40_59(55, A, B, C, D, E); - T_40_59(56, E, A, B, C, D); - T_40_59(57, D, E, A, B, C); - T_40_59(58, C, D, E, A, B); - T_40_59(59, B, C, D, E, A); - - /* Round 4 */ - T_60_79(60, A, B, C, D, E); - T_60_79(61, E, A, B, C, D); - T_60_79(62, D, E, A, B, C); - T_60_79(63, C, D, E, A, B); - T_60_79(64, B, C, D, E, A); - T_60_79(65, A, B, C, D, E); - T_60_79(66, E, A, B, C, D); - T_60_79(67, D, E, A, B, C); - T_60_79(68, C, D, E, A, B); - T_60_79(69, B, C, D, E, A); - T_60_79(70, A, B, C, D, E); - T_60_79(71, E, A, B, C, D); - T_60_79(72, D, E, A, B, C); - T_60_79(73, C, D, E, A, B); - T_60_79(74, B, C, D, E, A); - T_60_79(75, A, B, C, D, E); - T_60_79(76, E, A, B, C, D); - T_60_79(77, D, E, A, B, C); - T_60_79(78, C, D, E, A, B); - T_60_79(79, B, C, D, E, A); - - digest[0] += A; - digest[1] += B; - digest[2] += C; - digest[3] += D; - digest[4] += E; + __u32 a, b, c, d, e, t, i; + + for (i = 0; i < 16; i++) + W[i] = be32_to_cpu(((const __be32 *)in)[i]); + + for (i = 0; i < 64; i++) + W[i+16] = rol32(W[i+13] ^ W[i+8] ^ W[i+2] ^ W[i], 1); + + a = digest[0]; + b = digest[1]; + c = digest[2]; + d = digest[3]; + e = digest[4]; + + for (i = 0; i < 20; i++) { + t = f1(b, c, d) + K1 + rol32(a, 5) + e + W[i]; + e = d; d = c; c = rol32(b, 30); b = a; a = t; + } + + for (; i < 40; i ++) { + t = f2(b, c, d) + K2 + rol32(a, 5) + e + W[i]; + e = d; d = c; c = rol32(b, 30); b = a; a = t; + } + + for (; i < 60; i ++) { + t = f3(b, c, d) + K3 + rol32(a, 5) + e + W[i]; + e = d; d = c; c = rol32(b, 30); b = a; a = t; + } + + for (; i < 80; i ++) { + t = f2(b, c, d) + K4 + rol32(a, 5) + e + W[i]; + e = d; d = c; c = rol32(b, 30); b = a; a = t; + } + + digest[0] += a; + digest[1] += b; + digest[2] += c; + digest[3] += d; + digest[4] += e; } EXPORT_SYMBOL(sha_transform); @@ -197,3 +92,4 @@ void sha_init(__u32 *buf) buf[3] = 0x10325476; buf[4] = 0xc3d2e1f0; } + diff --git a/trunk/mm/failslab.c b/trunk/mm/failslab.c index 0dd7b8fec71c..1ce58c201dca 100644 --- a/trunk/mm/failslab.c +++ b/trunk/mm/failslab.c @@ -34,23 +34,23 @@ __setup("failslab=", setup_failslab); #ifdef CONFIG_FAULT_INJECTION_DEBUG_FS static int __init failslab_debugfs_init(void) { - struct dentry *dir; mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; + int err; - dir = fault_create_debugfs_attr("failslab", NULL, &failslab.attr); - if (IS_ERR(dir)) - return PTR_ERR(dir); + err = init_fault_attr_dentries(&failslab.attr, "failslab"); + if (err) + return err; - if (!debugfs_create_bool("ignore-gfp-wait", mode, dir, + if (!debugfs_create_bool("ignore-gfp-wait", mode, failslab.attr.dir, &failslab.ignore_gfp_wait)) goto fail; - if (!debugfs_create_bool("cache-filter", mode, dir, + if (!debugfs_create_bool("cache-filter", mode, failslab.attr.dir, &failslab.cache_filter)) goto fail; return 0; fail: - debugfs_remove_recursive(dir); + cleanup_fault_attr_dentries(&failslab.attr); return -ENOMEM; } diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 645a080ba4df..867d40222ec7 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -33,6 +33,7 @@ #include #include /* for BUG_ON(!in_atomic()) only */ #include +#include /* for page_is_file_cache() */ #include #include "internal.h" @@ -461,7 +462,6 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, int error; VM_BUG_ON(!PageLocked(page)); - VM_BUG_ON(PageSwapBacked(page)); error = mem_cgroup_cache_charge(page, current->mm, gfp_mask & GFP_RECLAIM_MASK); @@ -479,6 +479,8 @@ int add_to_page_cache_locked(struct page *page, struct address_space *mapping, if (likely(!error)) { mapping->nrpages++; __inc_zone_page_state(page, NR_FILE_PAGES); + if (PageSwapBacked(page)) + __inc_zone_page_state(page, NR_SHMEM); spin_unlock_irq(&mapping->tree_lock); } else { page->mapping = NULL; @@ -500,9 +502,22 @@ int add_to_page_cache_lru(struct page *page, struct address_space *mapping, { int ret; + /* + * Splice_read and readahead add shmem/tmpfs pages into the page cache + * before shmem_readpage has a chance to mark them as SwapBacked: they + * need to go on the anon lru below, and mem_cgroup_cache_charge + * (called in add_to_page_cache) needs to know where they're going too. + */ + if (mapping_cap_swap_backed(mapping)) + SetPageSwapBacked(page); + ret = add_to_page_cache(page, mapping, offset, gfp_mask); - if (ret == 0) - lru_cache_add_file(page); + if (ret == 0) { + if (page_is_file_cache(page)) + lru_cache_add_file(page); + else + lru_cache_add_anon(page); + } return ret; } EXPORT_SYMBOL_GPL(add_to_page_cache_lru); @@ -699,16 +714,9 @@ struct page *find_get_page(struct address_space *mapping, pgoff_t offset) page = radix_tree_deref_slot(pagep); if (unlikely(!page)) goto out; - if (radix_tree_exception(page)) { - if (radix_tree_deref_retry(page)) - goto repeat; - /* - * Otherwise, shmem/tmpfs must be storing a swap entry - * here as an exceptional entry: so return it without - * attempting to raise page count. - */ - goto out; - } + if (radix_tree_deref_retry(page)) + goto repeat; + if (!page_cache_get_speculative(page)) goto repeat; @@ -745,7 +753,7 @@ struct page *find_lock_page(struct address_space *mapping, pgoff_t offset) repeat: page = find_get_page(mapping, offset); - if (page && !radix_tree_exception(page)) { + if (page) { lock_page(page); /* Has the page been truncated? */ if (unlikely(page->mapping != mapping)) { @@ -832,7 +840,7 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, rcu_read_lock(); restart: nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, - (void ***)pages, NULL, start, nr_pages); + (void ***)pages, start, nr_pages); ret = 0; for (i = 0; i < nr_found; i++) { struct page *page; @@ -841,22 +849,13 @@ unsigned find_get_pages(struct address_space *mapping, pgoff_t start, if (unlikely(!page)) continue; - if (radix_tree_exception(page)) { - if (radix_tree_deref_retry(page)) { - /* - * Transient condition which can only trigger - * when entry at index 0 moves out of or back - * to root: none yet gotten, safe to restart. - */ - WARN_ON(start | i); - goto restart; - } - /* - * Otherwise, shmem/tmpfs must be storing a swap entry - * here as an exceptional entry: so skip over it - - * we only reach this from invalidate_mapping_pages(). - */ - continue; + /* + * This can only trigger when the entry at index 0 moves out + * of or back to the root: none yet gotten, safe to restart. + */ + if (radix_tree_deref_retry(page)) { + WARN_ON(start | i); + goto restart; } if (!page_cache_get_speculative(page)) @@ -904,7 +903,7 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, rcu_read_lock(); restart: nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, - (void ***)pages, NULL, index, nr_pages); + (void ***)pages, index, nr_pages); ret = 0; for (i = 0; i < nr_found; i++) { struct page *page; @@ -913,22 +912,12 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t index, if (unlikely(!page)) continue; - if (radix_tree_exception(page)) { - if (radix_tree_deref_retry(page)) { - /* - * Transient condition which can only trigger - * when entry at index 0 moves out of or back - * to root: none yet gotten, safe to restart. - */ - goto restart; - } - /* - * Otherwise, shmem/tmpfs must be storing a swap entry - * here as an exceptional entry: so stop looking for - * contiguous pages. - */ - break; - } + /* + * This can only trigger when the entry at index 0 moves out + * of or back to the root: none yet gotten, safe to restart. + */ + if (radix_tree_deref_retry(page)) + goto restart; if (!page_cache_get_speculative(page)) goto repeat; @@ -988,21 +977,12 @@ unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, if (unlikely(!page)) continue; - if (radix_tree_exception(page)) { - if (radix_tree_deref_retry(page)) { - /* - * Transient condition which can only trigger - * when entry at index 0 moves out of or back - * to root: none yet gotten, safe to restart. - */ - goto restart; - } - /* - * This function is never used on a shmem/tmpfs - * mapping, so a swap entry won't be found here. - */ - BUG(); - } + /* + * This can only trigger when the entry at index 0 moves out + * of or back to the root: none yet gotten, safe to restart. + */ + if (radix_tree_deref_retry(page)) + goto restart; if (!page_cache_get_speculative(page)) goto repeat; diff --git a/trunk/mm/memcontrol.c b/trunk/mm/memcontrol.c index 930de9437271..5f84d2351ddb 100644 --- a/trunk/mm/memcontrol.c +++ b/trunk/mm/memcontrol.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -2091,7 +2092,6 @@ struct memcg_stock_pcp { #define FLUSHING_CACHED_CHARGE (0) }; static DEFINE_PER_CPU(struct memcg_stock_pcp, memcg_stock); -static DEFINE_MUTEX(percpu_charge_mutex); /* * Try to consume stocked charge on this cpu. If success, one page is consumed @@ -2198,7 +2198,8 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync) for_each_online_cpu(cpu) { struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu); - if (test_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) + if (mem_cgroup_same_or_subtree(root_mem, stock->cached) && + test_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) flush_work(&stock->work); } out: @@ -2213,22 +2214,14 @@ static void drain_all_stock(struct mem_cgroup *root_mem, bool sync) */ static void drain_all_stock_async(struct mem_cgroup *root_mem) { - /* - * If someone calls draining, avoid adding more kworker runs. - */ - if (!mutex_trylock(&percpu_charge_mutex)) - return; drain_all_stock(root_mem, false); - mutex_unlock(&percpu_charge_mutex); } /* This is a synchronous drain interface. */ static void drain_all_stock_sync(struct mem_cgroup *root_mem) { /* called when force_empty is called */ - mutex_lock(&percpu_charge_mutex); drain_all_stock(root_mem, true); - mutex_unlock(&percpu_charge_mutex); } /* @@ -2880,6 +2873,30 @@ int mem_cgroup_cache_charge(struct page *page, struct mm_struct *mm, return 0; if (PageCompound(page)) return 0; + /* + * Corner case handling. This is called from add_to_page_cache() + * in usual. But some FS (shmem) precharges this page before calling it + * and call add_to_page_cache() with GFP_NOWAIT. + * + * For GFP_NOWAIT case, the page may be pre-charged before calling + * add_to_page_cache(). (See shmem.c) check it here and avoid to call + * charge twice. (It works but has to pay a bit larger cost.) + * And when the page is SwapCache, it should take swap information + * into account. This is under lock_page() now. + */ + if (!(gfp_mask & __GFP_WAIT)) { + struct page_cgroup *pc; + + pc = lookup_page_cgroup(page); + if (!pc) + return 0; + lock_page_cgroup(pc); + if (PageCgroupUsed(pc)) { + unlock_page_cgroup(pc); + return 0; + } + unlock_page_cgroup(pc); + } if (unlikely(!mm)) mm = &init_mm; @@ -3469,6 +3486,31 @@ void mem_cgroup_end_migration(struct mem_cgroup *mem, cgroup_release_and_wakeup_rmdir(&mem->css); } +/* + * A call to try to shrink memory usage on charge failure at shmem's swapin. + * Calling hierarchical_reclaim is not enough because we should update + * last_oom_jiffies to prevent pagefault_out_of_memory from invoking global OOM. + * Moreover considering hierarchy, we should reclaim from the mem_over_limit, + * not from the memcg which this page would be charged to. + * try_charge_swapin does all of these works properly. + */ +int mem_cgroup_shmem_charge_fallback(struct page *page, + struct mm_struct *mm, + gfp_t gfp_mask) +{ + struct mem_cgroup *mem; + int ret; + + if (mem_cgroup_disabled()) + return 0; + + ret = mem_cgroup_try_charge_swapin(mm, page, gfp_mask, &mem); + if (!ret) + mem_cgroup_cancel_charge_swapin(mem); /* it does !mem check */ + + return ret; +} + #ifdef CONFIG_DEBUG_VM static struct page_cgroup *lookup_page_cgroup_used(struct page *page) { @@ -5288,17 +5330,15 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, pgoff = pte_to_pgoff(ptent); /* page is moved even if it's not RSS of this task(page-faulted). */ - page = find_get_page(mapping, pgoff); - -#ifdef CONFIG_SWAP - /* shmem/tmpfs may report page out on swap: account for that too. */ - if (radix_tree_exceptional_entry(page)) { - swp_entry_t swap = radix_to_swp_entry(page); + if (!mapping_cap_swap_backed(mapping)) { /* normal file */ + page = find_get_page(mapping, pgoff); + } else { /* shmem/tmpfs file. we should take account of swap too. */ + swp_entry_t ent; + mem_cgroup_get_shmem_target(inode, pgoff, &page, &ent); if (do_swap_account) - *entry = swap; - page = find_get_page(&swapper_space, swap.val); + entry->val = ent.val; } -#endif + return page; } diff --git a/trunk/mm/memory-failure.c b/trunk/mm/memory-failure.c index 2b43ba051ac9..740c4f52059c 100644 --- a/trunk/mm/memory-failure.c +++ b/trunk/mm/memory-failure.c @@ -53,7 +53,6 @@ #include #include #include -#include #include "internal.h" int sysctl_memory_failure_early_kill __read_mostly = 0; @@ -1179,97 +1178,6 @@ void memory_failure(unsigned long pfn, int trapno) __memory_failure(pfn, trapno, 0); } -#define MEMORY_FAILURE_FIFO_ORDER 4 -#define MEMORY_FAILURE_FIFO_SIZE (1 << MEMORY_FAILURE_FIFO_ORDER) - -struct memory_failure_entry { - unsigned long pfn; - int trapno; - int flags; -}; - -struct memory_failure_cpu { - DECLARE_KFIFO(fifo, struct memory_failure_entry, - MEMORY_FAILURE_FIFO_SIZE); - spinlock_t lock; - struct work_struct work; -}; - -static DEFINE_PER_CPU(struct memory_failure_cpu, memory_failure_cpu); - -/** - * memory_failure_queue - Schedule handling memory failure of a page. - * @pfn: Page Number of the corrupted page - * @trapno: Trap number reported in the signal to user space. - * @flags: Flags for memory failure handling - * - * This function is called by the low level hardware error handler - * when it detects hardware memory corruption of a page. It schedules - * the recovering of error page, including dropping pages, killing - * processes etc. - * - * The function is primarily of use for corruptions that - * happen outside the current execution context (e.g. when - * detected by a background scrubber) - * - * Can run in IRQ context. - */ -void memory_failure_queue(unsigned long pfn, int trapno, int flags) -{ - struct memory_failure_cpu *mf_cpu; - unsigned long proc_flags; - struct memory_failure_entry entry = { - .pfn = pfn, - .trapno = trapno, - .flags = flags, - }; - - mf_cpu = &get_cpu_var(memory_failure_cpu); - spin_lock_irqsave(&mf_cpu->lock, proc_flags); - if (kfifo_put(&mf_cpu->fifo, &entry)) - schedule_work_on(smp_processor_id(), &mf_cpu->work); - else - pr_err("Memory failure: buffer overflow when queuing memory failure at 0x%#lx\n", - pfn); - spin_unlock_irqrestore(&mf_cpu->lock, proc_flags); - put_cpu_var(memory_failure_cpu); -} -EXPORT_SYMBOL_GPL(memory_failure_queue); - -static void memory_failure_work_func(struct work_struct *work) -{ - struct memory_failure_cpu *mf_cpu; - struct memory_failure_entry entry = { 0, }; - unsigned long proc_flags; - int gotten; - - mf_cpu = &__get_cpu_var(memory_failure_cpu); - for (;;) { - spin_lock_irqsave(&mf_cpu->lock, proc_flags); - gotten = kfifo_get(&mf_cpu->fifo, &entry); - spin_unlock_irqrestore(&mf_cpu->lock, proc_flags); - if (!gotten) - break; - __memory_failure(entry.pfn, entry.trapno, entry.flags); - } -} - -static int __init memory_failure_init(void) -{ - struct memory_failure_cpu *mf_cpu; - int cpu; - - for_each_possible_cpu(cpu) { - mf_cpu = &per_cpu(memory_failure_cpu, cpu); - spin_lock_init(&mf_cpu->lock); - INIT_KFIFO(mf_cpu->fifo); - INIT_WORK(&mf_cpu->work, memory_failure_work_func); - } - - return 0; -} -core_initcall(memory_failure_init); - /** * unpoison_memory - Unpoison a previously poisoned page * @pfn: Page number of the to be unpoisoned page diff --git a/trunk/mm/mincore.c b/trunk/mm/mincore.c index 636a86876ff2..a4e6b9d75c76 100644 --- a/trunk/mm/mincore.c +++ b/trunk/mm/mincore.c @@ -69,15 +69,12 @@ static unsigned char mincore_page(struct address_space *mapping, pgoff_t pgoff) * file will not get a swp_entry_t in its pte, but rather it is like * any other file mapping (ie. marked !present and faulted in with * tmpfs's .fault). So swapped out tmpfs mappings are tested here. + * + * However when tmpfs moves the page from pagecache and into swapcache, + * it is still in core, but the find_get_page below won't find it. + * No big deal, but make a note of it. */ page = find_get_page(mapping, pgoff); -#ifdef CONFIG_SWAP - /* shmem/tmpfs may return swap: account for swapcache page too. */ - if (radix_tree_exceptional_entry(page)) { - swp_entry_t swap = radix_to_swp_entry(page); - page = find_get_page(&swapper_space, swap.val); - } -#endif if (page) { present = PageUptodate(page); page_cache_release(page); diff --git a/trunk/mm/page_alloc.c b/trunk/mm/page_alloc.c index 6e8ecb6e021c..1dbcf8888f14 100644 --- a/trunk/mm/page_alloc.c +++ b/trunk/mm/page_alloc.c @@ -1409,11 +1409,14 @@ static int __init fail_page_alloc_debugfs(void) { mode_t mode = S_IFREG | S_IRUSR | S_IWUSR; struct dentry *dir; + int err; - dir = fault_create_debugfs_attr("fail_page_alloc", NULL, - &fail_page_alloc.attr); - if (IS_ERR(dir)) - return PTR_ERR(dir); + err = init_fault_attr_dentries(&fail_page_alloc.attr, + "fail_page_alloc"); + if (err) + return err; + + dir = fail_page_alloc.attr.dir; if (!debugfs_create_bool("ignore-gfp-wait", mode, dir, &fail_page_alloc.ignore_gfp_wait)) @@ -1427,7 +1430,7 @@ static int __init fail_page_alloc_debugfs(void) return 0; fail: - debugfs_remove_recursive(dir); + cleanup_fault_attr_dentries(&fail_page_alloc.attr); return -ENOMEM; } diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 32f6763f16fb..5cc21f8b4cd3 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -6,8 +6,7 @@ * 2000-2001 Christoph Rohland * 2000-2001 SAP AG * 2002 Red Hat Inc. - * Copyright (C) 2002-2011 Hugh Dickins. - * Copyright (C) 2011 Google Inc. + * Copyright (C) 2002-2005 Hugh Dickins. * Copyright (C) 2002-2005 VERITAS Software Corporation. * Copyright (C) 2004 Andi Kleen, SuSE Labs * @@ -29,6 +28,7 @@ #include #include #include +#include #include static struct vfsmount *shm_mnt; @@ -51,8 +51,6 @@ static struct vfsmount *shm_mnt; #include #include #include -#include -#include #include #include #include @@ -65,17 +63,43 @@ static struct vfsmount *shm_mnt; #include #include +#include #include +/* + * The maximum size of a shmem/tmpfs file is limited by the maximum size of + * its triple-indirect swap vector - see illustration at shmem_swp_entry(). + * + * With 4kB page size, maximum file size is just over 2TB on a 32-bit kernel, + * but one eighth of that on a 64-bit kernel. With 8kB page size, maximum + * file size is just over 4TB on a 64-bit kernel, but 16TB on a 32-bit kernel, + * MAX_LFS_FILESIZE being then more restrictive than swap vector layout. + * + * We use / and * instead of shifts in the definitions below, so that the swap + * vector can be tested with small even values (e.g. 20) for ENTRIES_PER_PAGE. + */ +#define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long)) +#define ENTRIES_PER_PAGEPAGE ((unsigned long long)ENTRIES_PER_PAGE*ENTRIES_PER_PAGE) + +#define SHMSWP_MAX_INDEX (SHMEM_NR_DIRECT + (ENTRIES_PER_PAGEPAGE/2) * (ENTRIES_PER_PAGE+1)) +#define SHMSWP_MAX_BYTES (SHMSWP_MAX_INDEX << PAGE_CACHE_SHIFT) + +#define SHMEM_MAX_BYTES min_t(unsigned long long, SHMSWP_MAX_BYTES, MAX_LFS_FILESIZE) +#define SHMEM_MAX_INDEX ((unsigned long)((SHMEM_MAX_BYTES+1) >> PAGE_CACHE_SHIFT)) + #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512) #define VM_ACCT(size) (PAGE_CACHE_ALIGN(size) >> PAGE_SHIFT) +/* info->flags needs VM_flags to handle pagein/truncate races efficiently */ +#define SHMEM_PAGEIN VM_READ +#define SHMEM_TRUNCATE VM_WRITE + +/* Definition to limit shmem_truncate's steps between cond_rescheds */ +#define LATENCY_LIMIT 64 + /* Pretend that each entry is of this size in directory's i_size */ #define BOGO_DIRENT_SIZE 20 -/* Symlink up to this size is kmalloc'ed instead of using a swappable page */ -#define SHORT_SYMLINK_LEN 128 - struct shmem_xattr { struct list_head list; /* anchored by shmem_inode_info->xattr_list */ char *name; /* xattr name */ @@ -83,7 +107,7 @@ struct shmem_xattr { char value[0]; }; -/* Flag allocation requirements to shmem_getpage */ +/* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */ enum sgp_type { SGP_READ, /* don't exceed i_size, don't allocate page */ SGP_CACHE, /* don't exceed i_size, may allocate page */ @@ -113,6 +137,56 @@ static inline int shmem_getpage(struct inode *inode, pgoff_t index, mapping_gfp_mask(inode->i_mapping), fault_type); } +static inline struct page *shmem_dir_alloc(gfp_t gfp_mask) +{ + /* + * The above definition of ENTRIES_PER_PAGE, and the use of + * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE: + * might be reconsidered if it ever diverges from PAGE_SIZE. + * + * Mobility flags are masked out as swap vectors cannot move + */ + return alloc_pages((gfp_mask & ~GFP_MOVABLE_MASK) | __GFP_ZERO, + PAGE_CACHE_SHIFT-PAGE_SHIFT); +} + +static inline void shmem_dir_free(struct page *page) +{ + __free_pages(page, PAGE_CACHE_SHIFT-PAGE_SHIFT); +} + +static struct page **shmem_dir_map(struct page *page) +{ + return (struct page **)kmap_atomic(page, KM_USER0); +} + +static inline void shmem_dir_unmap(struct page **dir) +{ + kunmap_atomic(dir, KM_USER0); +} + +static swp_entry_t *shmem_swp_map(struct page *page) +{ + return (swp_entry_t *)kmap_atomic(page, KM_USER1); +} + +static inline void shmem_swp_balance_unmap(void) +{ + /* + * When passing a pointer to an i_direct entry, to code which + * also handles indirect entries and so will shmem_swp_unmap, + * we must arrange for the preempt count to remain in balance. + * What kmap_atomic of a lowmem page does depends on config + * and architecture, so pretend to kmap_atomic some lowmem page. + */ + (void) kmap_atomic(ZERO_PAGE(0), KM_USER1); +} + +static inline void shmem_swp_unmap(swp_entry_t *entry) +{ + kunmap_atomic(entry, KM_USER1); +} + static inline struct shmem_sb_info *SHMEM_SB(struct super_block *sb) { return sb->s_fs_info; @@ -170,6 +244,15 @@ static struct backing_dev_info shmem_backing_dev_info __read_mostly = { static LIST_HEAD(shmem_swaplist); static DEFINE_MUTEX(shmem_swaplist_mutex); +static void shmem_free_blocks(struct inode *inode, long pages) +{ + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + if (sbinfo->max_blocks) { + percpu_counter_add(&sbinfo->used_blocks, -pages); + inode->i_blocks -= pages*BLOCKS_PER_PAGE; + } +} + static int shmem_reserve_inode(struct super_block *sb) { struct shmem_sb_info *sbinfo = SHMEM_SB(sb); @@ -196,7 +279,7 @@ static void shmem_free_inode(struct super_block *sb) } /** - * shmem_recalc_inode - recalculate the block usage of an inode + * shmem_recalc_inode - recalculate the size of an inode * @inode: inode to recalc * * We have to calculate the free blocks since the mm can drop @@ -214,297 +297,474 @@ static void shmem_recalc_inode(struct inode *inode) freed = info->alloced - info->swapped - inode->i_mapping->nrpages; if (freed > 0) { - struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -freed); info->alloced -= freed; - inode->i_blocks -= freed * BLOCKS_PER_PAGE; shmem_unacct_blocks(info->flags, freed); + shmem_free_blocks(inode, freed); } } -/* - * Replace item expected in radix tree by a new item, while holding tree lock. +/** + * shmem_swp_entry - find the swap vector position in the info structure + * @info: info structure for the inode + * @index: index of the page to find + * @page: optional page to add to the structure. Has to be preset to + * all zeros + * + * If there is no space allocated yet it will return NULL when + * page is NULL, else it will use the page for the needed block, + * setting it to NULL on return to indicate that it has been used. + * + * The swap vector is organized the following way: + * + * There are SHMEM_NR_DIRECT entries directly stored in the + * shmem_inode_info structure. So small files do not need an addional + * allocation. + * + * For pages with index > SHMEM_NR_DIRECT there is the pointer + * i_indirect which points to a page which holds in the first half + * doubly indirect blocks, in the second half triple indirect blocks: + * + * For an artificial ENTRIES_PER_PAGE = 4 this would lead to the + * following layout (for SHMEM_NR_DIRECT == 16): + * + * i_indirect -> dir --> 16-19 + * | +-> 20-23 + * | + * +-->dir2 --> 24-27 + * | +-> 28-31 + * | +-> 32-35 + * | +-> 36-39 + * | + * +-->dir3 --> 40-43 + * +-> 44-47 + * +-> 48-51 + * +-> 52-55 */ -static int shmem_radix_tree_replace(struct address_space *mapping, - pgoff_t index, void *expected, void *replacement) -{ - void **pslot; - void *item = NULL; - - VM_BUG_ON(!expected); - pslot = radix_tree_lookup_slot(&mapping->page_tree, index); - if (pslot) - item = radix_tree_deref_slot_protected(pslot, - &mapping->tree_lock); - if (item != expected) - return -ENOENT; - if (replacement) - radix_tree_replace_slot(pslot, replacement); - else - radix_tree_delete(&mapping->page_tree, index); - return 0; -} +static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, struct page **page) +{ + unsigned long offset; + struct page **dir; + struct page *subdir; -/* - * Like add_to_page_cache_locked, but error if expected item has gone. - */ -static int shmem_add_to_page_cache(struct page *page, - struct address_space *mapping, - pgoff_t index, gfp_t gfp, void *expected) -{ - int error = 0; - - VM_BUG_ON(!PageLocked(page)); - VM_BUG_ON(!PageSwapBacked(page)); - - if (!expected) - error = radix_tree_preload(gfp & GFP_RECLAIM_MASK); - if (!error) { - page_cache_get(page); - page->mapping = mapping; - page->index = index; - - spin_lock_irq(&mapping->tree_lock); - if (!expected) - error = radix_tree_insert(&mapping->page_tree, - index, page); - else - error = shmem_radix_tree_replace(mapping, index, - expected, page); - if (!error) { - mapping->nrpages++; - __inc_zone_page_state(page, NR_FILE_PAGES); - __inc_zone_page_state(page, NR_SHMEM); - spin_unlock_irq(&mapping->tree_lock); - } else { - page->mapping = NULL; - spin_unlock_irq(&mapping->tree_lock); - page_cache_release(page); + if (index < SHMEM_NR_DIRECT) { + shmem_swp_balance_unmap(); + return info->i_direct+index; + } + if (!info->i_indirect) { + if (page) { + info->i_indirect = *page; + *page = NULL; } - if (!expected) - radix_tree_preload_end(); + return NULL; /* need another page */ } - if (error) - mem_cgroup_uncharge_cache_page(page); - return error; + + index -= SHMEM_NR_DIRECT; + offset = index % ENTRIES_PER_PAGE; + index /= ENTRIES_PER_PAGE; + dir = shmem_dir_map(info->i_indirect); + + if (index >= ENTRIES_PER_PAGE/2) { + index -= ENTRIES_PER_PAGE/2; + dir += ENTRIES_PER_PAGE/2 + index/ENTRIES_PER_PAGE; + index %= ENTRIES_PER_PAGE; + subdir = *dir; + if (!subdir) { + if (page) { + *dir = *page; + *page = NULL; + } + shmem_dir_unmap(dir); + return NULL; /* need another page */ + } + shmem_dir_unmap(dir); + dir = shmem_dir_map(subdir); + } + + dir += index; + subdir = *dir; + if (!subdir) { + if (!page || !(subdir = *page)) { + shmem_dir_unmap(dir); + return NULL; /* need a page */ + } + *dir = subdir; + *page = NULL; + } + shmem_dir_unmap(dir); + return shmem_swp_map(subdir) + offset; } -/* - * Like delete_from_page_cache, but substitutes swap for page. - */ -static void shmem_delete_from_page_cache(struct page *page, void *radswap) +static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, unsigned long value) { - struct address_space *mapping = page->mapping; - int error; + long incdec = value? 1: -1; - spin_lock_irq(&mapping->tree_lock); - error = shmem_radix_tree_replace(mapping, page->index, page, radswap); - page->mapping = NULL; - mapping->nrpages--; - __dec_zone_page_state(page, NR_FILE_PAGES); - __dec_zone_page_state(page, NR_SHMEM); - spin_unlock_irq(&mapping->tree_lock); - page_cache_release(page); - BUG_ON(error); + entry->val = value; + info->swapped += incdec; + if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) { + struct page *page = kmap_atomic_to_page(entry); + set_page_private(page, page_private(page) + incdec); + } } -/* - * Like find_get_pages, but collecting swap entries as well as pages. +/** + * shmem_swp_alloc - get the position of the swap entry for the page. + * @info: info structure for the inode + * @index: index of the page to find + * @sgp: check and recheck i_size? skip allocation? + * @gfp: gfp mask to use for any page allocation + * + * If the entry does not exist, allocate it. */ -static unsigned shmem_find_get_pages_and_swap(struct address_space *mapping, - pgoff_t start, unsigned int nr_pages, - struct page **pages, pgoff_t *indices) -{ - unsigned int i; - unsigned int ret; - unsigned int nr_found; - - rcu_read_lock(); -restart: - nr_found = radix_tree_gang_lookup_slot(&mapping->page_tree, - (void ***)pages, indices, start, nr_pages); - ret = 0; - for (i = 0; i < nr_found; i++) { - struct page *page; -repeat: - page = radix_tree_deref_slot((void **)pages[i]); - if (unlikely(!page)) - continue; - if (radix_tree_exception(page)) { - if (radix_tree_deref_retry(page)) - goto restart; - /* - * Otherwise, we must be storing a swap entry - * here as an exceptional entry: so return it - * without attempting to raise page count. - */ - goto export; +static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, + unsigned long index, enum sgp_type sgp, gfp_t gfp) +{ + struct inode *inode = &info->vfs_inode; + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + struct page *page = NULL; + swp_entry_t *entry; + + if (sgp != SGP_WRITE && + ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) + return ERR_PTR(-EINVAL); + + while (!(entry = shmem_swp_entry(info, index, &page))) { + if (sgp == SGP_READ) + return shmem_swp_map(ZERO_PAGE(0)); + /* + * Test used_blocks against 1 less max_blocks, since we have 1 data + * page (and perhaps indirect index pages) yet to allocate: + * a waste to allocate index if we cannot allocate data. + */ + if (sbinfo->max_blocks) { + if (percpu_counter_compare(&sbinfo->used_blocks, + sbinfo->max_blocks - 1) >= 0) + return ERR_PTR(-ENOSPC); + percpu_counter_inc(&sbinfo->used_blocks); + inode->i_blocks += BLOCKS_PER_PAGE; } - if (!page_cache_get_speculative(page)) - goto repeat; - /* Has the page moved? */ - if (unlikely(page != *((void **)pages[i]))) { - page_cache_release(page); - goto repeat; + spin_unlock(&info->lock); + page = shmem_dir_alloc(gfp); + spin_lock(&info->lock); + + if (!page) { + shmem_free_blocks(inode, 1); + return ERR_PTR(-ENOMEM); } -export: - indices[ret] = indices[i]; - pages[ret] = page; - ret++; - } - if (unlikely(!ret && nr_found)) - goto restart; - rcu_read_unlock(); - return ret; + if (sgp != SGP_WRITE && + ((loff_t) index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) { + entry = ERR_PTR(-EINVAL); + break; + } + if (info->next_index <= index) + info->next_index = index + 1; + } + if (page) { + /* another task gave its page, or truncated the file */ + shmem_free_blocks(inode, 1); + shmem_dir_free(page); + } + if (info->next_index <= index && !IS_ERR(entry)) + info->next_index = index + 1; + return entry; } -/* - * Remove swap entry from radix tree, free the swap and its page cache. +/** + * shmem_free_swp - free some swap entries in a directory + * @dir: pointer to the directory + * @edir: pointer after last entry of the directory + * @punch_lock: pointer to spinlock when needed for the holepunch case */ -static int shmem_free_swap(struct address_space *mapping, - pgoff_t index, void *radswap) -{ - int error; - - spin_lock_irq(&mapping->tree_lock); - error = shmem_radix_tree_replace(mapping, index, radswap, NULL); - spin_unlock_irq(&mapping->tree_lock); - if (!error) - free_swap_and_cache(radix_to_swp_entry(radswap)); - return error; +static int shmem_free_swp(swp_entry_t *dir, swp_entry_t *edir, + spinlock_t *punch_lock) +{ + spinlock_t *punch_unlock = NULL; + swp_entry_t *ptr; + int freed = 0; + + for (ptr = dir; ptr < edir; ptr++) { + if (ptr->val) { + if (unlikely(punch_lock)) { + punch_unlock = punch_lock; + punch_lock = NULL; + spin_lock(punch_unlock); + if (!ptr->val) + continue; + } + free_swap_and_cache(*ptr); + *ptr = (swp_entry_t){0}; + freed++; + } + } + if (punch_unlock) + spin_unlock(punch_unlock); + return freed; +} + +static int shmem_map_and_free_swp(struct page *subdir, int offset, + int limit, struct page ***dir, spinlock_t *punch_lock) +{ + swp_entry_t *ptr; + int freed = 0; + + ptr = shmem_swp_map(subdir); + for (; offset < limit; offset += LATENCY_LIMIT) { + int size = limit - offset; + if (size > LATENCY_LIMIT) + size = LATENCY_LIMIT; + freed += shmem_free_swp(ptr+offset, ptr+offset+size, + punch_lock); + if (need_resched()) { + shmem_swp_unmap(ptr); + if (*dir) { + shmem_dir_unmap(*dir); + *dir = NULL; + } + cond_resched(); + ptr = shmem_swp_map(subdir); + } + } + shmem_swp_unmap(ptr); + return freed; } -/* - * Pagevec may contain swap entries, so shuffle up pages before releasing. - */ -static void shmem_pagevec_release(struct pagevec *pvec) +static void shmem_free_pages(struct list_head *next) { - int i, j; - - for (i = 0, j = 0; i < pagevec_count(pvec); i++) { - struct page *page = pvec->pages[i]; - if (!radix_tree_exceptional_entry(page)) - pvec->pages[j++] = page; - } - pvec->nr = j; - pagevec_release(pvec); + struct page *page; + int freed = 0; + + do { + page = container_of(next, struct page, lru); + next = next->next; + shmem_dir_free(page); + freed++; + if (freed >= LATENCY_LIMIT) { + cond_resched(); + freed = 0; + } + } while (next); } -/* - * Remove range of pages and swap entries from radix tree, and free them. - */ -void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend) +void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) { - struct address_space *mapping = inode->i_mapping; struct shmem_inode_info *info = SHMEM_I(inode); - pgoff_t start = (lstart + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; - unsigned partial = lstart & (PAGE_CACHE_SIZE - 1); - pgoff_t end = (lend >> PAGE_CACHE_SHIFT); - struct pagevec pvec; - pgoff_t indices[PAGEVEC_SIZE]; + unsigned long idx; + unsigned long size; + unsigned long limit; + unsigned long stage; + unsigned long diroff; + struct page **dir; + struct page *topdir; + struct page *middir; + struct page *subdir; + swp_entry_t *ptr; + LIST_HEAD(pages_to_free); + long nr_pages_to_free = 0; long nr_swaps_freed = 0; - pgoff_t index; - int i; - - BUG_ON((lend & (PAGE_CACHE_SIZE - 1)) != (PAGE_CACHE_SIZE - 1)); - - pagevec_init(&pvec, 0); - index = start; - while (index <= end) { - pvec.nr = shmem_find_get_pages_and_swap(mapping, index, - min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, - pvec.pages, indices); - if (!pvec.nr) - break; - mem_cgroup_uncharge_start(); - for (i = 0; i < pagevec_count(&pvec); i++) { - struct page *page = pvec.pages[i]; + int offset; + int freed; + int punch_hole; + spinlock_t *needs_lock; + spinlock_t *punch_lock; + unsigned long upper_limit; - index = indices[i]; - if (index > end) - break; + truncate_inode_pages_range(inode->i_mapping, start, end); - if (radix_tree_exceptional_entry(page)) { - nr_swaps_freed += !shmem_free_swap(mapping, - index, page); - continue; - } + inode->i_ctime = inode->i_mtime = CURRENT_TIME; + idx = (start + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + if (idx >= info->next_index) + return; - if (!trylock_page(page)) - continue; - if (page->mapping == mapping) { - VM_BUG_ON(PageWriteback(page)); - truncate_inode_page(mapping, page); - } - unlock_page(page); + spin_lock(&info->lock); + info->flags |= SHMEM_TRUNCATE; + if (likely(end == (loff_t) -1)) { + limit = info->next_index; + upper_limit = SHMEM_MAX_INDEX; + info->next_index = idx; + needs_lock = NULL; + punch_hole = 0; + } else { + if (end + 1 >= inode->i_size) { /* we may free a little more */ + limit = (inode->i_size + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT; + upper_limit = SHMEM_MAX_INDEX; + } else { + limit = (end + 1) >> PAGE_CACHE_SHIFT; + upper_limit = limit; } - shmem_pagevec_release(&pvec); - mem_cgroup_uncharge_end(); - cond_resched(); - index++; + needs_lock = &info->lock; + punch_hole = 1; } - if (partial) { - struct page *page = NULL; - shmem_getpage(inode, start - 1, &page, SGP_READ, NULL); - if (page) { - zero_user_segment(page, partial, PAGE_CACHE_SIZE); - set_page_dirty(page); - unlock_page(page); - page_cache_release(page); - } + topdir = info->i_indirect; + if (topdir && idx <= SHMEM_NR_DIRECT && !punch_hole) { + info->i_indirect = NULL; + nr_pages_to_free++; + list_add(&topdir->lru, &pages_to_free); } + spin_unlock(&info->lock); - index = start; - for ( ; ; ) { - cond_resched(); - pvec.nr = shmem_find_get_pages_and_swap(mapping, index, - min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, - pvec.pages, indices); - if (!pvec.nr) { - if (index == start) - break; - index = start; - continue; - } - if (index == start && indices[0] > end) { - shmem_pagevec_release(&pvec); - break; - } - mem_cgroup_uncharge_start(); - for (i = 0; i < pagevec_count(&pvec); i++) { - struct page *page = pvec.pages[i]; + if (info->swapped && idx < SHMEM_NR_DIRECT) { + ptr = info->i_direct; + size = limit; + if (size > SHMEM_NR_DIRECT) + size = SHMEM_NR_DIRECT; + nr_swaps_freed = shmem_free_swp(ptr+idx, ptr+size, needs_lock); + } - index = indices[i]; - if (index > end) - break; + /* + * If there are no indirect blocks or we are punching a hole + * below indirect blocks, nothing to be done. + */ + if (!topdir || limit <= SHMEM_NR_DIRECT) + goto done2; - if (radix_tree_exceptional_entry(page)) { - nr_swaps_freed += !shmem_free_swap(mapping, - index, page); - continue; + /* + * The truncation case has already dropped info->lock, and we're safe + * because i_size and next_index have already been lowered, preventing + * access beyond. But in the punch_hole case, we still need to take + * the lock when updating the swap directory, because there might be + * racing accesses by shmem_getpage(SGP_CACHE), shmem_unuse_inode or + * shmem_writepage. However, whenever we find we can remove a whole + * directory page (not at the misaligned start or end of the range), + * we first NULLify its pointer in the level above, and then have no + * need to take the lock when updating its contents: needs_lock and + * punch_lock (either pointing to info->lock or NULL) manage this. + */ + + upper_limit -= SHMEM_NR_DIRECT; + limit -= SHMEM_NR_DIRECT; + idx = (idx > SHMEM_NR_DIRECT)? (idx - SHMEM_NR_DIRECT): 0; + offset = idx % ENTRIES_PER_PAGE; + idx -= offset; + + dir = shmem_dir_map(topdir); + stage = ENTRIES_PER_PAGEPAGE/2; + if (idx < ENTRIES_PER_PAGEPAGE/2) { + middir = topdir; + diroff = idx/ENTRIES_PER_PAGE; + } else { + dir += ENTRIES_PER_PAGE/2; + dir += (idx - ENTRIES_PER_PAGEPAGE/2)/ENTRIES_PER_PAGEPAGE; + while (stage <= idx) + stage += ENTRIES_PER_PAGEPAGE; + middir = *dir; + if (*dir) { + diroff = ((idx - ENTRIES_PER_PAGEPAGE/2) % + ENTRIES_PER_PAGEPAGE) / ENTRIES_PER_PAGE; + if (!diroff && !offset && upper_limit >= stage) { + if (needs_lock) { + spin_lock(needs_lock); + *dir = NULL; + spin_unlock(needs_lock); + needs_lock = NULL; + } else + *dir = NULL; + nr_pages_to_free++; + list_add(&middir->lru, &pages_to_free); } + shmem_dir_unmap(dir); + dir = shmem_dir_map(middir); + } else { + diroff = 0; + offset = 0; + idx = stage; + } + } - lock_page(page); - if (page->mapping == mapping) { - VM_BUG_ON(PageWriteback(page)); - truncate_inode_page(mapping, page); + for (; idx < limit; idx += ENTRIES_PER_PAGE, diroff++) { + if (unlikely(idx == stage)) { + shmem_dir_unmap(dir); + dir = shmem_dir_map(topdir) + + ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE; + while (!*dir) { + dir++; + idx += ENTRIES_PER_PAGEPAGE; + if (idx >= limit) + goto done1; } - unlock_page(page); + stage = idx + ENTRIES_PER_PAGEPAGE; + middir = *dir; + if (punch_hole) + needs_lock = &info->lock; + if (upper_limit >= stage) { + if (needs_lock) { + spin_lock(needs_lock); + *dir = NULL; + spin_unlock(needs_lock); + needs_lock = NULL; + } else + *dir = NULL; + nr_pages_to_free++; + list_add(&middir->lru, &pages_to_free); + } + shmem_dir_unmap(dir); + cond_resched(); + dir = shmem_dir_map(middir); + diroff = 0; } - shmem_pagevec_release(&pvec); - mem_cgroup_uncharge_end(); - index++; + punch_lock = needs_lock; + subdir = dir[diroff]; + if (subdir && !offset && upper_limit-idx >= ENTRIES_PER_PAGE) { + if (needs_lock) { + spin_lock(needs_lock); + dir[diroff] = NULL; + spin_unlock(needs_lock); + punch_lock = NULL; + } else + dir[diroff] = NULL; + nr_pages_to_free++; + list_add(&subdir->lru, &pages_to_free); + } + if (subdir && page_private(subdir) /* has swap entries */) { + size = limit - idx; + if (size > ENTRIES_PER_PAGE) + size = ENTRIES_PER_PAGE; + freed = shmem_map_and_free_swp(subdir, + offset, size, &dir, punch_lock); + if (!dir) + dir = shmem_dir_map(middir); + nr_swaps_freed += freed; + if (offset || punch_lock) { + spin_lock(&info->lock); + set_page_private(subdir, + page_private(subdir) - freed); + spin_unlock(&info->lock); + } else + BUG_ON(page_private(subdir) != freed); + } + offset = 0; + } +done1: + shmem_dir_unmap(dir); +done2: + if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { + /* + * Call truncate_inode_pages again: racing shmem_unuse_inode + * may have swizzled a page in from swap since + * truncate_pagecache or generic_delete_inode did it, before we + * lowered next_index. Also, though shmem_getpage checks + * i_size before adding to cache, no recheck after: so fix the + * narrow window there too. + */ + truncate_inode_pages_range(inode->i_mapping, start, end); } spin_lock(&info->lock); + info->flags &= ~SHMEM_TRUNCATE; info->swapped -= nr_swaps_freed; + if (nr_pages_to_free) + shmem_free_blocks(inode, nr_pages_to_free); shmem_recalc_inode(inode); spin_unlock(&info->lock); - inode->i_ctime = inode->i_mtime = CURRENT_TIME; + /* + * Empty swap vector directory pages to be freed? + */ + if (!list_empty(&pages_to_free)) { + pages_to_free.prev->next = NULL; + shmem_free_pages(pages_to_free.next); + } } EXPORT_SYMBOL_GPL(shmem_truncate_range); @@ -520,7 +780,37 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr) if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { loff_t oldsize = inode->i_size; loff_t newsize = attr->ia_size; + struct page *page = NULL; + if (newsize < oldsize) { + /* + * If truncating down to a partial page, then + * if that page is already allocated, hold it + * in memory until the truncation is over, so + * truncate_partial_page cannot miss it were + * it assigned to swap. + */ + if (newsize & (PAGE_CACHE_SIZE-1)) { + (void) shmem_getpage(inode, + newsize >> PAGE_CACHE_SHIFT, + &page, SGP_READ, NULL); + if (page) + unlock_page(page); + } + /* + * Reset SHMEM_PAGEIN flag so that shmem_truncate can + * detect if any pages might have been added to cache + * after truncate_inode_pages. But we needn't bother + * if it's being fully truncated to zero-length: the + * nrpages check is efficient enough in that case. + */ + if (newsize) { + struct shmem_inode_info *info = SHMEM_I(inode); + spin_lock(&info->lock); + info->flags &= ~SHMEM_PAGEIN; + spin_unlock(&info->lock); + } + } if (newsize != oldsize) { i_size_write(inode, newsize); inode->i_ctime = inode->i_mtime = CURRENT_TIME; @@ -532,6 +822,8 @@ static int shmem_setattr(struct dentry *dentry, struct iattr *attr) /* unmap again to remove racily COWed private pages */ unmap_mapping_range(inode->i_mapping, holebegin, 0, 1); } + if (page) + page_cache_release(page); } setattr_copy(inode, attr); @@ -556,8 +848,7 @@ static void shmem_evict_inode(struct inode *inode) list_del_init(&info->swaplist); mutex_unlock(&shmem_swaplist_mutex); } - } else - kfree(info->symlink); + } list_for_each_entry_safe(xattr, nxattr, &info->xattr_list, list) { kfree(xattr->name); @@ -568,27 +859,106 @@ static void shmem_evict_inode(struct inode *inode) end_writeback(inode); } -/* - * If swap found in inode, free it and move page from swapcache to filecache. - */ -static int shmem_unuse_inode(struct shmem_inode_info *info, - swp_entry_t swap, struct page *page) +static inline int shmem_find_swp(swp_entry_t entry, swp_entry_t *dir, swp_entry_t *edir) { - struct address_space *mapping = info->vfs_inode.i_mapping; - void *radswap; - pgoff_t index; + swp_entry_t *ptr; + + for (ptr = dir; ptr < edir; ptr++) { + if (ptr->val == entry.val) + return ptr - dir; + } + return -1; +} + +static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, struct page *page) +{ + struct address_space *mapping; + unsigned long idx; + unsigned long size; + unsigned long limit; + unsigned long stage; + struct page **dir; + struct page *subdir; + swp_entry_t *ptr; + int offset; int error; - radswap = swp_to_radix_entry(swap); - index = radix_tree_locate_item(&mapping->page_tree, radswap); - if (index == -1) - return 0; + idx = 0; + ptr = info->i_direct; + spin_lock(&info->lock); + if (!info->swapped) { + list_del_init(&info->swaplist); + goto lost2; + } + limit = info->next_index; + size = limit; + if (size > SHMEM_NR_DIRECT) + size = SHMEM_NR_DIRECT; + offset = shmem_find_swp(entry, ptr, ptr+size); + if (offset >= 0) { + shmem_swp_balance_unmap(); + goto found; + } + if (!info->i_indirect) + goto lost2; + + dir = shmem_dir_map(info->i_indirect); + stage = SHMEM_NR_DIRECT + ENTRIES_PER_PAGEPAGE/2; + + for (idx = SHMEM_NR_DIRECT; idx < limit; idx += ENTRIES_PER_PAGE, dir++) { + if (unlikely(idx == stage)) { + shmem_dir_unmap(dir-1); + if (cond_resched_lock(&info->lock)) { + /* check it has not been truncated */ + if (limit > info->next_index) { + limit = info->next_index; + if (idx >= limit) + goto lost2; + } + } + dir = shmem_dir_map(info->i_indirect) + + ENTRIES_PER_PAGE/2 + idx/ENTRIES_PER_PAGEPAGE; + while (!*dir) { + dir++; + idx += ENTRIES_PER_PAGEPAGE; + if (idx >= limit) + goto lost1; + } + stage = idx + ENTRIES_PER_PAGEPAGE; + subdir = *dir; + shmem_dir_unmap(dir); + dir = shmem_dir_map(subdir); + } + subdir = *dir; + if (subdir && page_private(subdir)) { + ptr = shmem_swp_map(subdir); + size = limit - idx; + if (size > ENTRIES_PER_PAGE) + size = ENTRIES_PER_PAGE; + offset = shmem_find_swp(entry, ptr, ptr+size); + shmem_swp_unmap(ptr); + if (offset >= 0) { + shmem_dir_unmap(dir); + ptr = shmem_swp_map(subdir); + goto found; + } + } + } +lost1: + shmem_dir_unmap(dir-1); +lost2: + spin_unlock(&info->lock); + return 0; +found: + idx += offset; + ptr += offset; /* * Move _head_ to start search for next from here. * But be careful: shmem_evict_inode checks list_empty without taking * mutex, and there's an instant in list_move_tail when info->swaplist - * would appear empty, if it were the only one on shmem_swaplist. + * would appear empty, if it were the only one on shmem_swaplist. We + * could avoid doing it if inode NULL; or use this minor optimization. */ if (shmem_swaplist.next != &info->swaplist) list_move_tail(&shmem_swaplist, &info->swaplist); @@ -598,34 +968,29 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, * but also to hold up shmem_evict_inode(): so inode cannot be freed * beneath us (pagelock doesn't help until the page is in pagecache). */ - error = shmem_add_to_page_cache(page, mapping, index, - GFP_NOWAIT, radswap); + mapping = info->vfs_inode.i_mapping; + error = add_to_page_cache_locked(page, mapping, idx, GFP_NOWAIT); /* which does mem_cgroup_uncharge_cache_page on error */ if (error != -ENOMEM) { - /* - * Truncation and eviction use free_swap_and_cache(), which - * only does trylock page: if we raced, best clean up here. - */ delete_from_swap_cache(page); set_page_dirty(page); - if (!error) { - spin_lock(&info->lock); - info->swapped--; - spin_unlock(&info->lock); - swap_free(swap); - } + info->flags |= SHMEM_PAGEIN; + shmem_swp_set(info, ptr, 0); + swap_free(entry); error = 1; /* not an error, but entry was found */ } + shmem_swp_unmap(ptr); + spin_unlock(&info->lock); return error; } /* - * Search through swapped inodes to find and replace swap by page. + * shmem_unuse() search for an eventually swapped out shmem page. */ -int shmem_unuse(swp_entry_t swap, struct page *page) +int shmem_unuse(swp_entry_t entry, struct page *page) { - struct list_head *this, *next; + struct list_head *p, *next; struct shmem_inode_info *info; int found = 0; int error; @@ -634,25 +999,32 @@ int shmem_unuse(swp_entry_t swap, struct page *page) * Charge page using GFP_KERNEL while we can wait, before taking * the shmem_swaplist_mutex which might hold up shmem_writepage(). * Charged back to the user (not to caller) when swap account is used. + * add_to_page_cache() will be called with GFP_NOWAIT. */ error = mem_cgroup_cache_charge(page, current->mm, GFP_KERNEL); if (error) goto out; - /* No radix_tree_preload: swap entry keeps a place for page in tree */ + /* + * Try to preload while we can wait, to not make a habit of + * draining atomic reserves; but don't latch on to this cpu, + * it's okay if sometimes we get rescheduled after this. + */ + error = radix_tree_preload(GFP_KERNEL); + if (error) + goto uncharge; + radix_tree_preload_end(); mutex_lock(&shmem_swaplist_mutex); - list_for_each_safe(this, next, &shmem_swaplist) { - info = list_entry(this, struct shmem_inode_info, swaplist); - if (info->swapped) - found = shmem_unuse_inode(info, swap, page); - else - list_del_init(&info->swaplist); + list_for_each_safe(p, next, &shmem_swaplist) { + info = list_entry(p, struct shmem_inode_info, swaplist); + found = shmem_unuse_inode(info, entry, page); cond_resched(); if (found) break; } mutex_unlock(&shmem_swaplist_mutex); +uncharge: if (!found) mem_cgroup_uncharge_cache_page(page); if (found < 0) @@ -669,10 +1041,10 @@ int shmem_unuse(swp_entry_t swap, struct page *page) static int shmem_writepage(struct page *page, struct writeback_control *wbc) { struct shmem_inode_info *info; + swp_entry_t *entry, swap; struct address_space *mapping; + unsigned long index; struct inode *inode; - swp_entry_t swap; - pgoff_t index; BUG_ON(!PageLocked(page)); mapping = page->mapping; @@ -701,32 +1073,50 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc) /* * Add inode to shmem_unuse()'s list of swapped-out inodes, - * if it's not already there. Do it now before the page is - * moved to swap cache, when its pagelock no longer protects + * if it's not already there. Do it now because we cannot take + * mutex while holding spinlock, and must do so before the page + * is moved to swap cache, when its pagelock no longer protects * the inode from eviction. But don't unlock the mutex until - * we've incremented swapped, because shmem_unuse_inode() will - * prune a !swapped inode from the swaplist under this mutex. + * we've taken the spinlock, because shmem_unuse_inode() will + * prune a !swapped inode from the swaplist under both locks. */ mutex_lock(&shmem_swaplist_mutex); if (list_empty(&info->swaplist)) list_add_tail(&info->swaplist, &shmem_swaplist); + spin_lock(&info->lock); + mutex_unlock(&shmem_swaplist_mutex); + + if (index >= info->next_index) { + BUG_ON(!(info->flags & SHMEM_TRUNCATE)); + goto unlock; + } + entry = shmem_swp_entry(info, index, NULL); + if (entry->val) { + WARN_ON_ONCE(1); /* Still happens? Tell us about it! */ + free_swap_and_cache(*entry); + shmem_swp_set(info, entry, 0); + } + shmem_recalc_inode(inode); + if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) { + delete_from_page_cache(page); + shmem_swp_set(info, entry, swap.val); + shmem_swp_unmap(entry); swap_shmem_alloc(swap); - shmem_delete_from_page_cache(page, swp_to_radix_entry(swap)); - - spin_lock(&info->lock); - info->swapped++; - shmem_recalc_inode(inode); spin_unlock(&info->lock); - - mutex_unlock(&shmem_swaplist_mutex); BUG_ON(page_mapped(page)); swap_writepage(page, wbc); return 0; } - mutex_unlock(&shmem_swaplist_mutex); + shmem_swp_unmap(entry); +unlock: + spin_unlock(&info->lock); + /* + * add_to_swap_cache() doesn't return -EEXIST, so we can safely + * clear SWAP_HAS_CACHE flag. + */ swapcache_free(swap, NULL); redirty: set_page_dirty(page); @@ -763,33 +1153,35 @@ static struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo) } #endif /* CONFIG_TMPFS */ -static struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, - struct shmem_inode_info *info, pgoff_t index) +static struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp, + struct shmem_inode_info *info, unsigned long idx) { struct mempolicy mpol, *spol; struct vm_area_struct pvma; + struct page *page; spol = mpol_cond_copy(&mpol, - mpol_shared_policy_lookup(&info->policy, index)); + mpol_shared_policy_lookup(&info->policy, idx)); /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; - pvma.vm_pgoff = index; + pvma.vm_pgoff = idx; pvma.vm_ops = NULL; pvma.vm_policy = spol; - return swapin_readahead(swap, gfp, &pvma, 0); + page = swapin_readahead(entry, gfp, &pvma, 0); + return page; } static struct page *shmem_alloc_page(gfp_t gfp, - struct shmem_inode_info *info, pgoff_t index) + struct shmem_inode_info *info, unsigned long idx) { struct vm_area_struct pvma; /* Create a pseudo vma that just contains the policy */ pvma.vm_start = 0; - pvma.vm_pgoff = index; + pvma.vm_pgoff = idx; pvma.vm_ops = NULL; - pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, index); + pvma.vm_policy = mpol_shared_policy_lookup(&info->policy, idx); /* * alloc_page_vma() will drop the shared policy reference @@ -798,19 +1190,19 @@ static struct page *shmem_alloc_page(gfp_t gfp, } #else /* !CONFIG_NUMA */ #ifdef CONFIG_TMPFS -static inline void shmem_show_mpol(struct seq_file *seq, struct mempolicy *mpol) +static inline void shmem_show_mpol(struct seq_file *seq, struct mempolicy *p) { } #endif /* CONFIG_TMPFS */ -static inline struct page *shmem_swapin(swp_entry_t swap, gfp_t gfp, - struct shmem_inode_info *info, pgoff_t index) +static inline struct page *shmem_swapin(swp_entry_t entry, gfp_t gfp, + struct shmem_inode_info *info, unsigned long idx) { - return swapin_readahead(swap, gfp, NULL, 0); + return swapin_readahead(entry, gfp, NULL, 0); } static inline struct page *shmem_alloc_page(gfp_t gfp, - struct shmem_inode_info *info, pgoff_t index) + struct shmem_inode_info *info, unsigned long idx) { return alloc_page(gfp); } @@ -830,190 +1222,243 @@ static inline struct mempolicy *shmem_get_sbmpol(struct shmem_sb_info *sbinfo) * vm. If we swap it in we mark it dirty since we also free the swap * entry since a page cannot live in both the swap and page cache */ -static int shmem_getpage_gfp(struct inode *inode, pgoff_t index, +static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx, struct page **pagep, enum sgp_type sgp, gfp_t gfp, int *fault_type) { struct address_space *mapping = inode->i_mapping; - struct shmem_inode_info *info; + struct shmem_inode_info *info = SHMEM_I(inode); struct shmem_sb_info *sbinfo; struct page *page; + struct page *prealloc_page = NULL; + swp_entry_t *entry; swp_entry_t swap; int error; - int once = 0; + int ret; - if (index > (MAX_LFS_FILESIZE >> PAGE_CACHE_SHIFT)) + if (idx >= SHMEM_MAX_INDEX) return -EFBIG; repeat: - swap.val = 0; - page = find_lock_page(mapping, index); - if (radix_tree_exceptional_entry(page)) { - swap = radix_to_swp_entry(page); - page = NULL; - } - - if (sgp != SGP_WRITE && - ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) { - error = -EINVAL; - goto failed; - } - - if (page || (sgp == SGP_READ && !swap.val)) { + page = find_lock_page(mapping, idx); + if (page) { /* * Once we can get the page lock, it must be uptodate: * if there were an error in reading back from swap, * the page would not be inserted into the filecache. */ - BUG_ON(page && !PageUptodate(page)); - *pagep = page; - return 0; + BUG_ON(!PageUptodate(page)); + goto done; } /* - * Fast cache lookup did not find it: - * bring it back from swap or allocate. + * Try to preload while we can wait, to not make a habit of + * draining atomic reserves; but don't latch on to this cpu. */ - info = SHMEM_I(inode); - sbinfo = SHMEM_SB(inode->i_sb); + error = radix_tree_preload(gfp & GFP_RECLAIM_MASK); + if (error) + goto out; + radix_tree_preload_end(); + + if (sgp != SGP_READ && !prealloc_page) { + prealloc_page = shmem_alloc_page(gfp, info, idx); + if (prealloc_page) { + SetPageSwapBacked(prealloc_page); + if (mem_cgroup_cache_charge(prealloc_page, + current->mm, GFP_KERNEL)) { + page_cache_release(prealloc_page); + prealloc_page = NULL; + } + } + } + + spin_lock(&info->lock); + shmem_recalc_inode(inode); + entry = shmem_swp_alloc(info, idx, sgp, gfp); + if (IS_ERR(entry)) { + spin_unlock(&info->lock); + error = PTR_ERR(entry); + goto out; + } + swap = *entry; if (swap.val) { /* Look it up and read it in.. */ page = lookup_swap_cache(swap); if (!page) { + shmem_swp_unmap(entry); + spin_unlock(&info->lock); /* here we actually do the io */ if (fault_type) *fault_type |= VM_FAULT_MAJOR; - page = shmem_swapin(swap, gfp, info, index); + page = shmem_swapin(swap, gfp, info, idx); if (!page) { - error = -ENOMEM; - goto failed; + spin_lock(&info->lock); + entry = shmem_swp_alloc(info, idx, sgp, gfp); + if (IS_ERR(entry)) + error = PTR_ERR(entry); + else { + if (entry->val == swap.val) + error = -ENOMEM; + shmem_swp_unmap(entry); + } + spin_unlock(&info->lock); + if (error) + goto out; + goto repeat; } + wait_on_page_locked(page); + page_cache_release(page); + goto repeat; } /* We have to do this with page locked to prevent races */ - lock_page(page); + if (!trylock_page(page)) { + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + wait_on_page_locked(page); + page_cache_release(page); + goto repeat; + } + if (PageWriteback(page)) { + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + wait_on_page_writeback(page); + unlock_page(page); + page_cache_release(page); + goto repeat; + } if (!PageUptodate(page)) { + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + unlock_page(page); + page_cache_release(page); error = -EIO; - goto failed; - } - wait_on_page_writeback(page); - - /* Someone may have already done it for us */ - if (page->mapping) { - if (page->mapping == mapping && - page->index == index) - goto done; - error = -EEXIST; - goto failed; + goto out; } - error = mem_cgroup_cache_charge(page, current->mm, - gfp & GFP_RECLAIM_MASK); - if (!error) - error = shmem_add_to_page_cache(page, mapping, index, - gfp, swp_to_radix_entry(swap)); - if (error) - goto failed; - - spin_lock(&info->lock); - info->swapped--; - shmem_recalc_inode(inode); - spin_unlock(&info->lock); + error = add_to_page_cache_locked(page, mapping, + idx, GFP_NOWAIT); + if (error) { + shmem_swp_unmap(entry); + spin_unlock(&info->lock); + if (error == -ENOMEM) { + /* + * reclaim from proper memory cgroup and + * call memcg's OOM if needed. + */ + error = mem_cgroup_shmem_charge_fallback( + page, current->mm, gfp); + if (error) { + unlock_page(page); + page_cache_release(page); + goto out; + } + } + unlock_page(page); + page_cache_release(page); + goto repeat; + } + info->flags |= SHMEM_PAGEIN; + shmem_swp_set(info, entry, 0); + shmem_swp_unmap(entry); delete_from_swap_cache(page); + spin_unlock(&info->lock); set_page_dirty(page); swap_free(swap); - } else { - if (shmem_acct_block(info->flags)) { - error = -ENOSPC; - goto failed; + } else if (sgp == SGP_READ) { + shmem_swp_unmap(entry); + page = find_get_page(mapping, idx); + if (page && !trylock_page(page)) { + spin_unlock(&info->lock); + wait_on_page_locked(page); + page_cache_release(page); + goto repeat; } + spin_unlock(&info->lock); + + } else if (prealloc_page) { + shmem_swp_unmap(entry); + sbinfo = SHMEM_SB(inode->i_sb); if (sbinfo->max_blocks) { if (percpu_counter_compare(&sbinfo->used_blocks, - sbinfo->max_blocks) >= 0) { - error = -ENOSPC; - goto unacct; - } + sbinfo->max_blocks) >= 0 || + shmem_acct_block(info->flags)) + goto nospace; percpu_counter_inc(&sbinfo->used_blocks); + inode->i_blocks += BLOCKS_PER_PAGE; + } else if (shmem_acct_block(info->flags)) + goto nospace; + + page = prealloc_page; + prealloc_page = NULL; + + entry = shmem_swp_alloc(info, idx, sgp, gfp); + if (IS_ERR(entry)) + error = PTR_ERR(entry); + else { + swap = *entry; + shmem_swp_unmap(entry); } - - page = shmem_alloc_page(gfp, info, index); - if (!page) { - error = -ENOMEM; - goto decused; + ret = error || swap.val; + if (ret) + mem_cgroup_uncharge_cache_page(page); + else + ret = add_to_page_cache_lru(page, mapping, + idx, GFP_NOWAIT); + /* + * At add_to_page_cache_lru() failure, + * uncharge will be done automatically. + */ + if (ret) { + shmem_unacct_blocks(info->flags, 1); + shmem_free_blocks(inode, 1); + spin_unlock(&info->lock); + page_cache_release(page); + if (error) + goto out; + goto repeat; } - SetPageSwapBacked(page); - __set_page_locked(page); - error = mem_cgroup_cache_charge(page, current->mm, - gfp & GFP_RECLAIM_MASK); - if (!error) - error = shmem_add_to_page_cache(page, mapping, index, - gfp, NULL); - if (error) - goto decused; - lru_cache_add_anon(page); - - spin_lock(&info->lock); + info->flags |= SHMEM_PAGEIN; info->alloced++; - inode->i_blocks += BLOCKS_PER_PAGE; - shmem_recalc_inode(inode); spin_unlock(&info->lock); - clear_highpage(page); flush_dcache_page(page); SetPageUptodate(page); if (sgp == SGP_DIRTY) set_page_dirty(page); + + } else { + spin_unlock(&info->lock); + error = -ENOMEM; + goto out; } done: - /* Perhaps the file has been truncated since we checked */ - if (sgp != SGP_WRITE && - ((loff_t)index << PAGE_CACHE_SHIFT) >= i_size_read(inode)) { - error = -EINVAL; - goto trunc; - } *pagep = page; - return 0; + error = 0; +out: + if (prealloc_page) { + mem_cgroup_uncharge_cache_page(prealloc_page); + page_cache_release(prealloc_page); + } + return error; +nospace: /* - * Error recovery. + * Perhaps the page was brought in from swap between find_lock_page + * and taking info->lock? We allow for that at add_to_page_cache_lru, + * but must also avoid reporting a spurious ENOSPC while working on a + * full tmpfs. */ -trunc: - ClearPageDirty(page); - delete_from_page_cache(page); - spin_lock(&info->lock); - info->alloced--; - inode->i_blocks -= BLOCKS_PER_PAGE; + page = find_get_page(mapping, idx); spin_unlock(&info->lock); -decused: - if (sbinfo->max_blocks) - percpu_counter_add(&sbinfo->used_blocks, -1); -unacct: - shmem_unacct_blocks(info->flags, 1); -failed: - if (swap.val && error != -EINVAL) { - struct page *test = find_get_page(mapping, index); - if (test && !radix_tree_exceptional_entry(test)) - page_cache_release(test); - /* Have another try if the entry has changed */ - if (test != swp_to_radix_entry(swap)) - error = -EEXIST; - } if (page) { - unlock_page(page); page_cache_release(page); - } - if (error == -ENOSPC && !once++) { - info = SHMEM_I(inode); - spin_lock(&info->lock); - shmem_recalc_inode(inode); - spin_unlock(&info->lock); goto repeat; } - if (error == -EEXIST) - goto repeat; - return error; + error = -ENOSPC; + goto out; } static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) @@ -1022,6 +1467,9 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) int error; int ret = VM_FAULT_LOCKED; + if (((loff_t)vmf->pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) + return VM_FAULT_SIGBUS; + error = shmem_getpage(inode, vmf->pgoff, &vmf->page, SGP_CACHE, &ret); if (error) return ((error == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS); @@ -1034,20 +1482,20 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } #ifdef CONFIG_NUMA -static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *mpol) +static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new) { - struct inode *inode = vma->vm_file->f_path.dentry->d_inode; - return mpol_set_shared_policy(&SHMEM_I(inode)->policy, vma, mpol); + struct inode *i = vma->vm_file->f_path.dentry->d_inode; + return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new); } static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, unsigned long addr) { - struct inode *inode = vma->vm_file->f_path.dentry->d_inode; - pgoff_t index; + struct inode *i = vma->vm_file->f_path.dentry->d_inode; + unsigned long idx; - index = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; - return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy, index); + idx = ((addr - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff; + return mpol_shared_policy_lookup(&SHMEM_I(i)->policy, idx); } #endif @@ -1145,7 +1593,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode #ifdef CONFIG_TMPFS static const struct inode_operations shmem_symlink_inode_operations; -static const struct inode_operations shmem_short_symlink_operations; +static const struct inode_operations shmem_symlink_inline_operations; static int shmem_write_begin(struct file *file, struct address_space *mapping, @@ -1178,8 +1626,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ { struct inode *inode = filp->f_path.dentry->d_inode; struct address_space *mapping = inode->i_mapping; - pgoff_t index; - unsigned long offset; + unsigned long index, offset; enum sgp_type sgp = SGP_READ; /* @@ -1195,8 +1642,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ for (;;) { struct page *page = NULL; - pgoff_t end_index; - unsigned long nr, ret; + unsigned long end_index, nr, ret; loff_t i_size = i_size_read(inode); end_index = i_size >> PAGE_CACHE_SHIFT; @@ -1434,9 +1880,8 @@ static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) buf->f_namelen = NAME_MAX; if (sbinfo->max_blocks) { buf->f_blocks = sbinfo->max_blocks; - buf->f_bavail = - buf->f_bfree = sbinfo->max_blocks - - percpu_counter_sum(&sbinfo->used_blocks); + buf->f_bavail = buf->f_bfree = + sbinfo->max_blocks - percpu_counter_sum(&sbinfo->used_blocks); } if (sbinfo->max_inodes) { buf->f_files = sbinfo->max_inodes; @@ -1610,13 +2055,10 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s info = SHMEM_I(inode); inode->i_size = len-1; - if (len <= SHORT_SYMLINK_LEN) { - info->symlink = kmemdup(symname, len, GFP_KERNEL); - if (!info->symlink) { - iput(inode); - return -ENOMEM; - } - inode->i_op = &shmem_short_symlink_operations; + if (len <= SHMEM_SYMLINK_INLINE_LEN) { + /* do it inline */ + memcpy(info->inline_symlink, symname, len); + inode->i_op = &shmem_symlink_inline_operations; } else { error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); if (error) { @@ -1639,17 +2081,17 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s return 0; } -static void *shmem_follow_short_symlink(struct dentry *dentry, struct nameidata *nd) +static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) { - nd_set_link(nd, SHMEM_I(dentry->d_inode)->symlink); + nd_set_link(nd, SHMEM_I(dentry->d_inode)->inline_symlink); return NULL; } static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd) { struct page *page = NULL; - int error = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); - nd_set_link(nd, error ? ERR_PTR(error) : kmap(page)); + int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); + nd_set_link(nd, res ? ERR_PTR(res) : kmap(page)); if (page) unlock_page(page); return page; @@ -1760,6 +2202,7 @@ static int shmem_xattr_set(struct dentry *dentry, const char *name, return err; } + static const struct xattr_handler *shmem_xattr_handlers[] = { #ifdef CONFIG_TMPFS_POSIX_ACL &generic_acl_access_handler, @@ -1889,9 +2332,9 @@ static ssize_t shmem_listxattr(struct dentry *dentry, char *buffer, size_t size) } #endif /* CONFIG_TMPFS_XATTR */ -static const struct inode_operations shmem_short_symlink_operations = { +static const struct inode_operations shmem_symlink_inline_operations = { .readlink = generic_readlink, - .follow_link = shmem_follow_short_symlink, + .follow_link = shmem_follow_link_inline, #ifdef CONFIG_TMPFS_XATTR .setxattr = shmem_setxattr, .getxattr = shmem_getxattr, @@ -2091,7 +2534,8 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) if (config.max_inodes < inodes) goto out; /* - * Those tests disallow limited->unlimited while any are in use; + * Those tests also disallow limited->unlimited while any are in + * use, so i_blocks will always be zero when max_blocks is zero; * but we must separately disallow unlimited->limited, because * in that case we have no record of how much is already in use. */ @@ -2183,7 +2627,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) goto failed; sbinfo->free_inodes = sbinfo->max_inodes; - sb->s_maxbytes = MAX_LFS_FILESIZE; + sb->s_maxbytes = SHMEM_MAX_BYTES; sb->s_blocksize = PAGE_CACHE_SIZE; sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = TMPFS_MAGIC; @@ -2218,14 +2662,14 @@ static struct kmem_cache *shmem_inode_cachep; static struct inode *shmem_alloc_inode(struct super_block *sb) { - struct shmem_inode_info *info; - info = kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL); - if (!info) + struct shmem_inode_info *p; + p = (struct shmem_inode_info *)kmem_cache_alloc(shmem_inode_cachep, GFP_KERNEL); + if (!p) return NULL; - return &info->vfs_inode; + return &p->vfs_inode; } -static void shmem_destroy_callback(struct rcu_head *head) +static void shmem_i_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); INIT_LIST_HEAD(&inode->i_dentry); @@ -2234,26 +2678,29 @@ static void shmem_destroy_callback(struct rcu_head *head) static void shmem_destroy_inode(struct inode *inode) { - if ((inode->i_mode & S_IFMT) == S_IFREG) + if ((inode->i_mode & S_IFMT) == S_IFREG) { + /* only struct inode is valid if it's an inline symlink */ mpol_free_shared_policy(&SHMEM_I(inode)->policy); - call_rcu(&inode->i_rcu, shmem_destroy_callback); + } + call_rcu(&inode->i_rcu, shmem_i_callback); } -static void shmem_init_inode(void *foo) +static void init_once(void *foo) { - struct shmem_inode_info *info = foo; - inode_init_once(&info->vfs_inode); + struct shmem_inode_info *p = (struct shmem_inode_info *) foo; + + inode_init_once(&p->vfs_inode); } -static int shmem_init_inodecache(void) +static int init_inodecache(void) { shmem_inode_cachep = kmem_cache_create("shmem_inode_cache", sizeof(struct shmem_inode_info), - 0, SLAB_PANIC, shmem_init_inode); + 0, SLAB_PANIC, init_once); return 0; } -static void shmem_destroy_inodecache(void) +static void destroy_inodecache(void) { kmem_cache_destroy(shmem_inode_cachep); } @@ -2350,20 +2797,21 @@ static const struct vm_operations_struct shmem_vm_ops = { #endif }; + static struct dentry *shmem_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { return mount_nodev(fs_type, flags, data, shmem_fill_super); } -static struct file_system_type shmem_fs_type = { +static struct file_system_type tmpfs_fs_type = { .owner = THIS_MODULE, .name = "tmpfs", .mount = shmem_mount, .kill_sb = kill_litter_super, }; -int __init shmem_init(void) +int __init init_tmpfs(void) { int error; @@ -2371,18 +2819,18 @@ int __init shmem_init(void) if (error) goto out4; - error = shmem_init_inodecache(); + error = init_inodecache(); if (error) goto out3; - error = register_filesystem(&shmem_fs_type); + error = register_filesystem(&tmpfs_fs_type); if (error) { printk(KERN_ERR "Could not register tmpfs\n"); goto out2; } - shm_mnt = vfs_kern_mount(&shmem_fs_type, MS_NOUSER, - shmem_fs_type.name, NULL); + shm_mnt = vfs_kern_mount(&tmpfs_fs_type, MS_NOUSER, + tmpfs_fs_type.name, NULL); if (IS_ERR(shm_mnt)) { error = PTR_ERR(shm_mnt); printk(KERN_ERR "Could not kern_mount tmpfs\n"); @@ -2391,9 +2839,9 @@ int __init shmem_init(void) return 0; out1: - unregister_filesystem(&shmem_fs_type); + unregister_filesystem(&tmpfs_fs_type); out2: - shmem_destroy_inodecache(); + destroy_inodecache(); out3: bdi_destroy(&shmem_backing_dev_info); out4: @@ -2401,6 +2849,45 @@ int __init shmem_init(void) return error; } +#ifdef CONFIG_CGROUP_MEM_RES_CTLR +/** + * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file + * @inode: the inode to be searched + * @pgoff: the offset to be searched + * @pagep: the pointer for the found page to be stored + * @ent: the pointer for the found swap entry to be stored + * + * If a page is found, refcount of it is incremented. Callers should handle + * these refcount. + */ +void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, + struct page **pagep, swp_entry_t *ent) +{ + swp_entry_t entry = { .val = 0 }, *ptr; + struct page *page = NULL; + struct shmem_inode_info *info = SHMEM_I(inode); + + if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) + goto out; + + spin_lock(&info->lock); + ptr = shmem_swp_entry(info, pgoff, NULL); +#ifdef CONFIG_SWAP + if (ptr && ptr->val) { + entry.val = ptr->val; + page = find_get_page(&swapper_space, entry.val); + } else +#endif + page = find_get_page(inode->i_mapping, pgoff); + if (ptr) + shmem_swp_unmap(ptr); + spin_unlock(&info->lock); +out: + *pagep = page; + *ent = entry; +} +#endif + #else /* !CONFIG_SHMEM */ /* @@ -2414,23 +2901,23 @@ int __init shmem_init(void) #include -static struct file_system_type shmem_fs_type = { +static struct file_system_type tmpfs_fs_type = { .name = "tmpfs", .mount = ramfs_mount, .kill_sb = kill_litter_super, }; -int __init shmem_init(void) +int __init init_tmpfs(void) { - BUG_ON(register_filesystem(&shmem_fs_type) != 0); + BUG_ON(register_filesystem(&tmpfs_fs_type) != 0); - shm_mnt = kern_mount(&shmem_fs_type); + shm_mnt = kern_mount(&tmpfs_fs_type); BUG_ON(IS_ERR(shm_mnt)); return 0; } -int shmem_unuse(swp_entry_t swap, struct page *page) +int shmem_unuse(swp_entry_t entry, struct page *page) { return 0; } @@ -2440,17 +2927,43 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) return 0; } -void shmem_truncate_range(struct inode *inode, loff_t lstart, loff_t lend) +void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end) { - truncate_inode_pages_range(inode->i_mapping, lstart, lend); + truncate_inode_pages_range(inode->i_mapping, start, end); } EXPORT_SYMBOL_GPL(shmem_truncate_range); +#ifdef CONFIG_CGROUP_MEM_RES_CTLR +/** + * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file + * @inode: the inode to be searched + * @pgoff: the offset to be searched + * @pagep: the pointer for the found page to be stored + * @ent: the pointer for the found swap entry to be stored + * + * If a page is found, refcount of it is incremented. Callers should handle + * these refcount. + */ +void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, + struct page **pagep, swp_entry_t *ent) +{ + struct page *page = NULL; + + if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) + goto out; + page = find_get_page(inode->i_mapping, pgoff); +out: + *pagep = page; + *ent = (swp_entry_t){ .val = 0 }; +} +#endif + #define shmem_vm_ops generic_file_vm_ops #define shmem_file_operations ramfs_file_operations #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) #define shmem_acct_size(flags, size) 0 #define shmem_unacct_size(flags, size) do {} while (0) +#define SHMEM_MAX_BYTES MAX_LFS_FILESIZE #endif /* CONFIG_SHMEM */ @@ -2474,7 +2987,7 @@ struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags if (IS_ERR(shm_mnt)) return (void *)shm_mnt; - if (size < 0 || size > MAX_LFS_FILESIZE) + if (size < 0 || size > SHMEM_MAX_BYTES) return ERR_PTR(-EINVAL); if (shmem_acct_size(flags, size)) diff --git a/trunk/mm/slab.c b/trunk/mm/slab.c index 6d90a091fdca..95947400702b 100644 --- a/trunk/mm/slab.c +++ b/trunk/mm/slab.c @@ -622,51 +622,6 @@ int slab_is_available(void) static struct lock_class_key on_slab_l3_key; static struct lock_class_key on_slab_alc_key; -static struct lock_class_key debugobj_l3_key; -static struct lock_class_key debugobj_alc_key; - -static void slab_set_lock_classes(struct kmem_cache *cachep, - struct lock_class_key *l3_key, struct lock_class_key *alc_key, - int q) -{ - struct array_cache **alc; - struct kmem_list3 *l3; - int r; - - l3 = cachep->nodelists[q]; - if (!l3) - return; - - lockdep_set_class(&l3->list_lock, l3_key); - alc = l3->alien; - /* - * FIXME: This check for BAD_ALIEN_MAGIC - * should go away when common slab code is taught to - * work even without alien caches. - * Currently, non NUMA code returns BAD_ALIEN_MAGIC - * for alloc_alien_cache, - */ - if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC) - return; - for_each_node(r) { - if (alc[r]) - lockdep_set_class(&alc[r]->lock, alc_key); - } -} - -static void slab_set_debugobj_lock_classes_node(struct kmem_cache *cachep, int node) -{ - slab_set_lock_classes(cachep, &debugobj_l3_key, &debugobj_alc_key, node); -} - -static void slab_set_debugobj_lock_classes(struct kmem_cache *cachep) -{ - int node; - - for_each_online_node(node) - slab_set_debugobj_lock_classes_node(cachep, node); -} - static void init_node_lock_keys(int q) { struct cache_sizes *s = malloc_sizes; @@ -675,14 +630,29 @@ static void init_node_lock_keys(int q) return; for (s = malloc_sizes; s->cs_size != ULONG_MAX; s++) { + struct array_cache **alc; struct kmem_list3 *l3; + int r; l3 = s->cs_cachep->nodelists[q]; if (!l3 || OFF_SLAB(s->cs_cachep)) continue; - - slab_set_lock_classes(s->cs_cachep, &on_slab_l3_key, - &on_slab_alc_key, q); + lockdep_set_class(&l3->list_lock, &on_slab_l3_key); + alc = l3->alien; + /* + * FIXME: This check for BAD_ALIEN_MAGIC + * should go away when common slab code is taught to + * work even without alien caches. + * Currently, non NUMA code returns BAD_ALIEN_MAGIC + * for alloc_alien_cache, + */ + if (!alc || (unsigned long)alc == BAD_ALIEN_MAGIC) + continue; + for_each_node(r) { + if (alc[r]) + lockdep_set_class(&alc[r]->lock, + &on_slab_alc_key); + } } } @@ -701,14 +671,6 @@ static void init_node_lock_keys(int q) static inline void init_lock_keys(void) { } - -static void slab_set_debugobj_lock_classes_node(struct kmem_cache *cachep, int node) -{ -} - -static void slab_set_debugobj_lock_classes(struct kmem_cache *cachep) -{ -} #endif /* @@ -1302,8 +1264,6 @@ static int __cpuinit cpuup_prepare(long cpu) spin_unlock_irq(&l3->list_lock); kfree(shared); free_alien_cache(alien); - if (cachep->flags & SLAB_DEBUG_OBJECTS) - slab_set_debugobj_lock_classes_node(cachep, node); } init_node_lock_keys(node); @@ -1666,9 +1626,6 @@ void __init kmem_cache_init_late(void) { struct kmem_cache *cachep; - /* Annotate slab for lockdep -- annotate the malloc caches */ - init_lock_keys(); - /* 6) resize the head arrays to their final sizes */ mutex_lock(&cache_chain_mutex); list_for_each_entry(cachep, &cache_chain, next) @@ -1679,6 +1636,9 @@ void __init kmem_cache_init_late(void) /* Done! */ g_cpucache_up = FULL; + /* Annotate slab for lockdep -- annotate the malloc caches */ + init_lock_keys(); + /* * Register a cpu startup notifier callback that initializes * cpu_cache_get for all new cpus @@ -2466,16 +2426,6 @@ kmem_cache_create (const char *name, size_t size, size_t align, goto oops; } - if (flags & SLAB_DEBUG_OBJECTS) { - /* - * Would deadlock through slab_destroy()->call_rcu()-> - * debug_object_activate()->kmem_cache_alloc(). - */ - WARN_ON_ONCE(flags & SLAB_DESTROY_BY_RCU); - - slab_set_debugobj_lock_classes(cachep); - } - /* cache setup completed, link it into the list */ list_add(&cachep->next, &cache_chain); oops: diff --git a/trunk/mm/slub.c b/trunk/mm/slub.c index 9f662d70eb47..eb5a8f93338a 100644 --- a/trunk/mm/slub.c +++ b/trunk/mm/slub.c @@ -701,7 +701,7 @@ static u8 *check_bytes(u8 *start, u8 value, unsigned int bytes) return check_bytes8(start, value, bytes); value64 = value | value << 8 | value << 16 | value << 24; - value64 = (value64 & 0xffffffff) | value64 << 32; + value64 = value64 | value64 << 32; prefix = 8 - ((unsigned long)start) % 8; if (prefix) { @@ -1854,7 +1854,7 @@ static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c) new.frozen = 0; - if (!new.inuse && n->nr_partial > s->min_partial) + if (!new.inuse && n->nr_partial < s->min_partial) m = M_FREE; else if (new.freelist) { m = M_PARTIAL; @@ -2387,13 +2387,11 @@ static void __slab_free(struct kmem_cache *s, struct page *page, slab_empty: if (prior) { /* - * Slab on the partial list. + * Slab still on the partial list. */ remove_partial(n, page); stat(s, FREE_REMOVE_PARTIAL); - } else - /* Slab must be on the full list */ - remove_full(s, page); + } spin_unlock_irqrestore(&n->list_lock, flags); stat(s, FREE_SLAB); diff --git a/trunk/mm/swapfile.c b/trunk/mm/swapfile.c index 17bc224bce68..1b8c33907242 100644 --- a/trunk/mm/swapfile.c +++ b/trunk/mm/swapfile.c @@ -1924,24 +1924,20 @@ static unsigned long read_swap_header(struct swap_info_struct *p, /* * Find out how many pages are allowed for a single swap - * device. There are three limiting factors: 1) the number - * of bits for the swap offset in the swp_entry_t type, and - * 2) the number of bits in the swap pte as defined by the - * the different architectures, and 3) the number of free bits - * in an exceptional radix_tree entry. In order to find the - * largest possible bit mask, a swap entry with swap type 0 + * device. There are two limiting factors: 1) the number of + * bits for the swap offset in the swp_entry_t type and + * 2) the number of bits in the a swap pte as defined by + * the different architectures. In order to find the + * largest possible bit mask a swap entry with swap type 0 * and swap offset ~0UL is created, encoded to a swap pte, - * decoded to a swp_entry_t again, and finally the swap + * decoded to a swp_entry_t again and finally the swap * offset is extracted. This will mask all the bits from * the initial ~0UL mask that can't be encoded in either * the swp_entry_t or the architecture definition of a - * swap pte. Then the same is done for a radix_tree entry. + * swap pte. */ maxpages = swp_offset(pte_to_swp_entry( - swp_entry_to_pte(swp_entry(0, ~0UL)))); - maxpages = swp_offset(radix_to_swp_entry( - swp_to_radix_entry(swp_entry(0, maxpages)))) + 1; - + swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1; if (maxpages > swap_header->info.last_page) { maxpages = swap_header->info.last_page + 1; /* p->max is an unsigned int: don't overflow it */ diff --git a/trunk/mm/truncate.c b/trunk/mm/truncate.c index b40ac6d4e86e..232eb2736a79 100644 --- a/trunk/mm/truncate.c +++ b/trunk/mm/truncate.c @@ -336,14 +336,6 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, unsigned long count = 0; int i; - /* - * Note: this function may get called on a shmem/tmpfs mapping: - * pagevec_lookup() might then return 0 prematurely (because it - * got a gangful of swap entries); but it's hardly worth worrying - * about - it can rarely have anything to free from such a mapping - * (most pages are dirty), and already skips over any difficulties. - */ - pagevec_init(&pvec, 0); while (index <= end && pagevec_lookup(&pvec, mapping, index, min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1)) { diff --git a/trunk/net/atm/br2684.c b/trunk/net/atm/br2684.c index 52cfd0c3ea71..2252c2085dac 100644 --- a/trunk/net/atm/br2684.c +++ b/trunk/net/atm/br2684.c @@ -242,6 +242,8 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev, if (brdev->payload == p_bridged) { skb_push(skb, 2); memset(skb->data, 0, 2); + } else { /* p_routed */ + skb_pull(skb, ETH_HLEN); } } skb_debug(skb); diff --git a/trunk/net/bridge/br_if.c b/trunk/net/bridge/br_if.c index 2cdf0070419f..3176e2e13d9b 100644 --- a/trunk/net/bridge/br_if.c +++ b/trunk/net/bridge/br_if.c @@ -417,7 +417,6 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) int br_del_if(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; - bool changed_addr; p = br_port_get_rtnl(dev); if (!p || p->br != br) @@ -426,12 +425,9 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) del_nbp(p); spin_lock_bh(&br->lock); - changed_addr = br_stp_recalculate_bridge_id(br); + br_stp_recalculate_bridge_id(br); spin_unlock_bh(&br->lock); - if (changed_addr) - call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); - netdev_update_features(br->dev); return 0; diff --git a/trunk/net/bridge/br_notify.c b/trunk/net/bridge/br_notify.c index a76b62135558..6545ee9591d1 100644 --- a/trunk/net/bridge/br_notify.c +++ b/trunk/net/bridge/br_notify.c @@ -34,7 +34,6 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v struct net_device *dev = ptr; struct net_bridge_port *p; struct net_bridge *br; - bool changed_addr; int err; /* register of bridge completed, add sysfs entries */ @@ -58,12 +57,8 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v case NETDEV_CHANGEADDR: spin_lock_bh(&br->lock); br_fdb_changeaddr(p, dev->dev_addr); - changed_addr = br_stp_recalculate_bridge_id(br); + br_stp_recalculate_bridge_id(br); spin_unlock_bh(&br->lock); - - if (changed_addr) - call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); - break; case NETDEV_CHANGE: diff --git a/trunk/net/bridge/netfilter/ebtables.c b/trunk/net/bridge/netfilter/ebtables.c index 5864cc491369..2b5ca1a0054d 100644 --- a/trunk/net/bridge/netfilter/ebtables.c +++ b/trunk/net/bridge/netfilter/ebtables.c @@ -1198,8 +1198,7 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) if (table->check && table->check(newinfo, table->valid_hooks)) { BUGPRINT("The table doesn't like its own initial data, lol\n"); - ret = -EINVAL; - goto free_chainstack; + return ERR_PTR(-EINVAL); } table->private = newinfo; diff --git a/trunk/net/core/Makefile b/trunk/net/core/Makefile index 0d357b1c4e57..8a04dd22cf77 100644 --- a/trunk/net/core/Makefile +++ b/trunk/net/core/Makefile @@ -3,7 +3,7 @@ # obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ - gen_stats.o gen_estimator.o net_namespace.o secure_seq.o + gen_stats.o gen_estimator.o net_namespace.o obj-$(CONFIG_SYSCTL) += sysctl_net_core.o diff --git a/trunk/net/core/scm.c b/trunk/net/core/scm.c index 811b53fb330e..4c1ef026d695 100644 --- a/trunk/net/core/scm.c +++ b/trunk/net/core/scm.c @@ -192,7 +192,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) goto error; cred->uid = cred->euid = p->creds.uid; - cred->gid = cred->egid = p->creds.gid; + cred->gid = cred->egid = p->creds.uid; put_cred(p->cred); p->cred = cred; } diff --git a/trunk/net/core/secure_seq.c b/trunk/net/core/secure_seq.c deleted file mode 100644 index 45329d7c9dd9..000000000000 --- a/trunk/net/core/secure_seq.c +++ /dev/null @@ -1,184 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; - -static int __init net_secret_init(void) -{ - get_random_bytes(net_secret, sizeof(net_secret)); - return 0; -} -late_initcall(net_secret_init); - -static u32 seq_scale(u32 seq) -{ - /* - * As close as possible to RFC 793, which - * suggests using a 250 kHz clock. - * Further reading shows this assumes 2 Mb/s networks. - * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. - * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but - * we also need to limit the resolution so that the u32 seq - * overlaps less than one time per MSL (2 minutes). - * Choosing a clock of 64 ns period is OK. (period of 274 s) - */ - return seq + (ktime_to_ns(ktime_get_real()) >> 6); -} - -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, - __be16 sport, __be16 dport) -{ - u32 secret[MD5_MESSAGE_BYTES / 4]; - u32 hash[MD5_DIGEST_WORDS]; - u32 i; - - memcpy(hash, saddr, 16); - for (i = 0; i < 4; i++) - secret[i] = net_secret[i] + daddr[i]; - secret[4] = net_secret[4] + - (((__force u16)sport << 16) + (__force u16)dport); - for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) - secret[i] = net_secret[i]; - - md5_transform(hash, secret); - - return seq_scale(hash[0]); -} -EXPORT_SYMBOL(secure_tcpv6_sequence_number); - -u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, - __be16 dport) -{ - u32 secret[MD5_MESSAGE_BYTES / 4]; - u32 hash[MD5_DIGEST_WORDS]; - u32 i; - - memcpy(hash, saddr, 16); - for (i = 0; i < 4; i++) - secret[i] = net_secret[i] + (__force u32) daddr[i]; - secret[4] = net_secret[4] + (__force u32)dport; - for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) - secret[i] = net_secret[i]; - - md5_transform(hash, secret); - - return hash[0]; -} -#endif - -#ifdef CONFIG_INET -__u32 secure_ip_id(__be32 daddr) -{ - u32 hash[MD5_DIGEST_WORDS]; - - hash[0] = (__force __u32) daddr; - hash[1] = net_secret[13]; - hash[2] = net_secret[14]; - hash[3] = net_secret[15]; - - md5_transform(hash, net_secret); - - return hash[0]; -} - -__u32 secure_ipv6_id(const __be32 daddr[4]) -{ - __u32 hash[4]; - - memcpy(hash, daddr, 16); - md5_transform(hash, net_secret); - - return hash[0]; -} - -__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport) -{ - u32 hash[MD5_DIGEST_WORDS]; - - hash[0] = (__force u32)saddr; - hash[1] = (__force u32)daddr; - hash[2] = ((__force u16)sport << 16) + (__force u16)dport; - hash[3] = net_secret[15]; - - md5_transform(hash, net_secret); - - return seq_scale(hash[0]); -} - -u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) -{ - u32 hash[MD5_DIGEST_WORDS]; - - hash[0] = (__force u32)saddr; - hash[1] = (__force u32)daddr; - hash[2] = (__force u32)dport ^ net_secret[14]; - hash[3] = net_secret[15]; - - md5_transform(hash, net_secret); - - return hash[0]; -} -EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); -#endif - -#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) -u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, - __be16 sport, __be16 dport) -{ - u32 hash[MD5_DIGEST_WORDS]; - u64 seq; - - hash[0] = (__force u32)saddr; - hash[1] = (__force u32)daddr; - hash[2] = ((__force u16)sport << 16) + (__force u16)dport; - hash[3] = net_secret[15]; - - md5_transform(hash, net_secret); - - seq = hash[0] | (((u64)hash[1]) << 32); - seq += ktime_to_ns(ktime_get_real()); - seq &= (1ull << 48) - 1; - - return seq; -} -EXPORT_SYMBOL(secure_dccp_sequence_number); - -#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) -u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, - __be16 sport, __be16 dport) -{ - u32 secret[MD5_MESSAGE_BYTES / 4]; - u32 hash[MD5_DIGEST_WORDS]; - u64 seq; - u32 i; - - memcpy(hash, saddr, 16); - for (i = 0; i < 4; i++) - secret[i] = net_secret[i] + daddr[i]; - secret[4] = net_secret[4] + - (((__force u16)sport << 16) + (__force u16)dport); - for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) - secret[i] = net_secret[i]; - - md5_transform(hash, secret); - - seq = hash[0] | (((u64)hash[1]) << 32); - seq += ktime_to_ns(ktime_get_real()); - seq &= (1ull << 48) - 1; - - return seq; -} -EXPORT_SYMBOL(secure_dccpv6_sequence_number); -#endif -#endif diff --git a/trunk/net/core/skbuff.c b/trunk/net/core/skbuff.c index 27002dffe7ed..2beda824636e 100644 --- a/trunk/net/core/skbuff.c +++ b/trunk/net/core/skbuff.c @@ -1369,21 +1369,8 @@ unsigned char *__pskb_pull_tail(struct sk_buff *skb, int delta) } EXPORT_SYMBOL(__pskb_pull_tail); -/** - * skb_copy_bits - copy bits from skb to kernel buffer - * @skb: source skb - * @offset: offset in source - * @to: destination buffer - * @len: number of bytes to copy - * - * Copy the specified number of bytes from the source skb to the - * destination buffer. - * - * CAUTION ! : - * If its prototype is ever changed, - * check arch/{*}/net/{*}.S files, - * since it is called from BPF assembly code. - */ +/* Copy some data bits from skb to kernel buffer. */ + int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) { int start = skb_headlen(skb); diff --git a/trunk/net/dccp/ipv4.c b/trunk/net/dccp/ipv4.c index 332639b56f4d..8c36adfd1919 100644 --- a/trunk/net/dccp/ipv4.c +++ b/trunk/net/dccp/ipv4.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "ackvec.h" #include "ccid.h" diff --git a/trunk/net/dccp/ipv6.c b/trunk/net/dccp/ipv6.c index b74f76117dcf..8dc4348774a5 100644 --- a/trunk/net/dccp/ipv6.c +++ b/trunk/net/dccp/ipv6.c @@ -29,7 +29,6 @@ #include #include #include -#include #include "dccp.h" #include "ipv6.h" @@ -70,7 +69,13 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); } -static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) +static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, + __be16 sport, __be16 dport ) +{ + return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); +} + +static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) { return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, ipv6_hdr(skb)->saddr.s6_addr32, diff --git a/trunk/net/ipv4/igmp.c b/trunk/net/ipv4/igmp.c index 283c0a26e03f..f1d27f6c9351 100644 --- a/trunk/net/ipv4/igmp.c +++ b/trunk/net/ipv4/igmp.c @@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, pmc->sfcount[sfmode]--; for (j=0; jsfcount[MCAST_EXCLUDE] != 0)) { #ifdef CONFIG_IP_MULTICAST struct ip_sf_list *psf; diff --git a/trunk/net/ipv4/inet_hashtables.c b/trunk/net/ipv4/inet_hashtables.c index 984ec656b03b..3c0369a3a663 100644 --- a/trunk/net/ipv4/inet_hashtables.c +++ b/trunk/net/ipv4/inet_hashtables.c @@ -21,7 +21,6 @@ #include #include -#include #include /* diff --git a/trunk/net/ipv4/inetpeer.c b/trunk/net/ipv4/inetpeer.c index 86f13c67ea85..e38213817d0a 100644 --- a/trunk/net/ipv4/inetpeer.c +++ b/trunk/net/ipv4/inetpeer.c @@ -19,7 +19,6 @@ #include #include #include -#include /* * Theory of operations. diff --git a/trunk/net/ipv4/ip_output.c b/trunk/net/ipv4/ip_output.c index 8c6563361ab5..ccaaa851ab42 100644 --- a/trunk/net/ipv4/ip_output.c +++ b/trunk/net/ipv4/ip_output.c @@ -122,7 +122,6 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) newskb->pkt_type = PACKET_LOOPBACK; newskb->ip_summed = CHECKSUM_UNNECESSARY; WARN_ON(!skb_dst(newskb)); - skb_dst_force(newskb); netif_rx_ni(newskb); return 0; } @@ -205,15 +204,9 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - rcu_read_lock(); neigh = dst_get_neighbour(dst); - if (neigh) { - int res = neigh_output(neigh, skb); - - rcu_read_unlock(); - return res; - } - rcu_read_unlock(); + if (neigh) + return neigh_output(neigh, skb); if (net_ratelimit()) printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); diff --git a/trunk/net/ipv4/ip_sockglue.c b/trunk/net/ipv4/ip_sockglue.c index 8905e92f896a..ab0c9efd1efa 100644 --- a/trunk/net/ipv4/ip_sockglue.c +++ b/trunk/net/ipv4/ip_sockglue.c @@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); */ static int do_ip_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen, unsigned flags) + char __user *optval, int __user *optlen) { struct inet_sock *inet = inet_sk(sk); int val; @@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, msg.msg_control = optval; msg.msg_controllen = len; - msg.msg_flags = flags; + msg.msg_flags = 0; if (inet->cmsg_flags & IP_CMSG_PKTINFO) { struct in_pktinfo info; @@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, { int err; - err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); + err = do_ip_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER /* we need to exclude all possible ENOPROTOOPTs except default case */ if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && @@ -1327,8 +1327,7 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, return compat_mc_getsockopt(sk, level, optname, optval, optlen, ip_getsockopt); - err = do_ip_getsockopt(sk, level, optname, optval, optlen, - MSG_CMSG_COMPAT); + err = do_ip_getsockopt(sk, level, optname, optval, optlen); #ifdef CONFIG_NETFILTER /* we need to exclude all possible ENOPROTOOPTs except default case */ diff --git a/trunk/net/ipv4/netfilter.c b/trunk/net/ipv4/netfilter.c index 929b27bdeb79..2e97e3ec1eb7 100644 --- a/trunk/net/ipv4/netfilter.c +++ b/trunk/net/ipv4/netfilter.c @@ -18,15 +18,17 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) struct rtable *rt; struct flowi4 fl4 = {}; __be32 saddr = iph->saddr; - __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; + __u8 flags = 0; unsigned int hh_len; - if (addr_type == RTN_UNSPEC) - addr_type = inet_addr_type(net, saddr); - if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) - flags |= FLOWI_FLAG_ANYSRC; - else - saddr = 0; + if (!skb->sk && addr_type != RTN_LOCAL) { + if (addr_type == RTN_UNSPEC) + addr_type = inet_addr_type(net, saddr); + if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) + flags |= FLOWI_FLAG_ANYSRC; + else + saddr = 0; + } /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. @@ -36,7 +38,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) fl4.flowi4_tos = RT_TOS(iph->tos); fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; fl4.flowi4_mark = skb->mark; - fl4.flowi4_flags = flags; + fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; rt = ip_route_output_key(net, &fl4); if (IS_ERR(rt)) return -1; diff --git a/trunk/net/ipv4/netfilter/nf_nat_proto_common.c b/trunk/net/ipv4/netfilter/nf_nat_proto_common.c index f52d41ea0690..3e61faf23a9a 100644 --- a/trunk/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/trunk/net/ipv4/netfilter/nf_nat_proto_common.c @@ -12,7 +12,6 @@ #include #include -#include #include #include #include diff --git a/trunk/net/ipv4/raw.c b/trunk/net/ipv4/raw.c index 61714bd52925..1457acb39cec 100644 --- a/trunk/net/ipv4/raw.c +++ b/trunk/net/ipv4/raw.c @@ -563,8 +563,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, - inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, - daddr, saddr, 0, 0); + FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); if (!inet->hdrincl) { err = raw_probe_proto_opt(&fl4, msg); diff --git a/trunk/net/ipv4/route.c b/trunk/net/ipv4/route.c index 075212e41b83..1730689f560e 100644 --- a/trunk/net/ipv4/route.c +++ b/trunk/net/ipv4/route.c @@ -109,7 +109,6 @@ #include #endif #include -#include #define RT_FL_TOS(oldflp4) \ ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) @@ -722,7 +721,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1, { return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | - (rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0); + (rt1->rt_iif ^ rt2->rt_iif)) == 0); } static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) @@ -731,8 +730,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | (rt1->rt_mark ^ rt2->rt_mark) | (rt1->rt_key_tos ^ rt2->rt_key_tos) | - (rt1->rt_route_iif ^ rt2->rt_route_iif) | - (rt1->rt_oif ^ rt2->rt_oif)) == 0; + (rt1->rt_oif ^ rt2->rt_oif) | + (rt1->rt_iif ^ rt2->rt_iif)) == 0; } static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) @@ -1629,18 +1628,16 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) { struct rtable *rt = (struct rtable *) dst; __be32 orig_gw = rt->rt_gateway; - struct neighbour *n, *old_n; + struct neighbour *n; dst_confirm(&rt->dst); - rt->rt_gateway = peer->redirect_learned.a4; + neigh_release(dst_get_neighbour(&rt->dst)); + dst_set_neighbour(&rt->dst, NULL); - n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); - if (IS_ERR(n)) - return PTR_ERR(n); - old_n = xchg(&rt->dst._neighbour, n); - if (old_n) - neigh_release(old_n); + rt->rt_gateway = peer->redirect_learned.a4; + rt_bind_neighbour(rt); + n = dst_get_neighbour(&rt->dst); if (!n || !(n->nud_state & NUD_VALID)) { if (n) neigh_event_send(n, NULL); @@ -2320,7 +2317,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, rth = rcu_dereference(rth->dst.rt_next)) { if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | - (rth->rt_route_iif ^ iif) | + (rth->rt_iif ^ iif) | + rth->rt_oif | (rth->rt_key_tos ^ tos)) == 0 && rth->rt_mark == skb->mark && net_eq(dev_net(rth->dst.dev), net) && diff --git a/trunk/net/ipv4/syncookies.c b/trunk/net/ipv4/syncookies.c index 3bc5c8f7c71b..92bb9434b338 100644 --- a/trunk/net/ipv4/syncookies.c +++ b/trunk/net/ipv4/syncookies.c @@ -276,7 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, int mss; struct rtable *rt; __u8 rcv_wscale; - bool ecn_ok = false; + bool ecn_ok; if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; diff --git a/trunk/net/ipv4/tcp_ipv4.c b/trunk/net/ipv4/tcp_ipv4.c index 1c12b8ec849d..955b8e65b69e 100644 --- a/trunk/net/ipv4/tcp_ipv4.c +++ b/trunk/net/ipv4/tcp_ipv4.c @@ -72,7 +72,6 @@ #include #include #include -#include #include #include diff --git a/trunk/net/ipv6/addrconf.c b/trunk/net/ipv6/addrconf.c index f012ebd87b43..a55500cc0b29 100644 --- a/trunk/net/ipv6/addrconf.c +++ b/trunk/net/ipv6/addrconf.c @@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, * layer address of our nexhop router */ - if (dst_get_neighbour_raw(&rt->dst) == NULL) + if (dst_get_neighbour(&rt->dst) == NULL) ifa->flags &= ~IFA_F_OPTIMISTIC; ifa->idev = idev; diff --git a/trunk/net/ipv6/datagram.c b/trunk/net/ipv6/datagram.c index 9ef1831746ef..16560336eb72 100644 --- a/trunk/net/ipv6/datagram.c +++ b/trunk/net/ipv6/datagram.c @@ -33,11 +33,6 @@ #include #include -static inline int ipv6_mapped_addr_any(const struct in6_addr *a) -{ - return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); -} - int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) { struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; @@ -107,12 +102,10 @@ int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); - if (ipv6_addr_any(&np->saddr) || - ipv6_mapped_addr_any(&np->saddr)) + if (ipv6_addr_any(&np->saddr)) ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); - if (ipv6_addr_any(&np->rcv_saddr) || - ipv6_mapped_addr_any(&np->rcv_saddr)) { + if (ipv6_addr_any(&np->rcv_saddr)) { ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr); if (sk->sk_prot->rehash) diff --git a/trunk/net/ipv6/inet6_hashtables.c b/trunk/net/ipv6/inet6_hashtables.c index 73f1a00a96af..b53197233709 100644 --- a/trunk/net/ipv6/inet6_hashtables.c +++ b/trunk/net/ipv6/inet6_hashtables.c @@ -20,7 +20,6 @@ #include #include #include -#include #include int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) diff --git a/trunk/net/ipv6/ip6_fib.c b/trunk/net/ipv6/ip6_fib.c index 320d91d20ad7..54a4678955bf 100644 --- a/trunk/net/ipv6/ip6_fib.c +++ b/trunk/net/ipv6/ip6_fib.c @@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) RT6_TRACE("aging clone %p\n", rt); return -1; } else if ((rt->rt6i_flags & RTF_GATEWAY) && - (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) { + (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { RT6_TRACE("purging route %p via non-router but gateway\n", rt); return -1; diff --git a/trunk/net/ipv6/ip6_output.c b/trunk/net/ipv6/ip6_output.c index 4c882cf4e8a1..32e5339db0c8 100644 --- a/trunk/net/ipv6/ip6_output.c +++ b/trunk/net/ipv6/ip6_output.c @@ -135,15 +135,10 @@ static int ip6_finish_output2(struct sk_buff *skb) skb->len); } - rcu_read_lock(); neigh = dst_get_neighbour(dst); - if (neigh) { - int res = neigh_output(neigh, skb); + if (neigh) + return neigh_output(neigh, skb); - rcu_read_unlock(); - return res; - } - rcu_read_unlock(); IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); kfree_skb(skb); @@ -980,14 +975,12 @@ static int ip6_dst_lookup_tail(struct sock *sk, * dst entry and replace it instead with the * dst entry of the nexthop router */ - rcu_read_lock(); n = dst_get_neighbour(*dst); if (n && !(n->nud_state & NUD_VALID)) { struct inet6_ifaddr *ifp; struct flowi6 fl_gw6; int redirect; - rcu_read_unlock(); ifp = ipv6_get_ifaddr(net, &fl6->saddr, (*dst)->dev, 1); @@ -1007,8 +1000,6 @@ static int ip6_dst_lookup_tail(struct sock *sk, if ((err = (*dst)->error)) goto out_err_release; } - } else { - rcu_read_unlock(); } #endif diff --git a/trunk/net/ipv6/route.c b/trunk/net/ipv6/route.c index 9e69eb0ec6dd..e8987da06667 100644 --- a/trunk/net/ipv6/route.c +++ b/trunk/net/ipv6/route.c @@ -364,7 +364,7 @@ static inline struct rt6_info *rt6_device_match(struct net *net, #ifdef CONFIG_IPV6_ROUTER_PREF static void rt6_probe(struct rt6_info *rt) { - struct neighbour *neigh; + struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; /* * Okay, this does not seem to be appropriate * for now, however, we need to check if it @@ -373,10 +373,8 @@ static void rt6_probe(struct rt6_info *rt) * Router Reachability Probe MUST be rate-limited * to no more than one per minute. */ - rcu_read_lock(); - neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; if (!neigh || (neigh->nud_state & NUD_VALID)) - goto out; + return; read_lock_bh(&neigh->lock); if (!(neigh->nud_state & NUD_VALID) && time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { @@ -389,11 +387,8 @@ static void rt6_probe(struct rt6_info *rt) target = (struct in6_addr *)&neigh->primary_key; addrconf_addr_solict_mult(target, &mcaddr); ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); - } else { + } else read_unlock_bh(&neigh->lock); - } -out: - rcu_read_unlock(); } #else static inline void rt6_probe(struct rt6_info *rt) @@ -417,11 +412,8 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) static inline int rt6_check_neigh(struct rt6_info *rt) { - struct neighbour *neigh; + struct neighbour *neigh = dst_get_neighbour(&rt->dst); int m; - - rcu_read_lock(); - neigh = dst_get_neighbour(&rt->dst); if (rt->rt6i_flags & RTF_NONEXTHOP || !(rt->rt6i_flags & RTF_GATEWAY)) m = 1; @@ -438,7 +430,6 @@ static inline int rt6_check_neigh(struct rt6_info *rt) read_unlock_bh(&neigh->lock); } else m = 0; - rcu_read_unlock(); return m; } @@ -778,7 +769,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, rt->rt6i_dst.plen = 128; rt->rt6i_flags |= RTF_CACHE; rt->dst.flags |= DST_HOST; - dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst))); + dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); } return rt; } @@ -812,7 +803,7 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table, dst_hold(&rt->dst); read_unlock_bh(&table->tb6_lock); - if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) + if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); else if (!(rt->dst.flags & DST_HOST)) nrt = rt6_alloc_clone(rt, &fl6->daddr); @@ -1596,7 +1587,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, dst_confirm(&rt->dst); /* Duplicate redirect: silently ignore. */ - if (neigh == dst_get_neighbour_raw(&rt->dst)) + if (neigh == dst_get_neighbour(&rt->dst)) goto out; nrt = ip6_rt_copy(rt, dest); @@ -1691,7 +1682,7 @@ static void rt6_do_pmtu_disc(const struct in6_addr *daddr, const struct in6_addr 1. It is connected route. Action: COW 2. It is gatewayed route or NONEXTHOP route. Action: clone it. */ - if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) + if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) nrt = rt6_alloc_cow(rt, daddr, saddr); else nrt = rt6_alloc_clone(rt, daddr); @@ -2335,7 +2326,6 @@ static int rt6_fill_node(struct net *net, struct nlmsghdr *nlh; long expires; u32 table; - struct neighbour *n; if (prefix) { /* user wants prefix routes only */ if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { @@ -2424,11 +2414,8 @@ static int rt6_fill_node(struct net *net, if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) goto nla_put_failure; - rcu_read_lock(); - n = dst_get_neighbour(&rt->dst); - if (n) - NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); - rcu_read_unlock(); + if (dst_get_neighbour(&rt->dst)) + NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); if (rt->dst.dev) NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); @@ -2621,14 +2608,12 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) #else seq_puts(m, "00000000000000000000000000000000 00 "); #endif - rcu_read_lock(); n = dst_get_neighbour(&rt->dst); if (n) { seq_printf(m, "%pi6", n->primary_key); } else { seq_puts(m, "00000000000000000000000000000000"); } - rcu_read_unlock(); seq_printf(m, " %08x %08x %08x %08x %8s\n", rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), rt->dst.__use, rt->rt6i_flags, diff --git a/trunk/net/ipv6/syncookies.c b/trunk/net/ipv6/syncookies.c index ac838965ff34..89d5bf806222 100644 --- a/trunk/net/ipv6/syncookies.c +++ b/trunk/net/ipv6/syncookies.c @@ -165,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) int mss; struct dst_entry *dst; __u8 rcv_wscale; - bool ecn_ok = false; + bool ecn_ok; if (!sysctl_tcp_syncookies || !th->ack || th->rst) goto out; diff --git a/trunk/net/ipv6/tcp_ipv6.c b/trunk/net/ipv6/tcp_ipv6.c index d1fb63f4aeb7..78aa53492b3e 100644 --- a/trunk/net/ipv6/tcp_ipv6.c +++ b/trunk/net/ipv6/tcp_ipv6.c @@ -61,7 +61,6 @@ #include #include #include -#include #include diff --git a/trunk/net/netfilter/ipvs/ip_vs_ctl.c b/trunk/net/netfilter/ipvs/ip_vs_ctl.c index 2b771dc708a3..be43fd805bd0 100644 --- a/trunk/net/netfilter/ipvs/ip_vs_ctl.c +++ b/trunk/net/netfilter/ipvs/ip_vs_ctl.c @@ -3771,7 +3771,6 @@ int __init ip_vs_control_init(void) void ip_vs_control_cleanup(void) { EnterFunction(2); - unregister_netdevice_notifier(&ip_vs_dst_notifier); ip_vs_genl_unregister(); nf_unregister_sockopt(&ip_vs_sockopts); LeaveFunction(2); diff --git a/trunk/net/netfilter/nf_queue.c b/trunk/net/netfilter/nf_queue.c index 84d0fd47636a..5b466cd1272f 100644 --- a/trunk/net/netfilter/nf_queue.c +++ b/trunk/net/netfilter/nf_queue.c @@ -312,7 +312,6 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) } break; case NF_STOLEN: - break; default: kfree_skb(skb); } diff --git a/trunk/net/netlabel/Makefile b/trunk/net/netlabel/Makefile index d2732fc952e2..ea750e9df65f 100644 --- a/trunk/net/netlabel/Makefile +++ b/trunk/net/netlabel/Makefile @@ -1,6 +1,8 @@ # # Makefile for the NetLabel subsystem. # +# Feb 9, 2006, Paul Moore +# # base objects obj-y := netlabel_user.o netlabel_kapi.o diff --git a/trunk/net/netlabel/netlabel_addrlist.c b/trunk/net/netlabel/netlabel_addrlist.c index 96b749dacc34..c0519139679e 100644 --- a/trunk/net/netlabel/netlabel_addrlist.c +++ b/trunk/net/netlabel/netlabel_addrlist.c @@ -6,7 +6,7 @@ * system manages static and dynamic label mappings for network protocols such * as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_addrlist.h b/trunk/net/netlabel/netlabel_addrlist.h index fdbc1d2c7352..2b9644e19de0 100644 --- a/trunk/net/netlabel/netlabel_addrlist.h +++ b/trunk/net/netlabel/netlabel_addrlist.h @@ -6,7 +6,7 @@ * system manages static and dynamic label mappings for network protocols such * as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_cipso_v4.c b/trunk/net/netlabel/netlabel_cipso_v4.c index 6bf878335d94..dd53a36d89af 100644 --- a/trunk/net/netlabel/netlabel_cipso_v4.c +++ b/trunk/net/netlabel/netlabel_cipso_v4.c @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_cipso_v4.h b/trunk/net/netlabel/netlabel_cipso_v4.h index d24d774bfd62..af7f3355103e 100644 --- a/trunk/net/netlabel/netlabel_cipso_v4.h +++ b/trunk/net/netlabel/netlabel_cipso_v4.h @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_domainhash.c b/trunk/net/netlabel/netlabel_domainhash.c index 7d8083cde34f..2aa975e5452d 100644 --- a/trunk/net/netlabel/netlabel_domainhash.c +++ b/trunk/net/netlabel/netlabel_domainhash.c @@ -6,7 +6,7 @@ * system manages static and dynamic label mappings for network protocols such * as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_domainhash.h b/trunk/net/netlabel/netlabel_domainhash.h index bfcc0f7024c5..0261dda3f2d2 100644 --- a/trunk/net/netlabel/netlabel_domainhash.h +++ b/trunk/net/netlabel/netlabel_domainhash.h @@ -6,7 +6,7 @@ * system manages static and dynamic label mappings for network protocols such * as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_kapi.c b/trunk/net/netlabel/netlabel_kapi.c index 9c24de10a657..b528dd928d3c 100644 --- a/trunk/net/netlabel/netlabel_kapi.c +++ b/trunk/net/netlabel/netlabel_kapi.c @@ -5,7 +5,7 @@ * system manages static and dynamic label mappings for network protocols such * as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ @@ -341,11 +341,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, entry = kzalloc(sizeof(*entry), GFP_ATOMIC); if (entry == NULL) - goto out_entry; + return -ENOMEM; if (domain != NULL) { entry->domain = kstrdup(domain, GFP_ATOMIC); if (entry->domain == NULL) - goto out_domain; + goto cfg_cipsov4_map_add_failure; } if (addr == NULL && mask == NULL) { @@ -354,13 +354,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, } else if (addr != NULL && mask != NULL) { addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); if (addrmap == NULL) - goto out_addrmap; + goto cfg_cipsov4_map_add_failure; INIT_LIST_HEAD(&addrmap->list4); INIT_LIST_HEAD(&addrmap->list6); addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); if (addrinfo == NULL) - goto out_addrinfo; + goto cfg_cipsov4_map_add_failure; addrinfo->type_def.cipsov4 = doi_def; addrinfo->type = NETLBL_NLTYPE_CIPSOV4; addrinfo->list.addr = addr->s_addr & mask->s_addr; @@ -374,7 +374,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, entry->type = NETLBL_NLTYPE_ADDRSELECT; } else { ret_val = -EINVAL; - goto out_addrmap; + goto cfg_cipsov4_map_add_failure; } ret_val = netlbl_domhsh_add(entry, audit_info); @@ -384,15 +384,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, return 0; cfg_cipsov4_map_add_failure: - kfree(addrinfo); -out_addrinfo: - kfree(addrmap); -out_addrmap: + cipso_v4_doi_putdef(doi_def); kfree(entry->domain); -out_domain: kfree(entry); -out_entry: - cipso_v4_doi_putdef(doi_def); + kfree(addrmap); + kfree(addrinfo); return ret_val; } diff --git a/trunk/net/netlabel/netlabel_mgmt.c b/trunk/net/netlabel/netlabel_mgmt.c index bfa555869775..dff8a0809245 100644 --- a/trunk/net/netlabel/netlabel_mgmt.c +++ b/trunk/net/netlabel/netlabel_mgmt.c @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_mgmt.h b/trunk/net/netlabel/netlabel_mgmt.h index 5a9f31ce5799..8db37f4c10f7 100644 --- a/trunk/net/netlabel/netlabel_mgmt.h +++ b/trunk/net/netlabel/netlabel_mgmt.h @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_unlabeled.c b/trunk/net/netlabel/netlabel_unlabeled.c index e6e823656f9d..f1ecf848e3ac 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.c +++ b/trunk/net/netlabel/netlabel_unlabeled.c @@ -5,7 +5,7 @@ * NetLabel system. The NetLabel system manages static and dynamic label * mappings for network protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_unlabeled.h b/trunk/net/netlabel/netlabel_unlabeled.h index 700af49022a0..0bc8dc3f9e3c 100644 --- a/trunk/net/netlabel/netlabel_unlabeled.h +++ b/trunk/net/netlabel/netlabel_unlabeled.h @@ -5,7 +5,7 @@ * NetLabel system. The NetLabel system manages static and dynamic label * mappings for network protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_user.c b/trunk/net/netlabel/netlabel_user.c index 9fae63f10298..a3fd75ac3fa5 100644 --- a/trunk/net/netlabel/netlabel_user.c +++ b/trunk/net/netlabel/netlabel_user.c @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/netlabel/netlabel_user.h b/trunk/net/netlabel/netlabel_user.h index 81969785e279..f4fc4c9ad567 100644 --- a/trunk/net/netlabel/netlabel_user.h +++ b/trunk/net/netlabel/netlabel_user.h @@ -5,7 +5,7 @@ * NetLabel system manages static and dynamic label mappings for network * protocols such as CIPSO and RIPSO. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/net/sched/sch_prio.c b/trunk/net/sched/sch_prio.c index b5d56a22b1d2..2a318f2dc3e5 100644 --- a/trunk/net/sched/sch_prio.c +++ b/trunk/net/sched/sch_prio.c @@ -112,7 +112,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc *sch) for (prio = 0; prio < q->bands; prio++) { struct Qdisc *qdisc = q->queues[prio]; - struct sk_buff *skb = qdisc_dequeue_peeked(qdisc); + struct sk_buff *skb = qdisc->dequeue(qdisc); if (skb) { qdisc_bstats_update(sch, skb); sch->q.qlen--; diff --git a/trunk/net/sched/sch_sfq.c b/trunk/net/sched/sch_sfq.c index 4f5510e2bd6f..4536ee64383e 100644 --- a/trunk/net/sched/sch_sfq.c +++ b/trunk/net/sched/sch_sfq.c @@ -410,12 +410,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) /* Return Congestion Notification only if we dropped a packet * from this flow. */ - if (qlen != slot->qlen) - return NET_XMIT_CN; - - /* As we dropped a packet, better let upper stack know this */ - qdisc_tree_decrease_qlen(sch, 1); - return NET_XMIT_SUCCESS; + return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; } static struct sk_buff * diff --git a/trunk/net/socket.c b/trunk/net/socket.c index 24a77400b65e..b1cbbcd92558 100644 --- a/trunk/net/socket.c +++ b/trunk/net/socket.c @@ -1871,14 +1871,8 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) -struct used_address { - struct sockaddr_storage name; - unsigned int name_len; -}; - static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, - struct msghdr *msg_sys, unsigned flags, - struct used_address *used_address) + struct msghdr *msg_sys, unsigned flags, int nosec) { struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; @@ -1959,28 +1953,8 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, if (sock->file->f_flags & O_NONBLOCK) msg_sys->msg_flags |= MSG_DONTWAIT; - /* - * If this is sendmmsg() and current destination address is same as - * previously succeeded address, omit asking LSM's decision. - * used_address->name_len is initialized to UINT_MAX so that the first - * destination address never matches. - */ - if (used_address && used_address->name_len == msg_sys->msg_namelen && - !memcmp(&used_address->name, msg->msg_name, - used_address->name_len)) { - err = sock_sendmsg_nosec(sock, msg_sys, total_len); - goto out_freectl; - } - err = sock_sendmsg(sock, msg_sys, total_len); - /* - * If this is sendmmsg() and sending to current destination address was - * successful, remember it. - */ - if (used_address && err >= 0) { - used_address->name_len = msg_sys->msg_namelen; - memcpy(&used_address->name, msg->msg_name, - used_address->name_len); - } + err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, + total_len); out_freectl: if (ctl_buf != ctl) @@ -2005,7 +1979,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) if (!sock) goto out; - err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); fput_light(sock->file, fput_needed); out: @@ -2024,10 +1998,6 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, struct mmsghdr __user *entry; struct compat_mmsghdr __user *compat_entry; struct msghdr msg_sys; - struct used_address used_address; - - if (vlen > UIO_MAXIOV) - vlen = UIO_MAXIOV; datagrams = 0; @@ -2035,22 +2005,27 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, if (!sock) return err; - used_address.name_len = UINT_MAX; + err = sock_error(sock->sk); + if (err) + goto out_put; + entry = mmsg; compat_entry = (struct compat_mmsghdr __user *)mmsg; - err = 0; while (datagrams < vlen) { + /* + * No need to ask LSM for more than the first datagram. + */ if (MSG_CMSG_COMPAT & flags) { err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, - &msg_sys, flags, &used_address); + &msg_sys, flags, datagrams); if (err < 0) break; err = __put_user(err, &compat_entry->msg_len); ++compat_entry; } else { err = __sys_sendmsg(sock, (struct msghdr __user *)entry, - &msg_sys, flags, &used_address); + &msg_sys, flags, datagrams); if (err < 0) break; err = put_user(err, &entry->msg_len); @@ -2062,11 +2037,29 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, ++datagrams; } +out_put: fput_light(sock->file, fput_needed); - /* We only return an error if no datagrams were able to be sent */ - if (datagrams != 0) + if (err == 0) + return datagrams; + + if (datagrams != 0) { + /* + * We may send less entries than requested (vlen) if the + * sock is non blocking... + */ + if (err != -EAGAIN) { + /* + * ... or if sendmsg returns an error after we + * send some datagrams, where we record the + * error to return on the next call or if the + * app asks about it using getsockopt(SO_ERROR). + */ + sock->sk->sk_err = -err; + } + return datagrams; + } return err; } diff --git a/trunk/net/sunrpc/xprt.c b/trunk/net/sunrpc/xprt.c index f4385e45a5fc..9b6a4d1ea8f8 100644 --- a/trunk/net/sunrpc/xprt.c +++ b/trunk/net/sunrpc/xprt.c @@ -187,7 +187,6 @@ EXPORT_SYMBOL_GPL(xprt_load_transport); /** * xprt_reserve_xprt - serialize write access to transports * @task: task that is requesting access to the transport - * @xprt: pointer to the target transport * * This prevents mixing the payload of separate requests, and prevents * transport connects from colliding with writes. No congestion control diff --git a/trunk/net/wireless/nl80211.c b/trunk/net/wireless/nl80211.c index e83e7fee3bc0..28d2aa109bee 100644 --- a/trunk/net/wireless/nl80211.c +++ b/trunk/net/wireless/nl80211.c @@ -3464,7 +3464,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) tmp) { enum ieee80211_band band = nla_type(attr); - if (band < 0 || band >= IEEE80211_NUM_BANDS) { + if (band < 0 || band > IEEE80211_NUM_BANDS) { err = -EINVAL; goto out_free; } diff --git a/trunk/net/xfrm/xfrm_algo.c b/trunk/net/xfrm/xfrm_algo.c index 791ab2e77f3f..58064d9e565d 100644 --- a/trunk/net/xfrm/xfrm_algo.c +++ b/trunk/net/xfrm/xfrm_algo.c @@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { .desc = { .sadb_alg_id = SADB_X_EALG_AESCTR, .sadb_alg_ivlen = 8, - .sadb_alg_minbits = 160, - .sadb_alg_maxbits = 288 + .sadb_alg_minbits = 128, + .sadb_alg_maxbits = 256 } }, }; diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 266a2292451d..a38316b2e3f6 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -14,7 +14,7 @@ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Paul Moore * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. * Yuichi Nakamura * diff --git a/trunk/security/selinux/include/netif.h b/trunk/security/selinux/include/netif.h index 43d507242b42..ce23edd128b3 100644 --- a/trunk/security/selinux/include/netif.h +++ b/trunk/security/selinux/include/netif.h @@ -8,7 +8,7 @@ * * Copyright (C) 2003 Red Hat, Inc., James Morris * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Paul Moore, * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, diff --git a/trunk/security/selinux/include/netlabel.h b/trunk/security/selinux/include/netlabel.h index 8c59b8f150e8..cf2f628e6e28 100644 --- a/trunk/security/selinux/include/netlabel.h +++ b/trunk/security/selinux/include/netlabel.h @@ -1,7 +1,7 @@ /* * SELinux interface to the NetLabel subsystem * - * Author: Paul Moore + * Author : Paul Moore * */ diff --git a/trunk/security/selinux/include/netnode.h b/trunk/security/selinux/include/netnode.h index df7a5ed6c694..1b94450d11d2 100644 --- a/trunk/security/selinux/include/netnode.h +++ b/trunk/security/selinux/include/netnode.h @@ -6,7 +6,7 @@ * needed to reduce the lookup overhead since most of these queries happen on * a per-packet basis. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/security/selinux/include/netport.h b/trunk/security/selinux/include/netport.h index 4d965b83d735..8991752eaf93 100644 --- a/trunk/security/selinux/include/netport.h +++ b/trunk/security/selinux/include/netport.h @@ -5,7 +5,7 @@ * mapping is maintained as part of the normal policy but a fast cache is * needed to reduce the lookup overhead. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/security/selinux/netif.c b/trunk/security/selinux/netif.c index 326f22cbe405..58cc481c93d5 100644 --- a/trunk/security/selinux/netif.c +++ b/trunk/security/selinux/netif.c @@ -8,7 +8,7 @@ * * Copyright (C) 2003 Red Hat, Inc., James Morris * Copyright (C) 2007 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Paul Moore * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, diff --git a/trunk/security/selinux/netlabel.c b/trunk/security/selinux/netlabel.c index da4b8b233280..c3bf3ed07b06 100644 --- a/trunk/security/selinux/netlabel.c +++ b/trunk/security/selinux/netlabel.c @@ -4,7 +4,7 @@ * This file provides the necessary glue to tie NetLabel into the SELinux * subsystem. * - * Author: Paul Moore + * Author: Paul Moore * */ diff --git a/trunk/security/selinux/netnode.c b/trunk/security/selinux/netnode.c index 3bf46abaa688..8b691a863186 100644 --- a/trunk/security/selinux/netnode.c +++ b/trunk/security/selinux/netnode.c @@ -6,7 +6,7 @@ * needed to reduce the lookup overhead since most of these queries happen on * a per-packet basis. * - * Author: Paul Moore + * Author: Paul Moore * * This code is heavily based on the "netif" concept originally developed by * James Morris diff --git a/trunk/security/selinux/netport.c b/trunk/security/selinux/netport.c index 0b62bd112461..ae76e298de7d 100644 --- a/trunk/security/selinux/netport.c +++ b/trunk/security/selinux/netport.c @@ -5,7 +5,7 @@ * mapping is maintained as part of the normal policy but a fast cache is * needed to reduce the lookup overhead. * - * Author: Paul Moore + * Author: Paul Moore * * This code is heavily based on the "netif" concept originally developed by * James Morris diff --git a/trunk/security/selinux/selinuxfs.c b/trunk/security/selinux/selinuxfs.c index 55d92cbb177a..de7900ef53da 100644 --- a/trunk/security/selinux/selinuxfs.c +++ b/trunk/security/selinux/selinuxfs.c @@ -2,7 +2,7 @@ * * Added conditional policy language extensions * - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support for the policy capability bitmap * diff --git a/trunk/security/selinux/ss/ebitmap.c b/trunk/security/selinux/ss/ebitmap.c index 30f119b1d1ec..d42951fcbe87 100644 --- a/trunk/security/selinux/ss/ebitmap.c +++ b/trunk/security/selinux/ss/ebitmap.c @@ -4,7 +4,7 @@ * Author : Stephen Smalley, */ /* - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support to import/export the NetLabel category bitmap * diff --git a/trunk/security/selinux/ss/mls.c b/trunk/security/selinux/ss/mls.c index fbf9c5816c71..e96174216bc9 100644 --- a/trunk/security/selinux/ss/mls.c +++ b/trunk/security/selinux/ss/mls.c @@ -11,7 +11,7 @@ * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. */ /* - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support to import/export the MLS label from NetLabel * diff --git a/trunk/security/selinux/ss/mls.h b/trunk/security/selinux/ss/mls.h index e4369e3e6366..037bf9d82d41 100644 --- a/trunk/security/selinux/ss/mls.h +++ b/trunk/security/selinux/ss/mls.h @@ -11,7 +11,7 @@ * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. */ /* - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support to import/export the MLS label from NetLabel * diff --git a/trunk/security/selinux/ss/policydb.c b/trunk/security/selinux/ss/policydb.c index 2381d0ded228..d246aca3f4fb 100644 --- a/trunk/security/selinux/ss/policydb.c +++ b/trunk/security/selinux/ss/policydb.c @@ -13,7 +13,7 @@ * * Added conditional policy language extensions * - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support for the policy capability bitmap * diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index f6917bc0aa05..973e00e34fa9 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -13,7 +13,7 @@ * * Added conditional policy language extensions * - * Updated: Hewlett-Packard + * Updated: Hewlett-Packard * * Added support for NetLabel * Added support for the policy capability bitmap diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index b9c5e149903b..f375eb2e1957 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -9,7 +9,7 @@ * * Copyright (C) 2007 Casey Schaufler * Copyright (C) 2009 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Paul Moore * Copyright (C) 2010 Nokia Corporation * * This program is free software; you can redistribute it and/or modify diff --git a/trunk/security/tomoyo/common.c b/trunk/security/tomoyo/common.c index 2e43aec1c36b..c8439cf2a448 100644 --- a/trunk/security/tomoyo/common.c +++ b/trunk/security/tomoyo/common.c @@ -710,10 +710,8 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head) head->r.index++) if (ns->profile_ptr[head->r.index]) break; - if (head->r.index == TOMOYO_MAX_PROFILES) { - head->r.eof = true; + if (head->r.index == TOMOYO_MAX_PROFILES) return; - } head->r.step++; break; case 2: @@ -725,7 +723,6 @@ static void tomoyo_read_profile(struct tomoyo_io_buffer *head) tomoyo_io_printf(head, "%u-COMMENT=", index); tomoyo_set_string(head, comment ? comment->name : ""); tomoyo_set_lf(head); - tomoyo_print_namespace(head); tomoyo_io_printf(head, "%u-PREFERENCE={ ", index); for (i = 0; i < TOMOYO_MAX_PREF; i++) tomoyo_io_printf(head, "%s=%u ", diff --git a/trunk/sound/core/pcm_compat.c b/trunk/sound/core/pcm_compat.c index 91cdf9435fec..5fb2e28e796f 100644 --- a/trunk/sound/core/pcm_compat.c +++ b/trunk/sound/core/pcm_compat.c @@ -342,7 +342,7 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, kfree(bufs); return -EFAULT; } - bufs[i] = compat_ptr(ptr); + bufs[ch] = compat_ptr(ptr); bufptr++; } if (dir == SNDRV_PCM_STREAM_PLAYBACK) diff --git a/trunk/sound/core/rtctimer.c b/trunk/sound/core/rtctimer.c index e85e72baff9e..0851cd13e303 100644 --- a/trunk/sound/core/rtctimer.c +++ b/trunk/sound/core/rtctimer.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include #include #include diff --git a/trunk/sound/core/timer.c b/trunk/sound/core/timer.c index 67ebf1c21c04..7c1cbf0a0dc4 100644 --- a/trunk/sound/core/timer.c +++ b/trunk/sound/core/timer.c @@ -328,8 +328,6 @@ int snd_timer_close(struct snd_timer_instance *timeri) mutex_unlock(®ister_mutex); } else { timer = timeri->timer; - if (snd_BUG_ON(!timer)) - goto out; /* wait, until the active callback is finished */ spin_lock_irq(&timer->lock); while (timeri->flags & SNDRV_TIMER_IFLG_CALLBACK) { @@ -355,7 +353,6 @@ int snd_timer_close(struct snd_timer_instance *timeri) } mutex_unlock(®ister_mutex); } - out: if (timeri->private_free) timeri->private_free(timeri); kfree(timeri->owner); @@ -534,8 +531,6 @@ int snd_timer_stop(struct snd_timer_instance *timeri) if (err < 0) return err; timer = timeri->timer; - if (!timer) - return -EINVAL; spin_lock_irqsave(&timer->lock, flags); timeri->cticks = timeri->ticks; timeri->pticks = 0; diff --git a/trunk/sound/oss/pas2_pcm.c b/trunk/sound/oss/pas2_pcm.c index 6f13ab4afc6b..8f7d175767a2 100644 --- a/trunk/sound/oss/pas2_pcm.c +++ b/trunk/sound/oss/pas2_pcm.c @@ -63,13 +63,13 @@ static int pcm_set_speed(int arg) if (pcm_channels & 2) { - foo = ((PIT_TICK_RATE / 2) + (arg / 2)) / arg; - arg = ((PIT_TICK_RATE / 2) + (foo / 2)) / foo; + foo = ((CLOCK_TICK_RATE / 2) + (arg / 2)) / arg; + arg = ((CLOCK_TICK_RATE / 2) + (foo / 2)) / foo; } else { - foo = (PIT_TICK_RATE + (arg / 2)) / arg; - arg = (PIT_TICK_RATE + (foo / 2)) / foo; + foo = (CLOCK_TICK_RATE + (arg / 2)) / arg; + arg = (CLOCK_TICK_RATE + (foo / 2)) / foo; } pcm_speed = arg; diff --git a/trunk/sound/oss/pss.c b/trunk/sound/oss/pss.c index 2fc0624024b5..9b800ce5100e 100644 --- a/trunk/sound/oss/pss.c +++ b/trunk/sound/oss/pss.c @@ -673,8 +673,7 @@ static void configure_nonsound_components(void) if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */ printk(KERN_INFO "PSS: CDROM port not enabled.\n"); - } else if (!request_region(pss_cdrom_port, 2, "PSS CDROM")) { - pss_cdrom_port = -1; + } else if (check_region(pss_cdrom_port, 2)) { printk(KERN_ERR "PSS: CDROM I/O port conflict.\n"); } else { set_io_base(devc, CONF_CDROM, pss_cdrom_port); @@ -1233,8 +1232,7 @@ static void __exit cleanup_pss(void) if(pssmpu) unload_pss_mpu(&cfg_mpu); unload_pss(&cfg); - } else if (pss_cdrom_port != -1) - release_region(pss_cdrom_port, 2); + } if(!pss_keep_settings) /* Keep hardware settings if asked */ { diff --git a/trunk/sound/pci/Kconfig b/trunk/sound/pci/Kconfig index 88168044375f..50abf5bf8e09 100644 --- a/trunk/sound/pci/Kconfig +++ b/trunk/sound/pci/Kconfig @@ -1,10 +1,5 @@ # ALSA PCI drivers -config SND_TEA575X - tristate - depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 - default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 - menuconfig SND_PCI bool "PCI sound devices" depends on PCI @@ -568,6 +563,11 @@ config SND_FM801_TEA575X_BOOL FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and SF64-PCR) into the snd-fm801 driver. +config SND_TEA575X + tristate + depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO || RADIO_SF16FMR2 + default SND_FM801 || SND_ES1968 || RADIO_SF16FMR2 + source "sound/pci/hda/Kconfig" config SND_HDSP diff --git a/trunk/sound/pci/asihpi/hpicmn.c b/trunk/sound/pci/asihpi/hpicmn.c index bd47521b24ec..65b7ca13115b 100644 --- a/trunk/sound/pci/asihpi/hpicmn.c +++ b/trunk/sound/pci/asihpi/hpicmn.c @@ -631,12 +631,13 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, if (!p_cache) return NULL; - p_cache->p_info = kzalloc(sizeof(*p_cache->p_info) * control_count, - GFP_KERNEL); + p_cache->p_info = + kmalloc(sizeof(*p_cache->p_info) * control_count, GFP_KERNEL); if (!p_cache->p_info) { kfree(p_cache); return NULL; } + memset(p_cache->p_info, 0, sizeof(*p_cache->p_info) * control_count); p_cache->cache_size_in_bytes = size_in_bytes; p_cache->control_count = control_count; p_cache->p_cache = p_dsp_control_buffer; diff --git a/trunk/sound/pci/asihpi/hpidspcd.c b/trunk/sound/pci/asihpi/hpidspcd.c index 71d32c868c92..3a7afa31c1d8 100644 --- a/trunk/sound/pci/asihpi/hpidspcd.c +++ b/trunk/sound/pci/asihpi/hpidspcd.c @@ -43,7 +43,6 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, struct pci_dev *dev = os_data; struct code_header header; char fw_name[20]; - short err_ret = HPI_ERROR_DSP_FILE_NOT_FOUND; int err; sprintf(fw_name, "asihpi/dsp%04x.bin", adapter); @@ -86,10 +85,8 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name); dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL); - if (!dsp_code->pvt) { - err_ret = HPI_ERROR_MEMORY_ALLOC; - goto error2; - } + if (!dsp_code->pvt) + return HPI_ERROR_MEMORY_ALLOC; dsp_code->pvt->dev = dev; dsp_code->pvt->firmware = firmware; @@ -102,7 +99,7 @@ short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code, release_firmware(firmware); error1: dsp_code->block_length = 0; - return err_ret; + return HPI_ERROR_DSP_FILE_NOT_FOUND; } /*-------------------------------------------------------------------*/ diff --git a/trunk/sound/pci/asihpi/hpioctl.c b/trunk/sound/pci/asihpi/hpioctl.c index a32502e796de..9683f84ecdc8 100644 --- a/trunk/sound/pci/asihpi/hpioctl.c +++ b/trunk/sound/pci/asihpi/hpioctl.c @@ -177,21 +177,16 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } else { u16 __user *ptr = NULL; u32 size = 0; - u32 adapter_present; + /* -1=no data 0=read from user mem, 1=write to user mem */ int wrflag = -1; - struct hpi_adapter *pa; - - if (hm->h.adapter_index < HPI_MAX_ADAPTERS) { - pa = &adapters[hm->h.adapter_index]; - adapter_present = pa->type; - } else { - adapter_present = 0; - } + u32 adapter = hm->h.adapter_index; + struct hpi_adapter *pa = &adapters[adapter]; - if (!adapter_present) { - hpi_init_response(&hr->r0, hm->h.object, - hm->h.function, HPI_ERROR_BAD_ADAPTER_NUMBER); + if ((adapter >= HPI_MAX_ADAPTERS) || (!pa->type)) { + hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, + HPI_ADAPTER_OPEN, + HPI_ERROR_BAD_ADAPTER_NUMBER); uncopied_bytes = copy_to_user(puhr, hr, sizeof(hr->h)); diff --git a/trunk/sound/pci/hda/alc269_quirks.c b/trunk/sound/pci/hda/alc269_quirks.c index 5ac0e2162a46..14fdcf29b154 100644 --- a/trunk/sound/pci/hda/alc269_quirks.c +++ b/trunk/sound/pci/hda/alc269_quirks.c @@ -531,10 +531,17 @@ static const struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), + SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), + SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", + ALC269_DMIC), + SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", + ALC269_DMIC), + SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), + SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 9a1aa09f47fe..e125c60fe352 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -4484,22 +4484,6 @@ static void alc269_fixup_pcm_44k(struct hda_codec *codec, spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; } -static void alc269_fixup_stereo_dmic(struct hda_codec *codec, - const struct alc_fixup *fix, int action) -{ - int coef; - - if (action != ALC_FIXUP_ACT_INIT) - return; - /* The digital-mic unit sends PDM (differential signal) instead of - * the standard PCM, thus you can't record a valid mono stream as is. - * Below is a workaround specific to ALC269 to control the dmic - * signal source as mono. - */ - coef = alc_read_coef_idx(codec, 0x07); - alc_write_coef_idx(codec, 0x07, coef | 0x80); -} - enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -4510,7 +4494,6 @@ enum { ALC275_FIXUP_SONY_HWEQ, ALC271_FIXUP_DMIC, ALC269_FIXUP_PCM_44K, - ALC269_FIXUP_STEREO_DMIC, }; static const struct alc_fixup alc269_fixups[] = { @@ -4573,19 +4556,10 @@ static const struct alc_fixup alc269_fixups[] = { .type = ALC_FIXUP_FUNC, .v.func = alc269_fixup_pcm_44k, }, - [ALC269_FIXUP_STEREO_DMIC] = { - .type = ALC_FIXUP_FUNC, - .v.func = alc269_fixup_stereo_dmic, - }, }; static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), - SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), - SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index 4ebfbd874c9a..84d8798bf33a 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -2084,7 +2084,7 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec) struct via_spec *spec = codec->spec; struct nid_path *path; bool check_dac; - hda_nid_t pin, dac = 0; + hda_nid_t pin, dac; int err; pin = spec->autocfg.speaker_pins[0]; diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 493e3946756f..af130ee0c45d 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -521,7 +521,6 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) /* revisions >= 230 indicate AES32 card */ -#define HDSPM_MADI_ANCIENT_REV 204 #define HDSPM_MADI_OLD_REV 207 #define HDSPM_MADI_REV 210 #define HDSPM_RAYDAT_REV 211 @@ -1218,22 +1217,6 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) rate = 0; break; } - - /* QS and DS rates normally can not be detected - * automatically by the card. Only exception is MADI - * in 96k frame mode. - * - * So if we read SS values (32 .. 48k), check for - * user-provided DS/QS bits in the control register - * and multiply the base frequency accordingly. - */ - if (rate <= 48000) { - if (hdspm->control_register & HDSPM_QuadSpeed) - rate *= 4; - else if (hdspm->control_register & - HDSPM_DoubleSpeed) - rate *= 2; - } } break; } @@ -1339,10 +1322,6 @@ static u64 hdspm_calc_dds_value(struct hdspm *hdspm, u64 period) break; case MADIface: freq_const = 131072000000000ULL; - break; - default: - snd_BUG(); - return 0; } return div_u64(freq_const, period); @@ -1360,19 +1339,16 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) switch (hdspm->io_type) { case MADIface: - n = 131072000000000ULL; /* 125 MHz */ - break; + n = 131072000000000ULL; /* 125 MHz */ + break; case MADI: case AES32: - n = 110069313433624ULL; /* 105 MHz */ - break; + n = 110069313433624ULL; /* 105 MHz */ + break; case RayDAT: case AIO: - n = 104857600000000ULL; /* 100 MHz */ - break; - default: - snd_BUG(); - return; + n = 104857600000000ULL; /* 100 MHz */ + break; } n = div_u64(n, rate); @@ -3439,91 +3415,6 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol, return change; } -#define HDSPM_MADI_SPEEDMODE(xname, xindex) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ - .name = xname, \ - .index = xindex, \ - .info = snd_hdspm_info_madi_speedmode, \ - .get = snd_hdspm_get_madi_speedmode, \ - .put = snd_hdspm_put_madi_speedmode \ -} - -static int hdspm_madi_speedmode(struct hdspm *hdspm) -{ - if (hdspm->control_register & HDSPM_QuadSpeed) - return 2; - if (hdspm->control_register & HDSPM_DoubleSpeed) - return 1; - return 0; -} - -static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode) -{ - hdspm->control_register &= ~(HDSPM_DoubleSpeed | HDSPM_QuadSpeed); - switch (mode) { - case 0: - break; - case 1: - hdspm->control_register |= HDSPM_DoubleSpeed; - break; - case 2: - hdspm->control_register |= HDSPM_QuadSpeed; - break; - } - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - - return 0; -} - -static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - static char *texts[] = { "Single", "Double", "Quad" }; - - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 3; - - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) - uinfo->value.enumerated.item = - uinfo->value.enumerated.items - 1; - strcpy(uinfo->value.enumerated.name, - texts[uinfo->value.enumerated.item]); - - return 0; -} - -static int snd_hdspm_get_madi_speedmode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - - spin_lock_irq(&hdspm->lock); - ucontrol->value.enumerated.item[0] = hdspm_madi_speedmode(hdspm); - spin_unlock_irq(&hdspm->lock); - return 0; -} - -static int snd_hdspm_put_madi_speedmode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); - int change; - int val; - - if (!snd_hdspm_use_is_exclusive(hdspm)) - return -EBUSY; - val = ucontrol->value.integer.value[0]; - if (val < 0) - val = 0; - if (val > 2) - val = 2; - spin_lock_irq(&hdspm->lock); - change = val != hdspm_madi_speedmode(hdspm); - hdspm_set_madi_speedmode(hdspm, val); - spin_unlock_irq(&hdspm->lock); - return change; -} #define HDSPM_MIXER(xname, xindex) \ { .iface = SNDRV_CTL_ELEM_IFACE_HWDEP, \ @@ -4398,8 +4289,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_madi[] = { HDSPM_TX_64("TX 64 channels mode", 0), HDSPM_C_TMS("Clear Track Marker", 0), HDSPM_SAFE_MODE("Safe Mode", 0), - HDSPM_INPUT_SELECT("Input Select", 0), - HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0) + HDSPM_INPUT_SELECT("Input Select", 0) }; @@ -4412,8 +4302,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_madiface[] = { HDSPM_SYNC_CHECK("MADI SyncCheck", 0), HDSPM_TX_64("TX 64 channels mode", 0), HDSPM_C_TMS("Clear Track Marker", 0), - HDSPM_SAFE_MODE("Safe Mode", 0), - HDSPM_MADI_SPEEDMODE("MADI Speed Mode", 0) + HDSPM_SAFE_MODE("Safe Mode", 0) }; static struct snd_kcontrol_new snd_hdspm_controls_aio[] = { @@ -6492,7 +6381,6 @@ static int __devinit snd_hdspm_create(struct snd_card *card, switch (hdspm->firmware_rev) { case HDSPM_MADI_REV: case HDSPM_MADI_OLD_REV: - case HDSPM_MADI_ANCIENT_REV: hdspm->io_type = MADI; hdspm->card_name = "RME MADI"; hdspm->midiPorts = 3; diff --git a/trunk/sound/soc/codecs/Kconfig b/trunk/sound/soc/codecs/Kconfig index 665d9240c4ae..379b2e3afd98 100644 --- a/trunk/sound/soc/codecs/Kconfig +++ b/trunk/sound/soc/codecs/Kconfig @@ -78,6 +78,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8900 if I2C select SND_SOC_WM8903 if I2C select SND_SOC_WM8904 if I2C + select SND_SOC_WM8915 if I2C select SND_SOC_WM8940 if I2C select SND_SOC_WM8955 if I2C select SND_SOC_WM8960 if I2C @@ -94,7 +95,6 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8993 if I2C select SND_SOC_WM8994 if MFD_WM8994 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI - select SND_SOC_WM8996 if I2C select SND_SOC_WM9081 if I2C select SND_SOC_WM9090 if I2C select SND_SOC_WM9705 if SND_SOC_AC97_BUS @@ -329,6 +329,9 @@ config SND_SOC_WM8903 config SND_SOC_WM8904 tristate +config SND_SOC_WM8915 + tristate + config SND_SOC_WM8940 tristate @@ -377,9 +380,6 @@ config SND_SOC_WM8994 config SND_SOC_WM8995 tristate -config SND_SOC_WM8996 - tristate - config SND_SOC_WM9081 tristate diff --git a/trunk/sound/soc/codecs/Makefile b/trunk/sound/soc/codecs/Makefile index 5119a7e2c1a8..da9990fb8569 100644 --- a/trunk/sound/soc/codecs/Makefile +++ b/trunk/sound/soc/codecs/Makefile @@ -63,7 +63,7 @@ snd-soc-wm8804-objs := wm8804.o snd-soc-wm8900-objs := wm8900.o snd-soc-wm8903-objs := wm8903.o snd-soc-wm8904-objs := wm8904.o -snd-soc-wm8996-objs := wm8996.o +snd-soc-wm8915-objs := wm8915.o snd-soc-wm8940-objs := wm8940.o snd-soc-wm8955-objs := wm8955.o snd-soc-wm8960-objs := wm8960.o @@ -160,7 +160,7 @@ obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o obj-$(CONFIG_SND_SOC_WM8903) += snd-soc-wm8903.o obj-$(CONFIG_SND_SOC_WM8904) += snd-soc-wm8904.o -obj-$(CONFIG_SND_SOC_WM8996) += snd-soc-wm8996.o +obj-$(CONFIG_SND_SOC_WM8915) += snd-soc-wm8915.o obj-$(CONFIG_SND_SOC_WM8940) += snd-soc-wm8940.o obj-$(CONFIG_SND_SOC_WM8955) += snd-soc-wm8955.o obj-$(CONFIG_SND_SOC_WM8960) += snd-soc-wm8960.o diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index 7e4066e131e6..76258f2a2ffb 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -33,31 +33,73 @@ #define SGTL5000_DAP_REG_OFFSET 0x0100 #define SGTL5000_MAX_REG_OFFSET 0x013A -/* default value of sgtl5000 registers */ -static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET] = { - [SGTL5000_CHIP_CLK_CTRL] = 0x0008, - [SGTL5000_CHIP_I2S_CTRL] = 0x0010, - [SGTL5000_CHIP_SSS_CTRL] = 0x0008, - [SGTL5000_CHIP_DAC_VOL] = 0x3c3c, - [SGTL5000_CHIP_PAD_STRENGTH] = 0x015f, - [SGTL5000_CHIP_ANA_HP_CTRL] = 0x1818, - [SGTL5000_CHIP_ANA_CTRL] = 0x0111, - [SGTL5000_CHIP_LINE_OUT_VOL] = 0x0404, - [SGTL5000_CHIP_ANA_POWER] = 0x7060, - [SGTL5000_CHIP_PLL_CTRL] = 0x5000, - [SGTL5000_DAP_BASS_ENHANCE] = 0x0040, - [SGTL5000_DAP_BASS_ENHANCE_CTRL] = 0x051f, - [SGTL5000_DAP_SURROUND] = 0x0040, - [SGTL5000_DAP_EQ_BASS_BAND0] = 0x002f, - [SGTL5000_DAP_EQ_BASS_BAND1] = 0x002f, - [SGTL5000_DAP_EQ_BASS_BAND2] = 0x002f, - [SGTL5000_DAP_EQ_BASS_BAND3] = 0x002f, - [SGTL5000_DAP_EQ_BASS_BAND4] = 0x002f, - [SGTL5000_DAP_MAIN_CHAN] = 0x8000, - [SGTL5000_DAP_AVC_CTRL] = 0x0510, - [SGTL5000_DAP_AVC_THRESHOLD] = 0x1473, - [SGTL5000_DAP_AVC_ATTACK] = 0x0028, - [SGTL5000_DAP_AVC_DECAY] = 0x0050, +/* default value of sgtl5000 registers except DAP */ +static const u16 sgtl5000_regs[SGTL5000_MAX_REG_OFFSET >> 1] = { + 0xa011, /* 0x0000, CHIP_ID. 11 stand for revison 17 */ + 0x0000, /* 0x0002, CHIP_DIG_POWER. */ + 0x0008, /* 0x0004, CHIP_CKL_CTRL */ + 0x0010, /* 0x0006, CHIP_I2S_CTRL */ + 0x0000, /* 0x0008, reserved */ + 0x0008, /* 0x000A, CHIP_SSS_CTRL */ + 0x0000, /* 0x000C, reserved */ + 0x020c, /* 0x000E, CHIP_ADCDAC_CTRL */ + 0x3c3c, /* 0x0010, CHIP_DAC_VOL */ + 0x0000, /* 0x0012, reserved */ + 0x015f, /* 0x0014, CHIP_PAD_STRENGTH */ + 0x0000, /* 0x0016, reserved */ + 0x0000, /* 0x0018, reserved */ + 0x0000, /* 0x001A, reserved */ + 0x0000, /* 0x001E, reserved */ + 0x0000, /* 0x0020, CHIP_ANA_ADC_CTRL */ + 0x1818, /* 0x0022, CHIP_ANA_HP_CTRL */ + 0x0111, /* 0x0024, CHIP_ANN_CTRL */ + 0x0000, /* 0x0026, CHIP_LINREG_CTRL */ + 0x0000, /* 0x0028, CHIP_REF_CTRL */ + 0x0000, /* 0x002A, CHIP_MIC_CTRL */ + 0x0000, /* 0x002C, CHIP_LINE_OUT_CTRL */ + 0x0404, /* 0x002E, CHIP_LINE_OUT_VOL */ + 0x7060, /* 0x0030, CHIP_ANA_POWER */ + 0x5000, /* 0x0032, CHIP_PLL_CTRL */ + 0x0000, /* 0x0034, CHIP_CLK_TOP_CTRL */ + 0x0000, /* 0x0036, CHIP_ANA_STATUS */ + 0x0000, /* 0x0038, reserved */ + 0x0000, /* 0x003A, CHIP_ANA_TEST2 */ + 0x0000, /* 0x003C, CHIP_SHORT_CTRL */ + 0x0000, /* reserved */ +}; + +/* default value of dap registers */ +static const u16 sgtl5000_dap_regs[] = { + 0x0000, /* 0x0100, DAP_CONTROL */ + 0x0000, /* 0x0102, DAP_PEQ */ + 0x0040, /* 0x0104, DAP_BASS_ENHANCE */ + 0x051f, /* 0x0106, DAP_BASS_ENHANCE_CTRL */ + 0x0000, /* 0x0108, DAP_AUDIO_EQ */ + 0x0040, /* 0x010A, DAP_SGTL_SURROUND */ + 0x0000, /* 0x010C, DAP_FILTER_COEF_ACCESS */ + 0x0000, /* 0x010E, DAP_COEF_WR_B0_MSB */ + 0x0000, /* 0x0110, DAP_COEF_WR_B0_LSB */ + 0x0000, /* 0x0112, reserved */ + 0x0000, /* 0x0114, reserved */ + 0x002f, /* 0x0116, DAP_AUDIO_EQ_BASS_BAND0 */ + 0x002f, /* 0x0118, DAP_AUDIO_EQ_BAND0 */ + 0x002f, /* 0x011A, DAP_AUDIO_EQ_BAND2 */ + 0x002f, /* 0x011C, DAP_AUDIO_EQ_BAND3 */ + 0x002f, /* 0x011E, DAP_AUDIO_EQ_TREBLE_BAND4 */ + 0x8000, /* 0x0120, DAP_MAIN_CHAN */ + 0x0000, /* 0x0122, DAP_MIX_CHAN */ + 0x0510, /* 0x0124, DAP_AVC_CTRL */ + 0x1473, /* 0x0126, DAP_AVC_THRESHOLD */ + 0x0028, /* 0x0128, DAP_AVC_ATTACK */ + 0x0050, /* 0x012A, DAP_AVC_DECAY */ + 0x0000, /* 0x012C, DAP_COEF_WR_B1_MSB */ + 0x0000, /* 0x012E, DAP_COEF_WR_B1_LSB */ + 0x0000, /* 0x0130, DAP_COEF_WR_B2_MSB */ + 0x0000, /* 0x0132, DAP_COEF_WR_B2_LSB */ + 0x0000, /* 0x0134, DAP_COEF_WR_A1_MSB */ + 0x0000, /* 0x0136, DAP_COEF_WR_A1_LSB */ + 0x0000, /* 0x0138, DAP_COEF_WR_A2_MSB */ + 0x0000, /* 0x013A, DAP_COEF_WR_A2_LSB */ }; /* regulator supplies for sgtl5000, VDDD is an optional external supply */ @@ -981,10 +1023,12 @@ static int sgtl5000_suspend(struct snd_soc_codec *codec, pm_message_t state) static int sgtl5000_restore_regs(struct snd_soc_codec *codec) { u16 *cache = codec->reg_cache; - u16 reg; + int i; + int regular_regs = SGTL5000_CHIP_SHORT_CTRL >> 1; /* restore regular registers */ - for (reg = 0; reg <= SGTL5000_CHIP_SHORT_CTRL; reg += 2) { + for (i = 0; i < regular_regs; i++) { + int reg = i << 1; /* this regs depends on the others */ if (reg == SGTL5000_CHIP_ANA_POWER || @@ -994,31 +1038,35 @@ static int sgtl5000_restore_regs(struct snd_soc_codec *codec) reg == SGTL5000_CHIP_CLK_CTRL) continue; - snd_soc_write(codec, reg, cache[reg]); + snd_soc_write(codec, reg, cache[i]); } /* restore dap registers */ - for (reg = SGTL5000_DAP_REG_OFFSET; reg < SGTL5000_MAX_REG_OFFSET; reg += 2) - snd_soc_write(codec, reg, cache[reg]); + for (i = SGTL5000_DAP_REG_OFFSET >> 1; + i < SGTL5000_MAX_REG_OFFSET >> 1; i++) { + int reg = i << 1; + + snd_soc_write(codec, reg, cache[i]); + } /* * restore power and other regs according * to set_power() and set_clock() */ snd_soc_write(codec, SGTL5000_CHIP_LINREG_CTRL, - cache[SGTL5000_CHIP_LINREG_CTRL]); + cache[SGTL5000_CHIP_LINREG_CTRL >> 1]); snd_soc_write(codec, SGTL5000_CHIP_ANA_POWER, - cache[SGTL5000_CHIP_ANA_POWER]); + cache[SGTL5000_CHIP_ANA_POWER >> 1]); snd_soc_write(codec, SGTL5000_CHIP_CLK_CTRL, - cache[SGTL5000_CHIP_CLK_CTRL]); + cache[SGTL5000_CHIP_CLK_CTRL >> 1]); snd_soc_write(codec, SGTL5000_CHIP_REF_CTRL, - cache[SGTL5000_CHIP_REF_CTRL]); + cache[SGTL5000_CHIP_REF_CTRL >> 1]); snd_soc_write(codec, SGTL5000_CHIP_LINE_OUT_CTRL, - cache[SGTL5000_CHIP_LINE_OUT_CTRL]); + cache[SGTL5000_CHIP_LINE_OUT_CTRL >> 1]); return 0; } @@ -1406,6 +1454,16 @@ static __devinit int sgtl5000_i2c_probe(struct i2c_client *client, if (!sgtl5000) return -ENOMEM; + /* + * copy DAP default values to default value array. + * sgtl5000 register space has a big hole, merge it + * at init phase makes life easy. + * FIXME: should we drop 'const' of sgtl5000_regs? + */ + memcpy((void *)(&sgtl5000_regs[0] + (SGTL5000_DAP_REG_OFFSET >> 1)), + sgtl5000_dap_regs, + SGTL5000_MAX_REG_OFFSET - SGTL5000_DAP_REG_OFFSET); + i2c_set_clientdata(client, sgtl5000); ret = snd_soc_register_codec(&client->dev, diff --git a/trunk/sound/soc/codecs/wm8915.c b/trunk/sound/soc/codecs/wm8915.c new file mode 100644 index 000000000000..423baa9be241 --- /dev/null +++ b/trunk/sound/soc/codecs/wm8915.c @@ -0,0 +1,2995 @@ +/* + * wm8915.c - WM8915 audio codec interface + * + * Copyright 2011 Wolfson Microelectronics PLC. + * Author: Mark Brown + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "wm8915.h" + +#define WM8915_AIFS 2 + +#define HPOUT1L 1 +#define HPOUT1R 2 +#define HPOUT2L 4 +#define HPOUT2R 8 + +#define WM8915_NUM_SUPPLIES 4 +static const char *wm8915_supply_names[WM8915_NUM_SUPPLIES] = { + "DBVDD", + "AVDD1", + "AVDD2", + "CPVDD", +}; + +struct wm8915_priv { + struct snd_soc_codec *codec; + + int ldo1ena; + + int sysclk; + int sysclk_src; + + int fll_src; + int fll_fref; + int fll_fout; + + struct completion fll_lock; + + u16 dcs_pending; + struct completion dcs_done; + + u16 hpout_ena; + u16 hpout_pending; + + struct regulator_bulk_data supplies[WM8915_NUM_SUPPLIES]; + struct notifier_block disable_nb[WM8915_NUM_SUPPLIES]; + + struct wm8915_pdata pdata; + + int rx_rate[WM8915_AIFS]; + int bclk_rate[WM8915_AIFS]; + + /* Platform dependant ReTune mobile configuration */ + int num_retune_mobile_texts; + const char **retune_mobile_texts; + int retune_mobile_cfg[2]; + struct soc_enum retune_mobile_enum; + + struct snd_soc_jack *jack; + bool detecting; + bool jack_mic; + wm8915_polarity_fn polarity_cb; + +#ifdef CONFIG_GPIOLIB + struct gpio_chip gpio_chip; +#endif +}; + +/* We can't use the same notifier block for more than one supply and + * there's no way I can see to get from a callback to the caller + * except container_of(). + */ +#define WM8915_REGULATOR_EVENT(n) \ +static int wm8915_regulator_event_##n(struct notifier_block *nb, \ + unsigned long event, void *data) \ +{ \ + struct wm8915_priv *wm8915 = container_of(nb, struct wm8915_priv, \ + disable_nb[n]); \ + if (event & REGULATOR_EVENT_DISABLE) { \ + wm8915->codec->cache_sync = 1; \ + } \ + return 0; \ +} + +WM8915_REGULATOR_EVENT(0) +WM8915_REGULATOR_EVENT(1) +WM8915_REGULATOR_EVENT(2) +WM8915_REGULATOR_EVENT(3) + +static const u16 wm8915_reg[WM8915_MAX_REGISTER] = { + [WM8915_SOFTWARE_RESET] = 0x8915, + [WM8915_POWER_MANAGEMENT_7] = 0x10, + [WM8915_DAC1_HPOUT1_VOLUME] = 0x88, + [WM8915_DAC2_HPOUT2_VOLUME] = 0x88, + [WM8915_DAC1_LEFT_VOLUME] = 0x2c0, + [WM8915_DAC1_RIGHT_VOLUME] = 0x2c0, + [WM8915_DAC2_LEFT_VOLUME] = 0x2c0, + [WM8915_DAC2_RIGHT_VOLUME] = 0x2c0, + [WM8915_OUTPUT1_LEFT_VOLUME] = 0x80, + [WM8915_OUTPUT1_RIGHT_VOLUME] = 0x80, + [WM8915_OUTPUT2_LEFT_VOLUME] = 0x80, + [WM8915_OUTPUT2_RIGHT_VOLUME] = 0x80, + [WM8915_MICBIAS_1] = 0x39, + [WM8915_MICBIAS_2] = 0x39, + [WM8915_LDO_1] = 0x3, + [WM8915_LDO_2] = 0x13, + [WM8915_ACCESSORY_DETECT_MODE_1] = 0x4, + [WM8915_HEADPHONE_DETECT_1] = 0x20, + [WM8915_MIC_DETECT_1] = 0x7600, + [WM8915_MIC_DETECT_2] = 0xbf, + [WM8915_CHARGE_PUMP_1] = 0x1f25, + [WM8915_CHARGE_PUMP_2] = 0xab19, + [WM8915_DC_SERVO_5] = 0x2a2a, + [WM8915_CONTROL_INTERFACE_1] = 0x8004, + [WM8915_CLOCKING_1] = 0x10, + [WM8915_AIF_RATE] = 0x83, + [WM8915_FLL_CONTROL_4] = 0x5dc0, + [WM8915_FLL_CONTROL_5] = 0xc84, + [WM8915_FLL_EFS_2] = 0x2, + [WM8915_AIF1_TX_LRCLK_1] = 0x80, + [WM8915_AIF1_TX_LRCLK_2] = 0x8, + [WM8915_AIF1_RX_LRCLK_1] = 0x80, + [WM8915_AIF1TX_DATA_CONFIGURATION_1] = 0x1818, + [WM8915_AIF1RX_DATA_CONFIGURATION] = 0x1818, + [WM8915_AIF1TX_TEST] = 0x7, + [WM8915_AIF2_TX_LRCLK_1] = 0x80, + [WM8915_AIF2_TX_LRCLK_2] = 0x8, + [WM8915_AIF2_RX_LRCLK_1] = 0x80, + [WM8915_AIF2TX_DATA_CONFIGURATION_1] = 0x1818, + [WM8915_AIF2RX_DATA_CONFIGURATION] = 0x1818, + [WM8915_AIF2TX_TEST] = 0x1, + [WM8915_DSP1_TX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP1_TX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP1_RX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP1_RX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP1_TX_FILTERS] = 0x2000, + [WM8915_DSP1_RX_FILTERS_1] = 0x200, + [WM8915_DSP1_RX_FILTERS_2] = 0x10, + [WM8915_DSP1_DRC_1] = 0x98, + [WM8915_DSP1_DRC_2] = 0x845, + [WM8915_DSP1_RX_EQ_GAINS_1] = 0x6318, + [WM8915_DSP1_RX_EQ_GAINS_2] = 0x6300, + [WM8915_DSP1_RX_EQ_BAND_1_A] = 0xfca, + [WM8915_DSP1_RX_EQ_BAND_1_B] = 0x400, + [WM8915_DSP1_RX_EQ_BAND_1_PG] = 0xd8, + [WM8915_DSP1_RX_EQ_BAND_2_A] = 0x1eb5, + [WM8915_DSP1_RX_EQ_BAND_2_B] = 0xf145, + [WM8915_DSP1_RX_EQ_BAND_2_C] = 0xb75, + [WM8915_DSP1_RX_EQ_BAND_2_PG] = 0x1c5, + [WM8915_DSP1_RX_EQ_BAND_3_A] = 0x1c58, + [WM8915_DSP1_RX_EQ_BAND_3_B] = 0xf373, + [WM8915_DSP1_RX_EQ_BAND_3_C] = 0xa54, + [WM8915_DSP1_RX_EQ_BAND_3_PG] = 0x558, + [WM8915_DSP1_RX_EQ_BAND_4_A] = 0x168e, + [WM8915_DSP1_RX_EQ_BAND_4_B] = 0xf829, + [WM8915_DSP1_RX_EQ_BAND_4_C] = 0x7ad, + [WM8915_DSP1_RX_EQ_BAND_4_PG] = 0x1103, + [WM8915_DSP1_RX_EQ_BAND_5_A] = 0x564, + [WM8915_DSP1_RX_EQ_BAND_5_B] = 0x559, + [WM8915_DSP1_RX_EQ_BAND_5_PG] = 0x4000, + [WM8915_DSP2_TX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP2_TX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP2_RX_LEFT_VOLUME] = 0xc0, + [WM8915_DSP2_RX_RIGHT_VOLUME] = 0xc0, + [WM8915_DSP2_TX_FILTERS] = 0x2000, + [WM8915_DSP2_RX_FILTERS_1] = 0x200, + [WM8915_DSP2_RX_FILTERS_2] = 0x10, + [WM8915_DSP2_DRC_1] = 0x98, + [WM8915_DSP2_DRC_2] = 0x845, + [WM8915_DSP2_RX_EQ_GAINS_1] = 0x6318, + [WM8915_DSP2_RX_EQ_GAINS_2] = 0x6300, + [WM8915_DSP2_RX_EQ_BAND_1_A] = 0xfca, + [WM8915_DSP2_RX_EQ_BAND_1_B] = 0x400, + [WM8915_DSP2_RX_EQ_BAND_1_PG] = 0xd8, + [WM8915_DSP2_RX_EQ_BAND_2_A] = 0x1eb5, + [WM8915_DSP2_RX_EQ_BAND_2_B] = 0xf145, + [WM8915_DSP2_RX_EQ_BAND_2_C] = 0xb75, + [WM8915_DSP2_RX_EQ_BAND_2_PG] = 0x1c5, + [WM8915_DSP2_RX_EQ_BAND_3_A] = 0x1c58, + [WM8915_DSP2_RX_EQ_BAND_3_B] = 0xf373, + [WM8915_DSP2_RX_EQ_BAND_3_C] = 0xa54, + [WM8915_DSP2_RX_EQ_BAND_3_PG] = 0x558, + [WM8915_DSP2_RX_EQ_BAND_4_A] = 0x168e, + [WM8915_DSP2_RX_EQ_BAND_4_B] = 0xf829, + [WM8915_DSP2_RX_EQ_BAND_4_C] = 0x7ad, + [WM8915_DSP2_RX_EQ_BAND_4_PG] = 0x1103, + [WM8915_DSP2_RX_EQ_BAND_5_A] = 0x564, + [WM8915_DSP2_RX_EQ_BAND_5_B] = 0x559, + [WM8915_DSP2_RX_EQ_BAND_5_PG] = 0x4000, + [WM8915_OVERSAMPLING] = 0xd, + [WM8915_SIDETONE] = 0x1040, + [WM8915_GPIO_1] = 0xa101, + [WM8915_GPIO_2] = 0xa101, + [WM8915_GPIO_3] = 0xa101, + [WM8915_GPIO_4] = 0xa101, + [WM8915_GPIO_5] = 0xa101, + [WM8915_PULL_CONTROL_2] = 0x140, + [WM8915_INTERRUPT_STATUS_1_MASK] = 0x1f, + [WM8915_INTERRUPT_STATUS_2_MASK] = 0x1ecf, + [WM8915_RIGHT_PDM_SPEAKER] = 0x1, + [WM8915_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69, + [WM8915_PDM_SPEAKER_VOLUME] = 0x66, + [WM8915_WRITE_SEQUENCER_0] = 0x1, + [WM8915_WRITE_SEQUENCER_1] = 0x1, + [WM8915_WRITE_SEQUENCER_3] = 0x6, + [WM8915_WRITE_SEQUENCER_4] = 0x40, + [WM8915_WRITE_SEQUENCER_5] = 0x1, + [WM8915_WRITE_SEQUENCER_6] = 0xf, + [WM8915_WRITE_SEQUENCER_7] = 0x6, + [WM8915_WRITE_SEQUENCER_8] = 0x1, + [WM8915_WRITE_SEQUENCER_9] = 0x3, + [WM8915_WRITE_SEQUENCER_10] = 0x104, + [WM8915_WRITE_SEQUENCER_12] = 0x60, + [WM8915_WRITE_SEQUENCER_13] = 0x11, + [WM8915_WRITE_SEQUENCER_14] = 0x401, + [WM8915_WRITE_SEQUENCER_16] = 0x50, + [WM8915_WRITE_SEQUENCER_17] = 0x3, + [WM8915_WRITE_SEQUENCER_18] = 0x100, + [WM8915_WRITE_SEQUENCER_20] = 0x51, + [WM8915_WRITE_SEQUENCER_21] = 0x3, + [WM8915_WRITE_SEQUENCER_22] = 0x104, + [WM8915_WRITE_SEQUENCER_23] = 0xa, + [WM8915_WRITE_SEQUENCER_24] = 0x60, + [WM8915_WRITE_SEQUENCER_25] = 0x3b, + [WM8915_WRITE_SEQUENCER_26] = 0x502, + [WM8915_WRITE_SEQUENCER_27] = 0x100, + [WM8915_WRITE_SEQUENCER_28] = 0x2fff, + [WM8915_WRITE_SEQUENCER_32] = 0x2fff, + [WM8915_WRITE_SEQUENCER_36] = 0x2fff, + [WM8915_WRITE_SEQUENCER_40] = 0x2fff, + [WM8915_WRITE_SEQUENCER_44] = 0x2fff, + [WM8915_WRITE_SEQUENCER_48] = 0x2fff, + [WM8915_WRITE_SEQUENCER_52] = 0x2fff, + [WM8915_WRITE_SEQUENCER_56] = 0x2fff, + [WM8915_WRITE_SEQUENCER_60] = 0x2fff, + [WM8915_WRITE_SEQUENCER_64] = 0x1, + [WM8915_WRITE_SEQUENCER_65] = 0x1, + [WM8915_WRITE_SEQUENCER_67] = 0x6, + [WM8915_WRITE_SEQUENCER_68] = 0x40, + [WM8915_WRITE_SEQUENCER_69] = 0x1, + [WM8915_WRITE_SEQUENCER_70] = 0xf, + [WM8915_WRITE_SEQUENCER_71] = 0x6, + [WM8915_WRITE_SEQUENCER_72] = 0x1, + [WM8915_WRITE_SEQUENCER_73] = 0x3, + [WM8915_WRITE_SEQUENCER_74] = 0x104, + [WM8915_WRITE_SEQUENCER_76] = 0x60, + [WM8915_WRITE_SEQUENCER_77] = 0x11, + [WM8915_WRITE_SEQUENCER_78] = 0x401, + [WM8915_WRITE_SEQUENCER_80] = 0x50, + [WM8915_WRITE_SEQUENCER_81] = 0x3, + [WM8915_WRITE_SEQUENCER_82] = 0x100, + [WM8915_WRITE_SEQUENCER_84] = 0x60, + [WM8915_WRITE_SEQUENCER_85] = 0x3b, + [WM8915_WRITE_SEQUENCER_86] = 0x502, + [WM8915_WRITE_SEQUENCER_87] = 0x100, + [WM8915_WRITE_SEQUENCER_88] = 0x2fff, + [WM8915_WRITE_SEQUENCER_92] = 0x2fff, + [WM8915_WRITE_SEQUENCER_96] = 0x2fff, + [WM8915_WRITE_SEQUENCER_100] = 0x2fff, + [WM8915_WRITE_SEQUENCER_104] = 0x2fff, + [WM8915_WRITE_SEQUENCER_108] = 0x2fff, + [WM8915_WRITE_SEQUENCER_112] = 0x2fff, + [WM8915_WRITE_SEQUENCER_116] = 0x2fff, + [WM8915_WRITE_SEQUENCER_120] = 0x2fff, + [WM8915_WRITE_SEQUENCER_124] = 0x2fff, + [WM8915_WRITE_SEQUENCER_128] = 0x1, + [WM8915_WRITE_SEQUENCER_129] = 0x1, + [WM8915_WRITE_SEQUENCER_131] = 0x6, + [WM8915_WRITE_SEQUENCER_132] = 0x40, + [WM8915_WRITE_SEQUENCER_133] = 0x1, + [WM8915_WRITE_SEQUENCER_134] = 0xf, + [WM8915_WRITE_SEQUENCER_135] = 0x6, + [WM8915_WRITE_SEQUENCER_136] = 0x1, + [WM8915_WRITE_SEQUENCER_137] = 0x3, + [WM8915_WRITE_SEQUENCER_138] = 0x106, + [WM8915_WRITE_SEQUENCER_140] = 0x61, + [WM8915_WRITE_SEQUENCER_141] = 0x11, + [WM8915_WRITE_SEQUENCER_142] = 0x401, + [WM8915_WRITE_SEQUENCER_144] = 0x50, + [WM8915_WRITE_SEQUENCER_145] = 0x3, + [WM8915_WRITE_SEQUENCER_146] = 0x102, + [WM8915_WRITE_SEQUENCER_148] = 0x51, + [WM8915_WRITE_SEQUENCER_149] = 0x3, + [WM8915_WRITE_SEQUENCER_150] = 0x106, + [WM8915_WRITE_SEQUENCER_151] = 0xa, + [WM8915_WRITE_SEQUENCER_152] = 0x61, + [WM8915_WRITE_SEQUENCER_153] = 0x3b, + [WM8915_WRITE_SEQUENCER_154] = 0x502, + [WM8915_WRITE_SEQUENCER_155] = 0x100, + [WM8915_WRITE_SEQUENCER_156] = 0x2fff, + [WM8915_WRITE_SEQUENCER_160] = 0x2fff, + [WM8915_WRITE_SEQUENCER_164] = 0x2fff, + [WM8915_WRITE_SEQUENCER_168] = 0x2fff, + [WM8915_WRITE_SEQUENCER_172] = 0x2fff, + [WM8915_WRITE_SEQUENCER_176] = 0x2fff, + [WM8915_WRITE_SEQUENCER_180] = 0x2fff, + [WM8915_WRITE_SEQUENCER_184] = 0x2fff, + [WM8915_WRITE_SEQUENCER_188] = 0x2fff, + [WM8915_WRITE_SEQUENCER_192] = 0x1, + [WM8915_WRITE_SEQUENCER_193] = 0x1, + [WM8915_WRITE_SEQUENCER_195] = 0x6, + [WM8915_WRITE_SEQUENCER_196] = 0x40, + [WM8915_WRITE_SEQUENCER_197] = 0x1, + [WM8915_WRITE_SEQUENCER_198] = 0xf, + [WM8915_WRITE_SEQUENCER_199] = 0x6, + [WM8915_WRITE_SEQUENCER_200] = 0x1, + [WM8915_WRITE_SEQUENCER_201] = 0x3, + [WM8915_WRITE_SEQUENCER_202] = 0x106, + [WM8915_WRITE_SEQUENCER_204] = 0x61, + [WM8915_WRITE_SEQUENCER_205] = 0x11, + [WM8915_WRITE_SEQUENCER_206] = 0x401, + [WM8915_WRITE_SEQUENCER_208] = 0x50, + [WM8915_WRITE_SEQUENCER_209] = 0x3, + [WM8915_WRITE_SEQUENCER_210] = 0x102, + [WM8915_WRITE_SEQUENCER_212] = 0x61, + [WM8915_WRITE_SEQUENCER_213] = 0x3b, + [WM8915_WRITE_SEQUENCER_214] = 0x502, + [WM8915_WRITE_SEQUENCER_215] = 0x100, + [WM8915_WRITE_SEQUENCER_216] = 0x2fff, + [WM8915_WRITE_SEQUENCER_220] = 0x2fff, + [WM8915_WRITE_SEQUENCER_224] = 0x2fff, + [WM8915_WRITE_SEQUENCER_228] = 0x2fff, + [WM8915_WRITE_SEQUENCER_232] = 0x2fff, + [WM8915_WRITE_SEQUENCER_236] = 0x2fff, + [WM8915_WRITE_SEQUENCER_240] = 0x2fff, + [WM8915_WRITE_SEQUENCER_244] = 0x2fff, + [WM8915_WRITE_SEQUENCER_248] = 0x2fff, + [WM8915_WRITE_SEQUENCER_252] = 0x2fff, + [WM8915_WRITE_SEQUENCER_256] = 0x60, + [WM8915_WRITE_SEQUENCER_258] = 0x601, + [WM8915_WRITE_SEQUENCER_260] = 0x50, + [WM8915_WRITE_SEQUENCER_262] = 0x100, + [WM8915_WRITE_SEQUENCER_264] = 0x1, + [WM8915_WRITE_SEQUENCER_266] = 0x104, + [WM8915_WRITE_SEQUENCER_267] = 0x100, + [WM8915_WRITE_SEQUENCER_268] = 0x2fff, + [WM8915_WRITE_SEQUENCER_272] = 0x2fff, + [WM8915_WRITE_SEQUENCER_276] = 0x2fff, + [WM8915_WRITE_SEQUENCER_280] = 0x2fff, + [WM8915_WRITE_SEQUENCER_284] = 0x2fff, + [WM8915_WRITE_SEQUENCER_288] = 0x2fff, + [WM8915_WRITE_SEQUENCER_292] = 0x2fff, + [WM8915_WRITE_SEQUENCER_296] = 0x2fff, + [WM8915_WRITE_SEQUENCER_300] = 0x2fff, + [WM8915_WRITE_SEQUENCER_304] = 0x2fff, + [WM8915_WRITE_SEQUENCER_308] = 0x2fff, + [WM8915_WRITE_SEQUENCER_312] = 0x2fff, + [WM8915_WRITE_SEQUENCER_316] = 0x2fff, + [WM8915_WRITE_SEQUENCER_320] = 0x61, + [WM8915_WRITE_SEQUENCER_322] = 0x601, + [WM8915_WRITE_SEQUENCER_324] = 0x50, + [WM8915_WRITE_SEQUENCER_326] = 0x102, + [WM8915_WRITE_SEQUENCER_328] = 0x1, + [WM8915_WRITE_SEQUENCER_330] = 0x106, + [WM8915_WRITE_SEQUENCER_331] = 0x100, + [WM8915_WRITE_SEQUENCER_332] = 0x2fff, + [WM8915_WRITE_SEQUENCER_336] = 0x2fff, + [WM8915_WRITE_SEQUENCER_340] = 0x2fff, + [WM8915_WRITE_SEQUENCER_344] = 0x2fff, + [WM8915_WRITE_SEQUENCER_348] = 0x2fff, + [WM8915_WRITE_SEQUENCER_352] = 0x2fff, + [WM8915_WRITE_SEQUENCER_356] = 0x2fff, + [WM8915_WRITE_SEQUENCER_360] = 0x2fff, + [WM8915_WRITE_SEQUENCER_364] = 0x2fff, + [WM8915_WRITE_SEQUENCER_368] = 0x2fff, + [WM8915_WRITE_SEQUENCER_372] = 0x2fff, + [WM8915_WRITE_SEQUENCER_376] = 0x2fff, + [WM8915_WRITE_SEQUENCER_380] = 0x2fff, + [WM8915_WRITE_SEQUENCER_384] = 0x60, + [WM8915_WRITE_SEQUENCER_386] = 0x601, + [WM8915_WRITE_SEQUENCER_388] = 0x61, + [WM8915_WRITE_SEQUENCER_390] = 0x601, + [WM8915_WRITE_SEQUENCER_392] = 0x50, + [WM8915_WRITE_SEQUENCER_394] = 0x300, + [WM8915_WRITE_SEQUENCER_396] = 0x1, + [WM8915_WRITE_SEQUENCER_398] = 0x304, + [WM8915_WRITE_SEQUENCER_400] = 0x40, + [WM8915_WRITE_SEQUENCER_402] = 0xf, + [WM8915_WRITE_SEQUENCER_404] = 0x1, + [WM8915_WRITE_SEQUENCER_407] = 0x100, +}; + +static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); +static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0); +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0); +static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); +static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); +static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); + +static const char *sidetone_hpf_text[] = { + "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" +}; + +static const struct soc_enum sidetone_hpf = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 7, 6, sidetone_hpf_text); + +static const char *hpf_mode_text[] = { + "HiFi", "Custom", "Voice" +}; + +static const struct soc_enum dsp1tx_hpf_mode = + SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 3, 3, hpf_mode_text); + +static const struct soc_enum dsp2tx_hpf_mode = + SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 3, 3, hpf_mode_text); + +static const char *hpf_cutoff_text[] = { + "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" +}; + +static const struct soc_enum dsp1tx_hpf_cutoff = + SOC_ENUM_SINGLE(WM8915_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text); + +static const struct soc_enum dsp2tx_hpf_cutoff = + SOC_ENUM_SINGLE(WM8915_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text); + +static void wm8915_set_retune_mobile(struct snd_soc_codec *codec, int block) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + int base, best, best_val, save, i, cfg, iface; + + if (!wm8915->num_retune_mobile_texts) + return; + + switch (block) { + case 0: + base = WM8915_DSP1_RX_EQ_GAINS_1; + if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) & + WM8915_DSP1RX_SRC) + iface = 1; + else + iface = 0; + break; + case 1: + base = WM8915_DSP1_RX_EQ_GAINS_2; + if (snd_soc_read(codec, WM8915_POWER_MANAGEMENT_8) & + WM8915_DSP2RX_SRC) + iface = 1; + else + iface = 0; + break; + default: + return; + } + + /* Find the version of the currently selected configuration + * with the nearest sample rate. */ + cfg = wm8915->retune_mobile_cfg[block]; + best = 0; + best_val = INT_MAX; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8915->retune_mobile_texts[cfg]) == 0 && + abs(pdata->retune_mobile_cfgs[i].rate + - wm8915->rx_rate[iface]) < best_val) { + best = i; + best_val = abs(pdata->retune_mobile_cfgs[i].rate + - wm8915->rx_rate[iface]); + } + } + + dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n", + block, + pdata->retune_mobile_cfgs[best].name, + pdata->retune_mobile_cfgs[best].rate, + wm8915->rx_rate[iface]); + + /* The EQ will be disabled while reconfiguring it, remember the + * current configuration. + */ + save = snd_soc_read(codec, base); + save &= WM8915_DSP1RX_EQ_ENA; + + for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++) + snd_soc_update_bits(codec, base + i, 0xffff, + pdata->retune_mobile_cfgs[best].regs[i]); + + snd_soc_update_bits(codec, base, WM8915_DSP1RX_EQ_ENA, save); +} + +/* Icky as hell but saves code duplication */ +static int wm8915_get_retune_mobile_block(const char *name) +{ + if (strcmp(name, "DSP1 EQ Mode") == 0) + return 0; + if (strcmp(name, "DSP2 EQ Mode") == 0) + return 1; + return -EINVAL; +} + +static int wm8915_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + int block = wm8915_get_retune_mobile_block(kcontrol->id.name); + int value = ucontrol->value.integer.value[0]; + + if (block < 0) + return block; + + if (value >= pdata->num_retune_mobile_cfgs) + return -EINVAL; + + wm8915->retune_mobile_cfg[block] = value; + + wm8915_set_retune_mobile(codec, block); + + return 0; +} + +static int wm8915_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int block = wm8915_get_retune_mobile_block(kcontrol->id.name); + + ucontrol->value.enumerated.item[0] = wm8915->retune_mobile_cfg[block]; + + return 0; +} + +static const struct snd_kcontrol_new wm8915_snd_controls[] = { +SOC_DOUBLE_R_TLV("Capture Volume", WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv), +SOC_DOUBLE_R("Capture ZC Switch", WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0), + +SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8915_DAC1_MIXER_VOLUMES, + 0, 5, 24, 0, sidetone_tlv), +SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8915_DAC2_MIXER_VOLUMES, + 0, 5, 24, 0, sidetone_tlv), +SOC_SINGLE("Sidetone LPF Switch", WM8915_SIDETONE, 12, 1, 0), +SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf), +SOC_SINGLE("Sidetone HPF Switch", WM8915_SIDETONE, 6, 1, 0), + +SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8915_DSP1_TX_LEFT_VOLUME, + WM8915_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), +SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8915_DSP2_TX_LEFT_VOLUME, + WM8915_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), + +SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8915_DSP1_TX_FILTERS, + 13, 1, 0), +SOC_DOUBLE("DSP1 Capture HPF Switch", WM8915_DSP1_TX_FILTERS, 12, 11, 1, 0), +SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode), +SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff), + +SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8915_DSP2_TX_FILTERS, + 13, 1, 0), +SOC_DOUBLE("DSP2 Capture HPF Switch", WM8915_DSP2_TX_FILTERS, 12, 11, 1, 0), +SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode), +SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff), + +SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8915_DSP1_RX_LEFT_VOLUME, + WM8915_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_SINGLE("DSP1 Playback Switch", WM8915_DSP1_RX_FILTERS_1, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8915_DSP2_RX_LEFT_VOLUME, + WM8915_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_SINGLE("DSP2 Playback Switch", WM8915_DSP2_RX_FILTERS_1, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DAC1 Volume", WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_DOUBLE_R("DAC1 Switch", WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_RIGHT_VOLUME, 9, 1, 1), + +SOC_DOUBLE_R_TLV("DAC2 Volume", WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv), +SOC_DOUBLE_R("DAC2 Switch", WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_RIGHT_VOLUME, 9, 1, 1), + +SOC_SINGLE("Speaker High Performance Switch", WM8915_OVERSAMPLING, 3, 1, 0), +SOC_SINGLE("DMIC High Performance Switch", WM8915_OVERSAMPLING, 2, 1, 0), +SOC_SINGLE("ADC High Performance Switch", WM8915_OVERSAMPLING, 1, 1, 0), +SOC_SINGLE("DAC High Performance Switch", WM8915_OVERSAMPLING, 0, 1, 0), + +SOC_SINGLE("DAC Soft Mute Switch", WM8915_DAC_SOFTMUTE, 1, 1, 0), +SOC_SINGLE("DAC Slow Soft Mute Switch", WM8915_DAC_SOFTMUTE, 0, 1, 0), + +SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8915_DAC1_HPOUT1_VOLUME, 0, 4, + 8, 0, out_digital_tlv), +SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8915_DAC2_HPOUT2_VOLUME, 0, 4, + 8, 0, out_digital_tlv), + +SOC_DOUBLE_R_TLV("Output 1 Volume", WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv), +SOC_DOUBLE_R("Output 1 ZC Switch", WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_OUTPUT1_RIGHT_VOLUME, 7, 1, 0), + +SOC_DOUBLE_R_TLV("Output 2 Volume", WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv), +SOC_DOUBLE_R("Output 2 ZC Switch", WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_OUTPUT2_RIGHT_VOLUME, 7, 1, 0), + +SOC_DOUBLE_TLV("Speaker Volume", WM8915_PDM_SPEAKER_VOLUME, 0, 4, 8, 0, + spk_tlv), +SOC_DOUBLE_R("Speaker Switch", WM8915_LEFT_PDM_SPEAKER, + WM8915_RIGHT_PDM_SPEAKER, 3, 1, 1), +SOC_DOUBLE_R("Speaker ZC Switch", WM8915_LEFT_PDM_SPEAKER, + WM8915_RIGHT_PDM_SPEAKER, 2, 1, 0), + +SOC_SINGLE("DSP1 EQ Switch", WM8915_DSP1_RX_EQ_GAINS_1, 0, 1, 0), +SOC_SINGLE("DSP2 EQ Switch", WM8915_DSP2_RX_EQ_GAINS_1, 0, 1, 0), +}; + +static const struct snd_kcontrol_new wm8915_eq_controls[] = { +SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8915_DSP1_RX_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8915_DSP1_RX_EQ_GAINS_2, 6, 31, 0, + eq_tlv), + +SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 6, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8915_DSP2_RX_EQ_GAINS_1, 1, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 11, 31, 0, + eq_tlv), +SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8915_DSP2_RX_EQ_GAINS_2, 6, 31, 0, + eq_tlv), +}; + +static int cp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + switch (event) { + case SND_SOC_DAPM_POST_PMU: + msleep(5); + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static int rmv_short_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec); + + /* Record which outputs we enabled */ + switch (event) { + case SND_SOC_DAPM_PRE_PMD: + wm8915->hpout_pending &= ~w->shift; + break; + case SND_SOC_DAPM_PRE_PMU: + wm8915->hpout_pending |= w->shift; + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) +{ + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int i, ret; + unsigned long timeout = 200; + + snd_soc_write(codec, WM8915_DC_SERVO_2, mask); + + /* Use the interrupt if possible */ + do { + if (i2c->irq) { + timeout = wait_for_completion_timeout(&wm8915->dcs_done, + msecs_to_jiffies(200)); + if (timeout == 0) + dev_err(codec->dev, "DC servo timed out\n"); + + } else { + msleep(1); + if (--i) { + timeout = 0; + break; + } + } + + ret = snd_soc_read(codec, WM8915_DC_SERVO_2); + dev_dbg(codec->dev, "DC servo state: %x\n", ret); + } while (ret & mask); + + if (timeout == 0) + dev_err(codec->dev, "DC servo timed out for %x\n", mask); + else + dev_dbg(codec->dev, "DC servo complete for %x\n", mask); +} + +static void wm8915_seq_notifier(struct snd_soc_dapm_context *dapm, + enum snd_soc_dapm_type event, int subseq) +{ + struct snd_soc_codec *codec = container_of(dapm, + struct snd_soc_codec, dapm); + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + u16 val, mask; + + /* Complete any pending DC servo starts */ + if (wm8915->dcs_pending) { + dev_dbg(codec->dev, "Starting DC servo for %x\n", + wm8915->dcs_pending); + + /* Trigger a startup sequence */ + wait_for_dc_servo(codec, wm8915->dcs_pending + << WM8915_DCS_TRIG_STARTUP_0_SHIFT); + + wm8915->dcs_pending = 0; + } + + if (wm8915->hpout_pending != wm8915->hpout_ena) { + dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n", + wm8915->hpout_ena, wm8915->hpout_pending); + + val = 0; + mask = 0; + if (wm8915->hpout_pending & HPOUT1L) { + val |= WM8915_HPOUT1L_RMV_SHORT; + mask |= WM8915_HPOUT1L_RMV_SHORT; + } else { + mask |= WM8915_HPOUT1L_RMV_SHORT | + WM8915_HPOUT1L_OUTP | + WM8915_HPOUT1L_DLY; + } + + if (wm8915->hpout_pending & HPOUT1R) { + val |= WM8915_HPOUT1R_RMV_SHORT; + mask |= WM8915_HPOUT1R_RMV_SHORT; + } else { + mask |= WM8915_HPOUT1R_RMV_SHORT | + WM8915_HPOUT1R_OUTP | + WM8915_HPOUT1R_DLY; + } + + snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_1, mask, val); + + val = 0; + mask = 0; + if (wm8915->hpout_pending & HPOUT2L) { + val |= WM8915_HPOUT2L_RMV_SHORT; + mask |= WM8915_HPOUT2L_RMV_SHORT; + } else { + mask |= WM8915_HPOUT2L_RMV_SHORT | + WM8915_HPOUT2L_OUTP | + WM8915_HPOUT2L_DLY; + } + + if (wm8915->hpout_pending & HPOUT2R) { + val |= WM8915_HPOUT2R_RMV_SHORT; + mask |= WM8915_HPOUT2R_RMV_SHORT; + } else { + mask |= WM8915_HPOUT2R_RMV_SHORT | + WM8915_HPOUT2R_OUTP | + WM8915_HPOUT2R_DLY; + } + + snd_soc_update_bits(codec, WM8915_ANALOGUE_HP_2, mask, val); + + wm8915->hpout_ena = wm8915->hpout_pending; + } +} + +static int dcs_start(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(w->codec); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + wm8915->dcs_pending |= 1 << w->shift; + break; + default: + BUG(); + return -EINVAL; + } + + return 0; +} + +static const char *sidetone_text[] = { + "IN1", "IN2", +}; + +static const struct soc_enum left_sidetone_enum = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 0, 2, sidetone_text); + +static const struct snd_kcontrol_new left_sidetone = + SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum); + +static const struct soc_enum right_sidetone_enum = + SOC_ENUM_SINGLE(WM8915_SIDETONE, 1, 2, sidetone_text); + +static const struct snd_kcontrol_new right_sidetone = + SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum); + +static const char *spk_text[] = { + "DAC1L", "DAC1R", "DAC2L", "DAC2R" +}; + +static const struct soc_enum spkl_enum = + SOC_ENUM_SINGLE(WM8915_LEFT_PDM_SPEAKER, 0, 4, spk_text); + +static const struct snd_kcontrol_new spkl_mux = + SOC_DAPM_ENUM("SPKL", spkl_enum); + +static const struct soc_enum spkr_enum = + SOC_ENUM_SINGLE(WM8915_RIGHT_PDM_SPEAKER, 0, 4, spk_text); + +static const struct snd_kcontrol_new spkr_mux = + SOC_DAPM_ENUM("SPKR", spkr_enum); + +static const char *dsp1rx_text[] = { + "AIF1", "AIF2" +}; + +static const struct soc_enum dsp1rx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text); + +static const struct snd_kcontrol_new dsp1rx = + SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum); + +static const char *dsp2rx_text[] = { + "AIF2", "AIF1" +}; + +static const struct soc_enum dsp2rx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text); + +static const struct snd_kcontrol_new dsp2rx = + SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum); + +static const char *aif2tx_text[] = { + "DSP2", "DSP1", "AIF1" +}; + +static const struct soc_enum aif2tx_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_8, 6, 3, aif2tx_text); + +static const struct snd_kcontrol_new aif2tx = + SOC_DAPM_ENUM("AIF2TX", aif2tx_enum); + +static const char *inmux_text[] = { + "ADC", "DMIC1", "DMIC2" +}; + +static const struct soc_enum in1_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 0, 3, inmux_text); + +static const struct snd_kcontrol_new in1_mux = + SOC_DAPM_ENUM("IN1 Mux", in1_enum); + +static const struct soc_enum in2_enum = + SOC_ENUM_SINGLE(WM8915_POWER_MANAGEMENT_7, 4, 3, inmux_text); + +static const struct snd_kcontrol_new in2_mux = + SOC_DAPM_ENUM("IN2 Mux", in2_enum); + +static const struct snd_kcontrol_new dac2r_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac2l_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1r_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1l_mix[] = { +SOC_DAPM_SINGLE("Right Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, + 5, 1, 0), +SOC_DAPM_SINGLE("Left Sidetone Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, + 4, 1, 0), +SOC_DAPM_SINGLE("DSP2 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0), +SOC_DAPM_SINGLE("DSP1 Switch", WM8915_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp1txl[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp1txr[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP1_TX_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp2txl[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dsp2txr[] = { +SOC_DAPM_SINGLE("IN1 Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING, + 1, 1, 0), +SOC_DAPM_SINGLE("DAC Switch", WM8915_DSP2_TX_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + + +static const struct snd_soc_dapm_widget wm8915_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("IN1LN"), +SND_SOC_DAPM_INPUT("IN1LP"), +SND_SOC_DAPM_INPUT("IN1RN"), +SND_SOC_DAPM_INPUT("IN1RP"), + +SND_SOC_DAPM_INPUT("IN2LN"), +SND_SOC_DAPM_INPUT("IN2LP"), +SND_SOC_DAPM_INPUT("IN2RN"), +SND_SOC_DAPM_INPUT("IN2RP"), + +SND_SOC_DAPM_INPUT("DMIC1DAT"), +SND_SOC_DAPM_INPUT("DMIC2DAT"), + +SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8915_AIF_CLOCKING_1, 0, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8915_CLOCKING_1, 1, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8915_CLOCKING_1, 2, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8915_CHARGE_PUMP_1, 15, 0, cp_event, + SND_SOC_DAPM_POST_PMU), + +SND_SOC_DAPM_SUPPLY("LDO2", WM8915_POWER_MANAGEMENT_2, 1, 0, NULL, 0), +SND_SOC_DAPM_MICBIAS("MICB2", WM8915_POWER_MANAGEMENT_1, 9, 0), +SND_SOC_DAPM_MICBIAS("MICB1", WM8915_POWER_MANAGEMENT_1, 8, 0), + +SND_SOC_DAPM_PGA("IN1L PGA", WM8915_POWER_MANAGEMENT_2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN1R PGA", WM8915_POWER_MANAGEMENT_2, 4, 0, NULL, 0), + +SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux), +SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux), +SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux), +SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux), + +SND_SOC_DAPM_PGA("IN1L", WM8915_POWER_MANAGEMENT_7, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN1R", WM8915_POWER_MANAGEMENT_7, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN2L", WM8915_POWER_MANAGEMENT_7, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("IN2R", WM8915_POWER_MANAGEMENT_7, 7, 0, NULL, 0), + +SND_SOC_DAPM_SUPPLY("DMIC2", WM8915_POWER_MANAGEMENT_7, 9, 0, NULL, 0), +SND_SOC_DAPM_SUPPLY("DMIC1", WM8915_POWER_MANAGEMENT_7, 8, 0, NULL, 0), + +SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8915_POWER_MANAGEMENT_3, 5, 0), +SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8915_POWER_MANAGEMENT_3, 4, 0), +SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8915_POWER_MANAGEMENT_3, 3, 0), +SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8915_POWER_MANAGEMENT_3, 2, 0), + +SND_SOC_DAPM_ADC("ADCL", NULL, WM8915_POWER_MANAGEMENT_3, 1, 0), +SND_SOC_DAPM_ADC("ADCR", NULL, WM8915_POWER_MANAGEMENT_3, 0, 0), + +SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone), +SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone), + +SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 11, 0), +SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 10, 0), +SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8915_POWER_MANAGEMENT_3, 9, 0), +SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8915_POWER_MANAGEMENT_3, 8, 0), + +SND_SOC_DAPM_MIXER("DSP2TXL", WM8915_POWER_MANAGEMENT_5, 11, 0, + dsp2txl, ARRAY_SIZE(dsp2txl)), +SND_SOC_DAPM_MIXER("DSP2TXR", WM8915_POWER_MANAGEMENT_5, 10, 0, + dsp2txr, ARRAY_SIZE(dsp2txr)), +SND_SOC_DAPM_MIXER("DSP1TXL", WM8915_POWER_MANAGEMENT_5, 9, 0, + dsp1txl, ARRAY_SIZE(dsp1txl)), +SND_SOC_DAPM_MIXER("DSP1TXR", WM8915_POWER_MANAGEMENT_5, 8, 0, + dsp1txr, ARRAY_SIZE(dsp1txr)), + +SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0, + dac2l_mix, ARRAY_SIZE(dac2l_mix)), +SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0, + dac2r_mix, ARRAY_SIZE(dac2r_mix)), +SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, + dac1l_mix, ARRAY_SIZE(dac1l_mix)), +SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, + dac1r_mix, ARRAY_SIZE(dac1r_mix)), + +SND_SOC_DAPM_DAC("DAC2L", NULL, WM8915_POWER_MANAGEMENT_5, 3, 0), +SND_SOC_DAPM_DAC("DAC2R", NULL, WM8915_POWER_MANAGEMENT_5, 2, 0), +SND_SOC_DAPM_DAC("DAC1L", NULL, WM8915_POWER_MANAGEMENT_5, 1, 0), +SND_SOC_DAPM_DAC("DAC1R", NULL, WM8915_POWER_MANAGEMENT_5, 0, 0), + +SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, + WM8915_POWER_MANAGEMENT_4, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, + WM8915_POWER_MANAGEMENT_4, 8, 0), + +SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, + WM8915_POWER_MANAGEMENT_6, 9, 0), +SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, + WM8915_POWER_MANAGEMENT_6, 8, 0), + +SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, + WM8915_POWER_MANAGEMENT_4, 5, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, + WM8915_POWER_MANAGEMENT_4, 4, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, + WM8915_POWER_MANAGEMENT_4, 3, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, + WM8915_POWER_MANAGEMENT_4, 2, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, + WM8915_POWER_MANAGEMENT_4, 1, 0), +SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0, + WM8915_POWER_MANAGEMENT_4, 0, 0), + +SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5, + WM8915_POWER_MANAGEMENT_6, 5, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4, + WM8915_POWER_MANAGEMENT_6, 4, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3, + WM8915_POWER_MANAGEMENT_6, 3, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2, + WM8915_POWER_MANAGEMENT_6, 2, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1, + WM8915_POWER_MANAGEMENT_6, 1, 0), +SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0, + WM8915_POWER_MANAGEMENT_6, 0, 0), + +/* We route as stereo pairs so define some dummy widgets to squash + * things down for now. RXA = 0,1, RXB = 2,3 and so on */ +SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0), + +SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx), +SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx), +SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx), + +SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux), +SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux), +SND_SOC_DAPM_PGA("SPKL PGA", WM8915_LEFT_PDM_SPEAKER, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("SPKR PGA", WM8915_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0), + +SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8915_POWER_MANAGEMENT_1, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8915_ANALOGUE_HP_2, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8915_DC_SERVO_1, 2, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8915_ANALOGUE_HP_2, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8915_POWER_MANAGEMENT_1, 6, 0,NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8915_ANALOGUE_HP_2, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8915_DC_SERVO_1, 3, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8915_ANALOGUE_HP_2, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8915_POWER_MANAGEMENT_1, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8915_ANALOGUE_HP_1, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8915_DC_SERVO_1, 0, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8915_ANALOGUE_HP_1, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8915_POWER_MANAGEMENT_1, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8915_ANALOGUE_HP_1, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8915_DC_SERVO_1, 1, 0, dcs_start, + SND_SOC_DAPM_POST_PMU), +SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8915_ANALOGUE_HP_1, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, + rmv_short_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + +SND_SOC_DAPM_OUTPUT("HPOUT1L"), +SND_SOC_DAPM_OUTPUT("HPOUT1R"), +SND_SOC_DAPM_OUTPUT("HPOUT2L"), +SND_SOC_DAPM_OUTPUT("HPOUT2R"), +SND_SOC_DAPM_OUTPUT("SPKDAT"), +}; + +static const struct snd_soc_dapm_route wm8915_dapm_routes[] = { + { "AIFCLK", NULL, "SYSCLK" }, + { "SYSDSPCLK", NULL, "SYSCLK" }, + { "Charge Pump", NULL, "SYSCLK" }, + + { "MICB1", NULL, "LDO2" }, + { "MICB2", NULL, "LDO2" }, + + { "IN1L PGA", NULL, "IN2LN" }, + { "IN1L PGA", NULL, "IN2LP" }, + { "IN1L PGA", NULL, "IN1LN" }, + { "IN1L PGA", NULL, "IN1LP" }, + + { "IN1R PGA", NULL, "IN2RN" }, + { "IN1R PGA", NULL, "IN2RP" }, + { "IN1R PGA", NULL, "IN1RN" }, + { "IN1R PGA", NULL, "IN1RP" }, + + { "ADCL", NULL, "IN1L PGA" }, + + { "ADCR", NULL, "IN1R PGA" }, + + { "DMIC1L", NULL, "DMIC1DAT" }, + { "DMIC1R", NULL, "DMIC1DAT" }, + { "DMIC2L", NULL, "DMIC2DAT" }, + { "DMIC2R", NULL, "DMIC2DAT" }, + + { "DMIC2L", NULL, "DMIC2" }, + { "DMIC2R", NULL, "DMIC2" }, + { "DMIC1L", NULL, "DMIC1" }, + { "DMIC1R", NULL, "DMIC1" }, + + { "IN1L Mux", "ADC", "ADCL" }, + { "IN1L Mux", "DMIC1", "DMIC1L" }, + { "IN1L Mux", "DMIC2", "DMIC2L" }, + + { "IN1R Mux", "ADC", "ADCR" }, + { "IN1R Mux", "DMIC1", "DMIC1R" }, + { "IN1R Mux", "DMIC2", "DMIC2R" }, + + { "IN2L Mux", "ADC", "ADCL" }, + { "IN2L Mux", "DMIC1", "DMIC1L" }, + { "IN2L Mux", "DMIC2", "DMIC2L" }, + + { "IN2R Mux", "ADC", "ADCR" }, + { "IN2R Mux", "DMIC1", "DMIC1R" }, + { "IN2R Mux", "DMIC2", "DMIC2R" }, + + { "Left Sidetone", "IN1", "IN1L Mux" }, + { "Left Sidetone", "IN2", "IN2L Mux" }, + + { "Right Sidetone", "IN1", "IN1R Mux" }, + { "Right Sidetone", "IN2", "IN2R Mux" }, + + { "DSP1TXL", "IN1 Switch", "IN1L Mux" }, + { "DSP1TXR", "IN1 Switch", "IN1R Mux" }, + + { "DSP2TXL", "IN1 Switch", "IN2L Mux" }, + { "DSP2TXR", "IN1 Switch", "IN2R Mux" }, + + { "AIF1TX0", NULL, "DSP1TXL" }, + { "AIF1TX1", NULL, "DSP1TXR" }, + { "AIF1TX2", NULL, "DSP2TXL" }, + { "AIF1TX3", NULL, "DSP2TXR" }, + { "AIF1TX4", NULL, "AIF2RX0" }, + { "AIF1TX5", NULL, "AIF2RX1" }, + + { "AIF1RX0", NULL, "AIFCLK" }, + { "AIF1RX1", NULL, "AIFCLK" }, + { "AIF1RX2", NULL, "AIFCLK" }, + { "AIF1RX3", NULL, "AIFCLK" }, + { "AIF1RX4", NULL, "AIFCLK" }, + { "AIF1RX5", NULL, "AIFCLK" }, + + { "AIF2RX0", NULL, "AIFCLK" }, + { "AIF2RX1", NULL, "AIFCLK" }, + + { "DSP1RXL", NULL, "SYSDSPCLK" }, + { "DSP1RXR", NULL, "SYSDSPCLK" }, + { "DSP2RXL", NULL, "SYSDSPCLK" }, + { "DSP2RXR", NULL, "SYSDSPCLK" }, + { "DSP1TXL", NULL, "SYSDSPCLK" }, + { "DSP1TXR", NULL, "SYSDSPCLK" }, + { "DSP2TXL", NULL, "SYSDSPCLK" }, + { "DSP2TXR", NULL, "SYSDSPCLK" }, + + { "AIF1RXA", NULL, "AIF1RX0" }, + { "AIF1RXA", NULL, "AIF1RX1" }, + { "AIF1RXB", NULL, "AIF1RX2" }, + { "AIF1RXB", NULL, "AIF1RX3" }, + { "AIF1RXC", NULL, "AIF1RX4" }, + { "AIF1RXC", NULL, "AIF1RX5" }, + + { "AIF2RX", NULL, "AIF2RX0" }, + { "AIF2RX", NULL, "AIF2RX1" }, + + { "AIF2TX", "DSP2", "DSP2TX" }, + { "AIF2TX", "DSP1", "DSP1RX" }, + { "AIF2TX", "AIF1", "AIF1RXC" }, + + { "DSP1RXL", NULL, "DSP1RX" }, + { "DSP1RXR", NULL, "DSP1RX" }, + { "DSP2RXL", NULL, "DSP2RX" }, + { "DSP2RXR", NULL, "DSP2RX" }, + + { "DSP2TX", NULL, "DSP2TXL" }, + { "DSP2TX", NULL, "DSP2TXR" }, + + { "DSP1RX", "AIF1", "AIF1RXA" }, + { "DSP1RX", "AIF2", "AIF2RX" }, + + { "DSP2RX", "AIF1", "AIF1RXB" }, + { "DSP2RX", "AIF2", "AIF2RX" }, + + { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" }, + { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" }, + { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" }, + { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" }, + { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" }, + { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" }, + { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" }, + { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" }, + { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + + { "DAC1L", NULL, "DAC1L Mixer" }, + { "DAC1R", NULL, "DAC1R Mixer" }, + { "DAC2L", NULL, "DAC2L Mixer" }, + { "DAC2R", NULL, "DAC2R Mixer" }, + + { "HPOUT2L PGA", NULL, "Charge Pump" }, + { "HPOUT2L PGA", NULL, "DAC2L" }, + { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, + { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, + { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, + { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, + + { "HPOUT2R PGA", NULL, "Charge Pump" }, + { "HPOUT2R PGA", NULL, "DAC2R" }, + { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, + { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, + { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, + { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, + + { "HPOUT1L PGA", NULL, "Charge Pump" }, + { "HPOUT1L PGA", NULL, "DAC1L" }, + { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, + { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, + { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, + { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, + + { "HPOUT1R PGA", NULL, "Charge Pump" }, + { "HPOUT1R PGA", NULL, "DAC1R" }, + { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, + { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, + { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, + { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" }, + + { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, + { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, + { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" }, + { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" }, + + { "SPKL", "DAC1L", "DAC1L" }, + { "SPKL", "DAC1R", "DAC1R" }, + { "SPKL", "DAC2L", "DAC2L" }, + { "SPKL", "DAC2R", "DAC2R" }, + + { "SPKR", "DAC1L", "DAC1L" }, + { "SPKR", "DAC1R", "DAC1R" }, + { "SPKR", "DAC2L", "DAC2L" }, + { "SPKR", "DAC2R", "DAC2R" }, + + { "SPKL PGA", NULL, "SPKL" }, + { "SPKR PGA", NULL, "SPKR" }, + + { "SPKDAT", NULL, "SPKL PGA" }, + { "SPKDAT", NULL, "SPKR PGA" }, +}; + +static int wm8915_readable_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + /* Due to the sparseness of the register map the compiler + * output from an explicit switch statement ends up being much + * more efficient than a table. + */ + switch (reg) { + case WM8915_SOFTWARE_RESET: + case WM8915_POWER_MANAGEMENT_1: + case WM8915_POWER_MANAGEMENT_2: + case WM8915_POWER_MANAGEMENT_3: + case WM8915_POWER_MANAGEMENT_4: + case WM8915_POWER_MANAGEMENT_5: + case WM8915_POWER_MANAGEMENT_6: + case WM8915_POWER_MANAGEMENT_7: + case WM8915_POWER_MANAGEMENT_8: + case WM8915_LEFT_LINE_INPUT_VOLUME: + case WM8915_RIGHT_LINE_INPUT_VOLUME: + case WM8915_LINE_INPUT_CONTROL: + case WM8915_DAC1_HPOUT1_VOLUME: + case WM8915_DAC2_HPOUT2_VOLUME: + case WM8915_DAC1_LEFT_VOLUME: + case WM8915_DAC1_RIGHT_VOLUME: + case WM8915_DAC2_LEFT_VOLUME: + case WM8915_DAC2_RIGHT_VOLUME: + case WM8915_OUTPUT1_LEFT_VOLUME: + case WM8915_OUTPUT1_RIGHT_VOLUME: + case WM8915_OUTPUT2_LEFT_VOLUME: + case WM8915_OUTPUT2_RIGHT_VOLUME: + case WM8915_MICBIAS_1: + case WM8915_MICBIAS_2: + case WM8915_LDO_1: + case WM8915_LDO_2: + case WM8915_ACCESSORY_DETECT_MODE_1: + case WM8915_ACCESSORY_DETECT_MODE_2: + case WM8915_HEADPHONE_DETECT_1: + case WM8915_HEADPHONE_DETECT_2: + case WM8915_MIC_DETECT_1: + case WM8915_MIC_DETECT_2: + case WM8915_MIC_DETECT_3: + case WM8915_CHARGE_PUMP_1: + case WM8915_CHARGE_PUMP_2: + case WM8915_DC_SERVO_1: + case WM8915_DC_SERVO_2: + case WM8915_DC_SERVO_3: + case WM8915_DC_SERVO_5: + case WM8915_DC_SERVO_6: + case WM8915_DC_SERVO_7: + case WM8915_DC_SERVO_READBACK_0: + case WM8915_ANALOGUE_HP_1: + case WM8915_ANALOGUE_HP_2: + case WM8915_CHIP_REVISION: + case WM8915_CONTROL_INTERFACE_1: + case WM8915_WRITE_SEQUENCER_CTRL_1: + case WM8915_WRITE_SEQUENCER_CTRL_2: + case WM8915_AIF_CLOCKING_1: + case WM8915_AIF_CLOCKING_2: + case WM8915_CLOCKING_1: + case WM8915_CLOCKING_2: + case WM8915_AIF_RATE: + case WM8915_FLL_CONTROL_1: + case WM8915_FLL_CONTROL_2: + case WM8915_FLL_CONTROL_3: + case WM8915_FLL_CONTROL_4: + case WM8915_FLL_CONTROL_5: + case WM8915_FLL_CONTROL_6: + case WM8915_FLL_EFS_1: + case WM8915_FLL_EFS_2: + case WM8915_AIF1_CONTROL: + case WM8915_AIF1_BCLK: + case WM8915_AIF1_TX_LRCLK_1: + case WM8915_AIF1_TX_LRCLK_2: + case WM8915_AIF1_RX_LRCLK_1: + case WM8915_AIF1_RX_LRCLK_2: + case WM8915_AIF1TX_DATA_CONFIGURATION_1: + case WM8915_AIF1TX_DATA_CONFIGURATION_2: + case WM8915_AIF1RX_DATA_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_2_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_3_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_4_CONFIGURATION: + case WM8915_AIF1TX_CHANNEL_5_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_2_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_3_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_4_CONFIGURATION: + case WM8915_AIF1RX_CHANNEL_5_CONFIGURATION: + case WM8915_AIF1RX_MONO_CONFIGURATION: + case WM8915_AIF1TX_TEST: + case WM8915_AIF2_CONTROL: + case WM8915_AIF2_BCLK: + case WM8915_AIF2_TX_LRCLK_1: + case WM8915_AIF2_TX_LRCLK_2: + case WM8915_AIF2_RX_LRCLK_1: + case WM8915_AIF2_RX_LRCLK_2: + case WM8915_AIF2TX_DATA_CONFIGURATION_1: + case WM8915_AIF2TX_DATA_CONFIGURATION_2: + case WM8915_AIF2RX_DATA_CONFIGURATION: + case WM8915_AIF2TX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF2TX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF2RX_CHANNEL_0_CONFIGURATION: + case WM8915_AIF2RX_CHANNEL_1_CONFIGURATION: + case WM8915_AIF2RX_MONO_CONFIGURATION: + case WM8915_AIF2TX_TEST: + case WM8915_DSP1_TX_LEFT_VOLUME: + case WM8915_DSP1_TX_RIGHT_VOLUME: + case WM8915_DSP1_RX_LEFT_VOLUME: + case WM8915_DSP1_RX_RIGHT_VOLUME: + case WM8915_DSP1_TX_FILTERS: + case WM8915_DSP1_RX_FILTERS_1: + case WM8915_DSP1_RX_FILTERS_2: + case WM8915_DSP1_DRC_1: + case WM8915_DSP1_DRC_2: + case WM8915_DSP1_DRC_3: + case WM8915_DSP1_DRC_4: + case WM8915_DSP1_DRC_5: + case WM8915_DSP1_RX_EQ_GAINS_1: + case WM8915_DSP1_RX_EQ_GAINS_2: + case WM8915_DSP1_RX_EQ_BAND_1_A: + case WM8915_DSP1_RX_EQ_BAND_1_B: + case WM8915_DSP1_RX_EQ_BAND_1_PG: + case WM8915_DSP1_RX_EQ_BAND_2_A: + case WM8915_DSP1_RX_EQ_BAND_2_B: + case WM8915_DSP1_RX_EQ_BAND_2_C: + case WM8915_DSP1_RX_EQ_BAND_2_PG: + case WM8915_DSP1_RX_EQ_BAND_3_A: + case WM8915_DSP1_RX_EQ_BAND_3_B: + case WM8915_DSP1_RX_EQ_BAND_3_C: + case WM8915_DSP1_RX_EQ_BAND_3_PG: + case WM8915_DSP1_RX_EQ_BAND_4_A: + case WM8915_DSP1_RX_EQ_BAND_4_B: + case WM8915_DSP1_RX_EQ_BAND_4_C: + case WM8915_DSP1_RX_EQ_BAND_4_PG: + case WM8915_DSP1_RX_EQ_BAND_5_A: + case WM8915_DSP1_RX_EQ_BAND_5_B: + case WM8915_DSP1_RX_EQ_BAND_5_PG: + case WM8915_DSP2_TX_LEFT_VOLUME: + case WM8915_DSP2_TX_RIGHT_VOLUME: + case WM8915_DSP2_RX_LEFT_VOLUME: + case WM8915_DSP2_RX_RIGHT_VOLUME: + case WM8915_DSP2_TX_FILTERS: + case WM8915_DSP2_RX_FILTERS_1: + case WM8915_DSP2_RX_FILTERS_2: + case WM8915_DSP2_DRC_1: + case WM8915_DSP2_DRC_2: + case WM8915_DSP2_DRC_3: + case WM8915_DSP2_DRC_4: + case WM8915_DSP2_DRC_5: + case WM8915_DSP2_RX_EQ_GAINS_1: + case WM8915_DSP2_RX_EQ_GAINS_2: + case WM8915_DSP2_RX_EQ_BAND_1_A: + case WM8915_DSP2_RX_EQ_BAND_1_B: + case WM8915_DSP2_RX_EQ_BAND_1_PG: + case WM8915_DSP2_RX_EQ_BAND_2_A: + case WM8915_DSP2_RX_EQ_BAND_2_B: + case WM8915_DSP2_RX_EQ_BAND_2_C: + case WM8915_DSP2_RX_EQ_BAND_2_PG: + case WM8915_DSP2_RX_EQ_BAND_3_A: + case WM8915_DSP2_RX_EQ_BAND_3_B: + case WM8915_DSP2_RX_EQ_BAND_3_C: + case WM8915_DSP2_RX_EQ_BAND_3_PG: + case WM8915_DSP2_RX_EQ_BAND_4_A: + case WM8915_DSP2_RX_EQ_BAND_4_B: + case WM8915_DSP2_RX_EQ_BAND_4_C: + case WM8915_DSP2_RX_EQ_BAND_4_PG: + case WM8915_DSP2_RX_EQ_BAND_5_A: + case WM8915_DSP2_RX_EQ_BAND_5_B: + case WM8915_DSP2_RX_EQ_BAND_5_PG: + case WM8915_DAC1_MIXER_VOLUMES: + case WM8915_DAC1_LEFT_MIXER_ROUTING: + case WM8915_DAC1_RIGHT_MIXER_ROUTING: + case WM8915_DAC2_MIXER_VOLUMES: + case WM8915_DAC2_LEFT_MIXER_ROUTING: + case WM8915_DAC2_RIGHT_MIXER_ROUTING: + case WM8915_DSP1_TX_LEFT_MIXER_ROUTING: + case WM8915_DSP1_TX_RIGHT_MIXER_ROUTING: + case WM8915_DSP2_TX_LEFT_MIXER_ROUTING: + case WM8915_DSP2_TX_RIGHT_MIXER_ROUTING: + case WM8915_DSP_TX_MIXER_SELECT: + case WM8915_DAC_SOFTMUTE: + case WM8915_OVERSAMPLING: + case WM8915_SIDETONE: + case WM8915_GPIO_1: + case WM8915_GPIO_2: + case WM8915_GPIO_3: + case WM8915_GPIO_4: + case WM8915_GPIO_5: + case WM8915_PULL_CONTROL_1: + case WM8915_PULL_CONTROL_2: + case WM8915_INTERRUPT_STATUS_1: + case WM8915_INTERRUPT_STATUS_2: + case WM8915_INTERRUPT_RAW_STATUS_2: + case WM8915_INTERRUPT_STATUS_1_MASK: + case WM8915_INTERRUPT_STATUS_2_MASK: + case WM8915_INTERRUPT_CONTROL: + case WM8915_LEFT_PDM_SPEAKER: + case WM8915_RIGHT_PDM_SPEAKER: + case WM8915_PDM_SPEAKER_MUTE_SEQUENCE: + case WM8915_PDM_SPEAKER_VOLUME: + return 1; + default: + return 0; + } +} + +static int wm8915_volatile_register(struct snd_soc_codec *codec, + unsigned int reg) +{ + switch (reg) { + case WM8915_SOFTWARE_RESET: + case WM8915_CHIP_REVISION: + case WM8915_LDO_1: + case WM8915_LDO_2: + case WM8915_INTERRUPT_STATUS_1: + case WM8915_INTERRUPT_STATUS_2: + case WM8915_INTERRUPT_RAW_STATUS_2: + case WM8915_DC_SERVO_READBACK_0: + case WM8915_DC_SERVO_2: + case WM8915_DC_SERVO_6: + case WM8915_DC_SERVO_7: + case WM8915_FLL_CONTROL_6: + case WM8915_MIC_DETECT_3: + case WM8915_HEADPHONE_DETECT_1: + case WM8915_HEADPHONE_DETECT_2: + return 1; + default: + return 0; + } +} + +static int wm8915_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8915_SOFTWARE_RESET, 0x8915); +} + +static const int bclk_divs[] = { + 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 +}; + +static void wm8915_update_bclk(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int aif, best, cur_val, bclk_rate, bclk_reg, i; + + /* Don't bother if we're in a low frequency idle mode that + * can't support audio. + */ + if (wm8915->sysclk < 64000) + return; + + for (aif = 0; aif < WM8915_AIFS; aif++) { + switch (aif) { + case 0: + bclk_reg = WM8915_AIF1_BCLK; + break; + case 1: + bclk_reg = WM8915_AIF2_BCLK; + break; + } + + bclk_rate = wm8915->bclk_rate[aif]; + + /* Pick a divisor for BCLK as close as we can get to ideal */ + best = 0; + for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { + cur_val = (wm8915->sysclk / bclk_divs[i]) - bclk_rate; + if (cur_val < 0) /* BCLK table is sorted */ + break; + best = i; + } + bclk_rate = wm8915->sysclk / bclk_divs[best]; + dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", + bclk_divs[best], bclk_rate); + + snd_soc_update_bits(codec, bclk_reg, + WM8915_AIF1_BCLK_DIV_MASK, best); + } +} + +static int wm8915_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { + snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1, + WM8915_BG_ENA, WM8915_BG_ENA); + msleep(2); + } + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, + 1); + msleep(5); + } + + codec->cache_only = false; + snd_soc_cache_sync(codec); + } + + snd_soc_update_bits(codec, WM8915_POWER_MANAGEMENT_1, + WM8915_BG_ENA, 0); + break; + + case SND_SOC_BIAS_OFF: + codec->cache_only = true; + if (wm8915->pdata.ldo_ena >= 0) + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + break; + } + + codec->dapm.bias_level = level; + + return 0; +} + +static int wm8915_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec = dai->codec; + int aifctrl = 0; + int bclk = 0; + int lrclk_tx = 0; + int lrclk_rx = 0; + int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg; + + switch (dai->id) { + case 0: + aifctrl_reg = WM8915_AIF1_CONTROL; + bclk_reg = WM8915_AIF1_BCLK; + lrclk_tx_reg = WM8915_AIF1_TX_LRCLK_2; + lrclk_rx_reg = WM8915_AIF1_RX_LRCLK_2; + break; + case 1: + aifctrl_reg = WM8915_AIF2_CONTROL; + bclk_reg = WM8915_AIF2_BCLK; + lrclk_tx_reg = WM8915_AIF2_TX_LRCLK_2; + lrclk_rx_reg = WM8915_AIF2_RX_LRCLK_2; + break; + default: + BUG(); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + bclk |= WM8915_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + lrclk_tx |= WM8915_AIF1TX_LRCLK_INV; + lrclk_rx |= WM8915_AIF1RX_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_IF: + bclk |= WM8915_AIF1_BCLK_INV; + lrclk_tx |= WM8915_AIF1TX_LRCLK_INV; + lrclk_rx |= WM8915_AIF1RX_LRCLK_INV; + break; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBS_CFM: + lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR; + lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFS: + bclk |= WM8915_AIF1_BCLK_MSTR; + break; + case SND_SOC_DAIFMT_CBM_CFM: + bclk |= WM8915_AIF1_BCLK_MSTR; + lrclk_tx |= WM8915_AIF1TX_LRCLK_MSTR; + lrclk_rx |= WM8915_AIF1RX_LRCLK_MSTR; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + break; + case SND_SOC_DAIFMT_DSP_B: + aifctrl |= 1; + break; + case SND_SOC_DAIFMT_I2S: + aifctrl |= 2; + break; + case SND_SOC_DAIFMT_LEFT_J: + aifctrl |= 3; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, aifctrl_reg, WM8915_AIF1_FMT_MASK, aifctrl); + snd_soc_update_bits(codec, bclk_reg, + WM8915_AIF1_BCLK_INV | WM8915_AIF1_BCLK_MSTR, + bclk); + snd_soc_update_bits(codec, lrclk_tx_reg, + WM8915_AIF1TX_LRCLK_INV | + WM8915_AIF1TX_LRCLK_MSTR, + lrclk_tx); + snd_soc_update_bits(codec, lrclk_rx_reg, + WM8915_AIF1RX_LRCLK_INV | + WM8915_AIF1RX_LRCLK_MSTR, + lrclk_rx); + + return 0; +} + +static const int dsp_divs[] = { + 48000, 32000, 16000, 8000 +}; + +static int wm8915_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int bits, i, bclk_rate; + int aifdata = 0; + int lrclk = 0; + int dsp = 0; + int aifdata_reg, lrclk_reg, dsp_shift; + + switch (dai->id) { + case 0: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + (snd_soc_read(codec, WM8915_GPIO_1)) & WM8915_GP1_FN_MASK) { + aifdata_reg = WM8915_AIF1RX_DATA_CONFIGURATION; + lrclk_reg = WM8915_AIF1_RX_LRCLK_1; + } else { + aifdata_reg = WM8915_AIF1TX_DATA_CONFIGURATION_1; + lrclk_reg = WM8915_AIF1_TX_LRCLK_1; + } + dsp_shift = 0; + break; + case 1: + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || + (snd_soc_read(codec, WM8915_GPIO_2)) & WM8915_GP2_FN_MASK) { + aifdata_reg = WM8915_AIF2RX_DATA_CONFIGURATION; + lrclk_reg = WM8915_AIF2_RX_LRCLK_1; + } else { + aifdata_reg = WM8915_AIF2TX_DATA_CONFIGURATION_1; + lrclk_reg = WM8915_AIF2_TX_LRCLK_1; + } + dsp_shift = WM8915_DSP2_DIV_SHIFT; + break; + default: + BUG(); + return -EINVAL; + } + + bclk_rate = snd_soc_params_to_bclk(params); + if (bclk_rate < 0) { + dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate); + return bclk_rate; + } + + wm8915->bclk_rate[dai->id] = bclk_rate; + wm8915->rx_rate[dai->id] = params_rate(params); + + /* Needs looking at for TDM */ + bits = snd_pcm_format_width(params_format(params)); + if (bits < 0) + return bits; + aifdata |= (bits << WM8915_AIF1TX_WL_SHIFT) | bits; + + for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { + if (dsp_divs[i] == params_rate(params)) + break; + } + if (i == ARRAY_SIZE(dsp_divs)) { + dev_err(codec->dev, "Unsupported sample rate %dHz\n", + params_rate(params)); + return -EINVAL; + } + dsp |= i << dsp_shift; + + wm8915_update_bclk(codec); + + lrclk = bclk_rate / params_rate(params); + dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", + lrclk, bclk_rate / lrclk); + + snd_soc_update_bits(codec, aifdata_reg, + WM8915_AIF1TX_WL_MASK | + WM8915_AIF1TX_SLOT_LEN_MASK, + aifdata); + snd_soc_update_bits(codec, lrclk_reg, WM8915_AIF1RX_RATE_MASK, + lrclk); + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_2, + WM8915_DSP1_DIV_SHIFT << dsp_shift, dsp); + + return 0; +} + +static int wm8915_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec = dai->codec; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int lfclk = 0; + int ratediv = 0; + int src; + int old; + + if (freq == wm8915->sysclk && clk_id == wm8915->sysclk_src) + return 0; + + /* Disable SYSCLK while we reconfigure */ + old = snd_soc_read(codec, WM8915_AIF_CLOCKING_1) & WM8915_SYSCLK_ENA; + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_ENA, 0); + + switch (clk_id) { + case WM8915_SYSCLK_MCLK1: + wm8915->sysclk = freq; + src = 0; + break; + case WM8915_SYSCLK_MCLK2: + wm8915->sysclk = freq; + src = 1; + break; + case WM8915_SYSCLK_FLL: + wm8915->sysclk = freq; + src = 2; + break; + default: + dev_err(codec->dev, "Unsupported clock source %d\n", clk_id); + return -EINVAL; + } + + switch (wm8915->sysclk) { + case 6144000: + snd_soc_update_bits(codec, WM8915_AIF_RATE, + WM8915_SYSCLK_RATE, 0); + break; + case 24576000: + ratediv = WM8915_SYSCLK_DIV; + case 12288000: + snd_soc_update_bits(codec, WM8915_AIF_RATE, + WM8915_SYSCLK_RATE, WM8915_SYSCLK_RATE); + break; + case 32000: + case 32768: + lfclk = WM8915_LFCLK_ENA; + break; + default: + dev_warn(codec->dev, "Unsupported clock rate %dHz\n", + wm8915->sysclk); + return -EINVAL; + } + + wm8915_update_bclk(codec); + + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_SRC_MASK | WM8915_SYSCLK_DIV_MASK, + src << WM8915_SYSCLK_SRC_SHIFT | ratediv); + snd_soc_update_bits(codec, WM8915_CLOCKING_1, WM8915_LFCLK_ENA, lfclk); + snd_soc_update_bits(codec, WM8915_AIF_CLOCKING_1, + WM8915_SYSCLK_ENA, old); + + wm8915->sysclk_src = clk_id; + + return 0; +} + +struct _fll_div { + u16 fll_fratio; + u16 fll_outdiv; + u16 fll_refclk_div; + u16 fll_loop_gain; + u16 fll_ref_freq; + u16 n; + u16 theta; + u16 lambda; +}; + +static struct { + unsigned int min; + unsigned int max; + u16 fll_fratio; + int ratio; +} fll_fratios[] = { + { 0, 64000, 4, 16 }, + { 64000, 128000, 3, 8 }, + { 128000, 256000, 2, 4 }, + { 256000, 1000000, 1, 2 }, + { 1000000, 13500000, 0, 1 }, +}; + +static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, + unsigned int Fout) +{ + unsigned int target; + unsigned int div; + unsigned int fratio, gcd_fll; + int i; + + /* Fref must be <=13.5MHz */ + div = 1; + fll_div->fll_refclk_div = 0; + while ((Fref / div) > 13500000) { + div *= 2; + fll_div->fll_refclk_div++; + + if (div > 8) { + pr_err("Can't scale %dMHz input down to <=13.5MHz\n", + Fref); + return -EINVAL; + } + } + + pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); + + /* Apply the division for our remaining calculations */ + Fref /= div; + + if (Fref >= 3000000) + fll_div->fll_loop_gain = 5; + else + fll_div->fll_loop_gain = 0; + + if (Fref >= 48000) + fll_div->fll_ref_freq = 0; + else + fll_div->fll_ref_freq = 1; + + /* Fvco should be 90-100MHz; don't check the upper bound */ + div = 2; + while (Fout * div < 90000000) { + div++; + if (div > 64) { + pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", + Fout); + return -EINVAL; + } + } + target = Fout * div; + fll_div->fll_outdiv = div - 1; + + pr_debug("FLL Fvco=%dHz\n", target); + + /* Find an appropraite FLL_FRATIO and factor it out of the target */ + for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { + if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { + fll_div->fll_fratio = fll_fratios[i].fll_fratio; + fratio = fll_fratios[i].ratio; + break; + } + } + if (i == ARRAY_SIZE(fll_fratios)) { + pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); + return -EINVAL; + } + + fll_div->n = target / (fratio * Fref); + + if (target % Fref == 0) { + fll_div->theta = 0; + fll_div->lambda = 0; + } else { + gcd_fll = gcd(target, fratio * Fref); + + fll_div->theta = (target - (fll_div->n * fratio * Fref)) + / gcd_fll; + fll_div->lambda = (fratio * Fref) / gcd_fll; + } + + pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", + fll_div->n, fll_div->theta, fll_div->lambda); + pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", + fll_div->fll_fratio, fll_div->fll_outdiv, + fll_div->fll_refclk_div); + + return 0; +} + +static int wm8915_set_fll(struct snd_soc_codec *codec, int fll_id, int source, + unsigned int Fref, unsigned int Fout) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct _fll_div fll_div; + unsigned long timeout; + int ret, reg; + + /* Any change? */ + if (source == wm8915->fll_src && Fref == wm8915->fll_fref && + Fout == wm8915->fll_fout) + return 0; + + if (Fout == 0) { + dev_dbg(codec->dev, "FLL disabled\n"); + + wm8915->fll_fref = 0; + wm8915->fll_fout = 0; + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1, + WM8915_FLL_ENA, 0); + + return 0; + } + + ret = fll_factors(&fll_div, Fref, Fout); + if (ret != 0) + return ret; + + switch (source) { + case WM8915_FLL_MCLK1: + reg = 0; + break; + case WM8915_FLL_MCLK2: + reg = 1; + break; + case WM8915_FLL_DACLRCLK1: + reg = 2; + break; + case WM8915_FLL_BCLK1: + reg = 3; + break; + default: + dev_err(codec->dev, "Unknown FLL source %d\n", ret); + return -EINVAL; + } + + reg |= fll_div.fll_refclk_div << WM8915_FLL_REFCLK_DIV_SHIFT; + reg |= fll_div.fll_ref_freq << WM8915_FLL_REF_FREQ_SHIFT; + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_5, + WM8915_FLL_REFCLK_DIV_MASK | WM8915_FLL_REF_FREQ | + WM8915_FLL_REFCLK_SRC_MASK, reg); + + reg = 0; + if (fll_div.theta || fll_div.lambda) + reg |= WM8915_FLL_EFS_ENA | (3 << WM8915_FLL_LFSR_SEL_SHIFT); + else + reg |= 1 << WM8915_FLL_LFSR_SEL_SHIFT; + snd_soc_write(codec, WM8915_FLL_EFS_2, reg); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_2, + WM8915_FLL_OUTDIV_MASK | + WM8915_FLL_FRATIO_MASK, + (fll_div.fll_outdiv << WM8915_FLL_OUTDIV_SHIFT) | + (fll_div.fll_fratio)); + + snd_soc_write(codec, WM8915_FLL_CONTROL_3, fll_div.theta); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_4, + WM8915_FLL_N_MASK | WM8915_FLL_LOOP_GAIN_MASK, + (fll_div.n << WM8915_FLL_N_SHIFT) | + fll_div.fll_loop_gain); + + snd_soc_write(codec, WM8915_FLL_EFS_1, fll_div.lambda); + + snd_soc_update_bits(codec, WM8915_FLL_CONTROL_1, + WM8915_FLL_ENA, WM8915_FLL_ENA); + + /* The FLL supports live reconfiguration - kick that in case we were + * already enabled. + */ + snd_soc_write(codec, WM8915_FLL_CONTROL_6, WM8915_FLL_SWITCH_CLK); + + /* Wait for the FLL to lock, using the interrupt if possible */ + if (Fref > 1000000) + timeout = usecs_to_jiffies(300); + else + timeout = msecs_to_jiffies(2); + + /* Allow substantially longer if we've actually got the IRQ */ + if (i2c->irq) + timeout *= 1000; + + ret = wait_for_completion_timeout(&wm8915->fll_lock, timeout); + + if (ret == 0 && i2c->irq) { + dev_err(codec->dev, "Timed out waiting for FLL\n"); + ret = -ETIMEDOUT; + } else { + ret = 0; + } + + dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); + + wm8915->fll_fref = Fref; + wm8915->fll_fout = Fout; + wm8915->fll_src = source; + + return ret; +} + +#ifdef CONFIG_GPIOLIB +static inline struct wm8915_priv *gpio_to_wm8915(struct gpio_chip *chip) +{ + return container_of(chip, struct wm8915_priv, gpio_chip); +} + +static void wm8915_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + + snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_LVL, !!value << WM8915_GP1_LVL_SHIFT); +} + +static int wm8915_gpio_direction_out(struct gpio_chip *chip, + unsigned offset, int value) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + int val; + + val = (1 << WM8915_GP1_FN_SHIFT) | (!!value << WM8915_GP1_LVL_SHIFT); + + return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_FN_MASK | WM8915_GP1_DIR | + WM8915_GP1_LVL, val); +} + +static int wm8915_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + int ret; + + ret = snd_soc_read(codec, WM8915_GPIO_1 + offset); + if (ret < 0) + return ret; + + return (ret & WM8915_GP1_LVL) != 0; +} + +static int wm8915_gpio_direction_in(struct gpio_chip *chip, unsigned offset) +{ + struct wm8915_priv *wm8915 = gpio_to_wm8915(chip); + struct snd_soc_codec *codec = wm8915->codec; + + return snd_soc_update_bits(codec, WM8915_GPIO_1 + offset, + WM8915_GP1_FN_MASK | WM8915_GP1_DIR, + (1 << WM8915_GP1_FN_SHIFT) | + (1 << WM8915_GP1_DIR_SHIFT)); +} + +static struct gpio_chip wm8915_template_chip = { + .label = "wm8915", + .owner = THIS_MODULE, + .direction_output = wm8915_gpio_direction_out, + .set = wm8915_gpio_set, + .direction_input = wm8915_gpio_direction_in, + .get = wm8915_gpio_get, + .can_sleep = 1, +}; + +static void wm8915_init_gpio(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + wm8915->gpio_chip = wm8915_template_chip; + wm8915->gpio_chip.ngpio = 5; + wm8915->gpio_chip.dev = codec->dev; + + if (wm8915->pdata.gpio_base) + wm8915->gpio_chip.base = wm8915->pdata.gpio_base; + else + wm8915->gpio_chip.base = -1; + + ret = gpiochip_add(&wm8915->gpio_chip); + if (ret != 0) + dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); +} + +static void wm8915_free_gpio(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = gpiochip_remove(&wm8915->gpio_chip); + if (ret != 0) + dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); +} +#else +static void wm8915_init_gpio(struct snd_soc_codec *codec) +{ +} + +static void wm8915_free_gpio(struct snd_soc_codec *codec) +{ +} +#endif + +/** + * wm8915_detect - Enable default WM8915 jack detection + * + * The WM8915 has advanced accessory detection support for headsets. + * This function provides a default implementation which integrates + * the majority of this functionality with minimal user configuration. + * + * This will detect headset, headphone and short circuit button and + * will also detect inverted microphone ground connections and update + * the polarity of the connections. + */ +int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8915_polarity_fn polarity_cb) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + + wm8915->jack = jack; + wm8915->detecting = true; + wm8915->polarity_cb = polarity_cb; + + if (wm8915->polarity_cb) + wm8915->polarity_cb(codec, 0); + + /* Clear discarge to avoid noise during detection */ + snd_soc_update_bits(codec, WM8915_MICBIAS_1, + WM8915_MICB1_DISCH, 0); + snd_soc_update_bits(codec, WM8915_MICBIAS_2, + WM8915_MICB2_DISCH, 0); + + /* LDO2 powers the microphones, SYSCLK clocks detection */ + snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); + snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); + + /* We start off just enabling microphone detection - even a + * plain headphone will trigger detection. + */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_ENA, WM8915_MICD_ENA); + + /* Slowest detection rate, gives debounce for initial detection */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + WM8915_MICD_RATE_MASK); + + /* Enable interrupts and we're off */ + snd_soc_update_bits(codec, WM8915_INTERRUPT_STATUS_2_MASK, + WM8915_IM_MICD_EINT, 0); + + return 0; +} +EXPORT_SYMBOL_GPL(wm8915_detect); + +static void wm8915_micd(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int val, reg; + + val = snd_soc_read(codec, WM8915_MIC_DETECT_3); + + dev_dbg(codec->dev, "Microphone event: %x\n", val); + + if (!(val & WM8915_MICD_VALID)) { + dev_warn(codec->dev, "Microphone detection state invalid\n"); + return; + } + + /* No accessory, reset everything and report removal */ + if (!(val & WM8915_MICD_STS)) { + dev_dbg(codec->dev, "Jack removal detected\n"); + wm8915->jack_mic = false; + wm8915->detecting = true; + snd_soc_jack_report(wm8915->jack, 0, + SND_JACK_HEADSET | SND_JACK_BTN_0); + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + WM8915_MICD_RATE_MASK); + return; + } + + /* If the measurement is very high we've got a microphone but + * do a little debounce to account for mechanical issues. + */ + if (val & 0x400) { + dev_dbg(codec->dev, "Microphone detected\n"); + snd_soc_jack_report(wm8915->jack, SND_JACK_HEADSET, + SND_JACK_HEADSET | SND_JACK_BTN_0); + wm8915->jack_mic = true; + wm8915->detecting = false; + + /* Increase poll rate to give better responsiveness + * for buttons */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + 5 << WM8915_MICD_RATE_SHIFT); + } + + /* If we detected a lower impedence during initial startup + * then we probably have the wrong polarity, flip it. Don't + * do this for the lowest impedences to speed up detection of + * plain headphones. + */ + if (wm8915->detecting && (val & 0x3f0)) { + reg = snd_soc_read(codec, WM8915_ACCESSORY_DETECT_MODE_2); + reg ^= WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC | + WM8915_MICD_BIAS_SRC; + snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2, + WM8915_HPOUT1FB_SRC | WM8915_MICD_SRC | + WM8915_MICD_BIAS_SRC, reg); + + if (wm8915->polarity_cb) + wm8915->polarity_cb(codec, + (reg & WM8915_MICD_SRC) != 0); + + dev_dbg(codec->dev, "Set microphone polarity to %d\n", + (reg & WM8915_MICD_SRC) != 0); + + return; + } + + /* Don't distinguish between buttons, just report any low + * impedence as BTN_0. + */ + if (val & 0x3fc) { + if (wm8915->jack_mic) { + dev_dbg(codec->dev, "Mic button detected\n"); + snd_soc_jack_report(wm8915->jack, + SND_JACK_HEADSET | SND_JACK_BTN_0, + SND_JACK_HEADSET | SND_JACK_BTN_0); + } else { + dev_dbg(codec->dev, "Headphone detected\n"); + snd_soc_jack_report(wm8915->jack, + SND_JACK_HEADPHONE, + SND_JACK_HEADSET | + SND_JACK_BTN_0); + + /* Increase the detection rate a bit for + * responsiveness. + */ + snd_soc_update_bits(codec, WM8915_MIC_DETECT_1, + WM8915_MICD_RATE_MASK, + 7 << WM8915_MICD_RATE_SHIFT); + + wm8915->detecting = false; + } + } +} + +static irqreturn_t wm8915_irq(int irq, void *data) +{ + struct snd_soc_codec *codec = data; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + int irq_val; + + irq_val = snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2); + if (irq_val < 0) { + dev_err(codec->dev, "Failed to read IRQ status: %d\n", + irq_val); + return IRQ_NONE; + } + irq_val &= ~snd_soc_read(codec, WM8915_INTERRUPT_STATUS_2_MASK); + + if (irq_val & (WM8915_DCS_DONE_01_EINT | WM8915_DCS_DONE_23_EINT)) { + dev_dbg(codec->dev, "DC servo IRQ\n"); + complete(&wm8915->dcs_done); + } + + if (irq_val & WM8915_FIFOS_ERR_EINT) + dev_err(codec->dev, "Digital core FIFO error\n"); + + if (irq_val & WM8915_FLL_LOCK_EINT) { + dev_dbg(codec->dev, "FLL locked\n"); + complete(&wm8915->fll_lock); + } + + if (irq_val & WM8915_MICD_EINT) + wm8915_micd(codec); + + if (irq_val) { + snd_soc_write(codec, WM8915_INTERRUPT_STATUS_2, irq_val); + + return IRQ_HANDLED; + } else { + return IRQ_NONE; + } +} + +static irqreturn_t wm8915_edge_irq(int irq, void *data) +{ + irqreturn_t ret = IRQ_NONE; + irqreturn_t val; + + do { + val = wm8915_irq(irq, data); + if (val != IRQ_NONE) + ret = val; + } while (val != IRQ_NONE); + + return ret; +} + +static void wm8915_retune_mobile_pdata(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct wm8915_pdata *pdata = &wm8915->pdata; + + struct snd_kcontrol_new controls[] = { + SOC_ENUM_EXT("DSP1 EQ Mode", + wm8915->retune_mobile_enum, + wm8915_get_retune_mobile_enum, + wm8915_put_retune_mobile_enum), + SOC_ENUM_EXT("DSP2 EQ Mode", + wm8915->retune_mobile_enum, + wm8915_get_retune_mobile_enum, + wm8915_put_retune_mobile_enum), + }; + int ret, i, j; + const char **t; + + /* We need an array of texts for the enum API but the number + * of texts is likely to be less than the number of + * configurations due to the sample rate dependency of the + * configurations. */ + wm8915->num_retune_mobile_texts = 0; + wm8915->retune_mobile_texts = NULL; + for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { + for (j = 0; j < wm8915->num_retune_mobile_texts; j++) { + if (strcmp(pdata->retune_mobile_cfgs[i].name, + wm8915->retune_mobile_texts[j]) == 0) + break; + } + + if (j != wm8915->num_retune_mobile_texts) + continue; + + /* Expand the array... */ + t = krealloc(wm8915->retune_mobile_texts, + sizeof(char *) * + (wm8915->num_retune_mobile_texts + 1), + GFP_KERNEL); + if (t == NULL) + continue; + + /* ...store the new entry... */ + t[wm8915->num_retune_mobile_texts] = + pdata->retune_mobile_cfgs[i].name; + + /* ...and remember the new version. */ + wm8915->num_retune_mobile_texts++; + wm8915->retune_mobile_texts = t; + } + + dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", + wm8915->num_retune_mobile_texts); + + wm8915->retune_mobile_enum.max = wm8915->num_retune_mobile_texts; + wm8915->retune_mobile_enum.texts = wm8915->retune_mobile_texts; + + ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); + if (ret != 0) + dev_err(codec->dev, + "Failed to add ReTune Mobile controls: %d\n", ret); +} + +static int wm8915_probe(struct snd_soc_codec *codec) +{ + int ret; + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); + struct snd_soc_dapm_context *dapm = &codec->dapm; + int i, irq_flags; + + wm8915->codec = codec; + + init_completion(&wm8915->dcs_done); + init_completion(&wm8915->fll_lock); + + dapm->idle_bias_off = true; + dapm->bias_level = SND_SOC_BIAS_OFF; + + ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + goto err; + } + + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) + wm8915->supplies[i].supply = wm8915_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + goto err; + } + + wm8915->disable_nb[0].notifier_call = wm8915_regulator_event_0; + wm8915->disable_nb[1].notifier_call = wm8915_regulator_event_1; + wm8915->disable_nb[2].notifier_call = wm8915_regulator_event_2; + wm8915->disable_nb[3].notifier_call = wm8915_regulator_event_3; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) { + ret = regulator_register_notifier(wm8915->supplies[i].consumer, + &wm8915->disable_nb[i]); + if (ret != 0) { + dev_err(codec->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8915->supplies), + wm8915->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 1); + msleep(5); + } + + ret = snd_soc_read(codec, WM8915_SOFTWARE_RESET); + if (ret < 0) { + dev_err(codec->dev, "Failed to read ID register: %d\n", ret); + goto err_enable; + } + if (ret != 0x8915) { + dev_err(codec->dev, "Device is not a WM8915, ID %x\n", ret); + ret = -EINVAL; + goto err_enable; + } + + ret = snd_soc_read(codec, WM8915_CHIP_REVISION); + if (ret < 0) { + dev_err(codec->dev, "Failed to read device revision: %d\n", + ret); + goto err_enable; + } + + dev_info(codec->dev, "revision %c\n", + (ret & WM8915_CHIP_REV_MASK) + 'A'); + + if (wm8915->pdata.ldo_ena >= 0) { + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + } else { + ret = wm8915_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + goto err_enable; + } + } + + codec->cache_only = true; + + /* Apply platform data settings */ + snd_soc_update_bits(codec, WM8915_LINE_INPUT_CONTROL, + WM8915_INL_MODE_MASK | WM8915_INR_MODE_MASK, + wm8915->pdata.inl_mode << WM8915_INL_MODE_SHIFT | + wm8915->pdata.inr_mode); + + for (i = 0; i < ARRAY_SIZE(wm8915->pdata.gpio_default); i++) { + if (!wm8915->pdata.gpio_default[i]) + continue; + + snd_soc_write(codec, WM8915_GPIO_1 + i, + wm8915->pdata.gpio_default[i] & 0xffff); + } + + if (wm8915->pdata.spkmute_seq) + snd_soc_update_bits(codec, WM8915_PDM_SPEAKER_MUTE_SEQUENCE, + WM8915_SPK_MUTE_ENDIAN | + WM8915_SPK_MUTE_SEQ1_MASK, + wm8915->pdata.spkmute_seq); + + snd_soc_update_bits(codec, WM8915_ACCESSORY_DETECT_MODE_2, + WM8915_MICD_BIAS_SRC | WM8915_HPOUT1FB_SRC | + WM8915_MICD_SRC, wm8915->pdata.micdet_def); + + /* Latch volume update bits */ + snd_soc_update_bits(codec, WM8915_LEFT_LINE_INPUT_VOLUME, + WM8915_IN1_VU, WM8915_IN1_VU); + snd_soc_update_bits(codec, WM8915_RIGHT_LINE_INPUT_VOLUME, + WM8915_IN1_VU, WM8915_IN1_VU); + + snd_soc_update_bits(codec, WM8915_DAC1_LEFT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_DAC1_RIGHT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_DAC2_LEFT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + snd_soc_update_bits(codec, WM8915_DAC2_RIGHT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + + snd_soc_update_bits(codec, WM8915_OUTPUT1_LEFT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT1_RIGHT_VOLUME, + WM8915_DAC1_VU, WM8915_DAC1_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT2_LEFT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + snd_soc_update_bits(codec, WM8915_OUTPUT2_RIGHT_VOLUME, + WM8915_DAC2_VU, WM8915_DAC2_VU); + + snd_soc_update_bits(codec, WM8915_DSP1_TX_LEFT_VOLUME, + WM8915_DSP1TX_VU, WM8915_DSP1TX_VU); + snd_soc_update_bits(codec, WM8915_DSP1_TX_RIGHT_VOLUME, + WM8915_DSP1TX_VU, WM8915_DSP1TX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_TX_LEFT_VOLUME, + WM8915_DSP2TX_VU, WM8915_DSP2TX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_TX_RIGHT_VOLUME, + WM8915_DSP2TX_VU, WM8915_DSP2TX_VU); + + snd_soc_update_bits(codec, WM8915_DSP1_RX_LEFT_VOLUME, + WM8915_DSP1RX_VU, WM8915_DSP1RX_VU); + snd_soc_update_bits(codec, WM8915_DSP1_RX_RIGHT_VOLUME, + WM8915_DSP1RX_VU, WM8915_DSP1RX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_RX_LEFT_VOLUME, + WM8915_DSP2RX_VU, WM8915_DSP2RX_VU); + snd_soc_update_bits(codec, WM8915_DSP2_RX_RIGHT_VOLUME, + WM8915_DSP2RX_VU, WM8915_DSP2RX_VU); + + /* No support currently for the underclocked TDM modes and + * pick a default TDM layout with each channel pair working with + * slots 0 and 1. */ + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_0_CONFIGURATION, + WM8915_AIF1RX_CHAN0_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_1_CONFIGURATION, + WM8915_AIF1RX_CHAN1_SLOTS_MASK | + WM8915_AIF1RX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN1_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_2_CONFIGURATION, + WM8915_AIF1RX_CHAN2_SLOTS_MASK | + WM8915_AIF1RX_CHAN2_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN2_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_3_CONFIGURATION, + WM8915_AIF1RX_CHAN3_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN3_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_4_CONFIGURATION, + WM8915_AIF1RX_CHAN4_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN4_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1RX_CHANNEL_5_CONFIGURATION, + WM8915_AIF1RX_CHAN5_SLOTS_MASK | + WM8915_AIF1RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1RX_CHAN5_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_0_CONFIGURATION, + WM8915_AIF2RX_CHAN0_SLOTS_MASK | + WM8915_AIF2RX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF2RX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF2RX_CHANNEL_1_CONFIGURATION, + WM8915_AIF2RX_CHAN1_SLOTS_MASK | + WM8915_AIF2RX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF2RX_CHAN1_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_0_CONFIGURATION, + WM8915_AIF1TX_CHAN0_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8915_AIF1TX_CHAN1_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_2_CONFIGURATION, + WM8915_AIF1TX_CHAN2_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN2_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_3_CONFIGURATION, + WM8915_AIF1TX_CHAN3_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN3_SLOTS_SHIFT | 1); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_4_CONFIGURATION, + WM8915_AIF1TX_CHAN4_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN4_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_5_CONFIGURATION, + WM8915_AIF1TX_CHAN5_SLOTS_MASK | + WM8915_AIF1TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN5_SLOTS_SHIFT | 1); + + snd_soc_update_bits(codec, WM8915_AIF2TX_CHANNEL_0_CONFIGURATION, + WM8915_AIF2TX_CHAN0_SLOTS_MASK | + WM8915_AIF2TX_CHAN0_START_SLOT_MASK, + 1 << WM8915_AIF2TX_CHAN0_SLOTS_SHIFT | 0); + snd_soc_update_bits(codec, WM8915_AIF1TX_CHANNEL_1_CONFIGURATION, + WM8915_AIF2TX_CHAN1_SLOTS_MASK | + WM8915_AIF2TX_CHAN1_START_SLOT_MASK, + 1 << WM8915_AIF1TX_CHAN1_SLOTS_SHIFT | 1); + + if (wm8915->pdata.num_retune_mobile_cfgs) + wm8915_retune_mobile_pdata(codec); + else + snd_soc_add_controls(codec, wm8915_eq_controls, + ARRAY_SIZE(wm8915_eq_controls)); + + /* If the TX LRCLK pins are not in LRCLK mode configure the + * AIFs to source their clocks from the RX LRCLKs. + */ + if ((snd_soc_read(codec, WM8915_GPIO_1))) + snd_soc_update_bits(codec, WM8915_AIF1_TX_LRCLK_2, + WM8915_AIF1TX_LRCLK_MODE, + WM8915_AIF1TX_LRCLK_MODE); + + if ((snd_soc_read(codec, WM8915_GPIO_2))) + snd_soc_update_bits(codec, WM8915_AIF2_TX_LRCLK_2, + WM8915_AIF2TX_LRCLK_MODE, + WM8915_AIF2TX_LRCLK_MODE); + + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); + + wm8915_init_gpio(codec); + + if (i2c->irq) { + if (wm8915->pdata.irq_flags) + irq_flags = wm8915->pdata.irq_flags; + else + irq_flags = IRQF_TRIGGER_LOW; + + irq_flags |= IRQF_ONESHOT; + + if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) + ret = request_threaded_irq(i2c->irq, NULL, + wm8915_edge_irq, + irq_flags, "wm8915", codec); + else + ret = request_threaded_irq(i2c->irq, NULL, wm8915_irq, + irq_flags, "wm8915", codec); + + if (ret == 0) { + /* Unmask the interrupt */ + snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL, + WM8915_IM_IRQ, 0); + + /* Enable error reporting and DC servo status */ + snd_soc_update_bits(codec, + WM8915_INTERRUPT_STATUS_2_MASK, + WM8915_IM_DCS_DONE_23_EINT | + WM8915_IM_DCS_DONE_01_EINT | + WM8915_IM_FLL_LOCK_EINT | + WM8915_IM_FIFOS_ERR_EINT, + 0); + } else { + dev_err(codec->dev, "Failed to request IRQ: %d\n", + ret); + } + } + + return 0; + +err_enable: + if (wm8915->pdata.ldo_ena >= 0) + gpio_set_value_cansleep(wm8915->pdata.ldo_ena, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); +err: + return ret; +} + +static int wm8915_remove(struct snd_soc_codec *codec) +{ + struct wm8915_priv *wm8915 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c = to_i2c_client(codec->dev); + int i; + + snd_soc_update_bits(codec, WM8915_INTERRUPT_CONTROL, + WM8915_IM_IRQ, WM8915_IM_IRQ); + + if (i2c->irq) + free_irq(i2c->irq, codec); + + wm8915_free_gpio(codec); + + for (i = 0; i < ARRAY_SIZE(wm8915->supplies); i++) + regulator_unregister_notifier(wm8915->supplies[i].consumer, + &wm8915->disable_nb[i]); + regulator_bulk_free(ARRAY_SIZE(wm8915->supplies), wm8915->supplies); + + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8915 = { + .probe = wm8915_probe, + .remove = wm8915_remove, + .set_bias_level = wm8915_set_bias_level, + .seq_notifier = wm8915_seq_notifier, + .reg_cache_size = WM8915_MAX_REGISTER + 1, + .reg_word_size = sizeof(u16), + .reg_cache_default = wm8915_reg, + .volatile_register = wm8915_volatile_register, + .readable_register = wm8915_readable_register, + .compress_type = SND_SOC_RBTREE_COMPRESSION, + .controls = wm8915_snd_controls, + .num_controls = ARRAY_SIZE(wm8915_snd_controls), + .dapm_widgets = wm8915_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(wm8915_dapm_widgets), + .dapm_routes = wm8915_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(wm8915_dapm_routes), + .set_pll = wm8915_set_fll, +}; + +#define WM8915_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) +#define WM8915_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8915_dai_ops = { + .set_fmt = wm8915_set_fmt, + .hw_params = wm8915_hw_params, + .set_sysclk = wm8915_set_sysclk, +}; + +static struct snd_soc_dai_driver wm8915_dai[] = { + { + .name = "wm8915-aif1", + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 1, + .channels_max = 6, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 1, + .channels_max = 6, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .ops = &wm8915_dai_ops, + }, + { + .name = "wm8915-aif2", + .playback = { + .stream_name = "AIF2 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .capture = { + .stream_name = "AIF2 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = WM8915_RATES, + .formats = WM8915_FORMATS, + }, + .ops = &wm8915_dai_ops, + }, +}; + +static __devinit int wm8915_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8915_priv *wm8915; + int ret; + + wm8915 = kzalloc(sizeof(struct wm8915_priv), GFP_KERNEL); + if (wm8915 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, wm8915); + + if (dev_get_platdata(&i2c->dev)) + memcpy(&wm8915->pdata, dev_get_platdata(&i2c->dev), + sizeof(wm8915->pdata)); + + if (wm8915->pdata.ldo_ena > 0) { + ret = gpio_request_one(wm8915->pdata.ldo_ena, + GPIOF_OUT_INIT_LOW, "WM8915 ENA"); + if (ret < 0) { + dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n", + wm8915->pdata.ldo_ena, ret); + goto err; + } + } + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_wm8915, wm8915_dai, + ARRAY_SIZE(wm8915_dai)); + if (ret < 0) + goto err_gpio; + + return ret; + +err_gpio: + if (wm8915->pdata.ldo_ena > 0) + gpio_free(wm8915->pdata.ldo_ena); +err: + kfree(wm8915); + + return ret; +} + +static __devexit int wm8915_i2c_remove(struct i2c_client *client) +{ + struct wm8915_priv *wm8915 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + if (wm8915->pdata.ldo_ena > 0) + gpio_free(wm8915->pdata.ldo_ena); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id wm8915_i2c_id[] = { + { "wm8915", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8915_i2c_id); + +static struct i2c_driver wm8915_i2c_driver = { + .driver = { + .name = "wm8915", + .owner = THIS_MODULE, + }, + .probe = wm8915_i2c_probe, + .remove = __devexit_p(wm8915_i2c_remove), + .id_table = wm8915_i2c_id, +}; + +static int __init wm8915_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&wm8915_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8915 I2C driver: %d\n", + ret); + } + + return ret; +} +module_init(wm8915_modinit); + +static void __exit wm8915_exit(void) +{ + i2c_del_driver(&wm8915_i2c_driver); +} +module_exit(wm8915_exit); + +MODULE_DESCRIPTION("ASoC WM8915 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8915.h b/trunk/sound/soc/codecs/wm8915.h new file mode 100644 index 000000000000..200ffd7bf953 --- /dev/null +++ b/trunk/sound/soc/codecs/wm8915.h @@ -0,0 +1,3717 @@ +/* + * wm8915.h - WM8915 audio codec interface + * + * Copyright 2011 Wolfson Microelectronics PLC. + * Author: Mark Brown + * + * 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. + */ + +#ifndef _WM8915_H +#define _WM8915_H + +#define WM8915_SYSCLK_MCLK1 1 +#define WM8915_SYSCLK_MCLK2 2 +#define WM8915_SYSCLK_FLL 3 + +#define WM8915_FLL_MCLK1 1 +#define WM8915_FLL_MCLK2 2 +#define WM8915_FLL_DACLRCLK1 3 +#define WM8915_FLL_BCLK1 4 + +typedef void (*wm8915_polarity_fn)(struct snd_soc_codec *codec, int polarity); + +int wm8915_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8915_polarity_fn polarity_cb); + +/* + * Register values. + */ +#define WM8915_SOFTWARE_RESET 0x00 +#define WM8915_POWER_MANAGEMENT_1 0x01 +#define WM8915_POWER_MANAGEMENT_2 0x02 +#define WM8915_POWER_MANAGEMENT_3 0x03 +#define WM8915_POWER_MANAGEMENT_4 0x04 +#define WM8915_POWER_MANAGEMENT_5 0x05 +#define WM8915_POWER_MANAGEMENT_6 0x06 +#define WM8915_POWER_MANAGEMENT_7 0x07 +#define WM8915_POWER_MANAGEMENT_8 0x08 +#define WM8915_LEFT_LINE_INPUT_VOLUME 0x10 +#define WM8915_RIGHT_LINE_INPUT_VOLUME 0x11 +#define WM8915_LINE_INPUT_CONTROL 0x12 +#define WM8915_DAC1_HPOUT1_VOLUME 0x15 +#define WM8915_DAC2_HPOUT2_VOLUME 0x16 +#define WM8915_DAC1_LEFT_VOLUME 0x18 +#define WM8915_DAC1_RIGHT_VOLUME 0x19 +#define WM8915_DAC2_LEFT_VOLUME 0x1A +#define WM8915_DAC2_RIGHT_VOLUME 0x1B +#define WM8915_OUTPUT1_LEFT_VOLUME 0x1C +#define WM8915_OUTPUT1_RIGHT_VOLUME 0x1D +#define WM8915_OUTPUT2_LEFT_VOLUME 0x1E +#define WM8915_OUTPUT2_RIGHT_VOLUME 0x1F +#define WM8915_MICBIAS_1 0x20 +#define WM8915_MICBIAS_2 0x21 +#define WM8915_LDO_1 0x28 +#define WM8915_LDO_2 0x29 +#define WM8915_ACCESSORY_DETECT_MODE_1 0x30 +#define WM8915_ACCESSORY_DETECT_MODE_2 0x31 +#define WM8915_HEADPHONE_DETECT_1 0x34 +#define WM8915_HEADPHONE_DETECT_2 0x35 +#define WM8915_MIC_DETECT_1 0x38 +#define WM8915_MIC_DETECT_2 0x39 +#define WM8915_MIC_DETECT_3 0x3A +#define WM8915_CHARGE_PUMP_1 0x40 +#define WM8915_CHARGE_PUMP_2 0x41 +#define WM8915_DC_SERVO_1 0x50 +#define WM8915_DC_SERVO_2 0x51 +#define WM8915_DC_SERVO_3 0x52 +#define WM8915_DC_SERVO_5 0x54 +#define WM8915_DC_SERVO_6 0x55 +#define WM8915_DC_SERVO_7 0x56 +#define WM8915_DC_SERVO_READBACK_0 0x57 +#define WM8915_ANALOGUE_HP_1 0x60 +#define WM8915_ANALOGUE_HP_2 0x61 +#define WM8915_CHIP_REVISION 0x100 +#define WM8915_CONTROL_INTERFACE_1 0x101 +#define WM8915_WRITE_SEQUENCER_CTRL_1 0x110 +#define WM8915_WRITE_SEQUENCER_CTRL_2 0x111 +#define WM8915_AIF_CLOCKING_1 0x200 +#define WM8915_AIF_CLOCKING_2 0x201 +#define WM8915_CLOCKING_1 0x208 +#define WM8915_CLOCKING_2 0x209 +#define WM8915_AIF_RATE 0x210 +#define WM8915_FLL_CONTROL_1 0x220 +#define WM8915_FLL_CONTROL_2 0x221 +#define WM8915_FLL_CONTROL_3 0x222 +#define WM8915_FLL_CONTROL_4 0x223 +#define WM8915_FLL_CONTROL_5 0x224 +#define WM8915_FLL_CONTROL_6 0x225 +#define WM8915_FLL_EFS_1 0x226 +#define WM8915_FLL_EFS_2 0x227 +#define WM8915_AIF1_CONTROL 0x300 +#define WM8915_AIF1_BCLK 0x301 +#define WM8915_AIF1_TX_LRCLK_1 0x302 +#define WM8915_AIF1_TX_LRCLK_2 0x303 +#define WM8915_AIF1_RX_LRCLK_1 0x304 +#define WM8915_AIF1_RX_LRCLK_2 0x305 +#define WM8915_AIF1TX_DATA_CONFIGURATION_1 0x306 +#define WM8915_AIF1TX_DATA_CONFIGURATION_2 0x307 +#define WM8915_AIF1RX_DATA_CONFIGURATION 0x308 +#define WM8915_AIF1TX_CHANNEL_0_CONFIGURATION 0x309 +#define WM8915_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A +#define WM8915_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B +#define WM8915_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C +#define WM8915_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D +#define WM8915_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E +#define WM8915_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F +#define WM8915_AIF1RX_CHANNEL_1_CONFIGURATION 0x310 +#define WM8915_AIF1RX_CHANNEL_2_CONFIGURATION 0x311 +#define WM8915_AIF1RX_CHANNEL_3_CONFIGURATION 0x312 +#define WM8915_AIF1RX_CHANNEL_4_CONFIGURATION 0x313 +#define WM8915_AIF1RX_CHANNEL_5_CONFIGURATION 0x314 +#define WM8915_AIF1RX_MONO_CONFIGURATION 0x315 +#define WM8915_AIF1TX_TEST 0x31A +#define WM8915_AIF2_CONTROL 0x320 +#define WM8915_AIF2_BCLK 0x321 +#define WM8915_AIF2_TX_LRCLK_1 0x322 +#define WM8915_AIF2_TX_LRCLK_2 0x323 +#define WM8915_AIF2_RX_LRCLK_1 0x324 +#define WM8915_AIF2_RX_LRCLK_2 0x325 +#define WM8915_AIF2TX_DATA_CONFIGURATION_1 0x326 +#define WM8915_AIF2TX_DATA_CONFIGURATION_2 0x327 +#define WM8915_AIF2RX_DATA_CONFIGURATION 0x328 +#define WM8915_AIF2TX_CHANNEL_0_CONFIGURATION 0x329 +#define WM8915_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A +#define WM8915_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B +#define WM8915_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C +#define WM8915_AIF2RX_MONO_CONFIGURATION 0x32D +#define WM8915_AIF2TX_TEST 0x32F +#define WM8915_DSP1_TX_LEFT_VOLUME 0x400 +#define WM8915_DSP1_TX_RIGHT_VOLUME 0x401 +#define WM8915_DSP1_RX_LEFT_VOLUME 0x402 +#define WM8915_DSP1_RX_RIGHT_VOLUME 0x403 +#define WM8915_DSP1_TX_FILTERS 0x410 +#define WM8915_DSP1_RX_FILTERS_1 0x420 +#define WM8915_DSP1_RX_FILTERS_2 0x421 +#define WM8915_DSP1_DRC_1 0x440 +#define WM8915_DSP1_DRC_2 0x441 +#define WM8915_DSP1_DRC_3 0x442 +#define WM8915_DSP1_DRC_4 0x443 +#define WM8915_DSP1_DRC_5 0x444 +#define WM8915_DSP1_RX_EQ_GAINS_1 0x480 +#define WM8915_DSP1_RX_EQ_GAINS_2 0x481 +#define WM8915_DSP1_RX_EQ_BAND_1_A 0x482 +#define WM8915_DSP1_RX_EQ_BAND_1_B 0x483 +#define WM8915_DSP1_RX_EQ_BAND_1_PG 0x484 +#define WM8915_DSP1_RX_EQ_BAND_2_A 0x485 +#define WM8915_DSP1_RX_EQ_BAND_2_B 0x486 +#define WM8915_DSP1_RX_EQ_BAND_2_C 0x487 +#define WM8915_DSP1_RX_EQ_BAND_2_PG 0x488 +#define WM8915_DSP1_RX_EQ_BAND_3_A 0x489 +#define WM8915_DSP1_RX_EQ_BAND_3_B 0x48A +#define WM8915_DSP1_RX_EQ_BAND_3_C 0x48B +#define WM8915_DSP1_RX_EQ_BAND_3_PG 0x48C +#define WM8915_DSP1_RX_EQ_BAND_4_A 0x48D +#define WM8915_DSP1_RX_EQ_BAND_4_B 0x48E +#define WM8915_DSP1_RX_EQ_BAND_4_C 0x48F +#define WM8915_DSP1_RX_EQ_BAND_4_PG 0x490 +#define WM8915_DSP1_RX_EQ_BAND_5_A 0x491 +#define WM8915_DSP1_RX_EQ_BAND_5_B 0x492 +#define WM8915_DSP1_RX_EQ_BAND_5_PG 0x493 +#define WM8915_DSP2_TX_LEFT_VOLUME 0x500 +#define WM8915_DSP2_TX_RIGHT_VOLUME 0x501 +#define WM8915_DSP2_RX_LEFT_VOLUME 0x502 +#define WM8915_DSP2_RX_RIGHT_VOLUME 0x503 +#define WM8915_DSP2_TX_FILTERS 0x510 +#define WM8915_DSP2_RX_FILTERS_1 0x520 +#define WM8915_DSP2_RX_FILTERS_2 0x521 +#define WM8915_DSP2_DRC_1 0x540 +#define WM8915_DSP2_DRC_2 0x541 +#define WM8915_DSP2_DRC_3 0x542 +#define WM8915_DSP2_DRC_4 0x543 +#define WM8915_DSP2_DRC_5 0x544 +#define WM8915_DSP2_RX_EQ_GAINS_1 0x580 +#define WM8915_DSP2_RX_EQ_GAINS_2 0x581 +#define WM8915_DSP2_RX_EQ_BAND_1_A 0x582 +#define WM8915_DSP2_RX_EQ_BAND_1_B 0x583 +#define WM8915_DSP2_RX_EQ_BAND_1_PG 0x584 +#define WM8915_DSP2_RX_EQ_BAND_2_A 0x585 +#define WM8915_DSP2_RX_EQ_BAND_2_B 0x586 +#define WM8915_DSP2_RX_EQ_BAND_2_C 0x587 +#define WM8915_DSP2_RX_EQ_BAND_2_PG 0x588 +#define WM8915_DSP2_RX_EQ_BAND_3_A 0x589 +#define WM8915_DSP2_RX_EQ_BAND_3_B 0x58A +#define WM8915_DSP2_RX_EQ_BAND_3_C 0x58B +#define WM8915_DSP2_RX_EQ_BAND_3_PG 0x58C +#define WM8915_DSP2_RX_EQ_BAND_4_A 0x58D +#define WM8915_DSP2_RX_EQ_BAND_4_B 0x58E +#define WM8915_DSP2_RX_EQ_BAND_4_C 0x58F +#define WM8915_DSP2_RX_EQ_BAND_4_PG 0x590 +#define WM8915_DSP2_RX_EQ_BAND_5_A 0x591 +#define WM8915_DSP2_RX_EQ_BAND_5_B 0x592 +#define WM8915_DSP2_RX_EQ_BAND_5_PG 0x593 +#define WM8915_DAC1_MIXER_VOLUMES 0x600 +#define WM8915_DAC1_LEFT_MIXER_ROUTING 0x601 +#define WM8915_DAC1_RIGHT_MIXER_ROUTING 0x602 +#define WM8915_DAC2_MIXER_VOLUMES 0x603 +#define WM8915_DAC2_LEFT_MIXER_ROUTING 0x604 +#define WM8915_DAC2_RIGHT_MIXER_ROUTING 0x605 +#define WM8915_DSP1_TX_LEFT_MIXER_ROUTING 0x606 +#define WM8915_DSP1_TX_RIGHT_MIXER_ROUTING 0x607 +#define WM8915_DSP2_TX_LEFT_MIXER_ROUTING 0x608 +#define WM8915_DSP2_TX_RIGHT_MIXER_ROUTING 0x609 +#define WM8915_DSP_TX_MIXER_SELECT 0x60A +#define WM8915_DAC_SOFTMUTE 0x610 +#define WM8915_OVERSAMPLING 0x620 +#define WM8915_SIDETONE 0x621 +#define WM8915_GPIO_1 0x700 +#define WM8915_GPIO_2 0x701 +#define WM8915_GPIO_3 0x702 +#define WM8915_GPIO_4 0x703 +#define WM8915_GPIO_5 0x704 +#define WM8915_PULL_CONTROL_1 0x720 +#define WM8915_PULL_CONTROL_2 0x721 +#define WM8915_INTERRUPT_STATUS_1 0x730 +#define WM8915_INTERRUPT_STATUS_2 0x731 +#define WM8915_INTERRUPT_RAW_STATUS_2 0x732 +#define WM8915_INTERRUPT_STATUS_1_MASK 0x738 +#define WM8915_INTERRUPT_STATUS_2_MASK 0x739 +#define WM8915_INTERRUPT_CONTROL 0x740 +#define WM8915_LEFT_PDM_SPEAKER 0x800 +#define WM8915_RIGHT_PDM_SPEAKER 0x801 +#define WM8915_PDM_SPEAKER_MUTE_SEQUENCE 0x802 +#define WM8915_PDM_SPEAKER_VOLUME 0x803 +#define WM8915_WRITE_SEQUENCER_0 0x3000 +#define WM8915_WRITE_SEQUENCER_1 0x3001 +#define WM8915_WRITE_SEQUENCER_2 0x3002 +#define WM8915_WRITE_SEQUENCER_3 0x3003 +#define WM8915_WRITE_SEQUENCER_4 0x3004 +#define WM8915_WRITE_SEQUENCER_5 0x3005 +#define WM8915_WRITE_SEQUENCER_6 0x3006 +#define WM8915_WRITE_SEQUENCER_7 0x3007 +#define WM8915_WRITE_SEQUENCER_8 0x3008 +#define WM8915_WRITE_SEQUENCER_9 0x3009 +#define WM8915_WRITE_SEQUENCER_10 0x300A +#define WM8915_WRITE_SEQUENCER_11 0x300B +#define WM8915_WRITE_SEQUENCER_12 0x300C +#define WM8915_WRITE_SEQUENCER_13 0x300D +#define WM8915_WRITE_SEQUENCER_14 0x300E +#define WM8915_WRITE_SEQUENCER_15 0x300F +#define WM8915_WRITE_SEQUENCER_16 0x3010 +#define WM8915_WRITE_SEQUENCER_17 0x3011 +#define WM8915_WRITE_SEQUENCER_18 0x3012 +#define WM8915_WRITE_SEQUENCER_19 0x3013 +#define WM8915_WRITE_SEQUENCER_20 0x3014 +#define WM8915_WRITE_SEQUENCER_21 0x3015 +#define WM8915_WRITE_SEQUENCER_22 0x3016 +#define WM8915_WRITE_SEQUENCER_23 0x3017 +#define WM8915_WRITE_SEQUENCER_24 0x3018 +#define WM8915_WRITE_SEQUENCER_25 0x3019 +#define WM8915_WRITE_SEQUENCER_26 0x301A +#define WM8915_WRITE_SEQUENCER_27 0x301B +#define WM8915_WRITE_SEQUENCER_28 0x301C +#define WM8915_WRITE_SEQUENCER_29 0x301D +#define WM8915_WRITE_SEQUENCER_30 0x301E +#define WM8915_WRITE_SEQUENCER_31 0x301F +#define WM8915_WRITE_SEQUENCER_32 0x3020 +#define WM8915_WRITE_SEQUENCER_33 0x3021 +#define WM8915_WRITE_SEQUENCER_34 0x3022 +#define WM8915_WRITE_SEQUENCER_35 0x3023 +#define WM8915_WRITE_SEQUENCER_36 0x3024 +#define WM8915_WRITE_SEQUENCER_37 0x3025 +#define WM8915_WRITE_SEQUENCER_38 0x3026 +#define WM8915_WRITE_SEQUENCER_39 0x3027 +#define WM8915_WRITE_SEQUENCER_40 0x3028 +#define WM8915_WRITE_SEQUENCER_41 0x3029 +#define WM8915_WRITE_SEQUENCER_42 0x302A +#define WM8915_WRITE_SEQUENCER_43 0x302B +#define WM8915_WRITE_SEQUENCER_44 0x302C +#define WM8915_WRITE_SEQUENCER_45 0x302D +#define WM8915_WRITE_SEQUENCER_46 0x302E +#define WM8915_WRITE_SEQUENCER_47 0x302F +#define WM8915_WRITE_SEQUENCER_48 0x3030 +#define WM8915_WRITE_SEQUENCER_49 0x3031 +#define WM8915_WRITE_SEQUENCER_50 0x3032 +#define WM8915_WRITE_SEQUENCER_51 0x3033 +#define WM8915_WRITE_SEQUENCER_52 0x3034 +#define WM8915_WRITE_SEQUENCER_53 0x3035 +#define WM8915_WRITE_SEQUENCER_54 0x3036 +#define WM8915_WRITE_SEQUENCER_55 0x3037 +#define WM8915_WRITE_SEQUENCER_56 0x3038 +#define WM8915_WRITE_SEQUENCER_57 0x3039 +#define WM8915_WRITE_SEQUENCER_58 0x303A +#define WM8915_WRITE_SEQUENCER_59 0x303B +#define WM8915_WRITE_SEQUENCER_60 0x303C +#define WM8915_WRITE_SEQUENCER_61 0x303D +#define WM8915_WRITE_SEQUENCER_62 0x303E +#define WM8915_WRITE_SEQUENCER_63 0x303F +#define WM8915_WRITE_SEQUENCER_64 0x3040 +#define WM8915_WRITE_SEQUENCER_65 0x3041 +#define WM8915_WRITE_SEQUENCER_66 0x3042 +#define WM8915_WRITE_SEQUENCER_67 0x3043 +#define WM8915_WRITE_SEQUENCER_68 0x3044 +#define WM8915_WRITE_SEQUENCER_69 0x3045 +#define WM8915_WRITE_SEQUENCER_70 0x3046 +#define WM8915_WRITE_SEQUENCER_71 0x3047 +#define WM8915_WRITE_SEQUENCER_72 0x3048 +#define WM8915_WRITE_SEQUENCER_73 0x3049 +#define WM8915_WRITE_SEQUENCER_74 0x304A +#define WM8915_WRITE_SEQUENCER_75 0x304B +#define WM8915_WRITE_SEQUENCER_76 0x304C +#define WM8915_WRITE_SEQUENCER_77 0x304D +#define WM8915_WRITE_SEQUENCER_78 0x304E +#define WM8915_WRITE_SEQUENCER_79 0x304F +#define WM8915_WRITE_SEQUENCER_80 0x3050 +#define WM8915_WRITE_SEQUENCER_81 0x3051 +#define WM8915_WRITE_SEQUENCER_82 0x3052 +#define WM8915_WRITE_SEQUENCER_83 0x3053 +#define WM8915_WRITE_SEQUENCER_84 0x3054 +#define WM8915_WRITE_SEQUENCER_85 0x3055 +#define WM8915_WRITE_SEQUENCER_86 0x3056 +#define WM8915_WRITE_SEQUENCER_87 0x3057 +#define WM8915_WRITE_SEQUENCER_88 0x3058 +#define WM8915_WRITE_SEQUENCER_89 0x3059 +#define WM8915_WRITE_SEQUENCER_90 0x305A +#define WM8915_WRITE_SEQUENCER_91 0x305B +#define WM8915_WRITE_SEQUENCER_92 0x305C +#define WM8915_WRITE_SEQUENCER_93 0x305D +#define WM8915_WRITE_SEQUENCER_94 0x305E +#define WM8915_WRITE_SEQUENCER_95 0x305F +#define WM8915_WRITE_SEQUENCER_96 0x3060 +#define WM8915_WRITE_SEQUENCER_97 0x3061 +#define WM8915_WRITE_SEQUENCER_98 0x3062 +#define WM8915_WRITE_SEQUENCER_99 0x3063 +#define WM8915_WRITE_SEQUENCER_100 0x3064 +#define WM8915_WRITE_SEQUENCER_101 0x3065 +#define WM8915_WRITE_SEQUENCER_102 0x3066 +#define WM8915_WRITE_SEQUENCER_103 0x3067 +#define WM8915_WRITE_SEQUENCER_104 0x3068 +#define WM8915_WRITE_SEQUENCER_105 0x3069 +#define WM8915_WRITE_SEQUENCER_106 0x306A +#define WM8915_WRITE_SEQUENCER_107 0x306B +#define WM8915_WRITE_SEQUENCER_108 0x306C +#define WM8915_WRITE_SEQUENCER_109 0x306D +#define WM8915_WRITE_SEQUENCER_110 0x306E +#define WM8915_WRITE_SEQUENCER_111 0x306F +#define WM8915_WRITE_SEQUENCER_112 0x3070 +#define WM8915_WRITE_SEQUENCER_113 0x3071 +#define WM8915_WRITE_SEQUENCER_114 0x3072 +#define WM8915_WRITE_SEQUENCER_115 0x3073 +#define WM8915_WRITE_SEQUENCER_116 0x3074 +#define WM8915_WRITE_SEQUENCER_117 0x3075 +#define WM8915_WRITE_SEQUENCER_118 0x3076 +#define WM8915_WRITE_SEQUENCER_119 0x3077 +#define WM8915_WRITE_SEQUENCER_120 0x3078 +#define WM8915_WRITE_SEQUENCER_121 0x3079 +#define WM8915_WRITE_SEQUENCER_122 0x307A +#define WM8915_WRITE_SEQUENCER_123 0x307B +#define WM8915_WRITE_SEQUENCER_124 0x307C +#define WM8915_WRITE_SEQUENCER_125 0x307D +#define WM8915_WRITE_SEQUENCER_126 0x307E +#define WM8915_WRITE_SEQUENCER_127 0x307F +#define WM8915_WRITE_SEQUENCER_128 0x3080 +#define WM8915_WRITE_SEQUENCER_129 0x3081 +#define WM8915_WRITE_SEQUENCER_130 0x3082 +#define WM8915_WRITE_SEQUENCER_131 0x3083 +#define WM8915_WRITE_SEQUENCER_132 0x3084 +#define WM8915_WRITE_SEQUENCER_133 0x3085 +#define WM8915_WRITE_SEQUENCER_134 0x3086 +#define WM8915_WRITE_SEQUENCER_135 0x3087 +#define WM8915_WRITE_SEQUENCER_136 0x3088 +#define WM8915_WRITE_SEQUENCER_137 0x3089 +#define WM8915_WRITE_SEQUENCER_138 0x308A +#define WM8915_WRITE_SEQUENCER_139 0x308B +#define WM8915_WRITE_SEQUENCER_140 0x308C +#define WM8915_WRITE_SEQUENCER_141 0x308D +#define WM8915_WRITE_SEQUENCER_142 0x308E +#define WM8915_WRITE_SEQUENCER_143 0x308F +#define WM8915_WRITE_SEQUENCER_144 0x3090 +#define WM8915_WRITE_SEQUENCER_145 0x3091 +#define WM8915_WRITE_SEQUENCER_146 0x3092 +#define WM8915_WRITE_SEQUENCER_147 0x3093 +#define WM8915_WRITE_SEQUENCER_148 0x3094 +#define WM8915_WRITE_SEQUENCER_149 0x3095 +#define WM8915_WRITE_SEQUENCER_150 0x3096 +#define WM8915_WRITE_SEQUENCER_151 0x3097 +#define WM8915_WRITE_SEQUENCER_152 0x3098 +#define WM8915_WRITE_SEQUENCER_153 0x3099 +#define WM8915_WRITE_SEQUENCER_154 0x309A +#define WM8915_WRITE_SEQUENCER_155 0x309B +#define WM8915_WRITE_SEQUENCER_156 0x309C +#define WM8915_WRITE_SEQUENCER_157 0x309D +#define WM8915_WRITE_SEQUENCER_158 0x309E +#define WM8915_WRITE_SEQUENCER_159 0x309F +#define WM8915_WRITE_SEQUENCER_160 0x30A0 +#define WM8915_WRITE_SEQUENCER_161 0x30A1 +#define WM8915_WRITE_SEQUENCER_162 0x30A2 +#define WM8915_WRITE_SEQUENCER_163 0x30A3 +#define WM8915_WRITE_SEQUENCER_164 0x30A4 +#define WM8915_WRITE_SEQUENCER_165 0x30A5 +#define WM8915_WRITE_SEQUENCER_166 0x30A6 +#define WM8915_WRITE_SEQUENCER_167 0x30A7 +#define WM8915_WRITE_SEQUENCER_168 0x30A8 +#define WM8915_WRITE_SEQUENCER_169 0x30A9 +#define WM8915_WRITE_SEQUENCER_170 0x30AA +#define WM8915_WRITE_SEQUENCER_171 0x30AB +#define WM8915_WRITE_SEQUENCER_172 0x30AC +#define WM8915_WRITE_SEQUENCER_173 0x30AD +#define WM8915_WRITE_SEQUENCER_174 0x30AE +#define WM8915_WRITE_SEQUENCER_175 0x30AF +#define WM8915_WRITE_SEQUENCER_176 0x30B0 +#define WM8915_WRITE_SEQUENCER_177 0x30B1 +#define WM8915_WRITE_SEQUENCER_178 0x30B2 +#define WM8915_WRITE_SEQUENCER_179 0x30B3 +#define WM8915_WRITE_SEQUENCER_180 0x30B4 +#define WM8915_WRITE_SEQUENCER_181 0x30B5 +#define WM8915_WRITE_SEQUENCER_182 0x30B6 +#define WM8915_WRITE_SEQUENCER_183 0x30B7 +#define WM8915_WRITE_SEQUENCER_184 0x30B8 +#define WM8915_WRITE_SEQUENCER_185 0x30B9 +#define WM8915_WRITE_SEQUENCER_186 0x30BA +#define WM8915_WRITE_SEQUENCER_187 0x30BB +#define WM8915_WRITE_SEQUENCER_188 0x30BC +#define WM8915_WRITE_SEQUENCER_189 0x30BD +#define WM8915_WRITE_SEQUENCER_190 0x30BE +#define WM8915_WRITE_SEQUENCER_191 0x30BF +#define WM8915_WRITE_SEQUENCER_192 0x30C0 +#define WM8915_WRITE_SEQUENCER_193 0x30C1 +#define WM8915_WRITE_SEQUENCER_194 0x30C2 +#define WM8915_WRITE_SEQUENCER_195 0x30C3 +#define WM8915_WRITE_SEQUENCER_196 0x30C4 +#define WM8915_WRITE_SEQUENCER_197 0x30C5 +#define WM8915_WRITE_SEQUENCER_198 0x30C6 +#define WM8915_WRITE_SEQUENCER_199 0x30C7 +#define WM8915_WRITE_SEQUENCER_200 0x30C8 +#define WM8915_WRITE_SEQUENCER_201 0x30C9 +#define WM8915_WRITE_SEQUENCER_202 0x30CA +#define WM8915_WRITE_SEQUENCER_203 0x30CB +#define WM8915_WRITE_SEQUENCER_204 0x30CC +#define WM8915_WRITE_SEQUENCER_205 0x30CD +#define WM8915_WRITE_SEQUENCER_206 0x30CE +#define WM8915_WRITE_SEQUENCER_207 0x30CF +#define WM8915_WRITE_SEQUENCER_208 0x30D0 +#define WM8915_WRITE_SEQUENCER_209 0x30D1 +#define WM8915_WRITE_SEQUENCER_210 0x30D2 +#define WM8915_WRITE_SEQUENCER_211 0x30D3 +#define WM8915_WRITE_SEQUENCER_212 0x30D4 +#define WM8915_WRITE_SEQUENCER_213 0x30D5 +#define WM8915_WRITE_SEQUENCER_214 0x30D6 +#define WM8915_WRITE_SEQUENCER_215 0x30D7 +#define WM8915_WRITE_SEQUENCER_216 0x30D8 +#define WM8915_WRITE_SEQUENCER_217 0x30D9 +#define WM8915_WRITE_SEQUENCER_218 0x30DA +#define WM8915_WRITE_SEQUENCER_219 0x30DB +#define WM8915_WRITE_SEQUENCER_220 0x30DC +#define WM8915_WRITE_SEQUENCER_221 0x30DD +#define WM8915_WRITE_SEQUENCER_222 0x30DE +#define WM8915_WRITE_SEQUENCER_223 0x30DF +#define WM8915_WRITE_SEQUENCER_224 0x30E0 +#define WM8915_WRITE_SEQUENCER_225 0x30E1 +#define WM8915_WRITE_SEQUENCER_226 0x30E2 +#define WM8915_WRITE_SEQUENCER_227 0x30E3 +#define WM8915_WRITE_SEQUENCER_228 0x30E4 +#define WM8915_WRITE_SEQUENCER_229 0x30E5 +#define WM8915_WRITE_SEQUENCER_230 0x30E6 +#define WM8915_WRITE_SEQUENCER_231 0x30E7 +#define WM8915_WRITE_SEQUENCER_232 0x30E8 +#define WM8915_WRITE_SEQUENCER_233 0x30E9 +#define WM8915_WRITE_SEQUENCER_234 0x30EA +#define WM8915_WRITE_SEQUENCER_235 0x30EB +#define WM8915_WRITE_SEQUENCER_236 0x30EC +#define WM8915_WRITE_SEQUENCER_237 0x30ED +#define WM8915_WRITE_SEQUENCER_238 0x30EE +#define WM8915_WRITE_SEQUENCER_239 0x30EF +#define WM8915_WRITE_SEQUENCER_240 0x30F0 +#define WM8915_WRITE_SEQUENCER_241 0x30F1 +#define WM8915_WRITE_SEQUENCER_242 0x30F2 +#define WM8915_WRITE_SEQUENCER_243 0x30F3 +#define WM8915_WRITE_SEQUENCER_244 0x30F4 +#define WM8915_WRITE_SEQUENCER_245 0x30F5 +#define WM8915_WRITE_SEQUENCER_246 0x30F6 +#define WM8915_WRITE_SEQUENCER_247 0x30F7 +#define WM8915_WRITE_SEQUENCER_248 0x30F8 +#define WM8915_WRITE_SEQUENCER_249 0x30F9 +#define WM8915_WRITE_SEQUENCER_250 0x30FA +#define WM8915_WRITE_SEQUENCER_251 0x30FB +#define WM8915_WRITE_SEQUENCER_252 0x30FC +#define WM8915_WRITE_SEQUENCER_253 0x30FD +#define WM8915_WRITE_SEQUENCER_254 0x30FE +#define WM8915_WRITE_SEQUENCER_255 0x30FF +#define WM8915_WRITE_SEQUENCER_256 0x3100 +#define WM8915_WRITE_SEQUENCER_257 0x3101 +#define WM8915_WRITE_SEQUENCER_258 0x3102 +#define WM8915_WRITE_SEQUENCER_259 0x3103 +#define WM8915_WRITE_SEQUENCER_260 0x3104 +#define WM8915_WRITE_SEQUENCER_261 0x3105 +#define WM8915_WRITE_SEQUENCER_262 0x3106 +#define WM8915_WRITE_SEQUENCER_263 0x3107 +#define WM8915_WRITE_SEQUENCER_264 0x3108 +#define WM8915_WRITE_SEQUENCER_265 0x3109 +#define WM8915_WRITE_SEQUENCER_266 0x310A +#define WM8915_WRITE_SEQUENCER_267 0x310B +#define WM8915_WRITE_SEQUENCER_268 0x310C +#define WM8915_WRITE_SEQUENCER_269 0x310D +#define WM8915_WRITE_SEQUENCER_270 0x310E +#define WM8915_WRITE_SEQUENCER_271 0x310F +#define WM8915_WRITE_SEQUENCER_272 0x3110 +#define WM8915_WRITE_SEQUENCER_273 0x3111 +#define WM8915_WRITE_SEQUENCER_274 0x3112 +#define WM8915_WRITE_SEQUENCER_275 0x3113 +#define WM8915_WRITE_SEQUENCER_276 0x3114 +#define WM8915_WRITE_SEQUENCER_277 0x3115 +#define WM8915_WRITE_SEQUENCER_278 0x3116 +#define WM8915_WRITE_SEQUENCER_279 0x3117 +#define WM8915_WRITE_SEQUENCER_280 0x3118 +#define WM8915_WRITE_SEQUENCER_281 0x3119 +#define WM8915_WRITE_SEQUENCER_282 0x311A +#define WM8915_WRITE_SEQUENCER_283 0x311B +#define WM8915_WRITE_SEQUENCER_284 0x311C +#define WM8915_WRITE_SEQUENCER_285 0x311D +#define WM8915_WRITE_SEQUENCER_286 0x311E +#define WM8915_WRITE_SEQUENCER_287 0x311F +#define WM8915_WRITE_SEQUENCER_288 0x3120 +#define WM8915_WRITE_SEQUENCER_289 0x3121 +#define WM8915_WRITE_SEQUENCER_290 0x3122 +#define WM8915_WRITE_SEQUENCER_291 0x3123 +#define WM8915_WRITE_SEQUENCER_292 0x3124 +#define WM8915_WRITE_SEQUENCER_293 0x3125 +#define WM8915_WRITE_SEQUENCER_294 0x3126 +#define WM8915_WRITE_SEQUENCER_295 0x3127 +#define WM8915_WRITE_SEQUENCER_296 0x3128 +#define WM8915_WRITE_SEQUENCER_297 0x3129 +#define WM8915_WRITE_SEQUENCER_298 0x312A +#define WM8915_WRITE_SEQUENCER_299 0x312B +#define WM8915_WRITE_SEQUENCER_300 0x312C +#define WM8915_WRITE_SEQUENCER_301 0x312D +#define WM8915_WRITE_SEQUENCER_302 0x312E +#define WM8915_WRITE_SEQUENCER_303 0x312F +#define WM8915_WRITE_SEQUENCER_304 0x3130 +#define WM8915_WRITE_SEQUENCER_305 0x3131 +#define WM8915_WRITE_SEQUENCER_306 0x3132 +#define WM8915_WRITE_SEQUENCER_307 0x3133 +#define WM8915_WRITE_SEQUENCER_308 0x3134 +#define WM8915_WRITE_SEQUENCER_309 0x3135 +#define WM8915_WRITE_SEQUENCER_310 0x3136 +#define WM8915_WRITE_SEQUENCER_311 0x3137 +#define WM8915_WRITE_SEQUENCER_312 0x3138 +#define WM8915_WRITE_SEQUENCER_313 0x3139 +#define WM8915_WRITE_SEQUENCER_314 0x313A +#define WM8915_WRITE_SEQUENCER_315 0x313B +#define WM8915_WRITE_SEQUENCER_316 0x313C +#define WM8915_WRITE_SEQUENCER_317 0x313D +#define WM8915_WRITE_SEQUENCER_318 0x313E +#define WM8915_WRITE_SEQUENCER_319 0x313F +#define WM8915_WRITE_SEQUENCER_320 0x3140 +#define WM8915_WRITE_SEQUENCER_321 0x3141 +#define WM8915_WRITE_SEQUENCER_322 0x3142 +#define WM8915_WRITE_SEQUENCER_323 0x3143 +#define WM8915_WRITE_SEQUENCER_324 0x3144 +#define WM8915_WRITE_SEQUENCER_325 0x3145 +#define WM8915_WRITE_SEQUENCER_326 0x3146 +#define WM8915_WRITE_SEQUENCER_327 0x3147 +#define WM8915_WRITE_SEQUENCER_328 0x3148 +#define WM8915_WRITE_SEQUENCER_329 0x3149 +#define WM8915_WRITE_SEQUENCER_330 0x314A +#define WM8915_WRITE_SEQUENCER_331 0x314B +#define WM8915_WRITE_SEQUENCER_332 0x314C +#define WM8915_WRITE_SEQUENCER_333 0x314D +#define WM8915_WRITE_SEQUENCER_334 0x314E +#define WM8915_WRITE_SEQUENCER_335 0x314F +#define WM8915_WRITE_SEQUENCER_336 0x3150 +#define WM8915_WRITE_SEQUENCER_337 0x3151 +#define WM8915_WRITE_SEQUENCER_338 0x3152 +#define WM8915_WRITE_SEQUENCER_339 0x3153 +#define WM8915_WRITE_SEQUENCER_340 0x3154 +#define WM8915_WRITE_SEQUENCER_341 0x3155 +#define WM8915_WRITE_SEQUENCER_342 0x3156 +#define WM8915_WRITE_SEQUENCER_343 0x3157 +#define WM8915_WRITE_SEQUENCER_344 0x3158 +#define WM8915_WRITE_SEQUENCER_345 0x3159 +#define WM8915_WRITE_SEQUENCER_346 0x315A +#define WM8915_WRITE_SEQUENCER_347 0x315B +#define WM8915_WRITE_SEQUENCER_348 0x315C +#define WM8915_WRITE_SEQUENCER_349 0x315D +#define WM8915_WRITE_SEQUENCER_350 0x315E +#define WM8915_WRITE_SEQUENCER_351 0x315F +#define WM8915_WRITE_SEQUENCER_352 0x3160 +#define WM8915_WRITE_SEQUENCER_353 0x3161 +#define WM8915_WRITE_SEQUENCER_354 0x3162 +#define WM8915_WRITE_SEQUENCER_355 0x3163 +#define WM8915_WRITE_SEQUENCER_356 0x3164 +#define WM8915_WRITE_SEQUENCER_357 0x3165 +#define WM8915_WRITE_SEQUENCER_358 0x3166 +#define WM8915_WRITE_SEQUENCER_359 0x3167 +#define WM8915_WRITE_SEQUENCER_360 0x3168 +#define WM8915_WRITE_SEQUENCER_361 0x3169 +#define WM8915_WRITE_SEQUENCER_362 0x316A +#define WM8915_WRITE_SEQUENCER_363 0x316B +#define WM8915_WRITE_SEQUENCER_364 0x316C +#define WM8915_WRITE_SEQUENCER_365 0x316D +#define WM8915_WRITE_SEQUENCER_366 0x316E +#define WM8915_WRITE_SEQUENCER_367 0x316F +#define WM8915_WRITE_SEQUENCER_368 0x3170 +#define WM8915_WRITE_SEQUENCER_369 0x3171 +#define WM8915_WRITE_SEQUENCER_370 0x3172 +#define WM8915_WRITE_SEQUENCER_371 0x3173 +#define WM8915_WRITE_SEQUENCER_372 0x3174 +#define WM8915_WRITE_SEQUENCER_373 0x3175 +#define WM8915_WRITE_SEQUENCER_374 0x3176 +#define WM8915_WRITE_SEQUENCER_375 0x3177 +#define WM8915_WRITE_SEQUENCER_376 0x3178 +#define WM8915_WRITE_SEQUENCER_377 0x3179 +#define WM8915_WRITE_SEQUENCER_378 0x317A +#define WM8915_WRITE_SEQUENCER_379 0x317B +#define WM8915_WRITE_SEQUENCER_380 0x317C +#define WM8915_WRITE_SEQUENCER_381 0x317D +#define WM8915_WRITE_SEQUENCER_382 0x317E +#define WM8915_WRITE_SEQUENCER_383 0x317F +#define WM8915_WRITE_SEQUENCER_384 0x3180 +#define WM8915_WRITE_SEQUENCER_385 0x3181 +#define WM8915_WRITE_SEQUENCER_386 0x3182 +#define WM8915_WRITE_SEQUENCER_387 0x3183 +#define WM8915_WRITE_SEQUENCER_388 0x3184 +#define WM8915_WRITE_SEQUENCER_389 0x3185 +#define WM8915_WRITE_SEQUENCER_390 0x3186 +#define WM8915_WRITE_SEQUENCER_391 0x3187 +#define WM8915_WRITE_SEQUENCER_392 0x3188 +#define WM8915_WRITE_SEQUENCER_393 0x3189 +#define WM8915_WRITE_SEQUENCER_394 0x318A +#define WM8915_WRITE_SEQUENCER_395 0x318B +#define WM8915_WRITE_SEQUENCER_396 0x318C +#define WM8915_WRITE_SEQUENCER_397 0x318D +#define WM8915_WRITE_SEQUENCER_398 0x318E +#define WM8915_WRITE_SEQUENCER_399 0x318F +#define WM8915_WRITE_SEQUENCER_400 0x3190 +#define WM8915_WRITE_SEQUENCER_401 0x3191 +#define WM8915_WRITE_SEQUENCER_402 0x3192 +#define WM8915_WRITE_SEQUENCER_403 0x3193 +#define WM8915_WRITE_SEQUENCER_404 0x3194 +#define WM8915_WRITE_SEQUENCER_405 0x3195 +#define WM8915_WRITE_SEQUENCER_406 0x3196 +#define WM8915_WRITE_SEQUENCER_407 0x3197 +#define WM8915_WRITE_SEQUENCER_408 0x3198 +#define WM8915_WRITE_SEQUENCER_409 0x3199 +#define WM8915_WRITE_SEQUENCER_410 0x319A +#define WM8915_WRITE_SEQUENCER_411 0x319B +#define WM8915_WRITE_SEQUENCER_412 0x319C +#define WM8915_WRITE_SEQUENCER_413 0x319D +#define WM8915_WRITE_SEQUENCER_414 0x319E +#define WM8915_WRITE_SEQUENCER_415 0x319F +#define WM8915_WRITE_SEQUENCER_416 0x31A0 +#define WM8915_WRITE_SEQUENCER_417 0x31A1 +#define WM8915_WRITE_SEQUENCER_418 0x31A2 +#define WM8915_WRITE_SEQUENCER_419 0x31A3 +#define WM8915_WRITE_SEQUENCER_420 0x31A4 +#define WM8915_WRITE_SEQUENCER_421 0x31A5 +#define WM8915_WRITE_SEQUENCER_422 0x31A6 +#define WM8915_WRITE_SEQUENCER_423 0x31A7 +#define WM8915_WRITE_SEQUENCER_424 0x31A8 +#define WM8915_WRITE_SEQUENCER_425 0x31A9 +#define WM8915_WRITE_SEQUENCER_426 0x31AA +#define WM8915_WRITE_SEQUENCER_427 0x31AB +#define WM8915_WRITE_SEQUENCER_428 0x31AC +#define WM8915_WRITE_SEQUENCER_429 0x31AD +#define WM8915_WRITE_SEQUENCER_430 0x31AE +#define WM8915_WRITE_SEQUENCER_431 0x31AF +#define WM8915_WRITE_SEQUENCER_432 0x31B0 +#define WM8915_WRITE_SEQUENCER_433 0x31B1 +#define WM8915_WRITE_SEQUENCER_434 0x31B2 +#define WM8915_WRITE_SEQUENCER_435 0x31B3 +#define WM8915_WRITE_SEQUENCER_436 0x31B4 +#define WM8915_WRITE_SEQUENCER_437 0x31B5 +#define WM8915_WRITE_SEQUENCER_438 0x31B6 +#define WM8915_WRITE_SEQUENCER_439 0x31B7 +#define WM8915_WRITE_SEQUENCER_440 0x31B8 +#define WM8915_WRITE_SEQUENCER_441 0x31B9 +#define WM8915_WRITE_SEQUENCER_442 0x31BA +#define WM8915_WRITE_SEQUENCER_443 0x31BB +#define WM8915_WRITE_SEQUENCER_444 0x31BC +#define WM8915_WRITE_SEQUENCER_445 0x31BD +#define WM8915_WRITE_SEQUENCER_446 0x31BE +#define WM8915_WRITE_SEQUENCER_447 0x31BF +#define WM8915_WRITE_SEQUENCER_448 0x31C0 +#define WM8915_WRITE_SEQUENCER_449 0x31C1 +#define WM8915_WRITE_SEQUENCER_450 0x31C2 +#define WM8915_WRITE_SEQUENCER_451 0x31C3 +#define WM8915_WRITE_SEQUENCER_452 0x31C4 +#define WM8915_WRITE_SEQUENCER_453 0x31C5 +#define WM8915_WRITE_SEQUENCER_454 0x31C6 +#define WM8915_WRITE_SEQUENCER_455 0x31C7 +#define WM8915_WRITE_SEQUENCER_456 0x31C8 +#define WM8915_WRITE_SEQUENCER_457 0x31C9 +#define WM8915_WRITE_SEQUENCER_458 0x31CA +#define WM8915_WRITE_SEQUENCER_459 0x31CB +#define WM8915_WRITE_SEQUENCER_460 0x31CC +#define WM8915_WRITE_SEQUENCER_461 0x31CD +#define WM8915_WRITE_SEQUENCER_462 0x31CE +#define WM8915_WRITE_SEQUENCER_463 0x31CF +#define WM8915_WRITE_SEQUENCER_464 0x31D0 +#define WM8915_WRITE_SEQUENCER_465 0x31D1 +#define WM8915_WRITE_SEQUENCER_466 0x31D2 +#define WM8915_WRITE_SEQUENCER_467 0x31D3 +#define WM8915_WRITE_SEQUENCER_468 0x31D4 +#define WM8915_WRITE_SEQUENCER_469 0x31D5 +#define WM8915_WRITE_SEQUENCER_470 0x31D6 +#define WM8915_WRITE_SEQUENCER_471 0x31D7 +#define WM8915_WRITE_SEQUENCER_472 0x31D8 +#define WM8915_WRITE_SEQUENCER_473 0x31D9 +#define WM8915_WRITE_SEQUENCER_474 0x31DA +#define WM8915_WRITE_SEQUENCER_475 0x31DB +#define WM8915_WRITE_SEQUENCER_476 0x31DC +#define WM8915_WRITE_SEQUENCER_477 0x31DD +#define WM8915_WRITE_SEQUENCER_478 0x31DE +#define WM8915_WRITE_SEQUENCER_479 0x31DF +#define WM8915_WRITE_SEQUENCER_480 0x31E0 +#define WM8915_WRITE_SEQUENCER_481 0x31E1 +#define WM8915_WRITE_SEQUENCER_482 0x31E2 +#define WM8915_WRITE_SEQUENCER_483 0x31E3 +#define WM8915_WRITE_SEQUENCER_484 0x31E4 +#define WM8915_WRITE_SEQUENCER_485 0x31E5 +#define WM8915_WRITE_SEQUENCER_486 0x31E6 +#define WM8915_WRITE_SEQUENCER_487 0x31E7 +#define WM8915_WRITE_SEQUENCER_488 0x31E8 +#define WM8915_WRITE_SEQUENCER_489 0x31E9 +#define WM8915_WRITE_SEQUENCER_490 0x31EA +#define WM8915_WRITE_SEQUENCER_491 0x31EB +#define WM8915_WRITE_SEQUENCER_492 0x31EC +#define WM8915_WRITE_SEQUENCER_493 0x31ED +#define WM8915_WRITE_SEQUENCER_494 0x31EE +#define WM8915_WRITE_SEQUENCER_495 0x31EF +#define WM8915_WRITE_SEQUENCER_496 0x31F0 +#define WM8915_WRITE_SEQUENCER_497 0x31F1 +#define WM8915_WRITE_SEQUENCER_498 0x31F2 +#define WM8915_WRITE_SEQUENCER_499 0x31F3 +#define WM8915_WRITE_SEQUENCER_500 0x31F4 +#define WM8915_WRITE_SEQUENCER_501 0x31F5 +#define WM8915_WRITE_SEQUENCER_502 0x31F6 +#define WM8915_WRITE_SEQUENCER_503 0x31F7 +#define WM8915_WRITE_SEQUENCER_504 0x31F8 +#define WM8915_WRITE_SEQUENCER_505 0x31F9 +#define WM8915_WRITE_SEQUENCER_506 0x31FA +#define WM8915_WRITE_SEQUENCER_507 0x31FB +#define WM8915_WRITE_SEQUENCER_508 0x31FC +#define WM8915_WRITE_SEQUENCER_509 0x31FD +#define WM8915_WRITE_SEQUENCER_510 0x31FE +#define WM8915_WRITE_SEQUENCER_511 0x31FF + +#define WM8915_REGISTER_COUNT 706 +#define WM8915_MAX_REGISTER 0x31FF + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Software Reset + */ +#define WM8915_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */ +#define WM8915_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */ +#define WM8915_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */ + +/* + * R1 (0x01) - Power Management (1) + */ +#define WM8915_MICB2_ENA 0x0200 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_SHIFT 9 /* MICB2_ENA */ +#define WM8915_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ +#define WM8915_MICB1_ENA 0x0100 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_SHIFT 8 /* MICB1_ENA */ +#define WM8915_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ +#define WM8915_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */ +#define WM8915_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */ +#define WM8915_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */ +#define WM8915_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */ +#define WM8915_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */ +#define WM8915_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */ +#define WM8915_BG_ENA 0x0001 /* BG_ENA */ +#define WM8915_BG_ENA_MASK 0x0001 /* BG_ENA */ +#define WM8915_BG_ENA_SHIFT 0 /* BG_ENA */ +#define WM8915_BG_ENA_WIDTH 1 /* BG_ENA */ + +/* + * R2 (0x02) - Power Management (2) + */ +#define WM8915_OPCLK_ENA 0x0800 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ +#define WM8915_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8915_INL_ENA 0x0020 /* INL_ENA */ +#define WM8915_INL_ENA_MASK 0x0020 /* INL_ENA */ +#define WM8915_INL_ENA_SHIFT 5 /* INL_ENA */ +#define WM8915_INL_ENA_WIDTH 1 /* INL_ENA */ +#define WM8915_INR_ENA 0x0010 /* INR_ENA */ +#define WM8915_INR_ENA_MASK 0x0010 /* INR_ENA */ +#define WM8915_INR_ENA_SHIFT 4 /* INR_ENA */ +#define WM8915_INR_ENA_WIDTH 1 /* INR_ENA */ +#define WM8915_LDO2_ENA 0x0002 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_SHIFT 1 /* LDO2_ENA */ +#define WM8915_LDO2_ENA_WIDTH 1 /* LDO2_ENA */ + +/* + * R3 (0x03) - Power Management (3) + */ +#define WM8915_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */ +#define WM8915_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */ +#define WM8915_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */ +#define WM8915_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */ +#define WM8915_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */ +#define WM8915_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */ +#define WM8915_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */ +#define WM8915_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */ +#define WM8915_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */ +#define WM8915_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */ +#define WM8915_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */ +#define WM8915_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */ +#define WM8915_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */ +#define WM8915_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */ +#define WM8915_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8915_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8915_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8915_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R4 (0x04) - Power Management (4) + */ +#define WM8915_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */ +#define WM8915_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */ + +/* + * R5 (0x05) - Power Management (5) + */ +#define WM8915_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */ +#define WM8915_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */ +#define WM8915_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */ +#define WM8915_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */ +#define WM8915_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */ +#define WM8915_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */ +#define WM8915_DAC2L_ENA 0x0008 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */ +#define WM8915_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */ +#define WM8915_DAC2R_ENA 0x0004 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */ +#define WM8915_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */ +#define WM8915_DAC1L_ENA 0x0002 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */ +#define WM8915_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */ +#define WM8915_DAC1R_ENA 0x0001 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */ +#define WM8915_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */ + +/* + * R6 (0x06) - Power Management (6) + */ +#define WM8915_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */ +#define WM8915_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */ + +/* + * R7 (0x07) - Power Management (7) + */ +#define WM8915_DMIC2_FN 0x0200 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_SHIFT 9 /* DMIC2_FN */ +#define WM8915_DMIC2_FN_WIDTH 1 /* DMIC2_FN */ +#define WM8915_DMIC1_FN 0x0100 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_SHIFT 8 /* DMIC1_FN */ +#define WM8915_DMIC1_FN_WIDTH 1 /* DMIC1_FN */ +#define WM8915_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */ +#define WM8915_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */ +#define WM8915_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */ +#define WM8915_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */ +#define WM8915_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */ +#define WM8915_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */ + +/* + * R8 (0x08) - Power Management (8) + */ +#define WM8915_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */ +#define WM8915_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */ +#define WM8915_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */ +#define WM8915_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */ +#define WM8915_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */ +#define WM8915_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */ +#define WM8915_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */ + +/* + * R16 (0x10) - Left Line Input Volume + */ +#define WM8915_IN1_VU 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8915_IN1L_ZC 0x0020 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_SHIFT 5 /* IN1L_ZC */ +#define WM8915_IN1L_ZC_WIDTH 1 /* IN1L_ZC */ +#define WM8915_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */ +#define WM8915_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */ +#define WM8915_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */ + +/* + * R17 (0x11) - Right Line Input Volume + */ +#define WM8915_IN1_VU 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8915_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8915_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8915_IN1R_ZC 0x0020 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_SHIFT 5 /* IN1R_ZC */ +#define WM8915_IN1R_ZC_WIDTH 1 /* IN1R_ZC */ +#define WM8915_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */ +#define WM8915_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */ +#define WM8915_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */ + +/* + * R18 (0x12) - Line Input Control + */ +#define WM8915_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */ +#define WM8915_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */ +#define WM8915_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */ +#define WM8915_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */ +#define WM8915_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */ +#define WM8915_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */ + +/* + * R21 (0x15) - DAC1 HPOUT1 Volume + */ +#define WM8915_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ +#define WM8915_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */ +#define WM8915_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */ +#define WM8915_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */ + +/* + * R22 (0x16) - DAC2 HPOUT2 Volume + */ +#define WM8915_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ +#define WM8915_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */ +#define WM8915_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */ +#define WM8915_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */ + +/* + * R24 (0x18) - DAC1 Left Volume + */ +#define WM8915_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */ +#define WM8915_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */ +#define WM8915_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */ +#define WM8915_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */ + +/* + * R25 (0x19) - DAC1 Right Volume + */ +#define WM8915_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */ +#define WM8915_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */ +#define WM8915_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */ +#define WM8915_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */ + +/* + * R26 (0x1A) - DAC2 Left Volume + */ +#define WM8915_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */ +#define WM8915_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */ +#define WM8915_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */ +#define WM8915_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */ + +/* + * R27 (0x1B) - DAC2 Right Volume + */ +#define WM8915_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */ +#define WM8915_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */ +#define WM8915_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */ +#define WM8915_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */ + +/* + * R28 (0x1C) - Output1 Left Volume + */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */ +#define WM8915_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */ +#define WM8915_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */ +#define WM8915_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */ + +/* + * R29 (0x1D) - Output1 Right Volume + */ +#define WM8915_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8915_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8915_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8915_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */ +#define WM8915_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */ +#define WM8915_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */ +#define WM8915_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */ + +/* + * R30 (0x1E) - Output2 Left Volume + */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */ +#define WM8915_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */ +#define WM8915_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */ +#define WM8915_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */ + +/* + * R31 (0x1F) - Output2 Right Volume + */ +#define WM8915_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8915_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8915_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8915_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */ +#define WM8915_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */ +#define WM8915_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */ +#define WM8915_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */ + +/* + * R32 (0x20) - MICBIAS (1) + */ +#define WM8915_MICB1_RATE 0x0020 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ +#define WM8915_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ +#define WM8915_MICB1_MODE 0x0010 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_SHIFT 4 /* MICB1_MODE */ +#define WM8915_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ +#define WM8915_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */ +#define WM8915_MICB1_DISCH 0x0001 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */ +#define WM8915_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ + +/* + * R33 (0x21) - MICBIAS (2) + */ +#define WM8915_MICB2_RATE 0x0020 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ +#define WM8915_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ +#define WM8915_MICB2_MODE 0x0010 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_SHIFT 4 /* MICB2_MODE */ +#define WM8915_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ +#define WM8915_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */ +#define WM8915_MICB2_DISCH 0x0001 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */ +#define WM8915_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ + +/* + * R40 (0x28) - LDO 1 + */ +#define WM8915_LDO1_MODE 0x0020 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_SHIFT 5 /* LDO1_MODE */ +#define WM8915_LDO1_MODE_WIDTH 1 /* LDO1_MODE */ +#define WM8915_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */ +#define WM8915_LDO1_DISCH 0x0001 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */ +#define WM8915_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */ + +/* + * R41 (0x29) - LDO 2 + */ +#define WM8915_LDO2_MODE 0x0020 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_SHIFT 5 /* LDO2_MODE */ +#define WM8915_LDO2_MODE_WIDTH 1 /* LDO2_MODE */ +#define WM8915_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */ +#define WM8915_LDO2_DISCH 0x0001 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */ +#define WM8915_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ + +/* + * R48 (0x30) - Accessory Detect Mode 1 + */ +#define WM8915_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */ +#define WM8915_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */ +#define WM8915_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */ + +/* + * R49 (0x31) - Accessory Detect Mode 2 + */ +#define WM8915_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */ +#define WM8915_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */ +#define WM8915_MICD_SRC 0x0002 /* MICD_SRC */ +#define WM8915_MICD_SRC_MASK 0x0002 /* MICD_SRC */ +#define WM8915_MICD_SRC_SHIFT 1 /* MICD_SRC */ +#define WM8915_MICD_SRC_WIDTH 1 /* MICD_SRC */ +#define WM8915_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */ +#define WM8915_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */ + +/* + * R52 (0x34) - Headphone Detect 1 + */ +#define WM8915_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */ +#define WM8915_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */ +#define WM8915_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */ +#define WM8915_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */ +#define WM8915_HP_POLL 0x0001 /* HP_POLL */ +#define WM8915_HP_POLL_MASK 0x0001 /* HP_POLL */ +#define WM8915_HP_POLL_SHIFT 0 /* HP_POLL */ +#define WM8915_HP_POLL_WIDTH 1 /* HP_POLL */ + +/* + * R53 (0x35) - Headphone Detect 2 + */ +#define WM8915_HP_DONE 0x0080 /* HP_DONE */ +#define WM8915_HP_DONE_MASK 0x0080 /* HP_DONE */ +#define WM8915_HP_DONE_SHIFT 7 /* HP_DONE */ +#define WM8915_HP_DONE_WIDTH 1 /* HP_DONE */ +#define WM8915_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */ +#define WM8915_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */ +#define WM8915_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */ + +/* + * R56 (0x38) - Mic Detect 1 + */ +#define WM8915_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8915_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */ +#define WM8915_MICD_DBTIME 0x0002 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */ +#define WM8915_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */ +#define WM8915_MICD_ENA 0x0001 /* MICD_ENA */ +#define WM8915_MICD_ENA_MASK 0x0001 /* MICD_ENA */ +#define WM8915_MICD_ENA_SHIFT 0 /* MICD_ENA */ +#define WM8915_MICD_ENA_WIDTH 1 /* MICD_ENA */ + +/* + * R57 (0x39) - Mic Detect 2 + */ +#define WM8915_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */ +#define WM8915_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */ +#define WM8915_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */ + +/* + * R58 (0x3A) - Mic Detect 3 + */ +#define WM8915_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ +#define WM8915_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ +#define WM8915_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ +#define WM8915_MICD_VALID 0x0002 /* MICD_VALID */ +#define WM8915_MICD_VALID_MASK 0x0002 /* MICD_VALID */ +#define WM8915_MICD_VALID_SHIFT 1 /* MICD_VALID */ +#define WM8915_MICD_VALID_WIDTH 1 /* MICD_VALID */ +#define WM8915_MICD_STS 0x0001 /* MICD_STS */ +#define WM8915_MICD_STS_MASK 0x0001 /* MICD_STS */ +#define WM8915_MICD_STS_SHIFT 0 /* MICD_STS */ +#define WM8915_MICD_STS_WIDTH 1 /* MICD_STS */ + +/* + * R64 (0x40) - Charge Pump (1) + */ +#define WM8915_CP_ENA 0x8000 /* CP_ENA */ +#define WM8915_CP_ENA_MASK 0x8000 /* CP_ENA */ +#define WM8915_CP_ENA_SHIFT 15 /* CP_ENA */ +#define WM8915_CP_ENA_WIDTH 1 /* CP_ENA */ + +/* + * R65 (0x41) - Charge Pump (2) + */ +#define WM8915_CP_DISCH 0x8000 /* CP_DISCH */ +#define WM8915_CP_DISCH_MASK 0x8000 /* CP_DISCH */ +#define WM8915_CP_DISCH_SHIFT 15 /* CP_DISCH */ +#define WM8915_CP_DISCH_WIDTH 1 /* CP_DISCH */ + +/* + * R80 (0x50) - DC Servo (1) + */ +#define WM8915_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */ +#define WM8915_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */ +#define WM8915_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ +#define WM8915_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ +#define WM8915_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ + +/* + * R81 (0x51) - DC Servo (2) + */ +#define WM8915_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */ +#define WM8915_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */ +#define WM8915_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ +#define WM8915_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ +#define WM8915_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */ +#define WM8915_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */ +#define WM8915_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ +#define WM8915_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ +#define WM8915_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */ +#define WM8915_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */ +#define WM8915_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ +#define WM8915_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ +#define WM8915_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */ +#define WM8915_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */ +#define WM8915_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8915_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */ +#define WM8915_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ + +/* + * R82 (0x52) - DC Servo (3) + */ +#define WM8915_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8915_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8915_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8915_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ + +/* + * R84 (0x54) - DC Servo (5) + */ +#define WM8915_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8915_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8915_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8915_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */ + +/* + * R85 (0x55) - DC Servo (6) + */ +#define WM8915_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */ + +/* + * R86 (0x56) - DC Servo (7) + */ +#define WM8915_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8915_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8915_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ + +/* + * R87 (0x57) - DC Servo Readback 0 + */ +#define WM8915_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8915_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8915_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8915_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8915_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */ + +/* + * R96 (0x60) - Analogue HP (1) + */ +#define WM8915_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */ +#define WM8915_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */ +#define WM8915_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */ +#define WM8915_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */ +#define WM8915_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */ +#define WM8915_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ +#define WM8915_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ + +/* + * R97 (0x61) - Analogue HP (2) + */ +#define WM8915_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */ +#define WM8915_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */ +#define WM8915_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */ +#define WM8915_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */ +#define WM8915_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */ +#define WM8915_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */ +#define WM8915_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */ + +/* + * R256 (0x100) - Chip Revision + */ +#define WM8915_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */ +#define WM8915_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */ +#define WM8915_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */ + +/* + * R257 (0x101) - Control Interface (1) + */ +#define WM8915_AUTO_INC 0x0004 /* AUTO_INC */ +#define WM8915_AUTO_INC_MASK 0x0004 /* AUTO_INC */ +#define WM8915_AUTO_INC_SHIFT 2 /* AUTO_INC */ +#define WM8915_AUTO_INC_WIDTH 1 /* AUTO_INC */ + +/* + * R272 (0x110) - Write Sequencer Ctrl (1) + */ +#define WM8915_WSEQ_ENA 0x8000 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ +#define WM8915_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ +#define WM8915_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ +#define WM8915_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ +#define WM8915_WSEQ_START 0x0100 /* WSEQ_START */ +#define WM8915_WSEQ_START_MASK 0x0100 /* WSEQ_START */ +#define WM8915_WSEQ_START_SHIFT 8 /* WSEQ_START */ +#define WM8915_WSEQ_START_WIDTH 1 /* WSEQ_START */ +#define WM8915_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ +#define WM8915_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ +#define WM8915_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ + +/* + * R273 (0x111) - Write Sequencer Ctrl (2) + */ +#define WM8915_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */ +#define WM8915_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ +#define WM8915_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8915_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8915_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */ + +/* + * R512 (0x200) - AIF Clocking (1) + */ +#define WM8915_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */ +#define WM8915_SYSCLK_INV 0x0004 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */ +#define WM8915_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */ +#define WM8915_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */ +#define WM8915_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */ +#define WM8915_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ + +/* + * R513 (0x201) - AIF Clocking (2) + */ +#define WM8915_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */ +#define WM8915_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */ +#define WM8915_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */ +#define WM8915_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */ + +/* + * R520 (0x208) - Clocking (1) + */ +#define WM8915_LFCLK_ENA 0x0020 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */ +#define WM8915_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */ +#define WM8915_TOCLK_ENA 0x0010 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ +#define WM8915_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ +#define WM8915_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */ +#define WM8915_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */ +#define WM8915_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */ + +/* + * R521 (0x209) - Clocking (2) + */ +#define WM8915_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */ +#define WM8915_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */ +#define WM8915_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */ +#define WM8915_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */ +#define WM8915_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */ +#define WM8915_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */ +#define WM8915_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */ +#define WM8915_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */ +#define WM8915_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */ + +/* + * R528 (0x210) - AIF Rate + */ +#define WM8915_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */ +#define WM8915_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */ + +/* + * R544 (0x220) - FLL Control (1) + */ +#define WM8915_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */ +#define WM8915_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */ +#define WM8915_FLL_ENA 0x0001 /* FLL_ENA */ +#define WM8915_FLL_ENA_MASK 0x0001 /* FLL_ENA */ +#define WM8915_FLL_ENA_SHIFT 0 /* FLL_ENA */ +#define WM8915_FLL_ENA_WIDTH 1 /* FLL_ENA */ + +/* + * R545 (0x221) - FLL Control (2) + */ +#define WM8915_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ +#define WM8915_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ +#define WM8915_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ +#define WM8915_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ + +/* + * R546 (0x222) - FLL Control (3) + */ +#define WM8915_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */ +#define WM8915_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */ +#define WM8915_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */ + +/* + * R547 (0x223) - FLL Control (4) + */ +#define WM8915_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */ +#define WM8915_FLL_N_SHIFT 5 /* FLL_N - [14:5] */ +#define WM8915_FLL_N_WIDTH 10 /* FLL_N - [14:5] */ +#define WM8915_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */ +#define WM8915_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */ +#define WM8915_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */ + +/* + * R548 (0x224) - FLL Control (5) + */ +#define WM8915_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */ +#define WM8915_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */ +#define WM8915_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */ +#define WM8915_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */ +#define WM8915_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */ +#define WM8915_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */ +#define WM8915_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */ +#define WM8915_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */ +#define WM8915_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */ + +/* + * R549 (0x225) - FLL Control (6) + */ +#define WM8915_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */ +#define WM8915_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */ +#define WM8915_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */ + +/* + * R550 (0x226) - FLL EFS 1 + */ +#define WM8915_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */ +#define WM8915_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */ +#define WM8915_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */ + +/* + * R551 (0x227) - FLL EFS 2 + */ +#define WM8915_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */ +#define WM8915_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */ +#define WM8915_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */ + +/* + * R768 (0x300) - AIF1 Control + */ +#define WM8915_AIF1_TRI 0x0004 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_SHIFT 2 /* AIF1_TRI */ +#define WM8915_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ +#define WM8915_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */ +#define WM8915_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */ +#define WM8915_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */ + +/* + * R769 (0x301) - AIF1 BCLK + */ +#define WM8915_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ +#define WM8915_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ +#define WM8915_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ +#define WM8915_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */ +#define WM8915_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */ +#define WM8915_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */ + +/* + * R770 (0x302) - AIF1 TX LRCLK(1) + */ +#define WM8915_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */ +#define WM8915_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */ +#define WM8915_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */ + +/* + * R771 (0x303) - AIF1 TX LRCLK(2) + */ +#define WM8915_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */ +#define WM8915_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ +#define WM8915_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ +#define WM8915_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ +#define WM8915_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ + +/* + * R772 (0x304) - AIF1 RX LRCLK(1) + */ +#define WM8915_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */ +#define WM8915_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */ +#define WM8915_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */ + +/* + * R773 (0x305) - AIF1 RX LRCLK(2) + */ +#define WM8915_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ +#define WM8915_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ +#define WM8915_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ +#define WM8915_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ + +/* + * R774 (0x306) - AIF1TX Data Configuration (1) + */ +#define WM8915_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */ +#define WM8915_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ + +/* + * R775 (0x307) - AIF1TX Data Configuration (2) + */ +#define WM8915_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */ +#define WM8915_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ + +/* + * R776 (0x308) - AIF1RX Data Configuration + */ +#define WM8915_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */ +#define WM8915_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ + +/* + * R777 (0x309) - AIF1TX Channel 0 Configuration + */ +#define WM8915_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */ +#define WM8915_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ + +/* + * R778 (0x30A) - AIF1TX Channel 1 Configuration + */ +#define WM8915_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */ +#define WM8915_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ + +/* + * R779 (0x30B) - AIF1TX Channel 2 Configuration + */ +#define WM8915_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */ +#define WM8915_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ + +/* + * R780 (0x30C) - AIF1TX Channel 3 Configuration + */ +#define WM8915_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */ +#define WM8915_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ + +/* + * R781 (0x30D) - AIF1TX Channel 4 Configuration + */ +#define WM8915_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */ +#define WM8915_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ + +/* + * R782 (0x30E) - AIF1TX Channel 5 Configuration + */ +#define WM8915_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */ +#define WM8915_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ + +/* + * R783 (0x30F) - AIF1RX Channel 0 Configuration + */ +#define WM8915_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */ +#define WM8915_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ + +/* + * R784 (0x310) - AIF1RX Channel 1 Configuration + */ +#define WM8915_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */ +#define WM8915_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ + +/* + * R785 (0x311) - AIF1RX Channel 2 Configuration + */ +#define WM8915_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */ +#define WM8915_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ + +/* + * R786 (0x312) - AIF1RX Channel 3 Configuration + */ +#define WM8915_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */ +#define WM8915_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ + +/* + * R787 (0x313) - AIF1RX Channel 4 Configuration + */ +#define WM8915_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */ +#define WM8915_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ + +/* + * R788 (0x314) - AIF1RX Channel 5 Configuration + */ +#define WM8915_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */ +#define WM8915_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ +#define WM8915_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ + +/* + * R789 (0x315) - AIF1RX Mono Configuration + */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */ +#define WM8915_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */ + +/* + * R794 (0x31A) - AIF1TX Test + */ +#define WM8915_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */ +#define WM8915_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */ + +/* + * R800 (0x320) - AIF2 Control + */ +#define WM8915_AIF2_TRI 0x0004 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_SHIFT 2 /* AIF2_TRI */ +#define WM8915_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ +#define WM8915_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */ +#define WM8915_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */ +#define WM8915_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */ + +/* + * R801 (0x321) - AIF2 BCLK + */ +#define WM8915_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ +#define WM8915_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */ +#define WM8915_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */ +#define WM8915_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */ +#define WM8915_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */ +#define WM8915_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */ + +/* + * R802 (0x322) - AIF2 TX LRCLK(1) + */ +#define WM8915_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */ +#define WM8915_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */ +#define WM8915_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */ + +/* + * R803 (0x323) - AIF2 TX LRCLK(2) + */ +#define WM8915_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */ +#define WM8915_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */ +#define WM8915_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */ +#define WM8915_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */ +#define WM8915_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */ + +/* + * R804 (0x324) - AIF2 RX LRCLK(1) + */ +#define WM8915_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */ +#define WM8915_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */ +#define WM8915_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */ + +/* + * R805 (0x325) - AIF2 RX LRCLK(2) + */ +#define WM8915_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */ +#define WM8915_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */ +#define WM8915_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */ +#define WM8915_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */ + +/* + * R806 (0x326) - AIF2TX Data Configuration (1) + */ +#define WM8915_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */ +#define WM8915_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */ + +/* + * R807 (0x327) - AIF2TX Data Configuration (2) + */ +#define WM8915_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */ +#define WM8915_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */ + +/* + * R808 (0x328) - AIF2RX Data Configuration + */ +#define WM8915_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */ +#define WM8915_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */ +#define WM8915_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */ + +/* + * R809 (0x329) - AIF2TX Channel 0 Configuration + */ +#define WM8915_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */ +#define WM8915_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ + +/* + * R810 (0x32A) - AIF2TX Channel 1 Configuration + */ +#define WM8915_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */ +#define WM8915_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ + +/* + * R811 (0x32B) - AIF2RX Channel 0 Configuration + */ +#define WM8915_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */ +#define WM8915_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ + +/* + * R812 (0x32C) - AIF2RX Channel 1 Configuration + */ +#define WM8915_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */ +#define WM8915_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ +#define WM8915_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ + +/* + * R813 (0x32D) - AIF2RX Mono Configuration + */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */ +#define WM8915_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */ + +/* + * R815 (0x32F) - AIF2TX Test + */ +#define WM8915_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */ +#define WM8915_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */ + +/* + * R1024 (0x400) - DSP1 TX Left Volume + */ +#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ +#define WM8915_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */ +#define WM8915_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */ +#define WM8915_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */ + +/* + * R1025 (0x401) - DSP1 TX Right Volume + */ +#define WM8915_DSP1TX_VU 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ +#define WM8915_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ +#define WM8915_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */ +#define WM8915_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */ +#define WM8915_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */ + +/* + * R1026 (0x402) - DSP1 RX Left Volume + */ +#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ +#define WM8915_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */ +#define WM8915_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */ +#define WM8915_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */ + +/* + * R1027 (0x403) - DSP1 RX Right Volume + */ +#define WM8915_DSP1RX_VU 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ +#define WM8915_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ +#define WM8915_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */ +#define WM8915_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */ +#define WM8915_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */ + +/* + * R1040 (0x410) - DSP1 TX Filters + */ +#define WM8915_DSP1TX_NF 0x2000 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */ +#define WM8915_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */ +#define WM8915_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */ +#define WM8915_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */ +#define WM8915_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */ +#define WM8915_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */ +#define WM8915_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */ +#define WM8915_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */ +#define WM8915_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */ + +/* + * R1056 (0x420) - DSP1 RX Filters (1) + */ +#define WM8915_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */ +#define WM8915_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */ +#define WM8915_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */ +#define WM8915_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */ +#define WM8915_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */ + +/* + * R1057 (0x421) - DSP1 RX Filters (2) + */ +#define WM8915_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */ +#define WM8915_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */ +#define WM8915_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */ + +/* + * R1088 (0x440) - DSP1 DRC (1) + */ +#define WM8915_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */ +#define WM8915_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */ +#define WM8915_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */ +#define WM8915_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */ +#define WM8915_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */ +#define WM8915_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */ +#define WM8915_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */ + +/* + * R1089 (0x441) - DSP1 DRC (2) + */ +#define WM8915_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */ +#define WM8915_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */ +#define WM8915_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */ +#define WM8915_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */ + +/* + * R1090 (0x442) - DSP1 DRC (3) + */ +#define WM8915_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */ +#define WM8915_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */ +#define WM8915_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */ +#define WM8915_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */ +#define WM8915_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */ +#define WM8915_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */ +#define WM8915_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */ + +/* + * R1091 (0x443) - DSP1 DRC (4) + */ +#define WM8915_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */ + +/* + * R1092 (0x444) - DSP1 DRC (5) + */ +#define WM8915_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */ + +/* + * R1152 (0x480) - DSP1 RX EQ Gains (1) + */ +#define WM8915_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */ +#define WM8915_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */ + +/* + * R1153 (0x481) - DSP1 RX EQ Gains (2) + */ +#define WM8915_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */ + +/* + * R1154 (0x482) - DSP1 RX EQ Band 1 A + */ +#define WM8915_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */ + +/* + * R1155 (0x483) - DSP1 RX EQ Band 1 B + */ +#define WM8915_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */ + +/* + * R1156 (0x484) - DSP1 RX EQ Band 1 PG + */ +#define WM8915_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */ + +/* + * R1157 (0x485) - DSP1 RX EQ Band 2 A + */ +#define WM8915_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */ + +/* + * R1158 (0x486) - DSP1 RX EQ Band 2 B + */ +#define WM8915_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */ + +/* + * R1159 (0x487) - DSP1 RX EQ Band 2 C + */ +#define WM8915_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */ + +/* + * R1160 (0x488) - DSP1 RX EQ Band 2 PG + */ +#define WM8915_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */ + +/* + * R1161 (0x489) - DSP1 RX EQ Band 3 A + */ +#define WM8915_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */ + +/* + * R1162 (0x48A) - DSP1 RX EQ Band 3 B + */ +#define WM8915_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */ + +/* + * R1163 (0x48B) - DSP1 RX EQ Band 3 C + */ +#define WM8915_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */ + +/* + * R1164 (0x48C) - DSP1 RX EQ Band 3 PG + */ +#define WM8915_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */ + +/* + * R1165 (0x48D) - DSP1 RX EQ Band 4 A + */ +#define WM8915_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */ + +/* + * R1166 (0x48E) - DSP1 RX EQ Band 4 B + */ +#define WM8915_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */ + +/* + * R1167 (0x48F) - DSP1 RX EQ Band 4 C + */ +#define WM8915_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */ + +/* + * R1168 (0x490) - DSP1 RX EQ Band 4 PG + */ +#define WM8915_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */ + +/* + * R1169 (0x491) - DSP1 RX EQ Band 5 A + */ +#define WM8915_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */ + +/* + * R1170 (0x492) - DSP1 RX EQ Band 5 B + */ +#define WM8915_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */ + +/* + * R1171 (0x493) - DSP1 RX EQ Band 5 PG + */ +#define WM8915_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */ + +/* + * R1280 (0x500) - DSP2 TX Left Volume + */ +#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ +#define WM8915_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */ +#define WM8915_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */ +#define WM8915_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */ + +/* + * R1281 (0x501) - DSP2 TX Right Volume + */ +#define WM8915_DSP2TX_VU 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ +#define WM8915_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ +#define WM8915_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */ +#define WM8915_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */ +#define WM8915_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */ + +/* + * R1282 (0x502) - DSP2 RX Left Volume + */ +#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ +#define WM8915_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */ +#define WM8915_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */ +#define WM8915_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */ + +/* + * R1283 (0x503) - DSP2 RX Right Volume + */ +#define WM8915_DSP2RX_VU 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ +#define WM8915_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ +#define WM8915_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */ +#define WM8915_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */ +#define WM8915_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */ + +/* + * R1296 (0x510) - DSP2 TX Filters + */ +#define WM8915_DSP2TX_NF 0x2000 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */ +#define WM8915_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */ +#define WM8915_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */ +#define WM8915_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */ +#define WM8915_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */ +#define WM8915_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */ +#define WM8915_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */ +#define WM8915_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */ +#define WM8915_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */ + +/* + * R1312 (0x520) - DSP2 RX Filters (1) + */ +#define WM8915_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */ +#define WM8915_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */ +#define WM8915_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */ +#define WM8915_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */ +#define WM8915_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */ + +/* + * R1313 (0x521) - DSP2 RX Filters (2) + */ +#define WM8915_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */ +#define WM8915_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */ +#define WM8915_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */ + +/* + * R1344 (0x540) - DSP2 DRC (1) + */ +#define WM8915_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */ +#define WM8915_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */ +#define WM8915_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */ +#define WM8915_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */ +#define WM8915_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */ +#define WM8915_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */ +#define WM8915_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */ +#define WM8915_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */ +#define WM8915_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */ + +/* + * R1345 (0x541) - DSP2 DRC (2) + */ +#define WM8915_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */ +#define WM8915_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */ +#define WM8915_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */ +#define WM8915_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */ +#define WM8915_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */ + +/* + * R1346 (0x542) - DSP2 DRC (3) + */ +#define WM8915_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */ +#define WM8915_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */ +#define WM8915_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */ +#define WM8915_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */ +#define WM8915_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */ +#define WM8915_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */ +#define WM8915_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */ +#define WM8915_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */ + +/* + * R1347 (0x543) - DSP2 DRC (4) + */ +#define WM8915_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */ +#define WM8915_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */ + +/* + * R1348 (0x544) - DSP2 DRC (5) + */ +#define WM8915_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */ +#define WM8915_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */ +#define WM8915_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */ + +/* + * R1408 (0x580) - DSP2 RX EQ Gains (1) + */ +#define WM8915_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */ +#define WM8915_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */ +#define WM8915_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */ + +/* + * R1409 (0x581) - DSP2 RX EQ Gains (2) + */ +#define WM8915_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */ +#define WM8915_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */ + +/* + * R1410 (0x582) - DSP2 RX EQ Band 1 A + */ +#define WM8915_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */ + +/* + * R1411 (0x583) - DSP2 RX EQ Band 1 B + */ +#define WM8915_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */ + +/* + * R1412 (0x584) - DSP2 RX EQ Band 1 PG + */ +#define WM8915_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */ + +/* + * R1413 (0x585) - DSP2 RX EQ Band 2 A + */ +#define WM8915_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */ + +/* + * R1414 (0x586) - DSP2 RX EQ Band 2 B + */ +#define WM8915_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */ + +/* + * R1415 (0x587) - DSP2 RX EQ Band 2 C + */ +#define WM8915_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */ + +/* + * R1416 (0x588) - DSP2 RX EQ Band 2 PG + */ +#define WM8915_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */ + +/* + * R1417 (0x589) - DSP2 RX EQ Band 3 A + */ +#define WM8915_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */ + +/* + * R1418 (0x58A) - DSP2 RX EQ Band 3 B + */ +#define WM8915_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */ + +/* + * R1419 (0x58B) - DSP2 RX EQ Band 3 C + */ +#define WM8915_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */ + +/* + * R1420 (0x58C) - DSP2 RX EQ Band 3 PG + */ +#define WM8915_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */ + +/* + * R1421 (0x58D) - DSP2 RX EQ Band 4 A + */ +#define WM8915_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */ + +/* + * R1422 (0x58E) - DSP2 RX EQ Band 4 B + */ +#define WM8915_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */ + +/* + * R1423 (0x58F) - DSP2 RX EQ Band 4 C + */ +#define WM8915_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */ + +/* + * R1424 (0x590) - DSP2 RX EQ Band 4 PG + */ +#define WM8915_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */ + +/* + * R1425 (0x591) - DSP2 RX EQ Band 5 A + */ +#define WM8915_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */ + +/* + * R1426 (0x592) - DSP2 RX EQ Band 5 B + */ +#define WM8915_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */ + +/* + * R1427 (0x593) - DSP2 RX EQ Band 5 PG + */ +#define WM8915_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */ +#define WM8915_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */ + +/* + * R1536 (0x600) - DAC1 Mixer Volumes + */ +#define WM8915_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8915_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */ +#define WM8915_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */ +#define WM8915_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */ + +/* + * R1537 (0x601) - DAC1 Left Mixer Routing + */ +#define WM8915_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */ +#define WM8915_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */ +#define WM8915_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */ +#define WM8915_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */ + +/* + * R1538 (0x602) - DAC1 Right Mixer Routing + */ +#define WM8915_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */ +#define WM8915_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */ +#define WM8915_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */ +#define WM8915_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */ + +/* + * R1539 (0x603) - DAC2 Mixer Volumes + */ +#define WM8915_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8915_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */ +#define WM8915_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */ +#define WM8915_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */ + +/* + * R1540 (0x604) - DAC2 Left Mixer Routing + */ +#define WM8915_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */ +#define WM8915_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */ +#define WM8915_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */ +#define WM8915_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */ + +/* + * R1541 (0x605) - DAC2 Right Mixer Routing + */ +#define WM8915_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */ +#define WM8915_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */ +#define WM8915_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */ +#define WM8915_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */ + +/* + * R1542 (0x606) - DSP1 TX Left Mixer Routing + */ +#define WM8915_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */ +#define WM8915_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */ +#define WM8915_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */ + +/* + * R1543 (0x607) - DSP1 TX Right Mixer Routing + */ +#define WM8915_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */ +#define WM8915_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */ +#define WM8915_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */ + +/* + * R1544 (0x608) - DSP2 TX Left Mixer Routing + */ +#define WM8915_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */ +#define WM8915_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */ +#define WM8915_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */ + +/* + * R1545 (0x609) - DSP2 TX Right Mixer Routing + */ +#define WM8915_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */ +#define WM8915_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */ +#define WM8915_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */ + +/* + * R1546 (0x60A) - DSP TX Mixer Select + */ +#define WM8915_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */ +#define WM8915_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */ + +/* + * R1552 (0x610) - DAC Softmute + */ +#define WM8915_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */ +#define WM8915_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */ +#define WM8915_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ + +/* + * R1568 (0x620) - Oversampling + */ +#define WM8915_SPK_OSR128 0x0008 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */ +#define WM8915_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */ +#define WM8915_DMIC_OSR64 0x0004 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */ +#define WM8915_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */ +#define WM8915_ADC_OSR128 0x0002 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */ +#define WM8915_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ +#define WM8915_DAC_OSR128 0x0001 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */ +#define WM8915_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ + +/* + * R1569 (0x621) - Sidetone + */ +#define WM8915_ST_LPF 0x1000 /* ST_LPF */ +#define WM8915_ST_LPF_MASK 0x1000 /* ST_LPF */ +#define WM8915_ST_LPF_SHIFT 12 /* ST_LPF */ +#define WM8915_ST_LPF_WIDTH 1 /* ST_LPF */ +#define WM8915_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */ +#define WM8915_ST_HPF 0x0040 /* ST_HPF */ +#define WM8915_ST_HPF_MASK 0x0040 /* ST_HPF */ +#define WM8915_ST_HPF_SHIFT 6 /* ST_HPF */ +#define WM8915_ST_HPF_WIDTH 1 /* ST_HPF */ +#define WM8915_STR_SEL 0x0002 /* STR_SEL */ +#define WM8915_STR_SEL_MASK 0x0002 /* STR_SEL */ +#define WM8915_STR_SEL_SHIFT 1 /* STR_SEL */ +#define WM8915_STR_SEL_WIDTH 1 /* STR_SEL */ +#define WM8915_STL_SEL 0x0001 /* STL_SEL */ +#define WM8915_STL_SEL_MASK 0x0001 /* STL_SEL */ +#define WM8915_STL_SEL_SHIFT 0 /* STL_SEL */ +#define WM8915_STL_SEL_WIDTH 1 /* STL_SEL */ + +/* + * R1792 (0x700) - GPIO 1 + */ +#define WM8915_GP1_DIR 0x8000 /* GP1_DIR */ +#define WM8915_GP1_DIR_MASK 0x8000 /* GP1_DIR */ +#define WM8915_GP1_DIR_SHIFT 15 /* GP1_DIR */ +#define WM8915_GP1_DIR_WIDTH 1 /* GP1_DIR */ +#define WM8915_GP1_PU 0x4000 /* GP1_PU */ +#define WM8915_GP1_PU_MASK 0x4000 /* GP1_PU */ +#define WM8915_GP1_PU_SHIFT 14 /* GP1_PU */ +#define WM8915_GP1_PU_WIDTH 1 /* GP1_PU */ +#define WM8915_GP1_PD 0x2000 /* GP1_PD */ +#define WM8915_GP1_PD_MASK 0x2000 /* GP1_PD */ +#define WM8915_GP1_PD_SHIFT 13 /* GP1_PD */ +#define WM8915_GP1_PD_WIDTH 1 /* GP1_PD */ +#define WM8915_GP1_POL 0x0400 /* GP1_POL */ +#define WM8915_GP1_POL_MASK 0x0400 /* GP1_POL */ +#define WM8915_GP1_POL_SHIFT 10 /* GP1_POL */ +#define WM8915_GP1_POL_WIDTH 1 /* GP1_POL */ +#define WM8915_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ +#define WM8915_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ +#define WM8915_GP1_DB 0x0100 /* GP1_DB */ +#define WM8915_GP1_DB_MASK 0x0100 /* GP1_DB */ +#define WM8915_GP1_DB_SHIFT 8 /* GP1_DB */ +#define WM8915_GP1_DB_WIDTH 1 /* GP1_DB */ +#define WM8915_GP1_LVL 0x0040 /* GP1_LVL */ +#define WM8915_GP1_LVL_MASK 0x0040 /* GP1_LVL */ +#define WM8915_GP1_LVL_SHIFT 6 /* GP1_LVL */ +#define WM8915_GP1_LVL_WIDTH 1 /* GP1_LVL */ +#define WM8915_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */ +#define WM8915_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */ +#define WM8915_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */ + +/* + * R1793 (0x701) - GPIO 2 + */ +#define WM8915_GP2_DIR 0x8000 /* GP2_DIR */ +#define WM8915_GP2_DIR_MASK 0x8000 /* GP2_DIR */ +#define WM8915_GP2_DIR_SHIFT 15 /* GP2_DIR */ +#define WM8915_GP2_DIR_WIDTH 1 /* GP2_DIR */ +#define WM8915_GP2_PU 0x4000 /* GP2_PU */ +#define WM8915_GP2_PU_MASK 0x4000 /* GP2_PU */ +#define WM8915_GP2_PU_SHIFT 14 /* GP2_PU */ +#define WM8915_GP2_PU_WIDTH 1 /* GP2_PU */ +#define WM8915_GP2_PD 0x2000 /* GP2_PD */ +#define WM8915_GP2_PD_MASK 0x2000 /* GP2_PD */ +#define WM8915_GP2_PD_SHIFT 13 /* GP2_PD */ +#define WM8915_GP2_PD_WIDTH 1 /* GP2_PD */ +#define WM8915_GP2_POL 0x0400 /* GP2_POL */ +#define WM8915_GP2_POL_MASK 0x0400 /* GP2_POL */ +#define WM8915_GP2_POL_SHIFT 10 /* GP2_POL */ +#define WM8915_GP2_POL_WIDTH 1 /* GP2_POL */ +#define WM8915_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ +#define WM8915_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ +#define WM8915_GP2_DB 0x0100 /* GP2_DB */ +#define WM8915_GP2_DB_MASK 0x0100 /* GP2_DB */ +#define WM8915_GP2_DB_SHIFT 8 /* GP2_DB */ +#define WM8915_GP2_DB_WIDTH 1 /* GP2_DB */ +#define WM8915_GP2_LVL 0x0040 /* GP2_LVL */ +#define WM8915_GP2_LVL_MASK 0x0040 /* GP2_LVL */ +#define WM8915_GP2_LVL_SHIFT 6 /* GP2_LVL */ +#define WM8915_GP2_LVL_WIDTH 1 /* GP2_LVL */ +#define WM8915_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */ +#define WM8915_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */ +#define WM8915_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */ + +/* + * R1794 (0x702) - GPIO 3 + */ +#define WM8915_GP3_DIR 0x8000 /* GP3_DIR */ +#define WM8915_GP3_DIR_MASK 0x8000 /* GP3_DIR */ +#define WM8915_GP3_DIR_SHIFT 15 /* GP3_DIR */ +#define WM8915_GP3_DIR_WIDTH 1 /* GP3_DIR */ +#define WM8915_GP3_PU 0x4000 /* GP3_PU */ +#define WM8915_GP3_PU_MASK 0x4000 /* GP3_PU */ +#define WM8915_GP3_PU_SHIFT 14 /* GP3_PU */ +#define WM8915_GP3_PU_WIDTH 1 /* GP3_PU */ +#define WM8915_GP3_PD 0x2000 /* GP3_PD */ +#define WM8915_GP3_PD_MASK 0x2000 /* GP3_PD */ +#define WM8915_GP3_PD_SHIFT 13 /* GP3_PD */ +#define WM8915_GP3_PD_WIDTH 1 /* GP3_PD */ +#define WM8915_GP3_POL 0x0400 /* GP3_POL */ +#define WM8915_GP3_POL_MASK 0x0400 /* GP3_POL */ +#define WM8915_GP3_POL_SHIFT 10 /* GP3_POL */ +#define WM8915_GP3_POL_WIDTH 1 /* GP3_POL */ +#define WM8915_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ +#define WM8915_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ +#define WM8915_GP3_DB 0x0100 /* GP3_DB */ +#define WM8915_GP3_DB_MASK 0x0100 /* GP3_DB */ +#define WM8915_GP3_DB_SHIFT 8 /* GP3_DB */ +#define WM8915_GP3_DB_WIDTH 1 /* GP3_DB */ +#define WM8915_GP3_LVL 0x0040 /* GP3_LVL */ +#define WM8915_GP3_LVL_MASK 0x0040 /* GP3_LVL */ +#define WM8915_GP3_LVL_SHIFT 6 /* GP3_LVL */ +#define WM8915_GP3_LVL_WIDTH 1 /* GP3_LVL */ +#define WM8915_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */ +#define WM8915_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */ +#define WM8915_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */ + +/* + * R1795 (0x703) - GPIO 4 + */ +#define WM8915_GP4_DIR 0x8000 /* GP4_DIR */ +#define WM8915_GP4_DIR_MASK 0x8000 /* GP4_DIR */ +#define WM8915_GP4_DIR_SHIFT 15 /* GP4_DIR */ +#define WM8915_GP4_DIR_WIDTH 1 /* GP4_DIR */ +#define WM8915_GP4_PU 0x4000 /* GP4_PU */ +#define WM8915_GP4_PU_MASK 0x4000 /* GP4_PU */ +#define WM8915_GP4_PU_SHIFT 14 /* GP4_PU */ +#define WM8915_GP4_PU_WIDTH 1 /* GP4_PU */ +#define WM8915_GP4_PD 0x2000 /* GP4_PD */ +#define WM8915_GP4_PD_MASK 0x2000 /* GP4_PD */ +#define WM8915_GP4_PD_SHIFT 13 /* GP4_PD */ +#define WM8915_GP4_PD_WIDTH 1 /* GP4_PD */ +#define WM8915_GP4_POL 0x0400 /* GP4_POL */ +#define WM8915_GP4_POL_MASK 0x0400 /* GP4_POL */ +#define WM8915_GP4_POL_SHIFT 10 /* GP4_POL */ +#define WM8915_GP4_POL_WIDTH 1 /* GP4_POL */ +#define WM8915_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ +#define WM8915_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ +#define WM8915_GP4_DB 0x0100 /* GP4_DB */ +#define WM8915_GP4_DB_MASK 0x0100 /* GP4_DB */ +#define WM8915_GP4_DB_SHIFT 8 /* GP4_DB */ +#define WM8915_GP4_DB_WIDTH 1 /* GP4_DB */ +#define WM8915_GP4_LVL 0x0040 /* GP4_LVL */ +#define WM8915_GP4_LVL_MASK 0x0040 /* GP4_LVL */ +#define WM8915_GP4_LVL_SHIFT 6 /* GP4_LVL */ +#define WM8915_GP4_LVL_WIDTH 1 /* GP4_LVL */ +#define WM8915_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */ +#define WM8915_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */ +#define WM8915_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */ + +/* + * R1796 (0x704) - GPIO 5 + */ +#define WM8915_GP5_DIR 0x8000 /* GP5_DIR */ +#define WM8915_GP5_DIR_MASK 0x8000 /* GP5_DIR */ +#define WM8915_GP5_DIR_SHIFT 15 /* GP5_DIR */ +#define WM8915_GP5_DIR_WIDTH 1 /* GP5_DIR */ +#define WM8915_GP5_PU 0x4000 /* GP5_PU */ +#define WM8915_GP5_PU_MASK 0x4000 /* GP5_PU */ +#define WM8915_GP5_PU_SHIFT 14 /* GP5_PU */ +#define WM8915_GP5_PU_WIDTH 1 /* GP5_PU */ +#define WM8915_GP5_PD 0x2000 /* GP5_PD */ +#define WM8915_GP5_PD_MASK 0x2000 /* GP5_PD */ +#define WM8915_GP5_PD_SHIFT 13 /* GP5_PD */ +#define WM8915_GP5_PD_WIDTH 1 /* GP5_PD */ +#define WM8915_GP5_POL 0x0400 /* GP5_POL */ +#define WM8915_GP5_POL_MASK 0x0400 /* GP5_POL */ +#define WM8915_GP5_POL_SHIFT 10 /* GP5_POL */ +#define WM8915_GP5_POL_WIDTH 1 /* GP5_POL */ +#define WM8915_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */ +#define WM8915_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */ +#define WM8915_GP5_DB 0x0100 /* GP5_DB */ +#define WM8915_GP5_DB_MASK 0x0100 /* GP5_DB */ +#define WM8915_GP5_DB_SHIFT 8 /* GP5_DB */ +#define WM8915_GP5_DB_WIDTH 1 /* GP5_DB */ +#define WM8915_GP5_LVL 0x0040 /* GP5_LVL */ +#define WM8915_GP5_LVL_MASK 0x0040 /* GP5_LVL */ +#define WM8915_GP5_LVL_SHIFT 6 /* GP5_LVL */ +#define WM8915_GP5_LVL_WIDTH 1 /* GP5_LVL */ +#define WM8915_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */ +#define WM8915_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */ +#define WM8915_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */ + +/* + * R1824 (0x720) - Pull Control (1) + */ +#define WM8915_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */ +#define WM8915_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ +#define WM8915_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */ +#define WM8915_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ +#define WM8915_MCLK2_PU 0x0200 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_SHIFT 9 /* MCLK2_PU */ +#define WM8915_MCLK2_PU_WIDTH 1 /* MCLK2_PU */ +#define WM8915_MCLK2_PD 0x0100 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_SHIFT 8 /* MCLK2_PD */ +#define WM8915_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ +#define WM8915_MCLK1_PU 0x0080 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_SHIFT 7 /* MCLK1_PU */ +#define WM8915_MCLK1_PU_WIDTH 1 /* MCLK1_PU */ +#define WM8915_MCLK1_PD 0x0040 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_SHIFT 6 /* MCLK1_PD */ +#define WM8915_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ +#define WM8915_DACDAT1_PU 0x0020 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ +#define WM8915_DACDAT1_PD 0x0010 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */ +#define WM8915_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ +#define WM8915_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ +#define WM8915_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */ +#define WM8915_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ +#define WM8915_BCLK1_PU 0x0002 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_SHIFT 1 /* BCLK1_PU */ +#define WM8915_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ +#define WM8915_BCLK1_PD 0x0001 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_SHIFT 0 /* BCLK1_PD */ +#define WM8915_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ + +/* + * R1825 (0x721) - Pull Control (2) + */ +#define WM8915_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */ +#define WM8915_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ +#define WM8915_ADDR_PD 0x0040 /* ADDR_PD */ +#define WM8915_ADDR_PD_MASK 0x0040 /* ADDR_PD */ +#define WM8915_ADDR_PD_SHIFT 6 /* ADDR_PD */ +#define WM8915_ADDR_PD_WIDTH 1 /* ADDR_PD */ +#define WM8915_DACDAT2_PU 0x0020 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */ +#define WM8915_DACDAT2_PD 0x0010 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */ +#define WM8915_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */ +#define WM8915_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */ +#define WM8915_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */ +#define WM8915_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */ +#define WM8915_BCLK2_PU 0x0002 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_SHIFT 1 /* BCLK2_PU */ +#define WM8915_BCLK2_PU_WIDTH 1 /* BCLK2_PU */ +#define WM8915_BCLK2_PD 0x0001 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_SHIFT 0 /* BCLK2_PD */ +#define WM8915_BCLK2_PD_WIDTH 1 /* BCLK2_PD */ + +/* + * R1840 (0x730) - Interrupt Status 1 + */ +#define WM8915_GP5_EINT 0x0010 /* GP5_EINT */ +#define WM8915_GP5_EINT_MASK 0x0010 /* GP5_EINT */ +#define WM8915_GP5_EINT_SHIFT 4 /* GP5_EINT */ +#define WM8915_GP5_EINT_WIDTH 1 /* GP5_EINT */ +#define WM8915_GP4_EINT 0x0008 /* GP4_EINT */ +#define WM8915_GP4_EINT_MASK 0x0008 /* GP4_EINT */ +#define WM8915_GP4_EINT_SHIFT 3 /* GP4_EINT */ +#define WM8915_GP4_EINT_WIDTH 1 /* GP4_EINT */ +#define WM8915_GP3_EINT 0x0004 /* GP3_EINT */ +#define WM8915_GP3_EINT_MASK 0x0004 /* GP3_EINT */ +#define WM8915_GP3_EINT_SHIFT 2 /* GP3_EINT */ +#define WM8915_GP3_EINT_WIDTH 1 /* GP3_EINT */ +#define WM8915_GP2_EINT 0x0002 /* GP2_EINT */ +#define WM8915_GP2_EINT_MASK 0x0002 /* GP2_EINT */ +#define WM8915_GP2_EINT_SHIFT 1 /* GP2_EINT */ +#define WM8915_GP2_EINT_WIDTH 1 /* GP2_EINT */ +#define WM8915_GP1_EINT 0x0001 /* GP1_EINT */ +#define WM8915_GP1_EINT_MASK 0x0001 /* GP1_EINT */ +#define WM8915_GP1_EINT_SHIFT 0 /* GP1_EINT */ +#define WM8915_GP1_EINT_WIDTH 1 /* GP1_EINT */ + +/* + * R1841 (0x731) - Interrupt Status 2 + */ +#define WM8915_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */ +#define WM8915_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */ +#define WM8915_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */ +#define WM8915_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */ +#define WM8915_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */ +#define WM8915_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */ +#define WM8915_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */ +#define WM8915_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */ +#define WM8915_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ +#define WM8915_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */ +#define WM8915_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */ +#define WM8915_MICD_EINT 0x0001 /* MICD_EINT */ +#define WM8915_MICD_EINT_MASK 0x0001 /* MICD_EINT */ +#define WM8915_MICD_EINT_SHIFT 0 /* MICD_EINT */ +#define WM8915_MICD_EINT_WIDTH 1 /* MICD_EINT */ + +/* + * R1842 (0x732) - Interrupt Raw Status 2 + */ +#define WM8915_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */ +#define WM8915_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */ +#define WM8915_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */ +#define WM8915_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */ +#define WM8915_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */ +#define WM8915_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */ +#define WM8915_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */ +#define WM8915_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */ +#define WM8915_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */ + +/* + * R1848 (0x738) - Interrupt Status 1 Mask + */ +#define WM8915_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ +#define WM8915_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ +#define WM8915_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ +#define WM8915_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ +#define WM8915_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ +#define WM8915_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ +#define WM8915_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ +#define WM8915_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ +#define WM8915_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ +#define WM8915_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ + +/* + * R1849 (0x739) - Interrupt Status 2 Mask + */ +#define WM8915_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */ +#define WM8915_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ +#define WM8915_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */ +#define WM8915_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */ +#define WM8915_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */ +#define WM8915_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */ + +/* + * R1856 (0x740) - Interrupt Control + */ +#define WM8915_IM_IRQ 0x0001 /* IM_IRQ */ +#define WM8915_IM_IRQ_MASK 0x0001 /* IM_IRQ */ +#define WM8915_IM_IRQ_SHIFT 0 /* IM_IRQ */ +#define WM8915_IM_IRQ_WIDTH 1 /* IM_IRQ */ + +/* + * R2048 (0x800) - Left PDM Speaker + */ +#define WM8915_SPKL_ENA 0x0010 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_SHIFT 4 /* SPKL_ENA */ +#define WM8915_SPKL_ENA_WIDTH 1 /* SPKL_ENA */ +#define WM8915_SPKL_MUTE 0x0008 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */ +#define WM8915_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */ +#define WM8915_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */ +#define WM8915_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */ +#define WM8915_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */ + +/* + * R2049 (0x801) - Right PDM Speaker + */ +#define WM8915_SPKR_ENA 0x0010 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_SHIFT 4 /* SPKR_ENA */ +#define WM8915_SPKR_ENA_WIDTH 1 /* SPKR_ENA */ +#define WM8915_SPKR_MUTE 0x0008 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */ +#define WM8915_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */ +#define WM8915_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */ +#define WM8915_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */ +#define WM8915_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */ + +/* + * R2050 (0x802) - PDM Speaker Mute Sequence + */ +#define WM8915_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */ +#define WM8915_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */ +#define WM8915_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */ +#define WM8915_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */ + +/* + * R2051 (0x803) - PDM Speaker Volume + */ +#define WM8915_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */ +#define WM8915_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */ +#define WM8915_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */ +#define WM8915_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */ + +#endif diff --git a/trunk/sound/soc/codecs/wm8996.c b/trunk/sound/soc/codecs/wm8996.c deleted file mode 100644 index ab8e9d1aaff0..000000000000 --- a/trunk/sound/soc/codecs/wm8996.c +++ /dev/null @@ -1,2994 +0,0 @@ -/* - * wm8996.c - WM8996 audio codec interface - * - * Copyright 2011 Wolfson Microelectronics PLC. - * Author: Mark Brown - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "wm8996.h" - -#define WM8996_AIFS 2 - -#define HPOUT1L 1 -#define HPOUT1R 2 -#define HPOUT2L 4 -#define HPOUT2R 8 - -#define WM8996_NUM_SUPPLIES 4 -static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { - "DBVDD", - "AVDD1", - "AVDD2", - "CPVDD", -}; - -struct wm8996_priv { - struct snd_soc_codec *codec; - - int ldo1ena; - - int sysclk; - int sysclk_src; - - int fll_src; - int fll_fref; - int fll_fout; - - struct completion fll_lock; - - u16 dcs_pending; - struct completion dcs_done; - - u16 hpout_ena; - u16 hpout_pending; - - struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; - struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; - - struct wm8996_pdata pdata; - - int rx_rate[WM8996_AIFS]; - int bclk_rate[WM8996_AIFS]; - - /* Platform dependant ReTune mobile configuration */ - int num_retune_mobile_texts; - const char **retune_mobile_texts; - int retune_mobile_cfg[2]; - struct soc_enum retune_mobile_enum; - - struct snd_soc_jack *jack; - bool detecting; - bool jack_mic; - wm8996_polarity_fn polarity_cb; - -#ifdef CONFIG_GPIOLIB - struct gpio_chip gpio_chip; -#endif -}; - -/* We can't use the same notifier block for more than one supply and - * there's no way I can see to get from a callback to the caller - * except container_of(). - */ -#define WM8996_REGULATOR_EVENT(n) \ -static int wm8996_regulator_event_##n(struct notifier_block *nb, \ - unsigned long event, void *data) \ -{ \ - struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \ - disable_nb[n]); \ - if (event & REGULATOR_EVENT_DISABLE) { \ - wm8996->codec->cache_sync = 1; \ - } \ - return 0; \ -} - -WM8996_REGULATOR_EVENT(0) -WM8996_REGULATOR_EVENT(1) -WM8996_REGULATOR_EVENT(2) -WM8996_REGULATOR_EVENT(3) - -static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { - [WM8996_SOFTWARE_RESET] = 0x8996, - [WM8996_POWER_MANAGEMENT_7] = 0x10, - [WM8996_DAC1_HPOUT1_VOLUME] = 0x88, - [WM8996_DAC2_HPOUT2_VOLUME] = 0x88, - [WM8996_DAC1_LEFT_VOLUME] = 0x2c0, - [WM8996_DAC1_RIGHT_VOLUME] = 0x2c0, - [WM8996_DAC2_LEFT_VOLUME] = 0x2c0, - [WM8996_DAC2_RIGHT_VOLUME] = 0x2c0, - [WM8996_OUTPUT1_LEFT_VOLUME] = 0x80, - [WM8996_OUTPUT1_RIGHT_VOLUME] = 0x80, - [WM8996_OUTPUT2_LEFT_VOLUME] = 0x80, - [WM8996_OUTPUT2_RIGHT_VOLUME] = 0x80, - [WM8996_MICBIAS_1] = 0x39, - [WM8996_MICBIAS_2] = 0x39, - [WM8996_LDO_1] = 0x3, - [WM8996_LDO_2] = 0x13, - [WM8996_ACCESSORY_DETECT_MODE_1] = 0x4, - [WM8996_HEADPHONE_DETECT_1] = 0x20, - [WM8996_MIC_DETECT_1] = 0x7600, - [WM8996_MIC_DETECT_2] = 0xbf, - [WM8996_CHARGE_PUMP_1] = 0x1f25, - [WM8996_CHARGE_PUMP_2] = 0xab19, - [WM8996_DC_SERVO_5] = 0x2a2a, - [WM8996_CONTROL_INTERFACE_1] = 0x8004, - [WM8996_CLOCKING_1] = 0x10, - [WM8996_AIF_RATE] = 0x83, - [WM8996_FLL_CONTROL_4] = 0x5dc0, - [WM8996_FLL_CONTROL_5] = 0xc84, - [WM8996_FLL_EFS_2] = 0x2, - [WM8996_AIF1_TX_LRCLK_1] = 0x80, - [WM8996_AIF1_TX_LRCLK_2] = 0x8, - [WM8996_AIF1_RX_LRCLK_1] = 0x80, - [WM8996_AIF1TX_DATA_CONFIGURATION_1] = 0x1818, - [WM8996_AIF1RX_DATA_CONFIGURATION] = 0x1818, - [WM8996_AIF1TX_TEST] = 0x7, - [WM8996_AIF2_TX_LRCLK_1] = 0x80, - [WM8996_AIF2_TX_LRCLK_2] = 0x8, - [WM8996_AIF2_RX_LRCLK_1] = 0x80, - [WM8996_AIF2TX_DATA_CONFIGURATION_1] = 0x1818, - [WM8996_AIF2RX_DATA_CONFIGURATION] = 0x1818, - [WM8996_AIF2TX_TEST] = 0x1, - [WM8996_DSP1_TX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP1_TX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP1_RX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP1_RX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP1_TX_FILTERS] = 0x2000, - [WM8996_DSP1_RX_FILTERS_1] = 0x200, - [WM8996_DSP1_RX_FILTERS_2] = 0x10, - [WM8996_DSP1_DRC_1] = 0x98, - [WM8996_DSP1_DRC_2] = 0x845, - [WM8996_DSP1_RX_EQ_GAINS_1] = 0x6318, - [WM8996_DSP1_RX_EQ_GAINS_2] = 0x6300, - [WM8996_DSP1_RX_EQ_BAND_1_A] = 0xfca, - [WM8996_DSP1_RX_EQ_BAND_1_B] = 0x400, - [WM8996_DSP1_RX_EQ_BAND_1_PG] = 0xd8, - [WM8996_DSP1_RX_EQ_BAND_2_A] = 0x1eb5, - [WM8996_DSP1_RX_EQ_BAND_2_B] = 0xf145, - [WM8996_DSP1_RX_EQ_BAND_2_C] = 0xb75, - [WM8996_DSP1_RX_EQ_BAND_2_PG] = 0x1c5, - [WM8996_DSP1_RX_EQ_BAND_3_A] = 0x1c58, - [WM8996_DSP1_RX_EQ_BAND_3_B] = 0xf373, - [WM8996_DSP1_RX_EQ_BAND_3_C] = 0xa54, - [WM8996_DSP1_RX_EQ_BAND_3_PG] = 0x558, - [WM8996_DSP1_RX_EQ_BAND_4_A] = 0x168e, - [WM8996_DSP1_RX_EQ_BAND_4_B] = 0xf829, - [WM8996_DSP1_RX_EQ_BAND_4_C] = 0x7ad, - [WM8996_DSP1_RX_EQ_BAND_4_PG] = 0x1103, - [WM8996_DSP1_RX_EQ_BAND_5_A] = 0x564, - [WM8996_DSP1_RX_EQ_BAND_5_B] = 0x559, - [WM8996_DSP1_RX_EQ_BAND_5_PG] = 0x4000, - [WM8996_DSP2_TX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP2_TX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP2_RX_LEFT_VOLUME] = 0xc0, - [WM8996_DSP2_RX_RIGHT_VOLUME] = 0xc0, - [WM8996_DSP2_TX_FILTERS] = 0x2000, - [WM8996_DSP2_RX_FILTERS_1] = 0x200, - [WM8996_DSP2_RX_FILTERS_2] = 0x10, - [WM8996_DSP2_DRC_1] = 0x98, - [WM8996_DSP2_DRC_2] = 0x845, - [WM8996_DSP2_RX_EQ_GAINS_1] = 0x6318, - [WM8996_DSP2_RX_EQ_GAINS_2] = 0x6300, - [WM8996_DSP2_RX_EQ_BAND_1_A] = 0xfca, - [WM8996_DSP2_RX_EQ_BAND_1_B] = 0x400, - [WM8996_DSP2_RX_EQ_BAND_1_PG] = 0xd8, - [WM8996_DSP2_RX_EQ_BAND_2_A] = 0x1eb5, - [WM8996_DSP2_RX_EQ_BAND_2_B] = 0xf145, - [WM8996_DSP2_RX_EQ_BAND_2_C] = 0xb75, - [WM8996_DSP2_RX_EQ_BAND_2_PG] = 0x1c5, - [WM8996_DSP2_RX_EQ_BAND_3_A] = 0x1c58, - [WM8996_DSP2_RX_EQ_BAND_3_B] = 0xf373, - [WM8996_DSP2_RX_EQ_BAND_3_C] = 0xa54, - [WM8996_DSP2_RX_EQ_BAND_3_PG] = 0x558, - [WM8996_DSP2_RX_EQ_BAND_4_A] = 0x168e, - [WM8996_DSP2_RX_EQ_BAND_4_B] = 0xf829, - [WM8996_DSP2_RX_EQ_BAND_4_C] = 0x7ad, - [WM8996_DSP2_RX_EQ_BAND_4_PG] = 0x1103, - [WM8996_DSP2_RX_EQ_BAND_5_A] = 0x564, - [WM8996_DSP2_RX_EQ_BAND_5_B] = 0x559, - [WM8996_DSP2_RX_EQ_BAND_5_PG] = 0x4000, - [WM8996_OVERSAMPLING] = 0xd, - [WM8996_SIDETONE] = 0x1040, - [WM8996_GPIO_1] = 0xa101, - [WM8996_GPIO_2] = 0xa101, - [WM8996_GPIO_3] = 0xa101, - [WM8996_GPIO_4] = 0xa101, - [WM8996_GPIO_5] = 0xa101, - [WM8996_PULL_CONTROL_2] = 0x140, - [WM8996_INTERRUPT_STATUS_1_MASK] = 0x1f, - [WM8996_INTERRUPT_STATUS_2_MASK] = 0x1ecf, - [WM8996_RIGHT_PDM_SPEAKER] = 0x1, - [WM8996_PDM_SPEAKER_MUTE_SEQUENCE] = 0x69, - [WM8996_PDM_SPEAKER_VOLUME] = 0x66, - [WM8996_WRITE_SEQUENCER_0] = 0x1, - [WM8996_WRITE_SEQUENCER_1] = 0x1, - [WM8996_WRITE_SEQUENCER_3] = 0x6, - [WM8996_WRITE_SEQUENCER_4] = 0x40, - [WM8996_WRITE_SEQUENCER_5] = 0x1, - [WM8996_WRITE_SEQUENCER_6] = 0xf, - [WM8996_WRITE_SEQUENCER_7] = 0x6, - [WM8996_WRITE_SEQUENCER_8] = 0x1, - [WM8996_WRITE_SEQUENCER_9] = 0x3, - [WM8996_WRITE_SEQUENCER_10] = 0x104, - [WM8996_WRITE_SEQUENCER_12] = 0x60, - [WM8996_WRITE_SEQUENCER_13] = 0x11, - [WM8996_WRITE_SEQUENCER_14] = 0x401, - [WM8996_WRITE_SEQUENCER_16] = 0x50, - [WM8996_WRITE_SEQUENCER_17] = 0x3, - [WM8996_WRITE_SEQUENCER_18] = 0x100, - [WM8996_WRITE_SEQUENCER_20] = 0x51, - [WM8996_WRITE_SEQUENCER_21] = 0x3, - [WM8996_WRITE_SEQUENCER_22] = 0x104, - [WM8996_WRITE_SEQUENCER_23] = 0xa, - [WM8996_WRITE_SEQUENCER_24] = 0x60, - [WM8996_WRITE_SEQUENCER_25] = 0x3b, - [WM8996_WRITE_SEQUENCER_26] = 0x502, - [WM8996_WRITE_SEQUENCER_27] = 0x100, - [WM8996_WRITE_SEQUENCER_28] = 0x2fff, - [WM8996_WRITE_SEQUENCER_32] = 0x2fff, - [WM8996_WRITE_SEQUENCER_36] = 0x2fff, - [WM8996_WRITE_SEQUENCER_40] = 0x2fff, - [WM8996_WRITE_SEQUENCER_44] = 0x2fff, - [WM8996_WRITE_SEQUENCER_48] = 0x2fff, - [WM8996_WRITE_SEQUENCER_52] = 0x2fff, - [WM8996_WRITE_SEQUENCER_56] = 0x2fff, - [WM8996_WRITE_SEQUENCER_60] = 0x2fff, - [WM8996_WRITE_SEQUENCER_64] = 0x1, - [WM8996_WRITE_SEQUENCER_65] = 0x1, - [WM8996_WRITE_SEQUENCER_67] = 0x6, - [WM8996_WRITE_SEQUENCER_68] = 0x40, - [WM8996_WRITE_SEQUENCER_69] = 0x1, - [WM8996_WRITE_SEQUENCER_70] = 0xf, - [WM8996_WRITE_SEQUENCER_71] = 0x6, - [WM8996_WRITE_SEQUENCER_72] = 0x1, - [WM8996_WRITE_SEQUENCER_73] = 0x3, - [WM8996_WRITE_SEQUENCER_74] = 0x104, - [WM8996_WRITE_SEQUENCER_76] = 0x60, - [WM8996_WRITE_SEQUENCER_77] = 0x11, - [WM8996_WRITE_SEQUENCER_78] = 0x401, - [WM8996_WRITE_SEQUENCER_80] = 0x50, - [WM8996_WRITE_SEQUENCER_81] = 0x3, - [WM8996_WRITE_SEQUENCER_82] = 0x100, - [WM8996_WRITE_SEQUENCER_84] = 0x60, - [WM8996_WRITE_SEQUENCER_85] = 0x3b, - [WM8996_WRITE_SEQUENCER_86] = 0x502, - [WM8996_WRITE_SEQUENCER_87] = 0x100, - [WM8996_WRITE_SEQUENCER_88] = 0x2fff, - [WM8996_WRITE_SEQUENCER_92] = 0x2fff, - [WM8996_WRITE_SEQUENCER_96] = 0x2fff, - [WM8996_WRITE_SEQUENCER_100] = 0x2fff, - [WM8996_WRITE_SEQUENCER_104] = 0x2fff, - [WM8996_WRITE_SEQUENCER_108] = 0x2fff, - [WM8996_WRITE_SEQUENCER_112] = 0x2fff, - [WM8996_WRITE_SEQUENCER_116] = 0x2fff, - [WM8996_WRITE_SEQUENCER_120] = 0x2fff, - [WM8996_WRITE_SEQUENCER_124] = 0x2fff, - [WM8996_WRITE_SEQUENCER_128] = 0x1, - [WM8996_WRITE_SEQUENCER_129] = 0x1, - [WM8996_WRITE_SEQUENCER_131] = 0x6, - [WM8996_WRITE_SEQUENCER_132] = 0x40, - [WM8996_WRITE_SEQUENCER_133] = 0x1, - [WM8996_WRITE_SEQUENCER_134] = 0xf, - [WM8996_WRITE_SEQUENCER_135] = 0x6, - [WM8996_WRITE_SEQUENCER_136] = 0x1, - [WM8996_WRITE_SEQUENCER_137] = 0x3, - [WM8996_WRITE_SEQUENCER_138] = 0x106, - [WM8996_WRITE_SEQUENCER_140] = 0x61, - [WM8996_WRITE_SEQUENCER_141] = 0x11, - [WM8996_WRITE_SEQUENCER_142] = 0x401, - [WM8996_WRITE_SEQUENCER_144] = 0x50, - [WM8996_WRITE_SEQUENCER_145] = 0x3, - [WM8996_WRITE_SEQUENCER_146] = 0x102, - [WM8996_WRITE_SEQUENCER_148] = 0x51, - [WM8996_WRITE_SEQUENCER_149] = 0x3, - [WM8996_WRITE_SEQUENCER_150] = 0x106, - [WM8996_WRITE_SEQUENCER_151] = 0xa, - [WM8996_WRITE_SEQUENCER_152] = 0x61, - [WM8996_WRITE_SEQUENCER_153] = 0x3b, - [WM8996_WRITE_SEQUENCER_154] = 0x502, - [WM8996_WRITE_SEQUENCER_155] = 0x100, - [WM8996_WRITE_SEQUENCER_156] = 0x2fff, - [WM8996_WRITE_SEQUENCER_160] = 0x2fff, - [WM8996_WRITE_SEQUENCER_164] = 0x2fff, - [WM8996_WRITE_SEQUENCER_168] = 0x2fff, - [WM8996_WRITE_SEQUENCER_172] = 0x2fff, - [WM8996_WRITE_SEQUENCER_176] = 0x2fff, - [WM8996_WRITE_SEQUENCER_180] = 0x2fff, - [WM8996_WRITE_SEQUENCER_184] = 0x2fff, - [WM8996_WRITE_SEQUENCER_188] = 0x2fff, - [WM8996_WRITE_SEQUENCER_192] = 0x1, - [WM8996_WRITE_SEQUENCER_193] = 0x1, - [WM8996_WRITE_SEQUENCER_195] = 0x6, - [WM8996_WRITE_SEQUENCER_196] = 0x40, - [WM8996_WRITE_SEQUENCER_197] = 0x1, - [WM8996_WRITE_SEQUENCER_198] = 0xf, - [WM8996_WRITE_SEQUENCER_199] = 0x6, - [WM8996_WRITE_SEQUENCER_200] = 0x1, - [WM8996_WRITE_SEQUENCER_201] = 0x3, - [WM8996_WRITE_SEQUENCER_202] = 0x106, - [WM8996_WRITE_SEQUENCER_204] = 0x61, - [WM8996_WRITE_SEQUENCER_205] = 0x11, - [WM8996_WRITE_SEQUENCER_206] = 0x401, - [WM8996_WRITE_SEQUENCER_208] = 0x50, - [WM8996_WRITE_SEQUENCER_209] = 0x3, - [WM8996_WRITE_SEQUENCER_210] = 0x102, - [WM8996_WRITE_SEQUENCER_212] = 0x61, - [WM8996_WRITE_SEQUENCER_213] = 0x3b, - [WM8996_WRITE_SEQUENCER_214] = 0x502, - [WM8996_WRITE_SEQUENCER_215] = 0x100, - [WM8996_WRITE_SEQUENCER_216] = 0x2fff, - [WM8996_WRITE_SEQUENCER_220] = 0x2fff, - [WM8996_WRITE_SEQUENCER_224] = 0x2fff, - [WM8996_WRITE_SEQUENCER_228] = 0x2fff, - [WM8996_WRITE_SEQUENCER_232] = 0x2fff, - [WM8996_WRITE_SEQUENCER_236] = 0x2fff, - [WM8996_WRITE_SEQUENCER_240] = 0x2fff, - [WM8996_WRITE_SEQUENCER_244] = 0x2fff, - [WM8996_WRITE_SEQUENCER_248] = 0x2fff, - [WM8996_WRITE_SEQUENCER_252] = 0x2fff, - [WM8996_WRITE_SEQUENCER_256] = 0x60, - [WM8996_WRITE_SEQUENCER_258] = 0x601, - [WM8996_WRITE_SEQUENCER_260] = 0x50, - [WM8996_WRITE_SEQUENCER_262] = 0x100, - [WM8996_WRITE_SEQUENCER_264] = 0x1, - [WM8996_WRITE_SEQUENCER_266] = 0x104, - [WM8996_WRITE_SEQUENCER_267] = 0x100, - [WM8996_WRITE_SEQUENCER_268] = 0x2fff, - [WM8996_WRITE_SEQUENCER_272] = 0x2fff, - [WM8996_WRITE_SEQUENCER_276] = 0x2fff, - [WM8996_WRITE_SEQUENCER_280] = 0x2fff, - [WM8996_WRITE_SEQUENCER_284] = 0x2fff, - [WM8996_WRITE_SEQUENCER_288] = 0x2fff, - [WM8996_WRITE_SEQUENCER_292] = 0x2fff, - [WM8996_WRITE_SEQUENCER_296] = 0x2fff, - [WM8996_WRITE_SEQUENCER_300] = 0x2fff, - [WM8996_WRITE_SEQUENCER_304] = 0x2fff, - [WM8996_WRITE_SEQUENCER_308] = 0x2fff, - [WM8996_WRITE_SEQUENCER_312] = 0x2fff, - [WM8996_WRITE_SEQUENCER_316] = 0x2fff, - [WM8996_WRITE_SEQUENCER_320] = 0x61, - [WM8996_WRITE_SEQUENCER_322] = 0x601, - [WM8996_WRITE_SEQUENCER_324] = 0x50, - [WM8996_WRITE_SEQUENCER_326] = 0x102, - [WM8996_WRITE_SEQUENCER_328] = 0x1, - [WM8996_WRITE_SEQUENCER_330] = 0x106, - [WM8996_WRITE_SEQUENCER_331] = 0x100, - [WM8996_WRITE_SEQUENCER_332] = 0x2fff, - [WM8996_WRITE_SEQUENCER_336] = 0x2fff, - [WM8996_WRITE_SEQUENCER_340] = 0x2fff, - [WM8996_WRITE_SEQUENCER_344] = 0x2fff, - [WM8996_WRITE_SEQUENCER_348] = 0x2fff, - [WM8996_WRITE_SEQUENCER_352] = 0x2fff, - [WM8996_WRITE_SEQUENCER_356] = 0x2fff, - [WM8996_WRITE_SEQUENCER_360] = 0x2fff, - [WM8996_WRITE_SEQUENCER_364] = 0x2fff, - [WM8996_WRITE_SEQUENCER_368] = 0x2fff, - [WM8996_WRITE_SEQUENCER_372] = 0x2fff, - [WM8996_WRITE_SEQUENCER_376] = 0x2fff, - [WM8996_WRITE_SEQUENCER_380] = 0x2fff, - [WM8996_WRITE_SEQUENCER_384] = 0x60, - [WM8996_WRITE_SEQUENCER_386] = 0x601, - [WM8996_WRITE_SEQUENCER_388] = 0x61, - [WM8996_WRITE_SEQUENCER_390] = 0x601, - [WM8996_WRITE_SEQUENCER_392] = 0x50, - [WM8996_WRITE_SEQUENCER_394] = 0x300, - [WM8996_WRITE_SEQUENCER_396] = 0x1, - [WM8996_WRITE_SEQUENCER_398] = 0x304, - [WM8996_WRITE_SEQUENCER_400] = 0x40, - [WM8996_WRITE_SEQUENCER_402] = 0xf, - [WM8996_WRITE_SEQUENCER_404] = 0x1, - [WM8996_WRITE_SEQUENCER_407] = 0x100, -}; - -static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); -static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0); -static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); -static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0); -static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); -static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); -static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); - -static const char *sidetone_hpf_text[] = { - "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" -}; - -static const struct soc_enum sidetone_hpf = - SOC_ENUM_SINGLE(WM8996_SIDETONE, 7, 6, sidetone_hpf_text); - -static const char *hpf_mode_text[] = { - "HiFi", "Custom", "Voice" -}; - -static const struct soc_enum dsp1tx_hpf_mode = - SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 3, 3, hpf_mode_text); - -static const struct soc_enum dsp2tx_hpf_mode = - SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 3, 3, hpf_mode_text); - -static const char *hpf_cutoff_text[] = { - "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" -}; - -static const struct soc_enum dsp1tx_hpf_cutoff = - SOC_ENUM_SINGLE(WM8996_DSP1_TX_FILTERS, 0, 7, hpf_cutoff_text); - -static const struct soc_enum dsp2tx_hpf_cutoff = - SOC_ENUM_SINGLE(WM8996_DSP2_TX_FILTERS, 0, 7, hpf_cutoff_text); - -static void wm8996_set_retune_mobile(struct snd_soc_codec *codec, int block) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct wm8996_pdata *pdata = &wm8996->pdata; - int base, best, best_val, save, i, cfg, iface; - - if (!wm8996->num_retune_mobile_texts) - return; - - switch (block) { - case 0: - base = WM8996_DSP1_RX_EQ_GAINS_1; - if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) & - WM8996_DSP1RX_SRC) - iface = 1; - else - iface = 0; - break; - case 1: - base = WM8996_DSP1_RX_EQ_GAINS_2; - if (snd_soc_read(codec, WM8996_POWER_MANAGEMENT_8) & - WM8996_DSP2RX_SRC) - iface = 1; - else - iface = 0; - break; - default: - return; - } - - /* Find the version of the currently selected configuration - * with the nearest sample rate. */ - cfg = wm8996->retune_mobile_cfg[block]; - best = 0; - best_val = INT_MAX; - for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { - if (strcmp(pdata->retune_mobile_cfgs[i].name, - wm8996->retune_mobile_texts[cfg]) == 0 && - abs(pdata->retune_mobile_cfgs[i].rate - - wm8996->rx_rate[iface]) < best_val) { - best = i; - best_val = abs(pdata->retune_mobile_cfgs[i].rate - - wm8996->rx_rate[iface]); - } - } - - dev_dbg(codec->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n", - block, - pdata->retune_mobile_cfgs[best].name, - pdata->retune_mobile_cfgs[best].rate, - wm8996->rx_rate[iface]); - - /* The EQ will be disabled while reconfiguring it, remember the - * current configuration. - */ - save = snd_soc_read(codec, base); - save &= WM8996_DSP1RX_EQ_ENA; - - for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++) - snd_soc_update_bits(codec, base + i, 0xffff, - pdata->retune_mobile_cfgs[best].regs[i]); - - snd_soc_update_bits(codec, base, WM8996_DSP1RX_EQ_ENA, save); -} - -/* Icky as hell but saves code duplication */ -static int wm8996_get_retune_mobile_block(const char *name) -{ - if (strcmp(name, "DSP1 EQ Mode") == 0) - return 0; - if (strcmp(name, "DSP2 EQ Mode") == 0) - return 1; - return -EINVAL; -} - -static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct wm8996_pdata *pdata = &wm8996->pdata; - int block = wm8996_get_retune_mobile_block(kcontrol->id.name); - int value = ucontrol->value.integer.value[0]; - - if (block < 0) - return block; - - if (value >= pdata->num_retune_mobile_cfgs) - return -EINVAL; - - wm8996->retune_mobile_cfg[block] = value; - - wm8996_set_retune_mobile(codec, block); - - return 0; -} - -static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int block = wm8996_get_retune_mobile_block(kcontrol->id.name); - - ucontrol->value.enumerated.item[0] = wm8996->retune_mobile_cfg[block]; - - return 0; -} - -static const struct snd_kcontrol_new wm8996_snd_controls[] = { -SOC_DOUBLE_R_TLV("Capture Volume", WM8996_LEFT_LINE_INPUT_VOLUME, - WM8996_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv), -SOC_DOUBLE_R("Capture ZC Switch", WM8996_LEFT_LINE_INPUT_VOLUME, - WM8996_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0), - -SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8996_DAC1_MIXER_VOLUMES, - 0, 5, 24, 0, sidetone_tlv), -SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8996_DAC2_MIXER_VOLUMES, - 0, 5, 24, 0, sidetone_tlv), -SOC_SINGLE("Sidetone LPF Switch", WM8996_SIDETONE, 12, 1, 0), -SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf), -SOC_SINGLE("Sidetone HPF Switch", WM8996_SIDETONE, 6, 1, 0), - -SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8996_DSP1_TX_LEFT_VOLUME, - WM8996_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), -SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8996_DSP2_TX_LEFT_VOLUME, - WM8996_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv), - -SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8996_DSP1_TX_FILTERS, - 13, 1, 0), -SOC_DOUBLE("DSP1 Capture HPF Switch", WM8996_DSP1_TX_FILTERS, 12, 11, 1, 0), -SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode), -SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff), - -SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8996_DSP2_TX_FILTERS, - 13, 1, 0), -SOC_DOUBLE("DSP2 Capture HPF Switch", WM8996_DSP2_TX_FILTERS, 12, 11, 1, 0), -SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode), -SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff), - -SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8996_DSP1_RX_LEFT_VOLUME, - WM8996_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), -SOC_SINGLE("DSP1 Playback Switch", WM8996_DSP1_RX_FILTERS_1, 9, 1, 1), - -SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8996_DSP2_RX_LEFT_VOLUME, - WM8996_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv), -SOC_SINGLE("DSP2 Playback Switch", WM8996_DSP2_RX_FILTERS_1, 9, 1, 1), - -SOC_DOUBLE_R_TLV("DAC1 Volume", WM8996_DAC1_LEFT_VOLUME, - WM8996_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv), -SOC_DOUBLE_R("DAC1 Switch", WM8996_DAC1_LEFT_VOLUME, - WM8996_DAC1_RIGHT_VOLUME, 9, 1, 1), - -SOC_DOUBLE_R_TLV("DAC2 Volume", WM8996_DAC2_LEFT_VOLUME, - WM8996_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv), -SOC_DOUBLE_R("DAC2 Switch", WM8996_DAC2_LEFT_VOLUME, - WM8996_DAC2_RIGHT_VOLUME, 9, 1, 1), - -SOC_SINGLE("Speaker High Performance Switch", WM8996_OVERSAMPLING, 3, 1, 0), -SOC_SINGLE("DMIC High Performance Switch", WM8996_OVERSAMPLING, 2, 1, 0), -SOC_SINGLE("ADC High Performance Switch", WM8996_OVERSAMPLING, 1, 1, 0), -SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0), - -SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), -SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), - -SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, - 8, 0, out_digital_tlv), -SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, - 8, 0, out_digital_tlv), - -SOC_DOUBLE_R_TLV("Output 1 Volume", WM8996_OUTPUT1_LEFT_VOLUME, - WM8996_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv), -SOC_DOUBLE_R("Output 1 ZC Switch", WM8996_OUTPUT1_LEFT_VOLUME, - WM8996_OUTPUT1_RIGHT_VOLUME, 7, 1, 0), - -SOC_DOUBLE_R_TLV("Output 2 Volume", WM8996_OUTPUT2_LEFT_VOLUME, - WM8996_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv), -SOC_DOUBLE_R("Output 2 ZC Switch", WM8996_OUTPUT2_LEFT_VOLUME, - WM8996_OUTPUT2_RIGHT_VOLUME, 7, 1, 0), - -SOC_DOUBLE_TLV("Speaker Volume", WM8996_PDM_SPEAKER_VOLUME, 0, 4, 8, 0, - spk_tlv), -SOC_DOUBLE_R("Speaker Switch", WM8996_LEFT_PDM_SPEAKER, - WM8996_RIGHT_PDM_SPEAKER, 3, 1, 1), -SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER, - WM8996_RIGHT_PDM_SPEAKER, 2, 1, 0), - -SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), -SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), -}; - -static const struct snd_kcontrol_new wm8996_eq_controls[] = { -SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 11, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 6, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 1, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 11, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 6, 31, 0, - eq_tlv), - -SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 11, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 6, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 1, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 11, 31, 0, - eq_tlv), -SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0, - eq_tlv), -}; - -static int cp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - msleep(5); - break; - default: - BUG(); - return -EINVAL; - } - - return 0; -} - -static int rmv_short_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec); - - /* Record which outputs we enabled */ - switch (event) { - case SND_SOC_DAPM_PRE_PMD: - wm8996->hpout_pending &= ~w->shift; - break; - case SND_SOC_DAPM_PRE_PMU: - wm8996->hpout_pending |= w->shift; - break; - default: - BUG(); - return -EINVAL; - } - - return 0; -} - -static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) -{ - struct i2c_client *i2c = to_i2c_client(codec->dev); - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int i, ret; - unsigned long timeout = 200; - - snd_soc_write(codec, WM8996_DC_SERVO_2, mask); - - /* Use the interrupt if possible */ - do { - if (i2c->irq) { - timeout = wait_for_completion_timeout(&wm8996->dcs_done, - msecs_to_jiffies(200)); - if (timeout == 0) - dev_err(codec->dev, "DC servo timed out\n"); - - } else { - msleep(1); - if (--i) { - timeout = 0; - break; - } - } - - ret = snd_soc_read(codec, WM8996_DC_SERVO_2); - dev_dbg(codec->dev, "DC servo state: %x\n", ret); - } while (ret & mask); - - if (timeout == 0) - dev_err(codec->dev, "DC servo timed out for %x\n", mask); - else - dev_dbg(codec->dev, "DC servo complete for %x\n", mask); -} - -static void wm8996_seq_notifier(struct snd_soc_dapm_context *dapm, - enum snd_soc_dapm_type event, int subseq) -{ - struct snd_soc_codec *codec = container_of(dapm, - struct snd_soc_codec, dapm); - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - u16 val, mask; - - /* Complete any pending DC servo starts */ - if (wm8996->dcs_pending) { - dev_dbg(codec->dev, "Starting DC servo for %x\n", - wm8996->dcs_pending); - - /* Trigger a startup sequence */ - wait_for_dc_servo(codec, wm8996->dcs_pending - << WM8996_DCS_TRIG_STARTUP_0_SHIFT); - - wm8996->dcs_pending = 0; - } - - if (wm8996->hpout_pending != wm8996->hpout_ena) { - dev_dbg(codec->dev, "Applying RMV_SHORTs %x->%x\n", - wm8996->hpout_ena, wm8996->hpout_pending); - - val = 0; - mask = 0; - if (wm8996->hpout_pending & HPOUT1L) { - val |= WM8996_HPOUT1L_RMV_SHORT; - mask |= WM8996_HPOUT1L_RMV_SHORT; - } else { - mask |= WM8996_HPOUT1L_RMV_SHORT | - WM8996_HPOUT1L_OUTP | - WM8996_HPOUT1L_DLY; - } - - if (wm8996->hpout_pending & HPOUT1R) { - val |= WM8996_HPOUT1R_RMV_SHORT; - mask |= WM8996_HPOUT1R_RMV_SHORT; - } else { - mask |= WM8996_HPOUT1R_RMV_SHORT | - WM8996_HPOUT1R_OUTP | - WM8996_HPOUT1R_DLY; - } - - snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, mask, val); - - val = 0; - mask = 0; - if (wm8996->hpout_pending & HPOUT2L) { - val |= WM8996_HPOUT2L_RMV_SHORT; - mask |= WM8996_HPOUT2L_RMV_SHORT; - } else { - mask |= WM8996_HPOUT2L_RMV_SHORT | - WM8996_HPOUT2L_OUTP | - WM8996_HPOUT2L_DLY; - } - - if (wm8996->hpout_pending & HPOUT2R) { - val |= WM8996_HPOUT2R_RMV_SHORT; - mask |= WM8996_HPOUT2R_RMV_SHORT; - } else { - mask |= WM8996_HPOUT2R_RMV_SHORT | - WM8996_HPOUT2R_OUTP | - WM8996_HPOUT2R_DLY; - } - - snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_2, mask, val); - - wm8996->hpout_ena = wm8996->hpout_pending; - } -} - -static int dcs_start(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(w->codec); - - switch (event) { - case SND_SOC_DAPM_POST_PMU: - wm8996->dcs_pending |= 1 << w->shift; - break; - default: - BUG(); - return -EINVAL; - } - - return 0; -} - -static const char *sidetone_text[] = { - "IN1", "IN2", -}; - -static const struct soc_enum left_sidetone_enum = - SOC_ENUM_SINGLE(WM8996_SIDETONE, 0, 2, sidetone_text); - -static const struct snd_kcontrol_new left_sidetone = - SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum); - -static const struct soc_enum right_sidetone_enum = - SOC_ENUM_SINGLE(WM8996_SIDETONE, 1, 2, sidetone_text); - -static const struct snd_kcontrol_new right_sidetone = - SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum); - -static const char *spk_text[] = { - "DAC1L", "DAC1R", "DAC2L", "DAC2R" -}; - -static const struct soc_enum spkl_enum = - SOC_ENUM_SINGLE(WM8996_LEFT_PDM_SPEAKER, 0, 4, spk_text); - -static const struct snd_kcontrol_new spkl_mux = - SOC_DAPM_ENUM("SPKL", spkl_enum); - -static const struct soc_enum spkr_enum = - SOC_ENUM_SINGLE(WM8996_RIGHT_PDM_SPEAKER, 0, 4, spk_text); - -static const struct snd_kcontrol_new spkr_mux = - SOC_DAPM_ENUM("SPKR", spkr_enum); - -static const char *dsp1rx_text[] = { - "AIF1", "AIF2" -}; - -static const struct soc_enum dsp1rx_enum = - SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 0, 2, dsp1rx_text); - -static const struct snd_kcontrol_new dsp1rx = - SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum); - -static const char *dsp2rx_text[] = { - "AIF2", "AIF1" -}; - -static const struct soc_enum dsp2rx_enum = - SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 4, 2, dsp2rx_text); - -static const struct snd_kcontrol_new dsp2rx = - SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum); - -static const char *aif2tx_text[] = { - "DSP2", "DSP1", "AIF1" -}; - -static const struct soc_enum aif2tx_enum = - SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_8, 6, 3, aif2tx_text); - -static const struct snd_kcontrol_new aif2tx = - SOC_DAPM_ENUM("AIF2TX", aif2tx_enum); - -static const char *inmux_text[] = { - "ADC", "DMIC1", "DMIC2" -}; - -static const struct soc_enum in1_enum = - SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 0, 3, inmux_text); - -static const struct snd_kcontrol_new in1_mux = - SOC_DAPM_ENUM("IN1 Mux", in1_enum); - -static const struct soc_enum in2_enum = - SOC_ENUM_SINGLE(WM8996_POWER_MANAGEMENT_7, 4, 3, inmux_text); - -static const struct snd_kcontrol_new in2_mux = - SOC_DAPM_ENUM("IN2 Mux", in2_enum); - -static const struct snd_kcontrol_new dac2r_mix[] = { -SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, - 5, 1, 0), -SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, - 4, 1, 0), -SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0), -SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0), -}; - -static const struct snd_kcontrol_new dac2l_mix[] = { -SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, - 5, 1, 0), -SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, - 4, 1, 0), -SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0), -SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0), -}; - -static const struct snd_kcontrol_new dac1r_mix[] = { -SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, - 5, 1, 0), -SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, - 4, 1, 0), -SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0), -SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0), -}; - -static const struct snd_kcontrol_new dac1l_mix[] = { -SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, - 5, 1, 0), -SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, - 4, 1, 0), -SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0), -SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0), -}; - -static const struct snd_kcontrol_new dsp1txl[] = { -SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING, - 1, 1, 0), -SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING, - 0, 1, 0), -}; - -static const struct snd_kcontrol_new dsp1txr[] = { -SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, - 1, 1, 0), -SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, - 0, 1, 0), -}; - -static const struct snd_kcontrol_new dsp2txl[] = { -SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING, - 1, 1, 0), -SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING, - 0, 1, 0), -}; - -static const struct snd_kcontrol_new dsp2txr[] = { -SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, - 1, 1, 0), -SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, - 0, 1, 0), -}; - - -static const struct snd_soc_dapm_widget wm8996_dapm_widgets[] = { -SND_SOC_DAPM_INPUT("IN1LN"), -SND_SOC_DAPM_INPUT("IN1LP"), -SND_SOC_DAPM_INPUT("IN1RN"), -SND_SOC_DAPM_INPUT("IN1RP"), - -SND_SOC_DAPM_INPUT("IN2LN"), -SND_SOC_DAPM_INPUT("IN2LP"), -SND_SOC_DAPM_INPUT("IN2RN"), -SND_SOC_DAPM_INPUT("IN2RP"), - -SND_SOC_DAPM_INPUT("DMIC1DAT"), -SND_SOC_DAPM_INPUT("DMIC2DAT"), - -SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, - SND_SOC_DAPM_POST_PMU), - -SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), -SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), -SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), - -SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0), -SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0), - -SND_SOC_DAPM_MUX("IN1L Mux", SND_SOC_NOPM, 0, 0, &in1_mux), -SND_SOC_DAPM_MUX("IN1R Mux", SND_SOC_NOPM, 0, 0, &in1_mux), -SND_SOC_DAPM_MUX("IN2L Mux", SND_SOC_NOPM, 0, 0, &in2_mux), -SND_SOC_DAPM_MUX("IN2R Mux", SND_SOC_NOPM, 0, 0, &in2_mux), - -SND_SOC_DAPM_PGA("IN1L", WM8996_POWER_MANAGEMENT_7, 2, 0, NULL, 0), -SND_SOC_DAPM_PGA("IN1R", WM8996_POWER_MANAGEMENT_7, 3, 0, NULL, 0), -SND_SOC_DAPM_PGA("IN2L", WM8996_POWER_MANAGEMENT_7, 6, 0, NULL, 0), -SND_SOC_DAPM_PGA("IN2R", WM8996_POWER_MANAGEMENT_7, 7, 0, NULL, 0), - -SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0), -SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0), - -SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8996_POWER_MANAGEMENT_3, 5, 0), -SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8996_POWER_MANAGEMENT_3, 4, 0), -SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8996_POWER_MANAGEMENT_3, 3, 0), -SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8996_POWER_MANAGEMENT_3, 2, 0), - -SND_SOC_DAPM_ADC("ADCL", NULL, WM8996_POWER_MANAGEMENT_3, 1, 0), -SND_SOC_DAPM_ADC("ADCR", NULL, WM8996_POWER_MANAGEMENT_3, 0, 0), - -SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone), -SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone), - -SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 11, 0), -SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 10, 0), -SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 9, 0), -SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 8, 0), - -SND_SOC_DAPM_MIXER("DSP2TXL", WM8996_POWER_MANAGEMENT_5, 11, 0, - dsp2txl, ARRAY_SIZE(dsp2txl)), -SND_SOC_DAPM_MIXER("DSP2TXR", WM8996_POWER_MANAGEMENT_5, 10, 0, - dsp2txr, ARRAY_SIZE(dsp2txr)), -SND_SOC_DAPM_MIXER("DSP1TXL", WM8996_POWER_MANAGEMENT_5, 9, 0, - dsp1txl, ARRAY_SIZE(dsp1txl)), -SND_SOC_DAPM_MIXER("DSP1TXR", WM8996_POWER_MANAGEMENT_5, 8, 0, - dsp1txr, ARRAY_SIZE(dsp1txr)), - -SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0, - dac2l_mix, ARRAY_SIZE(dac2l_mix)), -SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0, - dac2r_mix, ARRAY_SIZE(dac2r_mix)), -SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, - dac1l_mix, ARRAY_SIZE(dac1l_mix)), -SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, - dac1r_mix, ARRAY_SIZE(dac1r_mix)), - -SND_SOC_DAPM_DAC("DAC2L", NULL, WM8996_POWER_MANAGEMENT_5, 3, 0), -SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0), -SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), -SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), - -SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, - WM8996_POWER_MANAGEMENT_4, 9, 0), -SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, - WM8996_POWER_MANAGEMENT_4, 8, 0), - -SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, - WM8996_POWER_MANAGEMENT_6, 9, 0), -SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, - WM8996_POWER_MANAGEMENT_6, 8, 0), - -SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, - WM8996_POWER_MANAGEMENT_4, 5, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 4, - WM8996_POWER_MANAGEMENT_4, 4, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 3, - WM8996_POWER_MANAGEMENT_4, 3, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 2, - WM8996_POWER_MANAGEMENT_4, 2, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 1, - WM8996_POWER_MANAGEMENT_4, 1, 0), -SND_SOC_DAPM_AIF_IN("AIF1RX0", "AIF1 Playback", 0, - WM8996_POWER_MANAGEMENT_4, 0, 0), - -SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 5, - WM8996_POWER_MANAGEMENT_6, 5, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 4, - WM8996_POWER_MANAGEMENT_6, 4, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 3, - WM8996_POWER_MANAGEMENT_6, 3, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 2, - WM8996_POWER_MANAGEMENT_6, 2, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 1, - WM8996_POWER_MANAGEMENT_6, 1, 0), -SND_SOC_DAPM_AIF_OUT("AIF1TX0", "AIF1 Capture", 0, - WM8996_POWER_MANAGEMENT_6, 0, 0), - -/* We route as stereo pairs so define some dummy widgets to squash - * things down for now. RXA = 0,1, RXB = 2,3 and so on */ -SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0), -SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0), - -SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx), -SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx), -SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx), - -SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux), -SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux), -SND_SOC_DAPM_PGA("SPKL PGA", WM8996_LEFT_PDM_SPEAKER, 4, 0, NULL, 0), -SND_SOC_DAPM_PGA("SPKR PGA", WM8996_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0), - -SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start, - SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT2L_OUTP", 3, WM8996_ANALOGUE_HP_2, 6, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0, - rmv_short_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - -SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start, - SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT2R_OUTP", 3, WM8996_ANALOGUE_HP_2, 2, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0, - rmv_short_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - -SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start, - SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT1L_OUTP", 3, WM8996_ANALOGUE_HP_1, 6, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0, - rmv_short_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - -SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start, - SND_SOC_DAPM_POST_PMU), -SND_SOC_DAPM_PGA_S("HPOUT1R_OUTP", 3, WM8996_ANALOGUE_HP_1, 2, 0, NULL, 0), -SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0, - rmv_short_event, - SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), - -SND_SOC_DAPM_OUTPUT("HPOUT1L"), -SND_SOC_DAPM_OUTPUT("HPOUT1R"), -SND_SOC_DAPM_OUTPUT("HPOUT2L"), -SND_SOC_DAPM_OUTPUT("HPOUT2R"), -SND_SOC_DAPM_OUTPUT("SPKDAT"), -}; - -static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { - { "AIFCLK", NULL, "SYSCLK" }, - { "SYSDSPCLK", NULL, "SYSCLK" }, - { "Charge Pump", NULL, "SYSCLK" }, - - { "MICB1", NULL, "LDO2" }, - { "MICB2", NULL, "LDO2" }, - - { "IN1L PGA", NULL, "IN2LN" }, - { "IN1L PGA", NULL, "IN2LP" }, - { "IN1L PGA", NULL, "IN1LN" }, - { "IN1L PGA", NULL, "IN1LP" }, - - { "IN1R PGA", NULL, "IN2RN" }, - { "IN1R PGA", NULL, "IN2RP" }, - { "IN1R PGA", NULL, "IN1RN" }, - { "IN1R PGA", NULL, "IN1RP" }, - - { "ADCL", NULL, "IN1L PGA" }, - - { "ADCR", NULL, "IN1R PGA" }, - - { "DMIC1L", NULL, "DMIC1DAT" }, - { "DMIC1R", NULL, "DMIC1DAT" }, - { "DMIC2L", NULL, "DMIC2DAT" }, - { "DMIC2R", NULL, "DMIC2DAT" }, - - { "DMIC2L", NULL, "DMIC2" }, - { "DMIC2R", NULL, "DMIC2" }, - { "DMIC1L", NULL, "DMIC1" }, - { "DMIC1R", NULL, "DMIC1" }, - - { "IN1L Mux", "ADC", "ADCL" }, - { "IN1L Mux", "DMIC1", "DMIC1L" }, - { "IN1L Mux", "DMIC2", "DMIC2L" }, - - { "IN1R Mux", "ADC", "ADCR" }, - { "IN1R Mux", "DMIC1", "DMIC1R" }, - { "IN1R Mux", "DMIC2", "DMIC2R" }, - - { "IN2L Mux", "ADC", "ADCL" }, - { "IN2L Mux", "DMIC1", "DMIC1L" }, - { "IN2L Mux", "DMIC2", "DMIC2L" }, - - { "IN2R Mux", "ADC", "ADCR" }, - { "IN2R Mux", "DMIC1", "DMIC1R" }, - { "IN2R Mux", "DMIC2", "DMIC2R" }, - - { "Left Sidetone", "IN1", "IN1L Mux" }, - { "Left Sidetone", "IN2", "IN2L Mux" }, - - { "Right Sidetone", "IN1", "IN1R Mux" }, - { "Right Sidetone", "IN2", "IN2R Mux" }, - - { "DSP1TXL", "IN1 Switch", "IN1L Mux" }, - { "DSP1TXR", "IN1 Switch", "IN1R Mux" }, - - { "DSP2TXL", "IN1 Switch", "IN2L Mux" }, - { "DSP2TXR", "IN1 Switch", "IN2R Mux" }, - - { "AIF1TX0", NULL, "DSP1TXL" }, - { "AIF1TX1", NULL, "DSP1TXR" }, - { "AIF1TX2", NULL, "DSP2TXL" }, - { "AIF1TX3", NULL, "DSP2TXR" }, - { "AIF1TX4", NULL, "AIF2RX0" }, - { "AIF1TX5", NULL, "AIF2RX1" }, - - { "AIF1RX0", NULL, "AIFCLK" }, - { "AIF1RX1", NULL, "AIFCLK" }, - { "AIF1RX2", NULL, "AIFCLK" }, - { "AIF1RX3", NULL, "AIFCLK" }, - { "AIF1RX4", NULL, "AIFCLK" }, - { "AIF1RX5", NULL, "AIFCLK" }, - - { "AIF2RX0", NULL, "AIFCLK" }, - { "AIF2RX1", NULL, "AIFCLK" }, - - { "DSP1RXL", NULL, "SYSDSPCLK" }, - { "DSP1RXR", NULL, "SYSDSPCLK" }, - { "DSP2RXL", NULL, "SYSDSPCLK" }, - { "DSP2RXR", NULL, "SYSDSPCLK" }, - { "DSP1TXL", NULL, "SYSDSPCLK" }, - { "DSP1TXR", NULL, "SYSDSPCLK" }, - { "DSP2TXL", NULL, "SYSDSPCLK" }, - { "DSP2TXR", NULL, "SYSDSPCLK" }, - - { "AIF1RXA", NULL, "AIF1RX0" }, - { "AIF1RXA", NULL, "AIF1RX1" }, - { "AIF1RXB", NULL, "AIF1RX2" }, - { "AIF1RXB", NULL, "AIF1RX3" }, - { "AIF1RXC", NULL, "AIF1RX4" }, - { "AIF1RXC", NULL, "AIF1RX5" }, - - { "AIF2RX", NULL, "AIF2RX0" }, - { "AIF2RX", NULL, "AIF2RX1" }, - - { "AIF2TX", "DSP2", "DSP2TX" }, - { "AIF2TX", "DSP1", "DSP1RX" }, - { "AIF2TX", "AIF1", "AIF1RXC" }, - - { "DSP1RXL", NULL, "DSP1RX" }, - { "DSP1RXR", NULL, "DSP1RX" }, - { "DSP2RXL", NULL, "DSP2RX" }, - { "DSP2RXR", NULL, "DSP2RX" }, - - { "DSP2TX", NULL, "DSP2TXL" }, - { "DSP2TX", NULL, "DSP2TXR" }, - - { "DSP1RX", "AIF1", "AIF1RXA" }, - { "DSP1RX", "AIF2", "AIF2RX" }, - - { "DSP2RX", "AIF1", "AIF1RXB" }, - { "DSP2RX", "AIF2", "AIF2RX" }, - - { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" }, - { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" }, - { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" }, - { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" }, - - { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" }, - { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" }, - { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" }, - { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" }, - - { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" }, - { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" }, - { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, - { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, - - { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" }, - { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" }, - { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" }, - { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" }, - - { "DAC1L", NULL, "DAC1L Mixer" }, - { "DAC1R", NULL, "DAC1R Mixer" }, - { "DAC2L", NULL, "DAC2L Mixer" }, - { "DAC2R", NULL, "DAC2R Mixer" }, - - { "HPOUT2L PGA", NULL, "Charge Pump" }, - { "HPOUT2L PGA", NULL, "DAC2L" }, - { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, - { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, - { "HPOUT2L_OUTP", NULL, "HPOUT2L_DCS" }, - { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, - - { "HPOUT2R PGA", NULL, "Charge Pump" }, - { "HPOUT2R PGA", NULL, "DAC2R" }, - { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, - { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, - { "HPOUT2R_OUTP", NULL, "HPOUT2R_DCS" }, - { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, - - { "HPOUT1L PGA", NULL, "Charge Pump" }, - { "HPOUT1L PGA", NULL, "DAC1L" }, - { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, - { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, - { "HPOUT1L_OUTP", NULL, "HPOUT1L_DCS" }, - { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, - - { "HPOUT1R PGA", NULL, "Charge Pump" }, - { "HPOUT1R PGA", NULL, "DAC1R" }, - { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, - { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, - { "HPOUT1R_OUTP", NULL, "HPOUT1R_DCS" }, - { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_OUTP" }, - - { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" }, - { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" }, - { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" }, - { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" }, - - { "SPKL", "DAC1L", "DAC1L" }, - { "SPKL", "DAC1R", "DAC1R" }, - { "SPKL", "DAC2L", "DAC2L" }, - { "SPKL", "DAC2R", "DAC2R" }, - - { "SPKR", "DAC1L", "DAC1L" }, - { "SPKR", "DAC1R", "DAC1R" }, - { "SPKR", "DAC2L", "DAC2L" }, - { "SPKR", "DAC2R", "DAC2R" }, - - { "SPKL PGA", NULL, "SPKL" }, - { "SPKR PGA", NULL, "SPKR" }, - - { "SPKDAT", NULL, "SPKL PGA" }, - { "SPKDAT", NULL, "SPKR PGA" }, -}; - -static int wm8996_readable_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - /* Due to the sparseness of the register map the compiler - * output from an explicit switch statement ends up being much - * more efficient than a table. - */ - switch (reg) { - case WM8996_SOFTWARE_RESET: - case WM8996_POWER_MANAGEMENT_1: - case WM8996_POWER_MANAGEMENT_2: - case WM8996_POWER_MANAGEMENT_3: - case WM8996_POWER_MANAGEMENT_4: - case WM8996_POWER_MANAGEMENT_5: - case WM8996_POWER_MANAGEMENT_6: - case WM8996_POWER_MANAGEMENT_7: - case WM8996_POWER_MANAGEMENT_8: - case WM8996_LEFT_LINE_INPUT_VOLUME: - case WM8996_RIGHT_LINE_INPUT_VOLUME: - case WM8996_LINE_INPUT_CONTROL: - case WM8996_DAC1_HPOUT1_VOLUME: - case WM8996_DAC2_HPOUT2_VOLUME: - case WM8996_DAC1_LEFT_VOLUME: - case WM8996_DAC1_RIGHT_VOLUME: - case WM8996_DAC2_LEFT_VOLUME: - case WM8996_DAC2_RIGHT_VOLUME: - case WM8996_OUTPUT1_LEFT_VOLUME: - case WM8996_OUTPUT1_RIGHT_VOLUME: - case WM8996_OUTPUT2_LEFT_VOLUME: - case WM8996_OUTPUT2_RIGHT_VOLUME: - case WM8996_MICBIAS_1: - case WM8996_MICBIAS_2: - case WM8996_LDO_1: - case WM8996_LDO_2: - case WM8996_ACCESSORY_DETECT_MODE_1: - case WM8996_ACCESSORY_DETECT_MODE_2: - case WM8996_HEADPHONE_DETECT_1: - case WM8996_HEADPHONE_DETECT_2: - case WM8996_MIC_DETECT_1: - case WM8996_MIC_DETECT_2: - case WM8996_MIC_DETECT_3: - case WM8996_CHARGE_PUMP_1: - case WM8996_CHARGE_PUMP_2: - case WM8996_DC_SERVO_1: - case WM8996_DC_SERVO_2: - case WM8996_DC_SERVO_3: - case WM8996_DC_SERVO_5: - case WM8996_DC_SERVO_6: - case WM8996_DC_SERVO_7: - case WM8996_DC_SERVO_READBACK_0: - case WM8996_ANALOGUE_HP_1: - case WM8996_ANALOGUE_HP_2: - case WM8996_CHIP_REVISION: - case WM8996_CONTROL_INTERFACE_1: - case WM8996_WRITE_SEQUENCER_CTRL_1: - case WM8996_WRITE_SEQUENCER_CTRL_2: - case WM8996_AIF_CLOCKING_1: - case WM8996_AIF_CLOCKING_2: - case WM8996_CLOCKING_1: - case WM8996_CLOCKING_2: - case WM8996_AIF_RATE: - case WM8996_FLL_CONTROL_1: - case WM8996_FLL_CONTROL_2: - case WM8996_FLL_CONTROL_3: - case WM8996_FLL_CONTROL_4: - case WM8996_FLL_CONTROL_5: - case WM8996_FLL_CONTROL_6: - case WM8996_FLL_EFS_1: - case WM8996_FLL_EFS_2: - case WM8996_AIF1_CONTROL: - case WM8996_AIF1_BCLK: - case WM8996_AIF1_TX_LRCLK_1: - case WM8996_AIF1_TX_LRCLK_2: - case WM8996_AIF1_RX_LRCLK_1: - case WM8996_AIF1_RX_LRCLK_2: - case WM8996_AIF1TX_DATA_CONFIGURATION_1: - case WM8996_AIF1TX_DATA_CONFIGURATION_2: - case WM8996_AIF1RX_DATA_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_0_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_1_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_2_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_3_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_4_CONFIGURATION: - case WM8996_AIF1TX_CHANNEL_5_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_0_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_1_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_2_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_3_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_4_CONFIGURATION: - case WM8996_AIF1RX_CHANNEL_5_CONFIGURATION: - case WM8996_AIF1RX_MONO_CONFIGURATION: - case WM8996_AIF1TX_TEST: - case WM8996_AIF2_CONTROL: - case WM8996_AIF2_BCLK: - case WM8996_AIF2_TX_LRCLK_1: - case WM8996_AIF2_TX_LRCLK_2: - case WM8996_AIF2_RX_LRCLK_1: - case WM8996_AIF2_RX_LRCLK_2: - case WM8996_AIF2TX_DATA_CONFIGURATION_1: - case WM8996_AIF2TX_DATA_CONFIGURATION_2: - case WM8996_AIF2RX_DATA_CONFIGURATION: - case WM8996_AIF2TX_CHANNEL_0_CONFIGURATION: - case WM8996_AIF2TX_CHANNEL_1_CONFIGURATION: - case WM8996_AIF2RX_CHANNEL_0_CONFIGURATION: - case WM8996_AIF2RX_CHANNEL_1_CONFIGURATION: - case WM8996_AIF2RX_MONO_CONFIGURATION: - case WM8996_AIF2TX_TEST: - case WM8996_DSP1_TX_LEFT_VOLUME: - case WM8996_DSP1_TX_RIGHT_VOLUME: - case WM8996_DSP1_RX_LEFT_VOLUME: - case WM8996_DSP1_RX_RIGHT_VOLUME: - case WM8996_DSP1_TX_FILTERS: - case WM8996_DSP1_RX_FILTERS_1: - case WM8996_DSP1_RX_FILTERS_2: - case WM8996_DSP1_DRC_1: - case WM8996_DSP1_DRC_2: - case WM8996_DSP1_DRC_3: - case WM8996_DSP1_DRC_4: - case WM8996_DSP1_DRC_5: - case WM8996_DSP1_RX_EQ_GAINS_1: - case WM8996_DSP1_RX_EQ_GAINS_2: - case WM8996_DSP1_RX_EQ_BAND_1_A: - case WM8996_DSP1_RX_EQ_BAND_1_B: - case WM8996_DSP1_RX_EQ_BAND_1_PG: - case WM8996_DSP1_RX_EQ_BAND_2_A: - case WM8996_DSP1_RX_EQ_BAND_2_B: - case WM8996_DSP1_RX_EQ_BAND_2_C: - case WM8996_DSP1_RX_EQ_BAND_2_PG: - case WM8996_DSP1_RX_EQ_BAND_3_A: - case WM8996_DSP1_RX_EQ_BAND_3_B: - case WM8996_DSP1_RX_EQ_BAND_3_C: - case WM8996_DSP1_RX_EQ_BAND_3_PG: - case WM8996_DSP1_RX_EQ_BAND_4_A: - case WM8996_DSP1_RX_EQ_BAND_4_B: - case WM8996_DSP1_RX_EQ_BAND_4_C: - case WM8996_DSP1_RX_EQ_BAND_4_PG: - case WM8996_DSP1_RX_EQ_BAND_5_A: - case WM8996_DSP1_RX_EQ_BAND_5_B: - case WM8996_DSP1_RX_EQ_BAND_5_PG: - case WM8996_DSP2_TX_LEFT_VOLUME: - case WM8996_DSP2_TX_RIGHT_VOLUME: - case WM8996_DSP2_RX_LEFT_VOLUME: - case WM8996_DSP2_RX_RIGHT_VOLUME: - case WM8996_DSP2_TX_FILTERS: - case WM8996_DSP2_RX_FILTERS_1: - case WM8996_DSP2_RX_FILTERS_2: - case WM8996_DSP2_DRC_1: - case WM8996_DSP2_DRC_2: - case WM8996_DSP2_DRC_3: - case WM8996_DSP2_DRC_4: - case WM8996_DSP2_DRC_5: - case WM8996_DSP2_RX_EQ_GAINS_1: - case WM8996_DSP2_RX_EQ_GAINS_2: - case WM8996_DSP2_RX_EQ_BAND_1_A: - case WM8996_DSP2_RX_EQ_BAND_1_B: - case WM8996_DSP2_RX_EQ_BAND_1_PG: - case WM8996_DSP2_RX_EQ_BAND_2_A: - case WM8996_DSP2_RX_EQ_BAND_2_B: - case WM8996_DSP2_RX_EQ_BAND_2_C: - case WM8996_DSP2_RX_EQ_BAND_2_PG: - case WM8996_DSP2_RX_EQ_BAND_3_A: - case WM8996_DSP2_RX_EQ_BAND_3_B: - case WM8996_DSP2_RX_EQ_BAND_3_C: - case WM8996_DSP2_RX_EQ_BAND_3_PG: - case WM8996_DSP2_RX_EQ_BAND_4_A: - case WM8996_DSP2_RX_EQ_BAND_4_B: - case WM8996_DSP2_RX_EQ_BAND_4_C: - case WM8996_DSP2_RX_EQ_BAND_4_PG: - case WM8996_DSP2_RX_EQ_BAND_5_A: - case WM8996_DSP2_RX_EQ_BAND_5_B: - case WM8996_DSP2_RX_EQ_BAND_5_PG: - case WM8996_DAC1_MIXER_VOLUMES: - case WM8996_DAC1_LEFT_MIXER_ROUTING: - case WM8996_DAC1_RIGHT_MIXER_ROUTING: - case WM8996_DAC2_MIXER_VOLUMES: - case WM8996_DAC2_LEFT_MIXER_ROUTING: - case WM8996_DAC2_RIGHT_MIXER_ROUTING: - case WM8996_DSP1_TX_LEFT_MIXER_ROUTING: - case WM8996_DSP1_TX_RIGHT_MIXER_ROUTING: - case WM8996_DSP2_TX_LEFT_MIXER_ROUTING: - case WM8996_DSP2_TX_RIGHT_MIXER_ROUTING: - case WM8996_DSP_TX_MIXER_SELECT: - case WM8996_DAC_SOFTMUTE: - case WM8996_OVERSAMPLING: - case WM8996_SIDETONE: - case WM8996_GPIO_1: - case WM8996_GPIO_2: - case WM8996_GPIO_3: - case WM8996_GPIO_4: - case WM8996_GPIO_5: - case WM8996_PULL_CONTROL_1: - case WM8996_PULL_CONTROL_2: - case WM8996_INTERRUPT_STATUS_1: - case WM8996_INTERRUPT_STATUS_2: - case WM8996_INTERRUPT_RAW_STATUS_2: - case WM8996_INTERRUPT_STATUS_1_MASK: - case WM8996_INTERRUPT_STATUS_2_MASK: - case WM8996_INTERRUPT_CONTROL: - case WM8996_LEFT_PDM_SPEAKER: - case WM8996_RIGHT_PDM_SPEAKER: - case WM8996_PDM_SPEAKER_MUTE_SEQUENCE: - case WM8996_PDM_SPEAKER_VOLUME: - return 1; - default: - return 0; - } -} - -static int wm8996_volatile_register(struct snd_soc_codec *codec, - unsigned int reg) -{ - switch (reg) { - case WM8996_SOFTWARE_RESET: - case WM8996_CHIP_REVISION: - case WM8996_LDO_1: - case WM8996_LDO_2: - case WM8996_INTERRUPT_STATUS_1: - case WM8996_INTERRUPT_STATUS_2: - case WM8996_INTERRUPT_RAW_STATUS_2: - case WM8996_DC_SERVO_READBACK_0: - case WM8996_DC_SERVO_2: - case WM8996_DC_SERVO_6: - case WM8996_DC_SERVO_7: - case WM8996_FLL_CONTROL_6: - case WM8996_MIC_DETECT_3: - case WM8996_HEADPHONE_DETECT_1: - case WM8996_HEADPHONE_DETECT_2: - return 1; - default: - return 0; - } -} - -static int wm8996_reset(struct snd_soc_codec *codec) -{ - return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915); -} - -static const int bclk_divs[] = { - 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 -}; - -static void wm8996_update_bclk(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int aif, best, cur_val, bclk_rate, bclk_reg, i; - - /* Don't bother if we're in a low frequency idle mode that - * can't support audio. - */ - if (wm8996->sysclk < 64000) - return; - - for (aif = 0; aif < WM8996_AIFS; aif++) { - switch (aif) { - case 0: - bclk_reg = WM8996_AIF1_BCLK; - break; - case 1: - bclk_reg = WM8996_AIF2_BCLK; - break; - } - - bclk_rate = wm8996->bclk_rate[aif]; - - /* Pick a divisor for BCLK as close as we can get to ideal */ - best = 0; - for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { - cur_val = (wm8996->sysclk / bclk_divs[i]) - bclk_rate; - if (cur_val < 0) /* BCLK table is sorted */ - break; - best = i; - } - bclk_rate = wm8996->sysclk / bclk_divs[best]; - dev_dbg(codec->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", - bclk_divs[best], bclk_rate); - - snd_soc_update_bits(codec, bclk_reg, - WM8996_AIF1_BCLK_DIV_MASK, best); - } -} - -static int wm8996_set_bias_level(struct snd_soc_codec *codec, - enum snd_soc_bias_level level) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int ret; - - switch (level) { - case SND_SOC_BIAS_ON: - break; - - case SND_SOC_BIAS_PREPARE: - if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { - snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, - WM8996_BG_ENA, WM8996_BG_ENA); - msleep(2); - } - break; - - case SND_SOC_BIAS_STANDBY: - if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { - ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); - if (ret != 0) { - dev_err(codec->dev, - "Failed to enable supplies: %d\n", - ret); - return ret; - } - - if (wm8996->pdata.ldo_ena >= 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, - 1); - msleep(5); - } - - codec->cache_only = false; - snd_soc_cache_sync(codec); - } - - snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, - WM8996_BG_ENA, 0); - break; - - case SND_SOC_BIAS_OFF: - codec->cache_only = true; - if (wm8996->pdata.ldo_ena >= 0) - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); - break; - } - - codec->dapm.bias_level = level; - - return 0; -} - -static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct snd_soc_codec *codec = dai->codec; - int aifctrl = 0; - int bclk = 0; - int lrclk_tx = 0; - int lrclk_rx = 0; - int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg; - - switch (dai->id) { - case 0: - aifctrl_reg = WM8996_AIF1_CONTROL; - bclk_reg = WM8996_AIF1_BCLK; - lrclk_tx_reg = WM8996_AIF1_TX_LRCLK_2; - lrclk_rx_reg = WM8996_AIF1_RX_LRCLK_2; - break; - case 1: - aifctrl_reg = WM8996_AIF2_CONTROL; - bclk_reg = WM8996_AIF2_BCLK; - lrclk_tx_reg = WM8996_AIF2_TX_LRCLK_2; - lrclk_rx_reg = WM8996_AIF2_RX_LRCLK_2; - break; - default: - BUG(); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_IB_NF: - bclk |= WM8996_AIF1_BCLK_INV; - break; - case SND_SOC_DAIFMT_NB_IF: - lrclk_tx |= WM8996_AIF1TX_LRCLK_INV; - lrclk_rx |= WM8996_AIF1RX_LRCLK_INV; - break; - case SND_SOC_DAIFMT_IB_IF: - bclk |= WM8996_AIF1_BCLK_INV; - lrclk_tx |= WM8996_AIF1TX_LRCLK_INV; - lrclk_rx |= WM8996_AIF1RX_LRCLK_INV; - break; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - break; - case SND_SOC_DAIFMT_CBS_CFM: - lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR; - lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR; - break; - case SND_SOC_DAIFMT_CBM_CFS: - bclk |= WM8996_AIF1_BCLK_MSTR; - break; - case SND_SOC_DAIFMT_CBM_CFM: - bclk |= WM8996_AIF1_BCLK_MSTR; - lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR; - lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - break; - case SND_SOC_DAIFMT_DSP_B: - aifctrl |= 1; - break; - case SND_SOC_DAIFMT_I2S: - aifctrl |= 2; - break; - case SND_SOC_DAIFMT_LEFT_J: - aifctrl |= 3; - break; - default: - return -EINVAL; - } - - snd_soc_update_bits(codec, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl); - snd_soc_update_bits(codec, bclk_reg, - WM8996_AIF1_BCLK_INV | WM8996_AIF1_BCLK_MSTR, - bclk); - snd_soc_update_bits(codec, lrclk_tx_reg, - WM8996_AIF1TX_LRCLK_INV | - WM8996_AIF1TX_LRCLK_MSTR, - lrclk_tx); - snd_soc_update_bits(codec, lrclk_rx_reg, - WM8996_AIF1RX_LRCLK_INV | - WM8996_AIF1RX_LRCLK_MSTR, - lrclk_rx); - - return 0; -} - -static const int dsp_divs[] = { - 48000, 32000, 16000, 8000 -}; - -static int wm8996_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int bits, i, bclk_rate; - int aifdata = 0; - int lrclk = 0; - int dsp = 0; - int aifdata_reg, lrclk_reg, dsp_shift; - - switch (dai->id) { - case 0: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || - (snd_soc_read(codec, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) { - aifdata_reg = WM8996_AIF1RX_DATA_CONFIGURATION; - lrclk_reg = WM8996_AIF1_RX_LRCLK_1; - } else { - aifdata_reg = WM8996_AIF1TX_DATA_CONFIGURATION_1; - lrclk_reg = WM8996_AIF1_TX_LRCLK_1; - } - dsp_shift = 0; - break; - case 1: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || - (snd_soc_read(codec, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) { - aifdata_reg = WM8996_AIF2RX_DATA_CONFIGURATION; - lrclk_reg = WM8996_AIF2_RX_LRCLK_1; - } else { - aifdata_reg = WM8996_AIF2TX_DATA_CONFIGURATION_1; - lrclk_reg = WM8996_AIF2_TX_LRCLK_1; - } - dsp_shift = WM8996_DSP2_DIV_SHIFT; - break; - default: - BUG(); - return -EINVAL; - } - - bclk_rate = snd_soc_params_to_bclk(params); - if (bclk_rate < 0) { - dev_err(codec->dev, "Unsupported BCLK rate: %d\n", bclk_rate); - return bclk_rate; - } - - wm8996->bclk_rate[dai->id] = bclk_rate; - wm8996->rx_rate[dai->id] = params_rate(params); - - /* Needs looking at for TDM */ - bits = snd_pcm_format_width(params_format(params)); - if (bits < 0) - return bits; - aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits; - - for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) { - if (dsp_divs[i] == params_rate(params)) - break; - } - if (i == ARRAY_SIZE(dsp_divs)) { - dev_err(codec->dev, "Unsupported sample rate %dHz\n", - params_rate(params)); - return -EINVAL; - } - dsp |= i << dsp_shift; - - wm8996_update_bclk(codec); - - lrclk = bclk_rate / params_rate(params); - dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", - lrclk, bclk_rate / lrclk); - - snd_soc_update_bits(codec, aifdata_reg, - WM8996_AIF1TX_WL_MASK | - WM8996_AIF1TX_SLOT_LEN_MASK, - aifdata); - snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, - lrclk); - snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, - WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp); - - return 0; -} - -static int wm8996_set_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int freq, int dir) -{ - struct snd_soc_codec *codec = dai->codec; - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int lfclk = 0; - int ratediv = 0; - int src; - int old; - - if (freq == wm8996->sysclk && clk_id == wm8996->sysclk_src) - return 0; - - /* Disable SYSCLK while we reconfigure */ - old = snd_soc_read(codec, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA; - snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, - WM8996_SYSCLK_ENA, 0); - - switch (clk_id) { - case WM8996_SYSCLK_MCLK1: - wm8996->sysclk = freq; - src = 0; - break; - case WM8996_SYSCLK_MCLK2: - wm8996->sysclk = freq; - src = 1; - break; - case WM8996_SYSCLK_FLL: - wm8996->sysclk = freq; - src = 2; - break; - default: - dev_err(codec->dev, "Unsupported clock source %d\n", clk_id); - return -EINVAL; - } - - switch (wm8996->sysclk) { - case 6144000: - snd_soc_update_bits(codec, WM8996_AIF_RATE, - WM8996_SYSCLK_RATE, 0); - break; - case 24576000: - ratediv = WM8996_SYSCLK_DIV; - case 12288000: - snd_soc_update_bits(codec, WM8996_AIF_RATE, - WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE); - break; - case 32000: - case 32768: - lfclk = WM8996_LFCLK_ENA; - break; - default: - dev_warn(codec->dev, "Unsupported clock rate %dHz\n", - wm8996->sysclk); - return -EINVAL; - } - - wm8996_update_bclk(codec); - - snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, - WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK, - src << WM8996_SYSCLK_SRC_SHIFT | ratediv); - snd_soc_update_bits(codec, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk); - snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_1, - WM8996_SYSCLK_ENA, old); - - wm8996->sysclk_src = clk_id; - - return 0; -} - -struct _fll_div { - u16 fll_fratio; - u16 fll_outdiv; - u16 fll_refclk_div; - u16 fll_loop_gain; - u16 fll_ref_freq; - u16 n; - u16 theta; - u16 lambda; -}; - -static struct { - unsigned int min; - unsigned int max; - u16 fll_fratio; - int ratio; -} fll_fratios[] = { - { 0, 64000, 4, 16 }, - { 64000, 128000, 3, 8 }, - { 128000, 256000, 2, 4 }, - { 256000, 1000000, 1, 2 }, - { 1000000, 13500000, 0, 1 }, -}; - -static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, - unsigned int Fout) -{ - unsigned int target; - unsigned int div; - unsigned int fratio, gcd_fll; - int i; - - /* Fref must be <=13.5MHz */ - div = 1; - fll_div->fll_refclk_div = 0; - while ((Fref / div) > 13500000) { - div *= 2; - fll_div->fll_refclk_div++; - - if (div > 8) { - pr_err("Can't scale %dMHz input down to <=13.5MHz\n", - Fref); - return -EINVAL; - } - } - - pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); - - /* Apply the division for our remaining calculations */ - Fref /= div; - - if (Fref >= 3000000) - fll_div->fll_loop_gain = 5; - else - fll_div->fll_loop_gain = 0; - - if (Fref >= 48000) - fll_div->fll_ref_freq = 0; - else - fll_div->fll_ref_freq = 1; - - /* Fvco should be 90-100MHz; don't check the upper bound */ - div = 2; - while (Fout * div < 90000000) { - div++; - if (div > 64) { - pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", - Fout); - return -EINVAL; - } - } - target = Fout * div; - fll_div->fll_outdiv = div - 1; - - pr_debug("FLL Fvco=%dHz\n", target); - - /* Find an appropraite FLL_FRATIO and factor it out of the target */ - for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { - if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { - fll_div->fll_fratio = fll_fratios[i].fll_fratio; - fratio = fll_fratios[i].ratio; - break; - } - } - if (i == ARRAY_SIZE(fll_fratios)) { - pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); - return -EINVAL; - } - - fll_div->n = target / (fratio * Fref); - - if (target % Fref == 0) { - fll_div->theta = 0; - fll_div->lambda = 0; - } else { - gcd_fll = gcd(target, fratio * Fref); - - fll_div->theta = (target - (fll_div->n * fratio * Fref)) - / gcd_fll; - fll_div->lambda = (fratio * Fref) / gcd_fll; - } - - pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", - fll_div->n, fll_div->theta, fll_div->lambda); - pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", - fll_div->fll_fratio, fll_div->fll_outdiv, - fll_div->fll_refclk_div); - - return 0; -} - -static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, - unsigned int Fref, unsigned int Fout) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c = to_i2c_client(codec->dev); - struct _fll_div fll_div; - unsigned long timeout; - int ret, reg; - - /* Any change? */ - if (source == wm8996->fll_src && Fref == wm8996->fll_fref && - Fout == wm8996->fll_fout) - return 0; - - if (Fout == 0) { - dev_dbg(codec->dev, "FLL disabled\n"); - - wm8996->fll_fref = 0; - wm8996->fll_fout = 0; - - snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, - WM8996_FLL_ENA, 0); - - return 0; - } - - ret = fll_factors(&fll_div, Fref, Fout); - if (ret != 0) - return ret; - - switch (source) { - case WM8996_FLL_MCLK1: - reg = 0; - break; - case WM8996_FLL_MCLK2: - reg = 1; - break; - case WM8996_FLL_DACLRCLK1: - reg = 2; - break; - case WM8996_FLL_BCLK1: - reg = 3; - break; - default: - dev_err(codec->dev, "Unknown FLL source %d\n", ret); - return -EINVAL; - } - - reg |= fll_div.fll_refclk_div << WM8996_FLL_REFCLK_DIV_SHIFT; - reg |= fll_div.fll_ref_freq << WM8996_FLL_REF_FREQ_SHIFT; - - snd_soc_update_bits(codec, WM8996_FLL_CONTROL_5, - WM8996_FLL_REFCLK_DIV_MASK | WM8996_FLL_REF_FREQ | - WM8996_FLL_REFCLK_SRC_MASK, reg); - - reg = 0; - if (fll_div.theta || fll_div.lambda) - reg |= WM8996_FLL_EFS_ENA | (3 << WM8996_FLL_LFSR_SEL_SHIFT); - else - reg |= 1 << WM8996_FLL_LFSR_SEL_SHIFT; - snd_soc_write(codec, WM8996_FLL_EFS_2, reg); - - snd_soc_update_bits(codec, WM8996_FLL_CONTROL_2, - WM8996_FLL_OUTDIV_MASK | - WM8996_FLL_FRATIO_MASK, - (fll_div.fll_outdiv << WM8996_FLL_OUTDIV_SHIFT) | - (fll_div.fll_fratio)); - - snd_soc_write(codec, WM8996_FLL_CONTROL_3, fll_div.theta); - - snd_soc_update_bits(codec, WM8996_FLL_CONTROL_4, - WM8996_FLL_N_MASK | WM8996_FLL_LOOP_GAIN_MASK, - (fll_div.n << WM8996_FLL_N_SHIFT) | - fll_div.fll_loop_gain); - - snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); - - snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, - WM8996_FLL_ENA, WM8996_FLL_ENA); - - /* The FLL supports live reconfiguration - kick that in case we were - * already enabled. - */ - snd_soc_write(codec, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK); - - /* Wait for the FLL to lock, using the interrupt if possible */ - if (Fref > 1000000) - timeout = usecs_to_jiffies(300); - else - timeout = msecs_to_jiffies(2); - - /* Allow substantially longer if we've actually got the IRQ */ - if (i2c->irq) - timeout *= 1000; - - ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); - - if (ret == 0 && i2c->irq) { - dev_err(codec->dev, "Timed out waiting for FLL\n"); - ret = -ETIMEDOUT; - } else { - ret = 0; - } - - dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); - - wm8996->fll_fref = Fref; - wm8996->fll_fout = Fout; - wm8996->fll_src = source; - - return ret; -} - -#ifdef CONFIG_GPIOLIB -static inline struct wm8996_priv *gpio_to_wm8996(struct gpio_chip *chip) -{ - return container_of(chip, struct wm8996_priv, gpio_chip); -} - -static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - - snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT); -} - -static int wm8996_gpio_direction_out(struct gpio_chip *chip, - unsigned offset, int value) -{ - struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - int val; - - val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT); - - return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_FN_MASK | WM8996_GP1_DIR | - WM8996_GP1_LVL, val); -} - -static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - int ret; - - ret = snd_soc_read(codec, WM8996_GPIO_1 + offset); - if (ret < 0) - return ret; - - return (ret & WM8996_GP1_LVL) != 0; -} - -static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset) -{ - struct wm8996_priv *wm8996 = gpio_to_wm8996(chip); - struct snd_soc_codec *codec = wm8996->codec; - - return snd_soc_update_bits(codec, WM8996_GPIO_1 + offset, - WM8996_GP1_FN_MASK | WM8996_GP1_DIR, - (1 << WM8996_GP1_FN_SHIFT) | - (1 << WM8996_GP1_DIR_SHIFT)); -} - -static struct gpio_chip wm8996_template_chip = { - .label = "wm8996", - .owner = THIS_MODULE, - .direction_output = wm8996_gpio_direction_out, - .set = wm8996_gpio_set, - .direction_input = wm8996_gpio_direction_in, - .get = wm8996_gpio_get, - .can_sleep = 1, -}; - -static void wm8996_init_gpio(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int ret; - - wm8996->gpio_chip = wm8996_template_chip; - wm8996->gpio_chip.ngpio = 5; - wm8996->gpio_chip.dev = codec->dev; - - if (wm8996->pdata.gpio_base) - wm8996->gpio_chip.base = wm8996->pdata.gpio_base; - else - wm8996->gpio_chip.base = -1; - - ret = gpiochip_add(&wm8996->gpio_chip); - if (ret != 0) - dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); -} - -static void wm8996_free_gpio(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int ret; - - ret = gpiochip_remove(&wm8996->gpio_chip); - if (ret != 0) - dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); -} -#else -static void wm8996_init_gpio(struct snd_soc_codec *codec) -{ -} - -static void wm8996_free_gpio(struct snd_soc_codec *codec) -{ -} -#endif - -/** - * wm8996_detect - Enable default WM8996 jack detection - * - * The WM8996 has advanced accessory detection support for headsets. - * This function provides a default implementation which integrates - * the majority of this functionality with minimal user configuration. - * - * This will detect headset, headphone and short circuit button and - * will also detect inverted microphone ground connections and update - * the polarity of the connections. - */ -int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - wm8996_polarity_fn polarity_cb) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - - wm8996->jack = jack; - wm8996->detecting = true; - wm8996->polarity_cb = polarity_cb; - - if (wm8996->polarity_cb) - wm8996->polarity_cb(codec, 0); - - /* Clear discarge to avoid noise during detection */ - snd_soc_update_bits(codec, WM8996_MICBIAS_1, - WM8996_MICB1_DISCH, 0); - snd_soc_update_bits(codec, WM8996_MICBIAS_2, - WM8996_MICB2_DISCH, 0); - - /* LDO2 powers the microphones, SYSCLK clocks detection */ - snd_soc_dapm_force_enable_pin(&codec->dapm, "LDO2"); - snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); - - /* We start off just enabling microphone detection - even a - * plain headphone will trigger detection. - */ - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_ENA, WM8996_MICD_ENA); - - /* Slowest detection rate, gives debounce for initial detection */ - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - WM8996_MICD_RATE_MASK); - - /* Enable interrupts and we're off */ - snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, - WM8996_IM_MICD_EINT, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(wm8996_detect); - -static void wm8996_micd(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int val, reg; - - val = snd_soc_read(codec, WM8996_MIC_DETECT_3); - - dev_dbg(codec->dev, "Microphone event: %x\n", val); - - if (!(val & WM8996_MICD_VALID)) { - dev_warn(codec->dev, "Microphone detection state invalid\n"); - return; - } - - /* No accessory, reset everything and report removal */ - if (!(val & WM8996_MICD_STS)) { - dev_dbg(codec->dev, "Jack removal detected\n"); - wm8996->jack_mic = false; - wm8996->detecting = true; - snd_soc_jack_report(wm8996->jack, 0, - SND_JACK_HEADSET | SND_JACK_BTN_0); - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - WM8996_MICD_RATE_MASK); - return; - } - - /* If the measurement is very high we've got a microphone but - * do a little debounce to account for mechanical issues. - */ - if (val & 0x400) { - dev_dbg(codec->dev, "Microphone detected\n"); - snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, - SND_JACK_HEADSET | SND_JACK_BTN_0); - wm8996->jack_mic = true; - wm8996->detecting = false; - - /* Increase poll rate to give better responsiveness - * for buttons */ - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - 5 << WM8996_MICD_RATE_SHIFT); - } - - /* If we detected a lower impedence during initial startup - * then we probably have the wrong polarity, flip it. Don't - * do this for the lowest impedences to speed up detection of - * plain headphones. - */ - if (wm8996->detecting && (val & 0x3f0)) { - reg = snd_soc_read(codec, WM8996_ACCESSORY_DETECT_MODE_2); - reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | - WM8996_MICD_BIAS_SRC; - snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2, - WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC | - WM8996_MICD_BIAS_SRC, reg); - - if (wm8996->polarity_cb) - wm8996->polarity_cb(codec, - (reg & WM8996_MICD_SRC) != 0); - - dev_dbg(codec->dev, "Set microphone polarity to %d\n", - (reg & WM8996_MICD_SRC) != 0); - - return; - } - - /* Don't distinguish between buttons, just report any low - * impedence as BTN_0. - */ - if (val & 0x3fc) { - if (wm8996->jack_mic) { - dev_dbg(codec->dev, "Mic button detected\n"); - snd_soc_jack_report(wm8996->jack, - SND_JACK_HEADSET | SND_JACK_BTN_0, - SND_JACK_HEADSET | SND_JACK_BTN_0); - } else { - dev_dbg(codec->dev, "Headphone detected\n"); - snd_soc_jack_report(wm8996->jack, - SND_JACK_HEADPHONE, - SND_JACK_HEADSET | - SND_JACK_BTN_0); - - /* Increase the detection rate a bit for - * responsiveness. - */ - snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, - WM8996_MICD_RATE_MASK, - 7 << WM8996_MICD_RATE_SHIFT); - - wm8996->detecting = false; - } - } -} - -static irqreturn_t wm8996_irq(int irq, void *data) -{ - struct snd_soc_codec *codec = data; - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - int irq_val; - - irq_val = snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2); - if (irq_val < 0) { - dev_err(codec->dev, "Failed to read IRQ status: %d\n", - irq_val); - return IRQ_NONE; - } - irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); - - snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); - - if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { - dev_dbg(codec->dev, "DC servo IRQ\n"); - complete(&wm8996->dcs_done); - } - - if (irq_val & WM8996_FIFOS_ERR_EINT) - dev_err(codec->dev, "Digital core FIFO error\n"); - - if (irq_val & WM8996_FLL_LOCK_EINT) { - dev_dbg(codec->dev, "FLL locked\n"); - complete(&wm8996->fll_lock); - } - - if (irq_val & WM8996_MICD_EINT) - wm8996_micd(codec); - - if (irq_val) - return IRQ_HANDLED; - else - return IRQ_NONE; -} - -static irqreturn_t wm8996_edge_irq(int irq, void *data) -{ - irqreturn_t ret = IRQ_NONE; - irqreturn_t val; - - do { - val = wm8996_irq(irq, data); - if (val != IRQ_NONE) - ret = val; - } while (val != IRQ_NONE); - - return ret; -} - -static void wm8996_retune_mobile_pdata(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct wm8996_pdata *pdata = &wm8996->pdata; - - struct snd_kcontrol_new controls[] = { - SOC_ENUM_EXT("DSP1 EQ Mode", - wm8996->retune_mobile_enum, - wm8996_get_retune_mobile_enum, - wm8996_put_retune_mobile_enum), - SOC_ENUM_EXT("DSP2 EQ Mode", - wm8996->retune_mobile_enum, - wm8996_get_retune_mobile_enum, - wm8996_put_retune_mobile_enum), - }; - int ret, i, j; - const char **t; - - /* We need an array of texts for the enum API but the number - * of texts is likely to be less than the number of - * configurations due to the sample rate dependency of the - * configurations. */ - wm8996->num_retune_mobile_texts = 0; - wm8996->retune_mobile_texts = NULL; - for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) { - for (j = 0; j < wm8996->num_retune_mobile_texts; j++) { - if (strcmp(pdata->retune_mobile_cfgs[i].name, - wm8996->retune_mobile_texts[j]) == 0) - break; - } - - if (j != wm8996->num_retune_mobile_texts) - continue; - - /* Expand the array... */ - t = krealloc(wm8996->retune_mobile_texts, - sizeof(char *) * - (wm8996->num_retune_mobile_texts + 1), - GFP_KERNEL); - if (t == NULL) - continue; - - /* ...store the new entry... */ - t[wm8996->num_retune_mobile_texts] = - pdata->retune_mobile_cfgs[i].name; - - /* ...and remember the new version. */ - wm8996->num_retune_mobile_texts++; - wm8996->retune_mobile_texts = t; - } - - dev_dbg(codec->dev, "Allocated %d unique ReTune Mobile names\n", - wm8996->num_retune_mobile_texts); - - wm8996->retune_mobile_enum.max = wm8996->num_retune_mobile_texts; - wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts; - - ret = snd_soc_add_controls(codec, controls, ARRAY_SIZE(controls)); - if (ret != 0) - dev_err(codec->dev, - "Failed to add ReTune Mobile controls: %d\n", ret); -} - -static int wm8996_probe(struct snd_soc_codec *codec) -{ - int ret; - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c = to_i2c_client(codec->dev); - struct snd_soc_dapm_context *dapm = &codec->dapm; - int i, irq_flags; - - wm8996->codec = codec; - - init_completion(&wm8996->dcs_done); - init_completion(&wm8996->fll_lock); - - dapm->idle_bias_off = true; - dapm->bias_level = SND_SOC_BIAS_OFF; - - ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); - if (ret != 0) { - dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); - goto err; - } - - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) - wm8996->supplies[i].supply = wm8996_supply_names[i]; - - ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to request supplies: %d\n", ret); - goto err; - } - - wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; - wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; - wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; - wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; - - /* This should really be moved into the regulator core */ - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { - ret = regulator_register_notifier(wm8996->supplies[i].consumer, - &wm8996->disable_nb[i]); - if (ret != 0) { - dev_err(codec->dev, - "Failed to register regulator notifier: %d\n", - ret); - } - } - - ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), - wm8996->supplies); - if (ret != 0) { - dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); - goto err_get; - } - - if (wm8996->pdata.ldo_ena >= 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1); - msleep(5); - } - - ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET); - if (ret < 0) { - dev_err(codec->dev, "Failed to read ID register: %d\n", ret); - goto err_enable; - } - if (ret != 0x8915) { - dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret); - ret = -EINVAL; - goto err_enable; - } - - ret = snd_soc_read(codec, WM8996_CHIP_REVISION); - if (ret < 0) { - dev_err(codec->dev, "Failed to read device revision: %d\n", - ret); - goto err_enable; - } - - dev_info(codec->dev, "revision %c\n", - (ret & WM8996_CHIP_REV_MASK) + 'A'); - - if (wm8996->pdata.ldo_ena >= 0) { - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - } else { - ret = wm8996_reset(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to issue reset\n"); - goto err_enable; - } - } - - codec->cache_only = true; - - /* Apply platform data settings */ - snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL, - WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK, - wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT | - wm8996->pdata.inr_mode); - - for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) { - if (!wm8996->pdata.gpio_default[i]) - continue; - - snd_soc_write(codec, WM8996_GPIO_1 + i, - wm8996->pdata.gpio_default[i] & 0xffff); - } - - if (wm8996->pdata.spkmute_seq) - snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE, - WM8996_SPK_MUTE_ENDIAN | - WM8996_SPK_MUTE_SEQ1_MASK, - wm8996->pdata.spkmute_seq); - - snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2, - WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC | - WM8996_MICD_SRC, wm8996->pdata.micdet_def); - - /* Latch volume update bits */ - snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME, - WM8996_IN1_VU, WM8996_IN1_VU); - snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME, - WM8996_IN1_VU, WM8996_IN1_VU); - - snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - - snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME, - WM8996_DAC1_VU, WM8996_DAC1_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME, - WM8996_DAC2_VU, WM8996_DAC2_VU); - - snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME, - WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); - snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME, - WM8996_DSP1TX_VU, WM8996_DSP1TX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME, - WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME, - WM8996_DSP2TX_VU, WM8996_DSP2TX_VU); - - snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME, - WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); - snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME, - WM8996_DSP1RX_VU, WM8996_DSP1RX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME, - WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); - snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME, - WM8996_DSP2RX_VU, WM8996_DSP2RX_VU); - - /* No support currently for the underclocked TDM modes and - * pick a default TDM layout with each channel pair working with - * slots 0 and 1. */ - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, - WM8996_AIF1RX_CHAN0_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, - WM8996_AIF1RX_CHAN1_SLOTS_MASK | - WM8996_AIF1RX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, - WM8996_AIF1RX_CHAN2_SLOTS_MASK | - WM8996_AIF1RX_CHAN2_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, - WM8996_AIF1RX_CHAN3_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, - WM8996_AIF1RX_CHAN4_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, - WM8996_AIF1RX_CHAN5_SLOTS_MASK | - WM8996_AIF1RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, - WM8996_AIF2RX_CHAN0_SLOTS_MASK | - WM8996_AIF2RX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, - WM8996_AIF2RX_CHAN1_SLOTS_MASK | - WM8996_AIF2RX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, - WM8996_AIF1TX_CHAN0_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, - WM8996_AIF1TX_CHAN1_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, - WM8996_AIF1TX_CHAN2_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, - WM8996_AIF1TX_CHAN3_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, - WM8996_AIF1TX_CHAN4_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, - WM8996_AIF1TX_CHAN5_SLOTS_MASK | - WM8996_AIF1TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1); - - snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, - WM8996_AIF2TX_CHAN0_SLOTS_MASK | - WM8996_AIF2TX_CHAN0_START_SLOT_MASK, - 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0); - snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, - WM8996_AIF2TX_CHAN1_SLOTS_MASK | - WM8996_AIF2TX_CHAN1_START_SLOT_MASK, - 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1); - - if (wm8996->pdata.num_retune_mobile_cfgs) - wm8996_retune_mobile_pdata(codec); - else - snd_soc_add_controls(codec, wm8996_eq_controls, - ARRAY_SIZE(wm8996_eq_controls)); - - /* If the TX LRCLK pins are not in LRCLK mode configure the - * AIFs to source their clocks from the RX LRCLKs. - */ - if ((snd_soc_read(codec, WM8996_GPIO_1))) - snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2, - WM8996_AIF1TX_LRCLK_MODE, - WM8996_AIF1TX_LRCLK_MODE); - - if ((snd_soc_read(codec, WM8996_GPIO_2))) - snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2, - WM8996_AIF2TX_LRCLK_MODE, - WM8996_AIF2TX_LRCLK_MODE); - - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); - - wm8996_init_gpio(codec); - - if (i2c->irq) { - if (wm8996->pdata.irq_flags) - irq_flags = wm8996->pdata.irq_flags; - else - irq_flags = IRQF_TRIGGER_LOW; - - irq_flags |= IRQF_ONESHOT; - - if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) - ret = request_threaded_irq(i2c->irq, NULL, - wm8996_edge_irq, - irq_flags, "wm8996", codec); - else - ret = request_threaded_irq(i2c->irq, NULL, wm8996_irq, - irq_flags, "wm8996", codec); - - if (ret == 0) { - /* Unmask the interrupt */ - snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, - WM8996_IM_IRQ, 0); - - /* Enable error reporting and DC servo status */ - snd_soc_update_bits(codec, - WM8996_INTERRUPT_STATUS_2_MASK, - WM8996_IM_DCS_DONE_23_EINT | - WM8996_IM_DCS_DONE_01_EINT | - WM8996_IM_FLL_LOCK_EINT | - WM8996_IM_FIFOS_ERR_EINT, - 0); - } else { - dev_err(codec->dev, "Failed to request IRQ: %d\n", - ret); - } - } - - return 0; - -err_enable: - if (wm8996->pdata.ldo_ena >= 0) - gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); - - regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); -err_get: - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); -err: - return ret; -} - -static int wm8996_remove(struct snd_soc_codec *codec) -{ - struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); - struct i2c_client *i2c = to_i2c_client(codec->dev); - int i; - - snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, - WM8996_IM_IRQ, WM8996_IM_IRQ); - - if (i2c->irq) - free_irq(i2c->irq, codec); - - wm8996_free_gpio(codec); - - for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) - regulator_unregister_notifier(wm8996->supplies[i].consumer, - &wm8996->disable_nb[i]); - regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); - - return 0; -} - -static struct snd_soc_codec_driver soc_codec_dev_wm8996 = { - .probe = wm8996_probe, - .remove = wm8996_remove, - .set_bias_level = wm8996_set_bias_level, - .seq_notifier = wm8996_seq_notifier, - .reg_cache_size = WM8996_MAX_REGISTER + 1, - .reg_word_size = sizeof(u16), - .reg_cache_default = wm8996_reg, - .volatile_register = wm8996_volatile_register, - .readable_register = wm8996_readable_register, - .compress_type = SND_SOC_RBTREE_COMPRESSION, - .controls = wm8996_snd_controls, - .num_controls = ARRAY_SIZE(wm8996_snd_controls), - .dapm_widgets = wm8996_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets), - .dapm_routes = wm8996_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes), - .set_pll = wm8996_set_fll, -}; - -#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\ - SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_48000) -#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\ - SNDRV_PCM_FMTBIT_S32_LE) - -static struct snd_soc_dai_ops wm8996_dai_ops = { - .set_fmt = wm8996_set_fmt, - .hw_params = wm8996_hw_params, - .set_sysclk = wm8996_set_sysclk, -}; - -static struct snd_soc_dai_driver wm8996_dai[] = { - { - .name = "wm8996-aif1", - .playback = { - .stream_name = "AIF1 Playback", - .channels_min = 1, - .channels_max = 6, - .rates = WM8996_RATES, - .formats = WM8996_FORMATS, - }, - .capture = { - .stream_name = "AIF1 Capture", - .channels_min = 1, - .channels_max = 6, - .rates = WM8996_RATES, - .formats = WM8996_FORMATS, - }, - .ops = &wm8996_dai_ops, - }, - { - .name = "wm8996-aif2", - .playback = { - .stream_name = "AIF2 Playback", - .channels_min = 1, - .channels_max = 2, - .rates = WM8996_RATES, - .formats = WM8996_FORMATS, - }, - .capture = { - .stream_name = "AIF2 Capture", - .channels_min = 1, - .channels_max = 2, - .rates = WM8996_RATES, - .formats = WM8996_FORMATS, - }, - .ops = &wm8996_dai_ops, - }, -}; - -static __devinit int wm8996_i2c_probe(struct i2c_client *i2c, - const struct i2c_device_id *id) -{ - struct wm8996_priv *wm8996; - int ret; - - wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL); - if (wm8996 == NULL) - return -ENOMEM; - - i2c_set_clientdata(i2c, wm8996); - - if (dev_get_platdata(&i2c->dev)) - memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev), - sizeof(wm8996->pdata)); - - if (wm8996->pdata.ldo_ena > 0) { - ret = gpio_request_one(wm8996->pdata.ldo_ena, - GPIOF_OUT_INIT_LOW, "WM8996 ENA"); - if (ret < 0) { - dev_err(&i2c->dev, "Failed to request GPIO %d: %d\n", - wm8996->pdata.ldo_ena, ret); - goto err; - } - } - - ret = snd_soc_register_codec(&i2c->dev, - &soc_codec_dev_wm8996, wm8996_dai, - ARRAY_SIZE(wm8996_dai)); - if (ret < 0) - goto err_gpio; - - return ret; - -err_gpio: - if (wm8996->pdata.ldo_ena > 0) - gpio_free(wm8996->pdata.ldo_ena); -err: - kfree(wm8996); - - return ret; -} - -static __devexit int wm8996_i2c_remove(struct i2c_client *client) -{ - struct wm8996_priv *wm8996 = i2c_get_clientdata(client); - - snd_soc_unregister_codec(&client->dev); - if (wm8996->pdata.ldo_ena > 0) - gpio_free(wm8996->pdata.ldo_ena); - kfree(i2c_get_clientdata(client)); - return 0; -} - -static const struct i2c_device_id wm8996_i2c_id[] = { - { "wm8996", 0 }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wm8996_i2c_id); - -static struct i2c_driver wm8996_i2c_driver = { - .driver = { - .name = "wm8996", - .owner = THIS_MODULE, - }, - .probe = wm8996_i2c_probe, - .remove = __devexit_p(wm8996_i2c_remove), - .id_table = wm8996_i2c_id, -}; - -static int __init wm8996_modinit(void) -{ - int ret; - - ret = i2c_add_driver(&wm8996_i2c_driver); - if (ret != 0) { - printk(KERN_ERR "Failed to register WM8996 I2C driver: %d\n", - ret); - } - - return ret; -} -module_init(wm8996_modinit); - -static void __exit wm8996_exit(void) -{ - i2c_del_driver(&wm8996_i2c_driver); -} -module_exit(wm8996_exit); - -MODULE_DESCRIPTION("ASoC WM8996 driver"); -MODULE_AUTHOR("Mark Brown "); -MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/wm8996.h b/trunk/sound/soc/codecs/wm8996.h deleted file mode 100644 index 0fde643194ce..000000000000 --- a/trunk/sound/soc/codecs/wm8996.h +++ /dev/null @@ -1,3717 +0,0 @@ -/* - * wm8996.h - WM8996 audio codec interface - * - * Copyright 2011 Wolfson Microelectronics PLC. - * Author: Mark Brown - * - * 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. - */ - -#ifndef _WM8996_H -#define _WM8996_H - -#define WM8996_SYSCLK_MCLK1 1 -#define WM8996_SYSCLK_MCLK2 2 -#define WM8996_SYSCLK_FLL 3 - -#define WM8996_FLL_MCLK1 1 -#define WM8996_FLL_MCLK2 2 -#define WM8996_FLL_DACLRCLK1 3 -#define WM8996_FLL_BCLK1 4 - -typedef void (*wm8996_polarity_fn)(struct snd_soc_codec *codec, int polarity); - -int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, - wm8996_polarity_fn polarity_cb); - -/* - * Register values. - */ -#define WM8996_SOFTWARE_RESET 0x00 -#define WM8996_POWER_MANAGEMENT_1 0x01 -#define WM8996_POWER_MANAGEMENT_2 0x02 -#define WM8996_POWER_MANAGEMENT_3 0x03 -#define WM8996_POWER_MANAGEMENT_4 0x04 -#define WM8996_POWER_MANAGEMENT_5 0x05 -#define WM8996_POWER_MANAGEMENT_6 0x06 -#define WM8996_POWER_MANAGEMENT_7 0x07 -#define WM8996_POWER_MANAGEMENT_8 0x08 -#define WM8996_LEFT_LINE_INPUT_VOLUME 0x10 -#define WM8996_RIGHT_LINE_INPUT_VOLUME 0x11 -#define WM8996_LINE_INPUT_CONTROL 0x12 -#define WM8996_DAC1_HPOUT1_VOLUME 0x15 -#define WM8996_DAC2_HPOUT2_VOLUME 0x16 -#define WM8996_DAC1_LEFT_VOLUME 0x18 -#define WM8996_DAC1_RIGHT_VOLUME 0x19 -#define WM8996_DAC2_LEFT_VOLUME 0x1A -#define WM8996_DAC2_RIGHT_VOLUME 0x1B -#define WM8996_OUTPUT1_LEFT_VOLUME 0x1C -#define WM8996_OUTPUT1_RIGHT_VOLUME 0x1D -#define WM8996_OUTPUT2_LEFT_VOLUME 0x1E -#define WM8996_OUTPUT2_RIGHT_VOLUME 0x1F -#define WM8996_MICBIAS_1 0x20 -#define WM8996_MICBIAS_2 0x21 -#define WM8996_LDO_1 0x28 -#define WM8996_LDO_2 0x29 -#define WM8996_ACCESSORY_DETECT_MODE_1 0x30 -#define WM8996_ACCESSORY_DETECT_MODE_2 0x31 -#define WM8996_HEADPHONE_DETECT_1 0x34 -#define WM8996_HEADPHONE_DETECT_2 0x35 -#define WM8996_MIC_DETECT_1 0x38 -#define WM8996_MIC_DETECT_2 0x39 -#define WM8996_MIC_DETECT_3 0x3A -#define WM8996_CHARGE_PUMP_1 0x40 -#define WM8996_CHARGE_PUMP_2 0x41 -#define WM8996_DC_SERVO_1 0x50 -#define WM8996_DC_SERVO_2 0x51 -#define WM8996_DC_SERVO_3 0x52 -#define WM8996_DC_SERVO_5 0x54 -#define WM8996_DC_SERVO_6 0x55 -#define WM8996_DC_SERVO_7 0x56 -#define WM8996_DC_SERVO_READBACK_0 0x57 -#define WM8996_ANALOGUE_HP_1 0x60 -#define WM8996_ANALOGUE_HP_2 0x61 -#define WM8996_CHIP_REVISION 0x100 -#define WM8996_CONTROL_INTERFACE_1 0x101 -#define WM8996_WRITE_SEQUENCER_CTRL_1 0x110 -#define WM8996_WRITE_SEQUENCER_CTRL_2 0x111 -#define WM8996_AIF_CLOCKING_1 0x200 -#define WM8996_AIF_CLOCKING_2 0x201 -#define WM8996_CLOCKING_1 0x208 -#define WM8996_CLOCKING_2 0x209 -#define WM8996_AIF_RATE 0x210 -#define WM8996_FLL_CONTROL_1 0x220 -#define WM8996_FLL_CONTROL_2 0x221 -#define WM8996_FLL_CONTROL_3 0x222 -#define WM8996_FLL_CONTROL_4 0x223 -#define WM8996_FLL_CONTROL_5 0x224 -#define WM8996_FLL_CONTROL_6 0x225 -#define WM8996_FLL_EFS_1 0x226 -#define WM8996_FLL_EFS_2 0x227 -#define WM8996_AIF1_CONTROL 0x300 -#define WM8996_AIF1_BCLK 0x301 -#define WM8996_AIF1_TX_LRCLK_1 0x302 -#define WM8996_AIF1_TX_LRCLK_2 0x303 -#define WM8996_AIF1_RX_LRCLK_1 0x304 -#define WM8996_AIF1_RX_LRCLK_2 0x305 -#define WM8996_AIF1TX_DATA_CONFIGURATION_1 0x306 -#define WM8996_AIF1TX_DATA_CONFIGURATION_2 0x307 -#define WM8996_AIF1RX_DATA_CONFIGURATION 0x308 -#define WM8996_AIF1TX_CHANNEL_0_CONFIGURATION 0x309 -#define WM8996_AIF1TX_CHANNEL_1_CONFIGURATION 0x30A -#define WM8996_AIF1TX_CHANNEL_2_CONFIGURATION 0x30B -#define WM8996_AIF1TX_CHANNEL_3_CONFIGURATION 0x30C -#define WM8996_AIF1TX_CHANNEL_4_CONFIGURATION 0x30D -#define WM8996_AIF1TX_CHANNEL_5_CONFIGURATION 0x30E -#define WM8996_AIF1RX_CHANNEL_0_CONFIGURATION 0x30F -#define WM8996_AIF1RX_CHANNEL_1_CONFIGURATION 0x310 -#define WM8996_AIF1RX_CHANNEL_2_CONFIGURATION 0x311 -#define WM8996_AIF1RX_CHANNEL_3_CONFIGURATION 0x312 -#define WM8996_AIF1RX_CHANNEL_4_CONFIGURATION 0x313 -#define WM8996_AIF1RX_CHANNEL_5_CONFIGURATION 0x314 -#define WM8996_AIF1RX_MONO_CONFIGURATION 0x315 -#define WM8996_AIF1TX_TEST 0x31A -#define WM8996_AIF2_CONTROL 0x320 -#define WM8996_AIF2_BCLK 0x321 -#define WM8996_AIF2_TX_LRCLK_1 0x322 -#define WM8996_AIF2_TX_LRCLK_2 0x323 -#define WM8996_AIF2_RX_LRCLK_1 0x324 -#define WM8996_AIF2_RX_LRCLK_2 0x325 -#define WM8996_AIF2TX_DATA_CONFIGURATION_1 0x326 -#define WM8996_AIF2TX_DATA_CONFIGURATION_2 0x327 -#define WM8996_AIF2RX_DATA_CONFIGURATION 0x328 -#define WM8996_AIF2TX_CHANNEL_0_CONFIGURATION 0x329 -#define WM8996_AIF2TX_CHANNEL_1_CONFIGURATION 0x32A -#define WM8996_AIF2RX_CHANNEL_0_CONFIGURATION 0x32B -#define WM8996_AIF2RX_CHANNEL_1_CONFIGURATION 0x32C -#define WM8996_AIF2RX_MONO_CONFIGURATION 0x32D -#define WM8996_AIF2TX_TEST 0x32F -#define WM8996_DSP1_TX_LEFT_VOLUME 0x400 -#define WM8996_DSP1_TX_RIGHT_VOLUME 0x401 -#define WM8996_DSP1_RX_LEFT_VOLUME 0x402 -#define WM8996_DSP1_RX_RIGHT_VOLUME 0x403 -#define WM8996_DSP1_TX_FILTERS 0x410 -#define WM8996_DSP1_RX_FILTERS_1 0x420 -#define WM8996_DSP1_RX_FILTERS_2 0x421 -#define WM8996_DSP1_DRC_1 0x440 -#define WM8996_DSP1_DRC_2 0x441 -#define WM8996_DSP1_DRC_3 0x442 -#define WM8996_DSP1_DRC_4 0x443 -#define WM8996_DSP1_DRC_5 0x444 -#define WM8996_DSP1_RX_EQ_GAINS_1 0x480 -#define WM8996_DSP1_RX_EQ_GAINS_2 0x481 -#define WM8996_DSP1_RX_EQ_BAND_1_A 0x482 -#define WM8996_DSP1_RX_EQ_BAND_1_B 0x483 -#define WM8996_DSP1_RX_EQ_BAND_1_PG 0x484 -#define WM8996_DSP1_RX_EQ_BAND_2_A 0x485 -#define WM8996_DSP1_RX_EQ_BAND_2_B 0x486 -#define WM8996_DSP1_RX_EQ_BAND_2_C 0x487 -#define WM8996_DSP1_RX_EQ_BAND_2_PG 0x488 -#define WM8996_DSP1_RX_EQ_BAND_3_A 0x489 -#define WM8996_DSP1_RX_EQ_BAND_3_B 0x48A -#define WM8996_DSP1_RX_EQ_BAND_3_C 0x48B -#define WM8996_DSP1_RX_EQ_BAND_3_PG 0x48C -#define WM8996_DSP1_RX_EQ_BAND_4_A 0x48D -#define WM8996_DSP1_RX_EQ_BAND_4_B 0x48E -#define WM8996_DSP1_RX_EQ_BAND_4_C 0x48F -#define WM8996_DSP1_RX_EQ_BAND_4_PG 0x490 -#define WM8996_DSP1_RX_EQ_BAND_5_A 0x491 -#define WM8996_DSP1_RX_EQ_BAND_5_B 0x492 -#define WM8996_DSP1_RX_EQ_BAND_5_PG 0x493 -#define WM8996_DSP2_TX_LEFT_VOLUME 0x500 -#define WM8996_DSP2_TX_RIGHT_VOLUME 0x501 -#define WM8996_DSP2_RX_LEFT_VOLUME 0x502 -#define WM8996_DSP2_RX_RIGHT_VOLUME 0x503 -#define WM8996_DSP2_TX_FILTERS 0x510 -#define WM8996_DSP2_RX_FILTERS_1 0x520 -#define WM8996_DSP2_RX_FILTERS_2 0x521 -#define WM8996_DSP2_DRC_1 0x540 -#define WM8996_DSP2_DRC_2 0x541 -#define WM8996_DSP2_DRC_3 0x542 -#define WM8996_DSP2_DRC_4 0x543 -#define WM8996_DSP2_DRC_5 0x544 -#define WM8996_DSP2_RX_EQ_GAINS_1 0x580 -#define WM8996_DSP2_RX_EQ_GAINS_2 0x581 -#define WM8996_DSP2_RX_EQ_BAND_1_A 0x582 -#define WM8996_DSP2_RX_EQ_BAND_1_B 0x583 -#define WM8996_DSP2_RX_EQ_BAND_1_PG 0x584 -#define WM8996_DSP2_RX_EQ_BAND_2_A 0x585 -#define WM8996_DSP2_RX_EQ_BAND_2_B 0x586 -#define WM8996_DSP2_RX_EQ_BAND_2_C 0x587 -#define WM8996_DSP2_RX_EQ_BAND_2_PG 0x588 -#define WM8996_DSP2_RX_EQ_BAND_3_A 0x589 -#define WM8996_DSP2_RX_EQ_BAND_3_B 0x58A -#define WM8996_DSP2_RX_EQ_BAND_3_C 0x58B -#define WM8996_DSP2_RX_EQ_BAND_3_PG 0x58C -#define WM8996_DSP2_RX_EQ_BAND_4_A 0x58D -#define WM8996_DSP2_RX_EQ_BAND_4_B 0x58E -#define WM8996_DSP2_RX_EQ_BAND_4_C 0x58F -#define WM8996_DSP2_RX_EQ_BAND_4_PG 0x590 -#define WM8996_DSP2_RX_EQ_BAND_5_A 0x591 -#define WM8996_DSP2_RX_EQ_BAND_5_B 0x592 -#define WM8996_DSP2_RX_EQ_BAND_5_PG 0x593 -#define WM8996_DAC1_MIXER_VOLUMES 0x600 -#define WM8996_DAC1_LEFT_MIXER_ROUTING 0x601 -#define WM8996_DAC1_RIGHT_MIXER_ROUTING 0x602 -#define WM8996_DAC2_MIXER_VOLUMES 0x603 -#define WM8996_DAC2_LEFT_MIXER_ROUTING 0x604 -#define WM8996_DAC2_RIGHT_MIXER_ROUTING 0x605 -#define WM8996_DSP1_TX_LEFT_MIXER_ROUTING 0x606 -#define WM8996_DSP1_TX_RIGHT_MIXER_ROUTING 0x607 -#define WM8996_DSP2_TX_LEFT_MIXER_ROUTING 0x608 -#define WM8996_DSP2_TX_RIGHT_MIXER_ROUTING 0x609 -#define WM8996_DSP_TX_MIXER_SELECT 0x60A -#define WM8996_DAC_SOFTMUTE 0x610 -#define WM8996_OVERSAMPLING 0x620 -#define WM8996_SIDETONE 0x621 -#define WM8996_GPIO_1 0x700 -#define WM8996_GPIO_2 0x701 -#define WM8996_GPIO_3 0x702 -#define WM8996_GPIO_4 0x703 -#define WM8996_GPIO_5 0x704 -#define WM8996_PULL_CONTROL_1 0x720 -#define WM8996_PULL_CONTROL_2 0x721 -#define WM8996_INTERRUPT_STATUS_1 0x730 -#define WM8996_INTERRUPT_STATUS_2 0x731 -#define WM8996_INTERRUPT_RAW_STATUS_2 0x732 -#define WM8996_INTERRUPT_STATUS_1_MASK 0x738 -#define WM8996_INTERRUPT_STATUS_2_MASK 0x739 -#define WM8996_INTERRUPT_CONTROL 0x740 -#define WM8996_LEFT_PDM_SPEAKER 0x800 -#define WM8996_RIGHT_PDM_SPEAKER 0x801 -#define WM8996_PDM_SPEAKER_MUTE_SEQUENCE 0x802 -#define WM8996_PDM_SPEAKER_VOLUME 0x803 -#define WM8996_WRITE_SEQUENCER_0 0x3000 -#define WM8996_WRITE_SEQUENCER_1 0x3001 -#define WM8996_WRITE_SEQUENCER_2 0x3002 -#define WM8996_WRITE_SEQUENCER_3 0x3003 -#define WM8996_WRITE_SEQUENCER_4 0x3004 -#define WM8996_WRITE_SEQUENCER_5 0x3005 -#define WM8996_WRITE_SEQUENCER_6 0x3006 -#define WM8996_WRITE_SEQUENCER_7 0x3007 -#define WM8996_WRITE_SEQUENCER_8 0x3008 -#define WM8996_WRITE_SEQUENCER_9 0x3009 -#define WM8996_WRITE_SEQUENCER_10 0x300A -#define WM8996_WRITE_SEQUENCER_11 0x300B -#define WM8996_WRITE_SEQUENCER_12 0x300C -#define WM8996_WRITE_SEQUENCER_13 0x300D -#define WM8996_WRITE_SEQUENCER_14 0x300E -#define WM8996_WRITE_SEQUENCER_15 0x300F -#define WM8996_WRITE_SEQUENCER_16 0x3010 -#define WM8996_WRITE_SEQUENCER_17 0x3011 -#define WM8996_WRITE_SEQUENCER_18 0x3012 -#define WM8996_WRITE_SEQUENCER_19 0x3013 -#define WM8996_WRITE_SEQUENCER_20 0x3014 -#define WM8996_WRITE_SEQUENCER_21 0x3015 -#define WM8996_WRITE_SEQUENCER_22 0x3016 -#define WM8996_WRITE_SEQUENCER_23 0x3017 -#define WM8996_WRITE_SEQUENCER_24 0x3018 -#define WM8996_WRITE_SEQUENCER_25 0x3019 -#define WM8996_WRITE_SEQUENCER_26 0x301A -#define WM8996_WRITE_SEQUENCER_27 0x301B -#define WM8996_WRITE_SEQUENCER_28 0x301C -#define WM8996_WRITE_SEQUENCER_29 0x301D -#define WM8996_WRITE_SEQUENCER_30 0x301E -#define WM8996_WRITE_SEQUENCER_31 0x301F -#define WM8996_WRITE_SEQUENCER_32 0x3020 -#define WM8996_WRITE_SEQUENCER_33 0x3021 -#define WM8996_WRITE_SEQUENCER_34 0x3022 -#define WM8996_WRITE_SEQUENCER_35 0x3023 -#define WM8996_WRITE_SEQUENCER_36 0x3024 -#define WM8996_WRITE_SEQUENCER_37 0x3025 -#define WM8996_WRITE_SEQUENCER_38 0x3026 -#define WM8996_WRITE_SEQUENCER_39 0x3027 -#define WM8996_WRITE_SEQUENCER_40 0x3028 -#define WM8996_WRITE_SEQUENCER_41 0x3029 -#define WM8996_WRITE_SEQUENCER_42 0x302A -#define WM8996_WRITE_SEQUENCER_43 0x302B -#define WM8996_WRITE_SEQUENCER_44 0x302C -#define WM8996_WRITE_SEQUENCER_45 0x302D -#define WM8996_WRITE_SEQUENCER_46 0x302E -#define WM8996_WRITE_SEQUENCER_47 0x302F -#define WM8996_WRITE_SEQUENCER_48 0x3030 -#define WM8996_WRITE_SEQUENCER_49 0x3031 -#define WM8996_WRITE_SEQUENCER_50 0x3032 -#define WM8996_WRITE_SEQUENCER_51 0x3033 -#define WM8996_WRITE_SEQUENCER_52 0x3034 -#define WM8996_WRITE_SEQUENCER_53 0x3035 -#define WM8996_WRITE_SEQUENCER_54 0x3036 -#define WM8996_WRITE_SEQUENCER_55 0x3037 -#define WM8996_WRITE_SEQUENCER_56 0x3038 -#define WM8996_WRITE_SEQUENCER_57 0x3039 -#define WM8996_WRITE_SEQUENCER_58 0x303A -#define WM8996_WRITE_SEQUENCER_59 0x303B -#define WM8996_WRITE_SEQUENCER_60 0x303C -#define WM8996_WRITE_SEQUENCER_61 0x303D -#define WM8996_WRITE_SEQUENCER_62 0x303E -#define WM8996_WRITE_SEQUENCER_63 0x303F -#define WM8996_WRITE_SEQUENCER_64 0x3040 -#define WM8996_WRITE_SEQUENCER_65 0x3041 -#define WM8996_WRITE_SEQUENCER_66 0x3042 -#define WM8996_WRITE_SEQUENCER_67 0x3043 -#define WM8996_WRITE_SEQUENCER_68 0x3044 -#define WM8996_WRITE_SEQUENCER_69 0x3045 -#define WM8996_WRITE_SEQUENCER_70 0x3046 -#define WM8996_WRITE_SEQUENCER_71 0x3047 -#define WM8996_WRITE_SEQUENCER_72 0x3048 -#define WM8996_WRITE_SEQUENCER_73 0x3049 -#define WM8996_WRITE_SEQUENCER_74 0x304A -#define WM8996_WRITE_SEQUENCER_75 0x304B -#define WM8996_WRITE_SEQUENCER_76 0x304C -#define WM8996_WRITE_SEQUENCER_77 0x304D -#define WM8996_WRITE_SEQUENCER_78 0x304E -#define WM8996_WRITE_SEQUENCER_79 0x304F -#define WM8996_WRITE_SEQUENCER_80 0x3050 -#define WM8996_WRITE_SEQUENCER_81 0x3051 -#define WM8996_WRITE_SEQUENCER_82 0x3052 -#define WM8996_WRITE_SEQUENCER_83 0x3053 -#define WM8996_WRITE_SEQUENCER_84 0x3054 -#define WM8996_WRITE_SEQUENCER_85 0x3055 -#define WM8996_WRITE_SEQUENCER_86 0x3056 -#define WM8996_WRITE_SEQUENCER_87 0x3057 -#define WM8996_WRITE_SEQUENCER_88 0x3058 -#define WM8996_WRITE_SEQUENCER_89 0x3059 -#define WM8996_WRITE_SEQUENCER_90 0x305A -#define WM8996_WRITE_SEQUENCER_91 0x305B -#define WM8996_WRITE_SEQUENCER_92 0x305C -#define WM8996_WRITE_SEQUENCER_93 0x305D -#define WM8996_WRITE_SEQUENCER_94 0x305E -#define WM8996_WRITE_SEQUENCER_95 0x305F -#define WM8996_WRITE_SEQUENCER_96 0x3060 -#define WM8996_WRITE_SEQUENCER_97 0x3061 -#define WM8996_WRITE_SEQUENCER_98 0x3062 -#define WM8996_WRITE_SEQUENCER_99 0x3063 -#define WM8996_WRITE_SEQUENCER_100 0x3064 -#define WM8996_WRITE_SEQUENCER_101 0x3065 -#define WM8996_WRITE_SEQUENCER_102 0x3066 -#define WM8996_WRITE_SEQUENCER_103 0x3067 -#define WM8996_WRITE_SEQUENCER_104 0x3068 -#define WM8996_WRITE_SEQUENCER_105 0x3069 -#define WM8996_WRITE_SEQUENCER_106 0x306A -#define WM8996_WRITE_SEQUENCER_107 0x306B -#define WM8996_WRITE_SEQUENCER_108 0x306C -#define WM8996_WRITE_SEQUENCER_109 0x306D -#define WM8996_WRITE_SEQUENCER_110 0x306E -#define WM8996_WRITE_SEQUENCER_111 0x306F -#define WM8996_WRITE_SEQUENCER_112 0x3070 -#define WM8996_WRITE_SEQUENCER_113 0x3071 -#define WM8996_WRITE_SEQUENCER_114 0x3072 -#define WM8996_WRITE_SEQUENCER_115 0x3073 -#define WM8996_WRITE_SEQUENCER_116 0x3074 -#define WM8996_WRITE_SEQUENCER_117 0x3075 -#define WM8996_WRITE_SEQUENCER_118 0x3076 -#define WM8996_WRITE_SEQUENCER_119 0x3077 -#define WM8996_WRITE_SEQUENCER_120 0x3078 -#define WM8996_WRITE_SEQUENCER_121 0x3079 -#define WM8996_WRITE_SEQUENCER_122 0x307A -#define WM8996_WRITE_SEQUENCER_123 0x307B -#define WM8996_WRITE_SEQUENCER_124 0x307C -#define WM8996_WRITE_SEQUENCER_125 0x307D -#define WM8996_WRITE_SEQUENCER_126 0x307E -#define WM8996_WRITE_SEQUENCER_127 0x307F -#define WM8996_WRITE_SEQUENCER_128 0x3080 -#define WM8996_WRITE_SEQUENCER_129 0x3081 -#define WM8996_WRITE_SEQUENCER_130 0x3082 -#define WM8996_WRITE_SEQUENCER_131 0x3083 -#define WM8996_WRITE_SEQUENCER_132 0x3084 -#define WM8996_WRITE_SEQUENCER_133 0x3085 -#define WM8996_WRITE_SEQUENCER_134 0x3086 -#define WM8996_WRITE_SEQUENCER_135 0x3087 -#define WM8996_WRITE_SEQUENCER_136 0x3088 -#define WM8996_WRITE_SEQUENCER_137 0x3089 -#define WM8996_WRITE_SEQUENCER_138 0x308A -#define WM8996_WRITE_SEQUENCER_139 0x308B -#define WM8996_WRITE_SEQUENCER_140 0x308C -#define WM8996_WRITE_SEQUENCER_141 0x308D -#define WM8996_WRITE_SEQUENCER_142 0x308E -#define WM8996_WRITE_SEQUENCER_143 0x308F -#define WM8996_WRITE_SEQUENCER_144 0x3090 -#define WM8996_WRITE_SEQUENCER_145 0x3091 -#define WM8996_WRITE_SEQUENCER_146 0x3092 -#define WM8996_WRITE_SEQUENCER_147 0x3093 -#define WM8996_WRITE_SEQUENCER_148 0x3094 -#define WM8996_WRITE_SEQUENCER_149 0x3095 -#define WM8996_WRITE_SEQUENCER_150 0x3096 -#define WM8996_WRITE_SEQUENCER_151 0x3097 -#define WM8996_WRITE_SEQUENCER_152 0x3098 -#define WM8996_WRITE_SEQUENCER_153 0x3099 -#define WM8996_WRITE_SEQUENCER_154 0x309A -#define WM8996_WRITE_SEQUENCER_155 0x309B -#define WM8996_WRITE_SEQUENCER_156 0x309C -#define WM8996_WRITE_SEQUENCER_157 0x309D -#define WM8996_WRITE_SEQUENCER_158 0x309E -#define WM8996_WRITE_SEQUENCER_159 0x309F -#define WM8996_WRITE_SEQUENCER_160 0x30A0 -#define WM8996_WRITE_SEQUENCER_161 0x30A1 -#define WM8996_WRITE_SEQUENCER_162 0x30A2 -#define WM8996_WRITE_SEQUENCER_163 0x30A3 -#define WM8996_WRITE_SEQUENCER_164 0x30A4 -#define WM8996_WRITE_SEQUENCER_165 0x30A5 -#define WM8996_WRITE_SEQUENCER_166 0x30A6 -#define WM8996_WRITE_SEQUENCER_167 0x30A7 -#define WM8996_WRITE_SEQUENCER_168 0x30A8 -#define WM8996_WRITE_SEQUENCER_169 0x30A9 -#define WM8996_WRITE_SEQUENCER_170 0x30AA -#define WM8996_WRITE_SEQUENCER_171 0x30AB -#define WM8996_WRITE_SEQUENCER_172 0x30AC -#define WM8996_WRITE_SEQUENCER_173 0x30AD -#define WM8996_WRITE_SEQUENCER_174 0x30AE -#define WM8996_WRITE_SEQUENCER_175 0x30AF -#define WM8996_WRITE_SEQUENCER_176 0x30B0 -#define WM8996_WRITE_SEQUENCER_177 0x30B1 -#define WM8996_WRITE_SEQUENCER_178 0x30B2 -#define WM8996_WRITE_SEQUENCER_179 0x30B3 -#define WM8996_WRITE_SEQUENCER_180 0x30B4 -#define WM8996_WRITE_SEQUENCER_181 0x30B5 -#define WM8996_WRITE_SEQUENCER_182 0x30B6 -#define WM8996_WRITE_SEQUENCER_183 0x30B7 -#define WM8996_WRITE_SEQUENCER_184 0x30B8 -#define WM8996_WRITE_SEQUENCER_185 0x30B9 -#define WM8996_WRITE_SEQUENCER_186 0x30BA -#define WM8996_WRITE_SEQUENCER_187 0x30BB -#define WM8996_WRITE_SEQUENCER_188 0x30BC -#define WM8996_WRITE_SEQUENCER_189 0x30BD -#define WM8996_WRITE_SEQUENCER_190 0x30BE -#define WM8996_WRITE_SEQUENCER_191 0x30BF -#define WM8996_WRITE_SEQUENCER_192 0x30C0 -#define WM8996_WRITE_SEQUENCER_193 0x30C1 -#define WM8996_WRITE_SEQUENCER_194 0x30C2 -#define WM8996_WRITE_SEQUENCER_195 0x30C3 -#define WM8996_WRITE_SEQUENCER_196 0x30C4 -#define WM8996_WRITE_SEQUENCER_197 0x30C5 -#define WM8996_WRITE_SEQUENCER_198 0x30C6 -#define WM8996_WRITE_SEQUENCER_199 0x30C7 -#define WM8996_WRITE_SEQUENCER_200 0x30C8 -#define WM8996_WRITE_SEQUENCER_201 0x30C9 -#define WM8996_WRITE_SEQUENCER_202 0x30CA -#define WM8996_WRITE_SEQUENCER_203 0x30CB -#define WM8996_WRITE_SEQUENCER_204 0x30CC -#define WM8996_WRITE_SEQUENCER_205 0x30CD -#define WM8996_WRITE_SEQUENCER_206 0x30CE -#define WM8996_WRITE_SEQUENCER_207 0x30CF -#define WM8996_WRITE_SEQUENCER_208 0x30D0 -#define WM8996_WRITE_SEQUENCER_209 0x30D1 -#define WM8996_WRITE_SEQUENCER_210 0x30D2 -#define WM8996_WRITE_SEQUENCER_211 0x30D3 -#define WM8996_WRITE_SEQUENCER_212 0x30D4 -#define WM8996_WRITE_SEQUENCER_213 0x30D5 -#define WM8996_WRITE_SEQUENCER_214 0x30D6 -#define WM8996_WRITE_SEQUENCER_215 0x30D7 -#define WM8996_WRITE_SEQUENCER_216 0x30D8 -#define WM8996_WRITE_SEQUENCER_217 0x30D9 -#define WM8996_WRITE_SEQUENCER_218 0x30DA -#define WM8996_WRITE_SEQUENCER_219 0x30DB -#define WM8996_WRITE_SEQUENCER_220 0x30DC -#define WM8996_WRITE_SEQUENCER_221 0x30DD -#define WM8996_WRITE_SEQUENCER_222 0x30DE -#define WM8996_WRITE_SEQUENCER_223 0x30DF -#define WM8996_WRITE_SEQUENCER_224 0x30E0 -#define WM8996_WRITE_SEQUENCER_225 0x30E1 -#define WM8996_WRITE_SEQUENCER_226 0x30E2 -#define WM8996_WRITE_SEQUENCER_227 0x30E3 -#define WM8996_WRITE_SEQUENCER_228 0x30E4 -#define WM8996_WRITE_SEQUENCER_229 0x30E5 -#define WM8996_WRITE_SEQUENCER_230 0x30E6 -#define WM8996_WRITE_SEQUENCER_231 0x30E7 -#define WM8996_WRITE_SEQUENCER_232 0x30E8 -#define WM8996_WRITE_SEQUENCER_233 0x30E9 -#define WM8996_WRITE_SEQUENCER_234 0x30EA -#define WM8996_WRITE_SEQUENCER_235 0x30EB -#define WM8996_WRITE_SEQUENCER_236 0x30EC -#define WM8996_WRITE_SEQUENCER_237 0x30ED -#define WM8996_WRITE_SEQUENCER_238 0x30EE -#define WM8996_WRITE_SEQUENCER_239 0x30EF -#define WM8996_WRITE_SEQUENCER_240 0x30F0 -#define WM8996_WRITE_SEQUENCER_241 0x30F1 -#define WM8996_WRITE_SEQUENCER_242 0x30F2 -#define WM8996_WRITE_SEQUENCER_243 0x30F3 -#define WM8996_WRITE_SEQUENCER_244 0x30F4 -#define WM8996_WRITE_SEQUENCER_245 0x30F5 -#define WM8996_WRITE_SEQUENCER_246 0x30F6 -#define WM8996_WRITE_SEQUENCER_247 0x30F7 -#define WM8996_WRITE_SEQUENCER_248 0x30F8 -#define WM8996_WRITE_SEQUENCER_249 0x30F9 -#define WM8996_WRITE_SEQUENCER_250 0x30FA -#define WM8996_WRITE_SEQUENCER_251 0x30FB -#define WM8996_WRITE_SEQUENCER_252 0x30FC -#define WM8996_WRITE_SEQUENCER_253 0x30FD -#define WM8996_WRITE_SEQUENCER_254 0x30FE -#define WM8996_WRITE_SEQUENCER_255 0x30FF -#define WM8996_WRITE_SEQUENCER_256 0x3100 -#define WM8996_WRITE_SEQUENCER_257 0x3101 -#define WM8996_WRITE_SEQUENCER_258 0x3102 -#define WM8996_WRITE_SEQUENCER_259 0x3103 -#define WM8996_WRITE_SEQUENCER_260 0x3104 -#define WM8996_WRITE_SEQUENCER_261 0x3105 -#define WM8996_WRITE_SEQUENCER_262 0x3106 -#define WM8996_WRITE_SEQUENCER_263 0x3107 -#define WM8996_WRITE_SEQUENCER_264 0x3108 -#define WM8996_WRITE_SEQUENCER_265 0x3109 -#define WM8996_WRITE_SEQUENCER_266 0x310A -#define WM8996_WRITE_SEQUENCER_267 0x310B -#define WM8996_WRITE_SEQUENCER_268 0x310C -#define WM8996_WRITE_SEQUENCER_269 0x310D -#define WM8996_WRITE_SEQUENCER_270 0x310E -#define WM8996_WRITE_SEQUENCER_271 0x310F -#define WM8996_WRITE_SEQUENCER_272 0x3110 -#define WM8996_WRITE_SEQUENCER_273 0x3111 -#define WM8996_WRITE_SEQUENCER_274 0x3112 -#define WM8996_WRITE_SEQUENCER_275 0x3113 -#define WM8996_WRITE_SEQUENCER_276 0x3114 -#define WM8996_WRITE_SEQUENCER_277 0x3115 -#define WM8996_WRITE_SEQUENCER_278 0x3116 -#define WM8996_WRITE_SEQUENCER_279 0x3117 -#define WM8996_WRITE_SEQUENCER_280 0x3118 -#define WM8996_WRITE_SEQUENCER_281 0x3119 -#define WM8996_WRITE_SEQUENCER_282 0x311A -#define WM8996_WRITE_SEQUENCER_283 0x311B -#define WM8996_WRITE_SEQUENCER_284 0x311C -#define WM8996_WRITE_SEQUENCER_285 0x311D -#define WM8996_WRITE_SEQUENCER_286 0x311E -#define WM8996_WRITE_SEQUENCER_287 0x311F -#define WM8996_WRITE_SEQUENCER_288 0x3120 -#define WM8996_WRITE_SEQUENCER_289 0x3121 -#define WM8996_WRITE_SEQUENCER_290 0x3122 -#define WM8996_WRITE_SEQUENCER_291 0x3123 -#define WM8996_WRITE_SEQUENCER_292 0x3124 -#define WM8996_WRITE_SEQUENCER_293 0x3125 -#define WM8996_WRITE_SEQUENCER_294 0x3126 -#define WM8996_WRITE_SEQUENCER_295 0x3127 -#define WM8996_WRITE_SEQUENCER_296 0x3128 -#define WM8996_WRITE_SEQUENCER_297 0x3129 -#define WM8996_WRITE_SEQUENCER_298 0x312A -#define WM8996_WRITE_SEQUENCER_299 0x312B -#define WM8996_WRITE_SEQUENCER_300 0x312C -#define WM8996_WRITE_SEQUENCER_301 0x312D -#define WM8996_WRITE_SEQUENCER_302 0x312E -#define WM8996_WRITE_SEQUENCER_303 0x312F -#define WM8996_WRITE_SEQUENCER_304 0x3130 -#define WM8996_WRITE_SEQUENCER_305 0x3131 -#define WM8996_WRITE_SEQUENCER_306 0x3132 -#define WM8996_WRITE_SEQUENCER_307 0x3133 -#define WM8996_WRITE_SEQUENCER_308 0x3134 -#define WM8996_WRITE_SEQUENCER_309 0x3135 -#define WM8996_WRITE_SEQUENCER_310 0x3136 -#define WM8996_WRITE_SEQUENCER_311 0x3137 -#define WM8996_WRITE_SEQUENCER_312 0x3138 -#define WM8996_WRITE_SEQUENCER_313 0x3139 -#define WM8996_WRITE_SEQUENCER_314 0x313A -#define WM8996_WRITE_SEQUENCER_315 0x313B -#define WM8996_WRITE_SEQUENCER_316 0x313C -#define WM8996_WRITE_SEQUENCER_317 0x313D -#define WM8996_WRITE_SEQUENCER_318 0x313E -#define WM8996_WRITE_SEQUENCER_319 0x313F -#define WM8996_WRITE_SEQUENCER_320 0x3140 -#define WM8996_WRITE_SEQUENCER_321 0x3141 -#define WM8996_WRITE_SEQUENCER_322 0x3142 -#define WM8996_WRITE_SEQUENCER_323 0x3143 -#define WM8996_WRITE_SEQUENCER_324 0x3144 -#define WM8996_WRITE_SEQUENCER_325 0x3145 -#define WM8996_WRITE_SEQUENCER_326 0x3146 -#define WM8996_WRITE_SEQUENCER_327 0x3147 -#define WM8996_WRITE_SEQUENCER_328 0x3148 -#define WM8996_WRITE_SEQUENCER_329 0x3149 -#define WM8996_WRITE_SEQUENCER_330 0x314A -#define WM8996_WRITE_SEQUENCER_331 0x314B -#define WM8996_WRITE_SEQUENCER_332 0x314C -#define WM8996_WRITE_SEQUENCER_333 0x314D -#define WM8996_WRITE_SEQUENCER_334 0x314E -#define WM8996_WRITE_SEQUENCER_335 0x314F -#define WM8996_WRITE_SEQUENCER_336 0x3150 -#define WM8996_WRITE_SEQUENCER_337 0x3151 -#define WM8996_WRITE_SEQUENCER_338 0x3152 -#define WM8996_WRITE_SEQUENCER_339 0x3153 -#define WM8996_WRITE_SEQUENCER_340 0x3154 -#define WM8996_WRITE_SEQUENCER_341 0x3155 -#define WM8996_WRITE_SEQUENCER_342 0x3156 -#define WM8996_WRITE_SEQUENCER_343 0x3157 -#define WM8996_WRITE_SEQUENCER_344 0x3158 -#define WM8996_WRITE_SEQUENCER_345 0x3159 -#define WM8996_WRITE_SEQUENCER_346 0x315A -#define WM8996_WRITE_SEQUENCER_347 0x315B -#define WM8996_WRITE_SEQUENCER_348 0x315C -#define WM8996_WRITE_SEQUENCER_349 0x315D -#define WM8996_WRITE_SEQUENCER_350 0x315E -#define WM8996_WRITE_SEQUENCER_351 0x315F -#define WM8996_WRITE_SEQUENCER_352 0x3160 -#define WM8996_WRITE_SEQUENCER_353 0x3161 -#define WM8996_WRITE_SEQUENCER_354 0x3162 -#define WM8996_WRITE_SEQUENCER_355 0x3163 -#define WM8996_WRITE_SEQUENCER_356 0x3164 -#define WM8996_WRITE_SEQUENCER_357 0x3165 -#define WM8996_WRITE_SEQUENCER_358 0x3166 -#define WM8996_WRITE_SEQUENCER_359 0x3167 -#define WM8996_WRITE_SEQUENCER_360 0x3168 -#define WM8996_WRITE_SEQUENCER_361 0x3169 -#define WM8996_WRITE_SEQUENCER_362 0x316A -#define WM8996_WRITE_SEQUENCER_363 0x316B -#define WM8996_WRITE_SEQUENCER_364 0x316C -#define WM8996_WRITE_SEQUENCER_365 0x316D -#define WM8996_WRITE_SEQUENCER_366 0x316E -#define WM8996_WRITE_SEQUENCER_367 0x316F -#define WM8996_WRITE_SEQUENCER_368 0x3170 -#define WM8996_WRITE_SEQUENCER_369 0x3171 -#define WM8996_WRITE_SEQUENCER_370 0x3172 -#define WM8996_WRITE_SEQUENCER_371 0x3173 -#define WM8996_WRITE_SEQUENCER_372 0x3174 -#define WM8996_WRITE_SEQUENCER_373 0x3175 -#define WM8996_WRITE_SEQUENCER_374 0x3176 -#define WM8996_WRITE_SEQUENCER_375 0x3177 -#define WM8996_WRITE_SEQUENCER_376 0x3178 -#define WM8996_WRITE_SEQUENCER_377 0x3179 -#define WM8996_WRITE_SEQUENCER_378 0x317A -#define WM8996_WRITE_SEQUENCER_379 0x317B -#define WM8996_WRITE_SEQUENCER_380 0x317C -#define WM8996_WRITE_SEQUENCER_381 0x317D -#define WM8996_WRITE_SEQUENCER_382 0x317E -#define WM8996_WRITE_SEQUENCER_383 0x317F -#define WM8996_WRITE_SEQUENCER_384 0x3180 -#define WM8996_WRITE_SEQUENCER_385 0x3181 -#define WM8996_WRITE_SEQUENCER_386 0x3182 -#define WM8996_WRITE_SEQUENCER_387 0x3183 -#define WM8996_WRITE_SEQUENCER_388 0x3184 -#define WM8996_WRITE_SEQUENCER_389 0x3185 -#define WM8996_WRITE_SEQUENCER_390 0x3186 -#define WM8996_WRITE_SEQUENCER_391 0x3187 -#define WM8996_WRITE_SEQUENCER_392 0x3188 -#define WM8996_WRITE_SEQUENCER_393 0x3189 -#define WM8996_WRITE_SEQUENCER_394 0x318A -#define WM8996_WRITE_SEQUENCER_395 0x318B -#define WM8996_WRITE_SEQUENCER_396 0x318C -#define WM8996_WRITE_SEQUENCER_397 0x318D -#define WM8996_WRITE_SEQUENCER_398 0x318E -#define WM8996_WRITE_SEQUENCER_399 0x318F -#define WM8996_WRITE_SEQUENCER_400 0x3190 -#define WM8996_WRITE_SEQUENCER_401 0x3191 -#define WM8996_WRITE_SEQUENCER_402 0x3192 -#define WM8996_WRITE_SEQUENCER_403 0x3193 -#define WM8996_WRITE_SEQUENCER_404 0x3194 -#define WM8996_WRITE_SEQUENCER_405 0x3195 -#define WM8996_WRITE_SEQUENCER_406 0x3196 -#define WM8996_WRITE_SEQUENCER_407 0x3197 -#define WM8996_WRITE_SEQUENCER_408 0x3198 -#define WM8996_WRITE_SEQUENCER_409 0x3199 -#define WM8996_WRITE_SEQUENCER_410 0x319A -#define WM8996_WRITE_SEQUENCER_411 0x319B -#define WM8996_WRITE_SEQUENCER_412 0x319C -#define WM8996_WRITE_SEQUENCER_413 0x319D -#define WM8996_WRITE_SEQUENCER_414 0x319E -#define WM8996_WRITE_SEQUENCER_415 0x319F -#define WM8996_WRITE_SEQUENCER_416 0x31A0 -#define WM8996_WRITE_SEQUENCER_417 0x31A1 -#define WM8996_WRITE_SEQUENCER_418 0x31A2 -#define WM8996_WRITE_SEQUENCER_419 0x31A3 -#define WM8996_WRITE_SEQUENCER_420 0x31A4 -#define WM8996_WRITE_SEQUENCER_421 0x31A5 -#define WM8996_WRITE_SEQUENCER_422 0x31A6 -#define WM8996_WRITE_SEQUENCER_423 0x31A7 -#define WM8996_WRITE_SEQUENCER_424 0x31A8 -#define WM8996_WRITE_SEQUENCER_425 0x31A9 -#define WM8996_WRITE_SEQUENCER_426 0x31AA -#define WM8996_WRITE_SEQUENCER_427 0x31AB -#define WM8996_WRITE_SEQUENCER_428 0x31AC -#define WM8996_WRITE_SEQUENCER_429 0x31AD -#define WM8996_WRITE_SEQUENCER_430 0x31AE -#define WM8996_WRITE_SEQUENCER_431 0x31AF -#define WM8996_WRITE_SEQUENCER_432 0x31B0 -#define WM8996_WRITE_SEQUENCER_433 0x31B1 -#define WM8996_WRITE_SEQUENCER_434 0x31B2 -#define WM8996_WRITE_SEQUENCER_435 0x31B3 -#define WM8996_WRITE_SEQUENCER_436 0x31B4 -#define WM8996_WRITE_SEQUENCER_437 0x31B5 -#define WM8996_WRITE_SEQUENCER_438 0x31B6 -#define WM8996_WRITE_SEQUENCER_439 0x31B7 -#define WM8996_WRITE_SEQUENCER_440 0x31B8 -#define WM8996_WRITE_SEQUENCER_441 0x31B9 -#define WM8996_WRITE_SEQUENCER_442 0x31BA -#define WM8996_WRITE_SEQUENCER_443 0x31BB -#define WM8996_WRITE_SEQUENCER_444 0x31BC -#define WM8996_WRITE_SEQUENCER_445 0x31BD -#define WM8996_WRITE_SEQUENCER_446 0x31BE -#define WM8996_WRITE_SEQUENCER_447 0x31BF -#define WM8996_WRITE_SEQUENCER_448 0x31C0 -#define WM8996_WRITE_SEQUENCER_449 0x31C1 -#define WM8996_WRITE_SEQUENCER_450 0x31C2 -#define WM8996_WRITE_SEQUENCER_451 0x31C3 -#define WM8996_WRITE_SEQUENCER_452 0x31C4 -#define WM8996_WRITE_SEQUENCER_453 0x31C5 -#define WM8996_WRITE_SEQUENCER_454 0x31C6 -#define WM8996_WRITE_SEQUENCER_455 0x31C7 -#define WM8996_WRITE_SEQUENCER_456 0x31C8 -#define WM8996_WRITE_SEQUENCER_457 0x31C9 -#define WM8996_WRITE_SEQUENCER_458 0x31CA -#define WM8996_WRITE_SEQUENCER_459 0x31CB -#define WM8996_WRITE_SEQUENCER_460 0x31CC -#define WM8996_WRITE_SEQUENCER_461 0x31CD -#define WM8996_WRITE_SEQUENCER_462 0x31CE -#define WM8996_WRITE_SEQUENCER_463 0x31CF -#define WM8996_WRITE_SEQUENCER_464 0x31D0 -#define WM8996_WRITE_SEQUENCER_465 0x31D1 -#define WM8996_WRITE_SEQUENCER_466 0x31D2 -#define WM8996_WRITE_SEQUENCER_467 0x31D3 -#define WM8996_WRITE_SEQUENCER_468 0x31D4 -#define WM8996_WRITE_SEQUENCER_469 0x31D5 -#define WM8996_WRITE_SEQUENCER_470 0x31D6 -#define WM8996_WRITE_SEQUENCER_471 0x31D7 -#define WM8996_WRITE_SEQUENCER_472 0x31D8 -#define WM8996_WRITE_SEQUENCER_473 0x31D9 -#define WM8996_WRITE_SEQUENCER_474 0x31DA -#define WM8996_WRITE_SEQUENCER_475 0x31DB -#define WM8996_WRITE_SEQUENCER_476 0x31DC -#define WM8996_WRITE_SEQUENCER_477 0x31DD -#define WM8996_WRITE_SEQUENCER_478 0x31DE -#define WM8996_WRITE_SEQUENCER_479 0x31DF -#define WM8996_WRITE_SEQUENCER_480 0x31E0 -#define WM8996_WRITE_SEQUENCER_481 0x31E1 -#define WM8996_WRITE_SEQUENCER_482 0x31E2 -#define WM8996_WRITE_SEQUENCER_483 0x31E3 -#define WM8996_WRITE_SEQUENCER_484 0x31E4 -#define WM8996_WRITE_SEQUENCER_485 0x31E5 -#define WM8996_WRITE_SEQUENCER_486 0x31E6 -#define WM8996_WRITE_SEQUENCER_487 0x31E7 -#define WM8996_WRITE_SEQUENCER_488 0x31E8 -#define WM8996_WRITE_SEQUENCER_489 0x31E9 -#define WM8996_WRITE_SEQUENCER_490 0x31EA -#define WM8996_WRITE_SEQUENCER_491 0x31EB -#define WM8996_WRITE_SEQUENCER_492 0x31EC -#define WM8996_WRITE_SEQUENCER_493 0x31ED -#define WM8996_WRITE_SEQUENCER_494 0x31EE -#define WM8996_WRITE_SEQUENCER_495 0x31EF -#define WM8996_WRITE_SEQUENCER_496 0x31F0 -#define WM8996_WRITE_SEQUENCER_497 0x31F1 -#define WM8996_WRITE_SEQUENCER_498 0x31F2 -#define WM8996_WRITE_SEQUENCER_499 0x31F3 -#define WM8996_WRITE_SEQUENCER_500 0x31F4 -#define WM8996_WRITE_SEQUENCER_501 0x31F5 -#define WM8996_WRITE_SEQUENCER_502 0x31F6 -#define WM8996_WRITE_SEQUENCER_503 0x31F7 -#define WM8996_WRITE_SEQUENCER_504 0x31F8 -#define WM8996_WRITE_SEQUENCER_505 0x31F9 -#define WM8996_WRITE_SEQUENCER_506 0x31FA -#define WM8996_WRITE_SEQUENCER_507 0x31FB -#define WM8996_WRITE_SEQUENCER_508 0x31FC -#define WM8996_WRITE_SEQUENCER_509 0x31FD -#define WM8996_WRITE_SEQUENCER_510 0x31FE -#define WM8996_WRITE_SEQUENCER_511 0x31FF - -#define WM8996_REGISTER_COUNT 706 -#define WM8996_MAX_REGISTER 0x31FF - -/* - * Field Definitions. - */ - -/* - * R0 (0x00) - Software Reset - */ -#define WM8996_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */ -#define WM8996_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */ -#define WM8996_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */ - -/* - * R1 (0x01) - Power Management (1) - */ -#define WM8996_MICB2_ENA 0x0200 /* MICB2_ENA */ -#define WM8996_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */ -#define WM8996_MICB2_ENA_SHIFT 9 /* MICB2_ENA */ -#define WM8996_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ -#define WM8996_MICB1_ENA 0x0100 /* MICB1_ENA */ -#define WM8996_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */ -#define WM8996_MICB1_ENA_SHIFT 8 /* MICB1_ENA */ -#define WM8996_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ -#define WM8996_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */ -#define WM8996_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */ -#define WM8996_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */ -#define WM8996_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */ -#define WM8996_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */ -#define WM8996_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */ -#define WM8996_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */ -#define WM8996_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */ -#define WM8996_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */ -#define WM8996_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */ -#define WM8996_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */ -#define WM8996_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */ -#define WM8996_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */ -#define WM8996_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */ -#define WM8996_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */ -#define WM8996_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */ -#define WM8996_BG_ENA 0x0001 /* BG_ENA */ -#define WM8996_BG_ENA_MASK 0x0001 /* BG_ENA */ -#define WM8996_BG_ENA_SHIFT 0 /* BG_ENA */ -#define WM8996_BG_ENA_WIDTH 1 /* BG_ENA */ - -/* - * R2 (0x02) - Power Management (2) - */ -#define WM8996_OPCLK_ENA 0x0800 /* OPCLK_ENA */ -#define WM8996_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ -#define WM8996_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ -#define WM8996_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ -#define WM8996_INL_ENA 0x0020 /* INL_ENA */ -#define WM8996_INL_ENA_MASK 0x0020 /* INL_ENA */ -#define WM8996_INL_ENA_SHIFT 5 /* INL_ENA */ -#define WM8996_INL_ENA_WIDTH 1 /* INL_ENA */ -#define WM8996_INR_ENA 0x0010 /* INR_ENA */ -#define WM8996_INR_ENA_MASK 0x0010 /* INR_ENA */ -#define WM8996_INR_ENA_SHIFT 4 /* INR_ENA */ -#define WM8996_INR_ENA_WIDTH 1 /* INR_ENA */ -#define WM8996_LDO2_ENA 0x0002 /* LDO2_ENA */ -#define WM8996_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */ -#define WM8996_LDO2_ENA_SHIFT 1 /* LDO2_ENA */ -#define WM8996_LDO2_ENA_WIDTH 1 /* LDO2_ENA */ - -/* - * R3 (0x03) - Power Management (3) - */ -#define WM8996_DSP2RXL_ENA 0x0800 /* DSP2RXL_ENA */ -#define WM8996_DSP2RXL_ENA_MASK 0x0800 /* DSP2RXL_ENA */ -#define WM8996_DSP2RXL_ENA_SHIFT 11 /* DSP2RXL_ENA */ -#define WM8996_DSP2RXL_ENA_WIDTH 1 /* DSP2RXL_ENA */ -#define WM8996_DSP2RXR_ENA 0x0400 /* DSP2RXR_ENA */ -#define WM8996_DSP2RXR_ENA_MASK 0x0400 /* DSP2RXR_ENA */ -#define WM8996_DSP2RXR_ENA_SHIFT 10 /* DSP2RXR_ENA */ -#define WM8996_DSP2RXR_ENA_WIDTH 1 /* DSP2RXR_ENA */ -#define WM8996_DSP1RXL_ENA 0x0200 /* DSP1RXL_ENA */ -#define WM8996_DSP1RXL_ENA_MASK 0x0200 /* DSP1RXL_ENA */ -#define WM8996_DSP1RXL_ENA_SHIFT 9 /* DSP1RXL_ENA */ -#define WM8996_DSP1RXL_ENA_WIDTH 1 /* DSP1RXL_ENA */ -#define WM8996_DSP1RXR_ENA 0x0100 /* DSP1RXR_ENA */ -#define WM8996_DSP1RXR_ENA_MASK 0x0100 /* DSP1RXR_ENA */ -#define WM8996_DSP1RXR_ENA_SHIFT 8 /* DSP1RXR_ENA */ -#define WM8996_DSP1RXR_ENA_WIDTH 1 /* DSP1RXR_ENA */ -#define WM8996_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */ -#define WM8996_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */ -#define WM8996_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */ -#define WM8996_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */ -#define WM8996_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */ -#define WM8996_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */ -#define WM8996_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */ -#define WM8996_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */ -#define WM8996_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */ -#define WM8996_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */ -#define WM8996_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */ -#define WM8996_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */ -#define WM8996_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */ -#define WM8996_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */ -#define WM8996_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */ -#define WM8996_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */ -#define WM8996_ADCL_ENA 0x0002 /* ADCL_ENA */ -#define WM8996_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ -#define WM8996_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ -#define WM8996_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ -#define WM8996_ADCR_ENA 0x0001 /* ADCR_ENA */ -#define WM8996_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ -#define WM8996_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ -#define WM8996_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ - -/* - * R4 (0x04) - Power Management (4) - */ -#define WM8996_AIF2RX_CHAN1_ENA 0x0200 /* AIF2RX_CHAN1_ENA */ -#define WM8996_AIF2RX_CHAN1_ENA_MASK 0x0200 /* AIF2RX_CHAN1_ENA */ -#define WM8996_AIF2RX_CHAN1_ENA_SHIFT 9 /* AIF2RX_CHAN1_ENA */ -#define WM8996_AIF2RX_CHAN1_ENA_WIDTH 1 /* AIF2RX_CHAN1_ENA */ -#define WM8996_AIF2RX_CHAN0_ENA 0x0100 /* AIF2RX_CHAN0_ENA */ -#define WM8996_AIF2RX_CHAN0_ENA_MASK 0x0100 /* AIF2RX_CHAN0_ENA */ -#define WM8996_AIF2RX_CHAN0_ENA_SHIFT 8 /* AIF2RX_CHAN0_ENA */ -#define WM8996_AIF2RX_CHAN0_ENA_WIDTH 1 /* AIF2RX_CHAN0_ENA */ -#define WM8996_AIF1RX_CHAN5_ENA 0x0020 /* AIF1RX_CHAN5_ENA */ -#define WM8996_AIF1RX_CHAN5_ENA_MASK 0x0020 /* AIF1RX_CHAN5_ENA */ -#define WM8996_AIF1RX_CHAN5_ENA_SHIFT 5 /* AIF1RX_CHAN5_ENA */ -#define WM8996_AIF1RX_CHAN5_ENA_WIDTH 1 /* AIF1RX_CHAN5_ENA */ -#define WM8996_AIF1RX_CHAN4_ENA 0x0010 /* AIF1RX_CHAN4_ENA */ -#define WM8996_AIF1RX_CHAN4_ENA_MASK 0x0010 /* AIF1RX_CHAN4_ENA */ -#define WM8996_AIF1RX_CHAN4_ENA_SHIFT 4 /* AIF1RX_CHAN4_ENA */ -#define WM8996_AIF1RX_CHAN4_ENA_WIDTH 1 /* AIF1RX_CHAN4_ENA */ -#define WM8996_AIF1RX_CHAN3_ENA 0x0008 /* AIF1RX_CHAN3_ENA */ -#define WM8996_AIF1RX_CHAN3_ENA_MASK 0x0008 /* AIF1RX_CHAN3_ENA */ -#define WM8996_AIF1RX_CHAN3_ENA_SHIFT 3 /* AIF1RX_CHAN3_ENA */ -#define WM8996_AIF1RX_CHAN3_ENA_WIDTH 1 /* AIF1RX_CHAN3_ENA */ -#define WM8996_AIF1RX_CHAN2_ENA 0x0004 /* AIF1RX_CHAN2_ENA */ -#define WM8996_AIF1RX_CHAN2_ENA_MASK 0x0004 /* AIF1RX_CHAN2_ENA */ -#define WM8996_AIF1RX_CHAN2_ENA_SHIFT 2 /* AIF1RX_CHAN2_ENA */ -#define WM8996_AIF1RX_CHAN2_ENA_WIDTH 1 /* AIF1RX_CHAN2_ENA */ -#define WM8996_AIF1RX_CHAN1_ENA 0x0002 /* AIF1RX_CHAN1_ENA */ -#define WM8996_AIF1RX_CHAN1_ENA_MASK 0x0002 /* AIF1RX_CHAN1_ENA */ -#define WM8996_AIF1RX_CHAN1_ENA_SHIFT 1 /* AIF1RX_CHAN1_ENA */ -#define WM8996_AIF1RX_CHAN1_ENA_WIDTH 1 /* AIF1RX_CHAN1_ENA */ -#define WM8996_AIF1RX_CHAN0_ENA 0x0001 /* AIF1RX_CHAN0_ENA */ -#define WM8996_AIF1RX_CHAN0_ENA_MASK 0x0001 /* AIF1RX_CHAN0_ENA */ -#define WM8996_AIF1RX_CHAN0_ENA_SHIFT 0 /* AIF1RX_CHAN0_ENA */ -#define WM8996_AIF1RX_CHAN0_ENA_WIDTH 1 /* AIF1RX_CHAN0_ENA */ - -/* - * R5 (0x05) - Power Management (5) - */ -#define WM8996_DSP2TXL_ENA 0x0800 /* DSP2TXL_ENA */ -#define WM8996_DSP2TXL_ENA_MASK 0x0800 /* DSP2TXL_ENA */ -#define WM8996_DSP2TXL_ENA_SHIFT 11 /* DSP2TXL_ENA */ -#define WM8996_DSP2TXL_ENA_WIDTH 1 /* DSP2TXL_ENA */ -#define WM8996_DSP2TXR_ENA 0x0400 /* DSP2TXR_ENA */ -#define WM8996_DSP2TXR_ENA_MASK 0x0400 /* DSP2TXR_ENA */ -#define WM8996_DSP2TXR_ENA_SHIFT 10 /* DSP2TXR_ENA */ -#define WM8996_DSP2TXR_ENA_WIDTH 1 /* DSP2TXR_ENA */ -#define WM8996_DSP1TXL_ENA 0x0200 /* DSP1TXL_ENA */ -#define WM8996_DSP1TXL_ENA_MASK 0x0200 /* DSP1TXL_ENA */ -#define WM8996_DSP1TXL_ENA_SHIFT 9 /* DSP1TXL_ENA */ -#define WM8996_DSP1TXL_ENA_WIDTH 1 /* DSP1TXL_ENA */ -#define WM8996_DSP1TXR_ENA 0x0100 /* DSP1TXR_ENA */ -#define WM8996_DSP1TXR_ENA_MASK 0x0100 /* DSP1TXR_ENA */ -#define WM8996_DSP1TXR_ENA_SHIFT 8 /* DSP1TXR_ENA */ -#define WM8996_DSP1TXR_ENA_WIDTH 1 /* DSP1TXR_ENA */ -#define WM8996_DAC2L_ENA 0x0008 /* DAC2L_ENA */ -#define WM8996_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */ -#define WM8996_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */ -#define WM8996_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */ -#define WM8996_DAC2R_ENA 0x0004 /* DAC2R_ENA */ -#define WM8996_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */ -#define WM8996_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */ -#define WM8996_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */ -#define WM8996_DAC1L_ENA 0x0002 /* DAC1L_ENA */ -#define WM8996_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */ -#define WM8996_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */ -#define WM8996_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */ -#define WM8996_DAC1R_ENA 0x0001 /* DAC1R_ENA */ -#define WM8996_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */ -#define WM8996_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */ -#define WM8996_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */ - -/* - * R6 (0x06) - Power Management (6) - */ -#define WM8996_AIF2TX_CHAN1_ENA 0x0200 /* AIF2TX_CHAN1_ENA */ -#define WM8996_AIF2TX_CHAN1_ENA_MASK 0x0200 /* AIF2TX_CHAN1_ENA */ -#define WM8996_AIF2TX_CHAN1_ENA_SHIFT 9 /* AIF2TX_CHAN1_ENA */ -#define WM8996_AIF2TX_CHAN1_ENA_WIDTH 1 /* AIF2TX_CHAN1_ENA */ -#define WM8996_AIF2TX_CHAN0_ENA 0x0100 /* AIF2TX_CHAN0_ENA */ -#define WM8996_AIF2TX_CHAN0_ENA_MASK 0x0100 /* AIF2TX_CHAN0_ENA */ -#define WM8996_AIF2TX_CHAN0_ENA_SHIFT 8 /* AIF2TX_CHAN0_ENA */ -#define WM8996_AIF2TX_CHAN0_ENA_WIDTH 1 /* AIF2TX_CHAN0_ENA */ -#define WM8996_AIF1TX_CHAN5_ENA 0x0020 /* AIF1TX_CHAN5_ENA */ -#define WM8996_AIF1TX_CHAN5_ENA_MASK 0x0020 /* AIF1TX_CHAN5_ENA */ -#define WM8996_AIF1TX_CHAN5_ENA_SHIFT 5 /* AIF1TX_CHAN5_ENA */ -#define WM8996_AIF1TX_CHAN5_ENA_WIDTH 1 /* AIF1TX_CHAN5_ENA */ -#define WM8996_AIF1TX_CHAN4_ENA 0x0010 /* AIF1TX_CHAN4_ENA */ -#define WM8996_AIF1TX_CHAN4_ENA_MASK 0x0010 /* AIF1TX_CHAN4_ENA */ -#define WM8996_AIF1TX_CHAN4_ENA_SHIFT 4 /* AIF1TX_CHAN4_ENA */ -#define WM8996_AIF1TX_CHAN4_ENA_WIDTH 1 /* AIF1TX_CHAN4_ENA */ -#define WM8996_AIF1TX_CHAN3_ENA 0x0008 /* AIF1TX_CHAN3_ENA */ -#define WM8996_AIF1TX_CHAN3_ENA_MASK 0x0008 /* AIF1TX_CHAN3_ENA */ -#define WM8996_AIF1TX_CHAN3_ENA_SHIFT 3 /* AIF1TX_CHAN3_ENA */ -#define WM8996_AIF1TX_CHAN3_ENA_WIDTH 1 /* AIF1TX_CHAN3_ENA */ -#define WM8996_AIF1TX_CHAN2_ENA 0x0004 /* AIF1TX_CHAN2_ENA */ -#define WM8996_AIF1TX_CHAN2_ENA_MASK 0x0004 /* AIF1TX_CHAN2_ENA */ -#define WM8996_AIF1TX_CHAN2_ENA_SHIFT 2 /* AIF1TX_CHAN2_ENA */ -#define WM8996_AIF1TX_CHAN2_ENA_WIDTH 1 /* AIF1TX_CHAN2_ENA */ -#define WM8996_AIF1TX_CHAN1_ENA 0x0002 /* AIF1TX_CHAN1_ENA */ -#define WM8996_AIF1TX_CHAN1_ENA_MASK 0x0002 /* AIF1TX_CHAN1_ENA */ -#define WM8996_AIF1TX_CHAN1_ENA_SHIFT 1 /* AIF1TX_CHAN1_ENA */ -#define WM8996_AIF1TX_CHAN1_ENA_WIDTH 1 /* AIF1TX_CHAN1_ENA */ -#define WM8996_AIF1TX_CHAN0_ENA 0x0001 /* AIF1TX_CHAN0_ENA */ -#define WM8996_AIF1TX_CHAN0_ENA_MASK 0x0001 /* AIF1TX_CHAN0_ENA */ -#define WM8996_AIF1TX_CHAN0_ENA_SHIFT 0 /* AIF1TX_CHAN0_ENA */ -#define WM8996_AIF1TX_CHAN0_ENA_WIDTH 1 /* AIF1TX_CHAN0_ENA */ - -/* - * R7 (0x07) - Power Management (7) - */ -#define WM8996_DMIC2_FN 0x0200 /* DMIC2_FN */ -#define WM8996_DMIC2_FN_MASK 0x0200 /* DMIC2_FN */ -#define WM8996_DMIC2_FN_SHIFT 9 /* DMIC2_FN */ -#define WM8996_DMIC2_FN_WIDTH 1 /* DMIC2_FN */ -#define WM8996_DMIC1_FN 0x0100 /* DMIC1_FN */ -#define WM8996_DMIC1_FN_MASK 0x0100 /* DMIC1_FN */ -#define WM8996_DMIC1_FN_SHIFT 8 /* DMIC1_FN */ -#define WM8996_DMIC1_FN_WIDTH 1 /* DMIC1_FN */ -#define WM8996_ADC_DMIC_DSP2R_ENA 0x0080 /* ADC_DMIC_DSP2R_ENA */ -#define WM8996_ADC_DMIC_DSP2R_ENA_MASK 0x0080 /* ADC_DMIC_DSP2R_ENA */ -#define WM8996_ADC_DMIC_DSP2R_ENA_SHIFT 7 /* ADC_DMIC_DSP2R_ENA */ -#define WM8996_ADC_DMIC_DSP2R_ENA_WIDTH 1 /* ADC_DMIC_DSP2R_ENA */ -#define WM8996_ADC_DMIC_DSP2L_ENA 0x0040 /* ADC_DMIC_DSP2L_ENA */ -#define WM8996_ADC_DMIC_DSP2L_ENA_MASK 0x0040 /* ADC_DMIC_DSP2L_ENA */ -#define WM8996_ADC_DMIC_DSP2L_ENA_SHIFT 6 /* ADC_DMIC_DSP2L_ENA */ -#define WM8996_ADC_DMIC_DSP2L_ENA_WIDTH 1 /* ADC_DMIC_DSP2L_ENA */ -#define WM8996_ADC_DMIC_SRC2_MASK 0x0030 /* ADC_DMIC_SRC2 - [5:4] */ -#define WM8996_ADC_DMIC_SRC2_SHIFT 4 /* ADC_DMIC_SRC2 - [5:4] */ -#define WM8996_ADC_DMIC_SRC2_WIDTH 2 /* ADC_DMIC_SRC2 - [5:4] */ -#define WM8996_ADC_DMIC_DSP1R_ENA 0x0008 /* ADC_DMIC_DSP1R_ENA */ -#define WM8996_ADC_DMIC_DSP1R_ENA_MASK 0x0008 /* ADC_DMIC_DSP1R_ENA */ -#define WM8996_ADC_DMIC_DSP1R_ENA_SHIFT 3 /* ADC_DMIC_DSP1R_ENA */ -#define WM8996_ADC_DMIC_DSP1R_ENA_WIDTH 1 /* ADC_DMIC_DSP1R_ENA */ -#define WM8996_ADC_DMIC_DSP1L_ENA 0x0004 /* ADC_DMIC_DSP1L_ENA */ -#define WM8996_ADC_DMIC_DSP1L_ENA_MASK 0x0004 /* ADC_DMIC_DSP1L_ENA */ -#define WM8996_ADC_DMIC_DSP1L_ENA_SHIFT 2 /* ADC_DMIC_DSP1L_ENA */ -#define WM8996_ADC_DMIC_DSP1L_ENA_WIDTH 1 /* ADC_DMIC_DSP1L_ENA */ -#define WM8996_ADC_DMIC_SRC1_MASK 0x0003 /* ADC_DMIC_SRC1 - [1:0] */ -#define WM8996_ADC_DMIC_SRC1_SHIFT 0 /* ADC_DMIC_SRC1 - [1:0] */ -#define WM8996_ADC_DMIC_SRC1_WIDTH 2 /* ADC_DMIC_SRC1 - [1:0] */ - -/* - * R8 (0x08) - Power Management (8) - */ -#define WM8996_AIF2TX_SRC_MASK 0x00C0 /* AIF2TX_SRC - [7:6] */ -#define WM8996_AIF2TX_SRC_SHIFT 6 /* AIF2TX_SRC - [7:6] */ -#define WM8996_AIF2TX_SRC_WIDTH 2 /* AIF2TX_SRC - [7:6] */ -#define WM8996_DSP2RX_SRC 0x0010 /* DSP2RX_SRC */ -#define WM8996_DSP2RX_SRC_MASK 0x0010 /* DSP2RX_SRC */ -#define WM8996_DSP2RX_SRC_SHIFT 4 /* DSP2RX_SRC */ -#define WM8996_DSP2RX_SRC_WIDTH 1 /* DSP2RX_SRC */ -#define WM8996_DSP1RX_SRC 0x0001 /* DSP1RX_SRC */ -#define WM8996_DSP1RX_SRC_MASK 0x0001 /* DSP1RX_SRC */ -#define WM8996_DSP1RX_SRC_SHIFT 0 /* DSP1RX_SRC */ -#define WM8996_DSP1RX_SRC_WIDTH 1 /* DSP1RX_SRC */ - -/* - * R16 (0x10) - Left Line Input Volume - */ -#define WM8996_IN1_VU 0x0080 /* IN1_VU */ -#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */ -#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */ -#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */ -#define WM8996_IN1L_ZC 0x0020 /* IN1L_ZC */ -#define WM8996_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */ -#define WM8996_IN1L_ZC_SHIFT 5 /* IN1L_ZC */ -#define WM8996_IN1L_ZC_WIDTH 1 /* IN1L_ZC */ -#define WM8996_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */ -#define WM8996_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */ -#define WM8996_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */ - -/* - * R17 (0x11) - Right Line Input Volume - */ -#define WM8996_IN1_VU 0x0080 /* IN1_VU */ -#define WM8996_IN1_VU_MASK 0x0080 /* IN1_VU */ -#define WM8996_IN1_VU_SHIFT 7 /* IN1_VU */ -#define WM8996_IN1_VU_WIDTH 1 /* IN1_VU */ -#define WM8996_IN1R_ZC 0x0020 /* IN1R_ZC */ -#define WM8996_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */ -#define WM8996_IN1R_ZC_SHIFT 5 /* IN1R_ZC */ -#define WM8996_IN1R_ZC_WIDTH 1 /* IN1R_ZC */ -#define WM8996_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */ -#define WM8996_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */ -#define WM8996_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */ - -/* - * R18 (0x12) - Line Input Control - */ -#define WM8996_INL_MODE_MASK 0x000C /* INL_MODE - [3:2] */ -#define WM8996_INL_MODE_SHIFT 2 /* INL_MODE - [3:2] */ -#define WM8996_INL_MODE_WIDTH 2 /* INL_MODE - [3:2] */ -#define WM8996_INR_MODE_MASK 0x0003 /* INR_MODE - [1:0] */ -#define WM8996_INR_MODE_SHIFT 0 /* INR_MODE - [1:0] */ -#define WM8996_INR_MODE_WIDTH 2 /* INR_MODE - [1:0] */ - -/* - * R21 (0x15) - DAC1 HPOUT1 Volume - */ -#define WM8996_DAC1R_HPOUT1R_VOL_MASK 0x00F0 /* DAC1R_HPOUT1R_VOL - [7:4] */ -#define WM8996_DAC1R_HPOUT1R_VOL_SHIFT 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ -#define WM8996_DAC1R_HPOUT1R_VOL_WIDTH 4 /* DAC1R_HPOUT1R_VOL - [7:4] */ -#define WM8996_DAC1L_HPOUT1L_VOL_MASK 0x000F /* DAC1L_HPOUT1L_VOL - [3:0] */ -#define WM8996_DAC1L_HPOUT1L_VOL_SHIFT 0 /* DAC1L_HPOUT1L_VOL - [3:0] */ -#define WM8996_DAC1L_HPOUT1L_VOL_WIDTH 4 /* DAC1L_HPOUT1L_VOL - [3:0] */ - -/* - * R22 (0x16) - DAC2 HPOUT2 Volume - */ -#define WM8996_DAC2R_HPOUT2R_VOL_MASK 0x00F0 /* DAC2R_HPOUT2R_VOL - [7:4] */ -#define WM8996_DAC2R_HPOUT2R_VOL_SHIFT 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ -#define WM8996_DAC2R_HPOUT2R_VOL_WIDTH 4 /* DAC2R_HPOUT2R_VOL - [7:4] */ -#define WM8996_DAC2L_HPOUT2L_VOL_MASK 0x000F /* DAC2L_HPOUT2L_VOL - [3:0] */ -#define WM8996_DAC2L_HPOUT2L_VOL_SHIFT 0 /* DAC2L_HPOUT2L_VOL - [3:0] */ -#define WM8996_DAC2L_HPOUT2L_VOL_WIDTH 4 /* DAC2L_HPOUT2L_VOL - [3:0] */ - -/* - * R24 (0x18) - DAC1 Left Volume - */ -#define WM8996_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */ -#define WM8996_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */ -#define WM8996_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */ -#define WM8996_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */ -#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */ -#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */ -#define WM8996_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */ -#define WM8996_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */ -#define WM8996_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */ - -/* - * R25 (0x19) - DAC1 Right Volume - */ -#define WM8996_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */ -#define WM8996_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */ -#define WM8996_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */ -#define WM8996_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */ -#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */ -#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */ -#define WM8996_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */ -#define WM8996_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */ -#define WM8996_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */ - -/* - * R26 (0x1A) - DAC2 Left Volume - */ -#define WM8996_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */ -#define WM8996_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */ -#define WM8996_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */ -#define WM8996_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */ -#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */ -#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */ -#define WM8996_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */ -#define WM8996_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */ -#define WM8996_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */ - -/* - * R27 (0x1B) - DAC2 Right Volume - */ -#define WM8996_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */ -#define WM8996_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */ -#define WM8996_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */ -#define WM8996_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */ -#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */ -#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */ -#define WM8996_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */ -#define WM8996_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */ -#define WM8996_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */ - -/* - * R28 (0x1C) - Output1 Left Volume - */ -#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */ -#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */ -#define WM8996_HPOUT1L_ZC 0x0080 /* HPOUT1L_ZC */ -#define WM8996_HPOUT1L_ZC_MASK 0x0080 /* HPOUT1L_ZC */ -#define WM8996_HPOUT1L_ZC_SHIFT 7 /* HPOUT1L_ZC */ -#define WM8996_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */ -#define WM8996_HPOUT1L_VOL_MASK 0x000F /* HPOUT1L_VOL - [3:0] */ -#define WM8996_HPOUT1L_VOL_SHIFT 0 /* HPOUT1L_VOL - [3:0] */ -#define WM8996_HPOUT1L_VOL_WIDTH 4 /* HPOUT1L_VOL - [3:0] */ - -/* - * R29 (0x1D) - Output1 Right Volume - */ -#define WM8996_DAC1_VU 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_MASK 0x0100 /* DAC1_VU */ -#define WM8996_DAC1_VU_SHIFT 8 /* DAC1_VU */ -#define WM8996_DAC1_VU_WIDTH 1 /* DAC1_VU */ -#define WM8996_HPOUT1R_ZC 0x0080 /* HPOUT1R_ZC */ -#define WM8996_HPOUT1R_ZC_MASK 0x0080 /* HPOUT1R_ZC */ -#define WM8996_HPOUT1R_ZC_SHIFT 7 /* HPOUT1R_ZC */ -#define WM8996_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */ -#define WM8996_HPOUT1R_VOL_MASK 0x000F /* HPOUT1R_VOL - [3:0] */ -#define WM8996_HPOUT1R_VOL_SHIFT 0 /* HPOUT1R_VOL - [3:0] */ -#define WM8996_HPOUT1R_VOL_WIDTH 4 /* HPOUT1R_VOL - [3:0] */ - -/* - * R30 (0x1E) - Output2 Left Volume - */ -#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */ -#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */ -#define WM8996_HPOUT2L_ZC 0x0080 /* HPOUT2L_ZC */ -#define WM8996_HPOUT2L_ZC_MASK 0x0080 /* HPOUT2L_ZC */ -#define WM8996_HPOUT2L_ZC_SHIFT 7 /* HPOUT2L_ZC */ -#define WM8996_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */ -#define WM8996_HPOUT2L_VOL_MASK 0x000F /* HPOUT2L_VOL - [3:0] */ -#define WM8996_HPOUT2L_VOL_SHIFT 0 /* HPOUT2L_VOL - [3:0] */ -#define WM8996_HPOUT2L_VOL_WIDTH 4 /* HPOUT2L_VOL - [3:0] */ - -/* - * R31 (0x1F) - Output2 Right Volume - */ -#define WM8996_DAC2_VU 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_MASK 0x0100 /* DAC2_VU */ -#define WM8996_DAC2_VU_SHIFT 8 /* DAC2_VU */ -#define WM8996_DAC2_VU_WIDTH 1 /* DAC2_VU */ -#define WM8996_HPOUT2R_ZC 0x0080 /* HPOUT2R_ZC */ -#define WM8996_HPOUT2R_ZC_MASK 0x0080 /* HPOUT2R_ZC */ -#define WM8996_HPOUT2R_ZC_SHIFT 7 /* HPOUT2R_ZC */ -#define WM8996_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */ -#define WM8996_HPOUT2R_VOL_MASK 0x000F /* HPOUT2R_VOL - [3:0] */ -#define WM8996_HPOUT2R_VOL_SHIFT 0 /* HPOUT2R_VOL - [3:0] */ -#define WM8996_HPOUT2R_VOL_WIDTH 4 /* HPOUT2R_VOL - [3:0] */ - -/* - * R32 (0x20) - MICBIAS (1) - */ -#define WM8996_MICB1_RATE 0x0020 /* MICB1_RATE */ -#define WM8996_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ -#define WM8996_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ -#define WM8996_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ -#define WM8996_MICB1_MODE 0x0010 /* MICB1_MODE */ -#define WM8996_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */ -#define WM8996_MICB1_MODE_SHIFT 4 /* MICB1_MODE */ -#define WM8996_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ -#define WM8996_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */ -#define WM8996_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */ -#define WM8996_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */ -#define WM8996_MICB1_DISCH 0x0001 /* MICB1_DISCH */ -#define WM8996_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */ -#define WM8996_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */ -#define WM8996_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ - -/* - * R33 (0x21) - MICBIAS (2) - */ -#define WM8996_MICB2_RATE 0x0020 /* MICB2_RATE */ -#define WM8996_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ -#define WM8996_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ -#define WM8996_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ -#define WM8996_MICB2_MODE 0x0010 /* MICB2_MODE */ -#define WM8996_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */ -#define WM8996_MICB2_MODE_SHIFT 4 /* MICB2_MODE */ -#define WM8996_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ -#define WM8996_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */ -#define WM8996_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */ -#define WM8996_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */ -#define WM8996_MICB2_DISCH 0x0001 /* MICB2_DISCH */ -#define WM8996_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */ -#define WM8996_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */ -#define WM8996_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ - -/* - * R40 (0x28) - LDO 1 - */ -#define WM8996_LDO1_MODE 0x0020 /* LDO1_MODE */ -#define WM8996_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */ -#define WM8996_LDO1_MODE_SHIFT 5 /* LDO1_MODE */ -#define WM8996_LDO1_MODE_WIDTH 1 /* LDO1_MODE */ -#define WM8996_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */ -#define WM8996_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */ -#define WM8996_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */ -#define WM8996_LDO1_DISCH 0x0001 /* LDO1_DISCH */ -#define WM8996_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */ -#define WM8996_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */ -#define WM8996_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */ - -/* - * R41 (0x29) - LDO 2 - */ -#define WM8996_LDO2_MODE 0x0020 /* LDO2_MODE */ -#define WM8996_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */ -#define WM8996_LDO2_MODE_SHIFT 5 /* LDO2_MODE */ -#define WM8996_LDO2_MODE_WIDTH 1 /* LDO2_MODE */ -#define WM8996_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */ -#define WM8996_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */ -#define WM8996_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */ -#define WM8996_LDO2_DISCH 0x0001 /* LDO2_DISCH */ -#define WM8996_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */ -#define WM8996_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */ -#define WM8996_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ - -/* - * R48 (0x30) - Accessory Detect Mode 1 - */ -#define WM8996_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */ -#define WM8996_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */ -#define WM8996_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */ - -/* - * R49 (0x31) - Accessory Detect Mode 2 - */ -#define WM8996_HPOUT1FB_SRC 0x0004 /* HPOUT1FB_SRC */ -#define WM8996_HPOUT1FB_SRC_MASK 0x0004 /* HPOUT1FB_SRC */ -#define WM8996_HPOUT1FB_SRC_SHIFT 2 /* HPOUT1FB_SRC */ -#define WM8996_HPOUT1FB_SRC_WIDTH 1 /* HPOUT1FB_SRC */ -#define WM8996_MICD_SRC 0x0002 /* MICD_SRC */ -#define WM8996_MICD_SRC_MASK 0x0002 /* MICD_SRC */ -#define WM8996_MICD_SRC_SHIFT 1 /* MICD_SRC */ -#define WM8996_MICD_SRC_WIDTH 1 /* MICD_SRC */ -#define WM8996_MICD_BIAS_SRC 0x0001 /* MICD_BIAS_SRC */ -#define WM8996_MICD_BIAS_SRC_MASK 0x0001 /* MICD_BIAS_SRC */ -#define WM8996_MICD_BIAS_SRC_SHIFT 0 /* MICD_BIAS_SRC */ -#define WM8996_MICD_BIAS_SRC_WIDTH 1 /* MICD_BIAS_SRC */ - -/* - * R52 (0x34) - Headphone Detect 1 - */ -#define WM8996_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */ -#define WM8996_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */ -#define WM8996_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */ -#define WM8996_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */ -#define WM8996_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */ -#define WM8996_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */ -#define WM8996_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */ -#define WM8996_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */ -#define WM8996_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */ -#define WM8996_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */ -#define WM8996_HP_POLL 0x0001 /* HP_POLL */ -#define WM8996_HP_POLL_MASK 0x0001 /* HP_POLL */ -#define WM8996_HP_POLL_SHIFT 0 /* HP_POLL */ -#define WM8996_HP_POLL_WIDTH 1 /* HP_POLL */ - -/* - * R53 (0x35) - Headphone Detect 2 - */ -#define WM8996_HP_DONE 0x0080 /* HP_DONE */ -#define WM8996_HP_DONE_MASK 0x0080 /* HP_DONE */ -#define WM8996_HP_DONE_SHIFT 7 /* HP_DONE */ -#define WM8996_HP_DONE_WIDTH 1 /* HP_DONE */ -#define WM8996_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */ -#define WM8996_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */ -#define WM8996_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */ - -/* - * R56 (0x38) - Mic Detect 1 - */ -#define WM8996_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */ -#define WM8996_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */ -#define WM8996_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */ -#define WM8996_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */ -#define WM8996_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */ -#define WM8996_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */ -#define WM8996_MICD_DBTIME 0x0002 /* MICD_DBTIME */ -#define WM8996_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */ -#define WM8996_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */ -#define WM8996_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */ -#define WM8996_MICD_ENA 0x0001 /* MICD_ENA */ -#define WM8996_MICD_ENA_MASK 0x0001 /* MICD_ENA */ -#define WM8996_MICD_ENA_SHIFT 0 /* MICD_ENA */ -#define WM8996_MICD_ENA_WIDTH 1 /* MICD_ENA */ - -/* - * R57 (0x39) - Mic Detect 2 - */ -#define WM8996_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */ -#define WM8996_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */ -#define WM8996_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */ - -/* - * R58 (0x3A) - Mic Detect 3 - */ -#define WM8996_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ -#define WM8996_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ -#define WM8996_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ -#define WM8996_MICD_VALID 0x0002 /* MICD_VALID */ -#define WM8996_MICD_VALID_MASK 0x0002 /* MICD_VALID */ -#define WM8996_MICD_VALID_SHIFT 1 /* MICD_VALID */ -#define WM8996_MICD_VALID_WIDTH 1 /* MICD_VALID */ -#define WM8996_MICD_STS 0x0001 /* MICD_STS */ -#define WM8996_MICD_STS_MASK 0x0001 /* MICD_STS */ -#define WM8996_MICD_STS_SHIFT 0 /* MICD_STS */ -#define WM8996_MICD_STS_WIDTH 1 /* MICD_STS */ - -/* - * R64 (0x40) - Charge Pump (1) - */ -#define WM8996_CP_ENA 0x8000 /* CP_ENA */ -#define WM8996_CP_ENA_MASK 0x8000 /* CP_ENA */ -#define WM8996_CP_ENA_SHIFT 15 /* CP_ENA */ -#define WM8996_CP_ENA_WIDTH 1 /* CP_ENA */ - -/* - * R65 (0x41) - Charge Pump (2) - */ -#define WM8996_CP_DISCH 0x8000 /* CP_DISCH */ -#define WM8996_CP_DISCH_MASK 0x8000 /* CP_DISCH */ -#define WM8996_CP_DISCH_SHIFT 15 /* CP_DISCH */ -#define WM8996_CP_DISCH_WIDTH 1 /* CP_DISCH */ - -/* - * R80 (0x50) - DC Servo (1) - */ -#define WM8996_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */ -#define WM8996_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */ -#define WM8996_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */ -#define WM8996_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */ -#define WM8996_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */ -#define WM8996_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */ -#define WM8996_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */ -#define WM8996_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */ -#define WM8996_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ -#define WM8996_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ -#define WM8996_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ -#define WM8996_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ -#define WM8996_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ -#define WM8996_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ -#define WM8996_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ -#define WM8996_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ - -/* - * R81 (0x51) - DC Servo (2) - */ -#define WM8996_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */ -#define WM8996_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */ -#define WM8996_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */ -#define WM8996_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */ -#define WM8996_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */ -#define WM8996_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */ -#define WM8996_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */ -#define WM8996_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */ -#define WM8996_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ -#define WM8996_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ -#define WM8996_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ -#define WM8996_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ -#define WM8996_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ -#define WM8996_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ -#define WM8996_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ -#define WM8996_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ -#define WM8996_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */ -#define WM8996_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */ -#define WM8996_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */ -#define WM8996_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */ -#define WM8996_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */ -#define WM8996_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */ -#define WM8996_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */ -#define WM8996_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */ -#define WM8996_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ -#define WM8996_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ -#define WM8996_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ -#define WM8996_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ -#define WM8996_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ -#define WM8996_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ -#define WM8996_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ -#define WM8996_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ -#define WM8996_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */ -#define WM8996_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */ -#define WM8996_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */ -#define WM8996_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */ -#define WM8996_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */ -#define WM8996_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */ -#define WM8996_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */ -#define WM8996_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */ -#define WM8996_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ -#define WM8996_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ -#define WM8996_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ -#define WM8996_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ -#define WM8996_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ -#define WM8996_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ -#define WM8996_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ -#define WM8996_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ -#define WM8996_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */ -#define WM8996_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */ -#define WM8996_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */ -#define WM8996_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */ -#define WM8996_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */ -#define WM8996_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */ -#define WM8996_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */ -#define WM8996_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */ -#define WM8996_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */ -#define WM8996_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */ -#define WM8996_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */ -#define WM8996_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ -#define WM8996_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */ -#define WM8996_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */ -#define WM8996_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */ -#define WM8996_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ - -/* - * R82 (0x52) - DC Servo (3) - */ -#define WM8996_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */ -#define WM8996_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */ -#define WM8996_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */ -#define WM8996_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ -#define WM8996_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ -#define WM8996_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ - -/* - * R84 (0x54) - DC Servo (5) - */ -#define WM8996_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */ -#define WM8996_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */ -#define WM8996_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */ -#define WM8996_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */ -#define WM8996_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */ -#define WM8996_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */ - -/* - * R85 (0x55) - DC Servo (6) - */ -#define WM8996_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */ -#define WM8996_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */ -#define WM8996_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */ - -/* - * R86 (0x56) - DC Servo (7) - */ -#define WM8996_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ -#define WM8996_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ -#define WM8996_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ -#define WM8996_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ - -/* - * R87 (0x57) - DC Servo Readback 0 - */ -#define WM8996_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */ -#define WM8996_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */ -#define WM8996_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */ -#define WM8996_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */ -#define WM8996_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ -#define WM8996_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ -#define WM8996_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */ -#define WM8996_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */ -#define WM8996_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */ - -/* - * R96 (0x60) - Analogue HP (1) - */ -#define WM8996_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ -#define WM8996_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ -#define WM8996_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ -#define WM8996_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */ -#define WM8996_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */ -#define WM8996_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */ -#define WM8996_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */ -#define WM8996_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */ -#define WM8996_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */ -#define WM8996_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */ -#define WM8996_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */ -#define WM8996_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */ -#define WM8996_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */ -#define WM8996_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */ -#define WM8996_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */ -#define WM8996_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */ -#define WM8996_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */ -#define WM8996_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */ -#define WM8996_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */ -#define WM8996_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */ -#define WM8996_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */ -#define WM8996_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */ -#define WM8996_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ -#define WM8996_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ - -/* - * R97 (0x61) - Analogue HP (2) - */ -#define WM8996_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */ -#define WM8996_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */ -#define WM8996_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */ -#define WM8996_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */ -#define WM8996_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */ -#define WM8996_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */ -#define WM8996_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */ -#define WM8996_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */ -#define WM8996_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */ -#define WM8996_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */ -#define WM8996_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */ -#define WM8996_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */ -#define WM8996_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */ -#define WM8996_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */ -#define WM8996_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */ -#define WM8996_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */ -#define WM8996_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */ -#define WM8996_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */ -#define WM8996_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */ -#define WM8996_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */ -#define WM8996_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */ -#define WM8996_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */ -#define WM8996_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */ -#define WM8996_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */ - -/* - * R256 (0x100) - Chip Revision - */ -#define WM8996_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */ -#define WM8996_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */ -#define WM8996_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */ - -/* - * R257 (0x101) - Control Interface (1) - */ -#define WM8996_AUTO_INC 0x0004 /* AUTO_INC */ -#define WM8996_AUTO_INC_MASK 0x0004 /* AUTO_INC */ -#define WM8996_AUTO_INC_SHIFT 2 /* AUTO_INC */ -#define WM8996_AUTO_INC_WIDTH 1 /* AUTO_INC */ - -/* - * R272 (0x110) - Write Sequencer Ctrl (1) - */ -#define WM8996_WSEQ_ENA 0x8000 /* WSEQ_ENA */ -#define WM8996_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ -#define WM8996_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ -#define WM8996_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ -#define WM8996_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ -#define WM8996_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ -#define WM8996_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ -#define WM8996_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ -#define WM8996_WSEQ_START 0x0100 /* WSEQ_START */ -#define WM8996_WSEQ_START_MASK 0x0100 /* WSEQ_START */ -#define WM8996_WSEQ_START_SHIFT 8 /* WSEQ_START */ -#define WM8996_WSEQ_START_WIDTH 1 /* WSEQ_START */ -#define WM8996_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ -#define WM8996_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ -#define WM8996_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ - -/* - * R273 (0x111) - Write Sequencer Ctrl (2) - */ -#define WM8996_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */ -#define WM8996_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */ -#define WM8996_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */ -#define WM8996_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ -#define WM8996_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */ -#define WM8996_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */ -#define WM8996_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */ - -/* - * R512 (0x200) - AIF Clocking (1) - */ -#define WM8996_SYSCLK_SRC_MASK 0x0018 /* SYSCLK_SRC - [4:3] */ -#define WM8996_SYSCLK_SRC_SHIFT 3 /* SYSCLK_SRC - [4:3] */ -#define WM8996_SYSCLK_SRC_WIDTH 2 /* SYSCLK_SRC - [4:3] */ -#define WM8996_SYSCLK_INV 0x0004 /* SYSCLK_INV */ -#define WM8996_SYSCLK_INV_MASK 0x0004 /* SYSCLK_INV */ -#define WM8996_SYSCLK_INV_SHIFT 2 /* SYSCLK_INV */ -#define WM8996_SYSCLK_INV_WIDTH 1 /* SYSCLK_INV */ -#define WM8996_SYSCLK_DIV 0x0002 /* SYSCLK_DIV */ -#define WM8996_SYSCLK_DIV_MASK 0x0002 /* SYSCLK_DIV */ -#define WM8996_SYSCLK_DIV_SHIFT 1 /* SYSCLK_DIV */ -#define WM8996_SYSCLK_DIV_WIDTH 1 /* SYSCLK_DIV */ -#define WM8996_SYSCLK_ENA 0x0001 /* SYSCLK_ENA */ -#define WM8996_SYSCLK_ENA_MASK 0x0001 /* SYSCLK_ENA */ -#define WM8996_SYSCLK_ENA_SHIFT 0 /* SYSCLK_ENA */ -#define WM8996_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ - -/* - * R513 (0x201) - AIF Clocking (2) - */ -#define WM8996_DSP2_DIV_MASK 0x0018 /* DSP2_DIV - [4:3] */ -#define WM8996_DSP2_DIV_SHIFT 3 /* DSP2_DIV - [4:3] */ -#define WM8996_DSP2_DIV_WIDTH 2 /* DSP2_DIV - [4:3] */ -#define WM8996_DSP1_DIV_MASK 0x0003 /* DSP1_DIV - [1:0] */ -#define WM8996_DSP1_DIV_SHIFT 0 /* DSP1_DIV - [1:0] */ -#define WM8996_DSP1_DIV_WIDTH 2 /* DSP1_DIV - [1:0] */ - -/* - * R520 (0x208) - Clocking (1) - */ -#define WM8996_LFCLK_ENA 0x0020 /* LFCLK_ENA */ -#define WM8996_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */ -#define WM8996_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */ -#define WM8996_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */ -#define WM8996_TOCLK_ENA 0x0010 /* TOCLK_ENA */ -#define WM8996_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ -#define WM8996_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ -#define WM8996_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ -#define WM8996_AIFCLK_ENA 0x0004 /* AIFCLK_ENA */ -#define WM8996_AIFCLK_ENA_MASK 0x0004 /* AIFCLK_ENA */ -#define WM8996_AIFCLK_ENA_SHIFT 2 /* AIFCLK_ENA */ -#define WM8996_AIFCLK_ENA_WIDTH 1 /* AIFCLK_ENA */ -#define WM8996_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */ -#define WM8996_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */ -#define WM8996_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */ -#define WM8996_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */ - -/* - * R521 (0x209) - Clocking (2) - */ -#define WM8996_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */ -#define WM8996_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */ -#define WM8996_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */ -#define WM8996_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */ -#define WM8996_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */ -#define WM8996_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */ -#define WM8996_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */ -#define WM8996_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */ -#define WM8996_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */ - -/* - * R528 (0x210) - AIF Rate - */ -#define WM8996_SYSCLK_RATE 0x0001 /* SYSCLK_RATE */ -#define WM8996_SYSCLK_RATE_MASK 0x0001 /* SYSCLK_RATE */ -#define WM8996_SYSCLK_RATE_SHIFT 0 /* SYSCLK_RATE */ -#define WM8996_SYSCLK_RATE_WIDTH 1 /* SYSCLK_RATE */ - -/* - * R544 (0x220) - FLL Control (1) - */ -#define WM8996_FLL_OSC_ENA 0x0002 /* FLL_OSC_ENA */ -#define WM8996_FLL_OSC_ENA_MASK 0x0002 /* FLL_OSC_ENA */ -#define WM8996_FLL_OSC_ENA_SHIFT 1 /* FLL_OSC_ENA */ -#define WM8996_FLL_OSC_ENA_WIDTH 1 /* FLL_OSC_ENA */ -#define WM8996_FLL_ENA 0x0001 /* FLL_ENA */ -#define WM8996_FLL_ENA_MASK 0x0001 /* FLL_ENA */ -#define WM8996_FLL_ENA_SHIFT 0 /* FLL_ENA */ -#define WM8996_FLL_ENA_WIDTH 1 /* FLL_ENA */ - -/* - * R545 (0x221) - FLL Control (2) - */ -#define WM8996_FLL_OUTDIV_MASK 0x3F00 /* FLL_OUTDIV - [13:8] */ -#define WM8996_FLL_OUTDIV_SHIFT 8 /* FLL_OUTDIV - [13:8] */ -#define WM8996_FLL_OUTDIV_WIDTH 6 /* FLL_OUTDIV - [13:8] */ -#define WM8996_FLL_FRATIO_MASK 0x0007 /* FLL_FRATIO - [2:0] */ -#define WM8996_FLL_FRATIO_SHIFT 0 /* FLL_FRATIO - [2:0] */ -#define WM8996_FLL_FRATIO_WIDTH 3 /* FLL_FRATIO - [2:0] */ - -/* - * R546 (0x222) - FLL Control (3) - */ -#define WM8996_FLL_THETA_MASK 0xFFFF /* FLL_THETA - [15:0] */ -#define WM8996_FLL_THETA_SHIFT 0 /* FLL_THETA - [15:0] */ -#define WM8996_FLL_THETA_WIDTH 16 /* FLL_THETA - [15:0] */ - -/* - * R547 (0x223) - FLL Control (4) - */ -#define WM8996_FLL_N_MASK 0x7FE0 /* FLL_N - [14:5] */ -#define WM8996_FLL_N_SHIFT 5 /* FLL_N - [14:5] */ -#define WM8996_FLL_N_WIDTH 10 /* FLL_N - [14:5] */ -#define WM8996_FLL_LOOP_GAIN_MASK 0x000F /* FLL_LOOP_GAIN - [3:0] */ -#define WM8996_FLL_LOOP_GAIN_SHIFT 0 /* FLL_LOOP_GAIN - [3:0] */ -#define WM8996_FLL_LOOP_GAIN_WIDTH 4 /* FLL_LOOP_GAIN - [3:0] */ - -/* - * R548 (0x224) - FLL Control (5) - */ -#define WM8996_FLL_FRC_NCO_VAL_MASK 0x1F80 /* FLL_FRC_NCO_VAL - [12:7] */ -#define WM8996_FLL_FRC_NCO_VAL_SHIFT 7 /* FLL_FRC_NCO_VAL - [12:7] */ -#define WM8996_FLL_FRC_NCO_VAL_WIDTH 6 /* FLL_FRC_NCO_VAL - [12:7] */ -#define WM8996_FLL_FRC_NCO 0x0040 /* FLL_FRC_NCO */ -#define WM8996_FLL_FRC_NCO_MASK 0x0040 /* FLL_FRC_NCO */ -#define WM8996_FLL_FRC_NCO_SHIFT 6 /* FLL_FRC_NCO */ -#define WM8996_FLL_FRC_NCO_WIDTH 1 /* FLL_FRC_NCO */ -#define WM8996_FLL_REFCLK_DIV_MASK 0x0018 /* FLL_REFCLK_DIV - [4:3] */ -#define WM8996_FLL_REFCLK_DIV_SHIFT 3 /* FLL_REFCLK_DIV - [4:3] */ -#define WM8996_FLL_REFCLK_DIV_WIDTH 2 /* FLL_REFCLK_DIV - [4:3] */ -#define WM8996_FLL_REF_FREQ 0x0004 /* FLL_REF_FREQ */ -#define WM8996_FLL_REF_FREQ_MASK 0x0004 /* FLL_REF_FREQ */ -#define WM8996_FLL_REF_FREQ_SHIFT 2 /* FLL_REF_FREQ */ -#define WM8996_FLL_REF_FREQ_WIDTH 1 /* FLL_REF_FREQ */ -#define WM8996_FLL_REFCLK_SRC_MASK 0x0003 /* FLL_REFCLK_SRC - [1:0] */ -#define WM8996_FLL_REFCLK_SRC_SHIFT 0 /* FLL_REFCLK_SRC - [1:0] */ -#define WM8996_FLL_REFCLK_SRC_WIDTH 2 /* FLL_REFCLK_SRC - [1:0] */ - -/* - * R549 (0x225) - FLL Control (6) - */ -#define WM8996_FLL_REFCLK_SRC_STS_MASK 0x000C /* FLL_REFCLK_SRC_STS - [3:2] */ -#define WM8996_FLL_REFCLK_SRC_STS_SHIFT 2 /* FLL_REFCLK_SRC_STS - [3:2] */ -#define WM8996_FLL_REFCLK_SRC_STS_WIDTH 2 /* FLL_REFCLK_SRC_STS - [3:2] */ -#define WM8996_FLL_SWITCH_CLK 0x0001 /* FLL_SWITCH_CLK */ -#define WM8996_FLL_SWITCH_CLK_MASK 0x0001 /* FLL_SWITCH_CLK */ -#define WM8996_FLL_SWITCH_CLK_SHIFT 0 /* FLL_SWITCH_CLK */ -#define WM8996_FLL_SWITCH_CLK_WIDTH 1 /* FLL_SWITCH_CLK */ - -/* - * R550 (0x226) - FLL EFS 1 - */ -#define WM8996_FLL_LAMBDA_MASK 0xFFFF /* FLL_LAMBDA - [15:0] */ -#define WM8996_FLL_LAMBDA_SHIFT 0 /* FLL_LAMBDA - [15:0] */ -#define WM8996_FLL_LAMBDA_WIDTH 16 /* FLL_LAMBDA - [15:0] */ - -/* - * R551 (0x227) - FLL EFS 2 - */ -#define WM8996_FLL_LFSR_SEL_MASK 0x0006 /* FLL_LFSR_SEL - [2:1] */ -#define WM8996_FLL_LFSR_SEL_SHIFT 1 /* FLL_LFSR_SEL - [2:1] */ -#define WM8996_FLL_LFSR_SEL_WIDTH 2 /* FLL_LFSR_SEL - [2:1] */ -#define WM8996_FLL_EFS_ENA 0x0001 /* FLL_EFS_ENA */ -#define WM8996_FLL_EFS_ENA_MASK 0x0001 /* FLL_EFS_ENA */ -#define WM8996_FLL_EFS_ENA_SHIFT 0 /* FLL_EFS_ENA */ -#define WM8996_FLL_EFS_ENA_WIDTH 1 /* FLL_EFS_ENA */ - -/* - * R768 (0x300) - AIF1 Control - */ -#define WM8996_AIF1_TRI 0x0004 /* AIF1_TRI */ -#define WM8996_AIF1_TRI_MASK 0x0004 /* AIF1_TRI */ -#define WM8996_AIF1_TRI_SHIFT 2 /* AIF1_TRI */ -#define WM8996_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ -#define WM8996_AIF1_FMT_MASK 0x0003 /* AIF1_FMT - [1:0] */ -#define WM8996_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [1:0] */ -#define WM8996_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [1:0] */ - -/* - * R769 (0x301) - AIF1 BCLK - */ -#define WM8996_AIF1_BCLK_INV 0x0400 /* AIF1_BCLK_INV */ -#define WM8996_AIF1_BCLK_INV_MASK 0x0400 /* AIF1_BCLK_INV */ -#define WM8996_AIF1_BCLK_INV_SHIFT 10 /* AIF1_BCLK_INV */ -#define WM8996_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ -#define WM8996_AIF1_BCLK_FRC 0x0200 /* AIF1_BCLK_FRC */ -#define WM8996_AIF1_BCLK_FRC_MASK 0x0200 /* AIF1_BCLK_FRC */ -#define WM8996_AIF1_BCLK_FRC_SHIFT 9 /* AIF1_BCLK_FRC */ -#define WM8996_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ -#define WM8996_AIF1_BCLK_MSTR 0x0100 /* AIF1_BCLK_MSTR */ -#define WM8996_AIF1_BCLK_MSTR_MASK 0x0100 /* AIF1_BCLK_MSTR */ -#define WM8996_AIF1_BCLK_MSTR_SHIFT 8 /* AIF1_BCLK_MSTR */ -#define WM8996_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ -#define WM8996_AIF1_BCLK_DIV_MASK 0x000F /* AIF1_BCLK_DIV - [3:0] */ -#define WM8996_AIF1_BCLK_DIV_SHIFT 0 /* AIF1_BCLK_DIV - [3:0] */ -#define WM8996_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [3:0] */ - -/* - * R770 (0x302) - AIF1 TX LRCLK(1) - */ -#define WM8996_AIF1TX_RATE_MASK 0x07FF /* AIF1TX_RATE - [10:0] */ -#define WM8996_AIF1TX_RATE_SHIFT 0 /* AIF1TX_RATE - [10:0] */ -#define WM8996_AIF1TX_RATE_WIDTH 11 /* AIF1TX_RATE - [10:0] */ - -/* - * R771 (0x303) - AIF1 TX LRCLK(2) - */ -#define WM8996_AIF1TX_LRCLK_MODE 0x0008 /* AIF1TX_LRCLK_MODE */ -#define WM8996_AIF1TX_LRCLK_MODE_MASK 0x0008 /* AIF1TX_LRCLK_MODE */ -#define WM8996_AIF1TX_LRCLK_MODE_SHIFT 3 /* AIF1TX_LRCLK_MODE */ -#define WM8996_AIF1TX_LRCLK_MODE_WIDTH 1 /* AIF1TX_LRCLK_MODE */ -#define WM8996_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ -#define WM8996_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ -#define WM8996_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ -#define WM8996_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ -#define WM8996_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ -#define WM8996_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ -#define WM8996_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ -#define WM8996_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ -#define WM8996_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ -#define WM8996_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ -#define WM8996_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ -#define WM8996_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ - -/* - * R772 (0x304) - AIF1 RX LRCLK(1) - */ -#define WM8996_AIF1RX_RATE_MASK 0x07FF /* AIF1RX_RATE - [10:0] */ -#define WM8996_AIF1RX_RATE_SHIFT 0 /* AIF1RX_RATE - [10:0] */ -#define WM8996_AIF1RX_RATE_WIDTH 11 /* AIF1RX_RATE - [10:0] */ - -/* - * R773 (0x305) - AIF1 RX LRCLK(2) - */ -#define WM8996_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ -#define WM8996_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ -#define WM8996_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ -#define WM8996_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ -#define WM8996_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ -#define WM8996_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ -#define WM8996_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ -#define WM8996_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ -#define WM8996_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ -#define WM8996_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ -#define WM8996_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ -#define WM8996_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ - -/* - * R774 (0x306) - AIF1TX Data Configuration (1) - */ -#define WM8996_AIF1TX_WL_MASK 0xFF00 /* AIF1TX_WL - [15:8] */ -#define WM8996_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [15:8] */ -#define WM8996_AIF1TX_WL_WIDTH 8 /* AIF1TX_WL - [15:8] */ -#define WM8996_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ -#define WM8996_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ -#define WM8996_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ - -/* - * R775 (0x307) - AIF1TX Data Configuration (2) - */ -#define WM8996_AIF1TX_DAT_TRI 0x0001 /* AIF1TX_DAT_TRI */ -#define WM8996_AIF1TX_DAT_TRI_MASK 0x0001 /* AIF1TX_DAT_TRI */ -#define WM8996_AIF1TX_DAT_TRI_SHIFT 0 /* AIF1TX_DAT_TRI */ -#define WM8996_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ - -/* - * R776 (0x308) - AIF1RX Data Configuration - */ -#define WM8996_AIF1RX_WL_MASK 0xFF00 /* AIF1RX_WL - [15:8] */ -#define WM8996_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [15:8] */ -#define WM8996_AIF1RX_WL_WIDTH 8 /* AIF1RX_WL - [15:8] */ -#define WM8996_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ -#define WM8996_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ -#define WM8996_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ - -/* - * R777 (0x309) - AIF1TX Channel 0 Configuration - */ -#define WM8996_AIF1TX_CHAN0_DAT_INV 0x8000 /* AIF1TX_CHAN0_DAT_INV */ -#define WM8996_AIF1TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN0_DAT_INV */ -#define WM8996_AIF1TX_CHAN0_DAT_INV_SHIFT 15 /* AIF1TX_CHAN0_DAT_INV */ -#define WM8996_AIF1TX_CHAN0_DAT_INV_WIDTH 1 /* AIF1TX_CHAN0_DAT_INV */ -#define WM8996_AIF1TX_CHAN0_SPACING_MASK 0x7E00 /* AIF1TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN0_SPACING_SHIFT 9 /* AIF1TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN0_SPACING_WIDTH 6 /* AIF1TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN0_SLOTS_SHIFT 6 /* AIF1TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN0_SLOTS_WIDTH 3 /* AIF1TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN0_START_SLOT_MASK 0x003F /* AIF1TX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN0_START_SLOT_SHIFT 0 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN0_START_SLOT_WIDTH 6 /* AIF1TX_CHAN0_START_SLOT - [5:0] */ - -/* - * R778 (0x30A) - AIF1TX Channel 1 Configuration - */ -#define WM8996_AIF1TX_CHAN1_DAT_INV 0x8000 /* AIF1TX_CHAN1_DAT_INV */ -#define WM8996_AIF1TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN1_DAT_INV */ -#define WM8996_AIF1TX_CHAN1_DAT_INV_SHIFT 15 /* AIF1TX_CHAN1_DAT_INV */ -#define WM8996_AIF1TX_CHAN1_DAT_INV_WIDTH 1 /* AIF1TX_CHAN1_DAT_INV */ -#define WM8996_AIF1TX_CHAN1_SPACING_MASK 0x7E00 /* AIF1TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN1_SPACING_SHIFT 9 /* AIF1TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN1_SPACING_WIDTH 6 /* AIF1TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN1_SLOTS_SHIFT 6 /* AIF1TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN1_SLOTS_WIDTH 3 /* AIF1TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN1_START_SLOT_MASK 0x003F /* AIF1TX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN1_START_SLOT_SHIFT 0 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN1_START_SLOT_WIDTH 6 /* AIF1TX_CHAN1_START_SLOT - [5:0] */ - -/* - * R779 (0x30B) - AIF1TX Channel 2 Configuration - */ -#define WM8996_AIF1TX_CHAN2_DAT_INV 0x8000 /* AIF1TX_CHAN2_DAT_INV */ -#define WM8996_AIF1TX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN2_DAT_INV */ -#define WM8996_AIF1TX_CHAN2_DAT_INV_SHIFT 15 /* AIF1TX_CHAN2_DAT_INV */ -#define WM8996_AIF1TX_CHAN2_DAT_INV_WIDTH 1 /* AIF1TX_CHAN2_DAT_INV */ -#define WM8996_AIF1TX_CHAN2_SPACING_MASK 0x7E00 /* AIF1TX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN2_SPACING_SHIFT 9 /* AIF1TX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN2_SPACING_WIDTH 6 /* AIF1TX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN2_SLOTS_SHIFT 6 /* AIF1TX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN2_SLOTS_WIDTH 3 /* AIF1TX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN2_START_SLOT_MASK 0x003F /* AIF1TX_CHAN2_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN2_START_SLOT_SHIFT 0 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN2_START_SLOT_WIDTH 6 /* AIF1TX_CHAN2_START_SLOT - [5:0] */ - -/* - * R780 (0x30C) - AIF1TX Channel 3 Configuration - */ -#define WM8996_AIF1TX_CHAN3_DAT_INV 0x8000 /* AIF1TX_CHAN3_DAT_INV */ -#define WM8996_AIF1TX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN3_DAT_INV */ -#define WM8996_AIF1TX_CHAN3_DAT_INV_SHIFT 15 /* AIF1TX_CHAN3_DAT_INV */ -#define WM8996_AIF1TX_CHAN3_DAT_INV_WIDTH 1 /* AIF1TX_CHAN3_DAT_INV */ -#define WM8996_AIF1TX_CHAN3_SPACING_MASK 0x7E00 /* AIF1TX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN3_SPACING_SHIFT 9 /* AIF1TX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN3_SPACING_WIDTH 6 /* AIF1TX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN3_SLOTS_SHIFT 6 /* AIF1TX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN3_SLOTS_WIDTH 3 /* AIF1TX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN3_START_SLOT_MASK 0x003F /* AIF1TX_CHAN3_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN3_START_SLOT_SHIFT 0 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN3_START_SLOT_WIDTH 6 /* AIF1TX_CHAN3_START_SLOT - [5:0] */ - -/* - * R781 (0x30D) - AIF1TX Channel 4 Configuration - */ -#define WM8996_AIF1TX_CHAN4_DAT_INV 0x8000 /* AIF1TX_CHAN4_DAT_INV */ -#define WM8996_AIF1TX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN4_DAT_INV */ -#define WM8996_AIF1TX_CHAN4_DAT_INV_SHIFT 15 /* AIF1TX_CHAN4_DAT_INV */ -#define WM8996_AIF1TX_CHAN4_DAT_INV_WIDTH 1 /* AIF1TX_CHAN4_DAT_INV */ -#define WM8996_AIF1TX_CHAN4_SPACING_MASK 0x7E00 /* AIF1TX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN4_SPACING_SHIFT 9 /* AIF1TX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN4_SPACING_WIDTH 6 /* AIF1TX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN4_SLOTS_SHIFT 6 /* AIF1TX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN4_SLOTS_WIDTH 3 /* AIF1TX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN4_START_SLOT_MASK 0x003F /* AIF1TX_CHAN4_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN4_START_SLOT_SHIFT 0 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN4_START_SLOT_WIDTH 6 /* AIF1TX_CHAN4_START_SLOT - [5:0] */ - -/* - * R782 (0x30E) - AIF1TX Channel 5 Configuration - */ -#define WM8996_AIF1TX_CHAN5_DAT_INV 0x8000 /* AIF1TX_CHAN5_DAT_INV */ -#define WM8996_AIF1TX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1TX_CHAN5_DAT_INV */ -#define WM8996_AIF1TX_CHAN5_DAT_INV_SHIFT 15 /* AIF1TX_CHAN5_DAT_INV */ -#define WM8996_AIF1TX_CHAN5_DAT_INV_WIDTH 1 /* AIF1TX_CHAN5_DAT_INV */ -#define WM8996_AIF1TX_CHAN5_SPACING_MASK 0x7E00 /* AIF1TX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN5_SPACING_SHIFT 9 /* AIF1TX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN5_SPACING_WIDTH 6 /* AIF1TX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1TX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1TX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN5_SLOTS_SHIFT 6 /* AIF1TX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN5_SLOTS_WIDTH 3 /* AIF1TX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1TX_CHAN5_START_SLOT_MASK 0x003F /* AIF1TX_CHAN5_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN5_START_SLOT_SHIFT 0 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ -#define WM8996_AIF1TX_CHAN5_START_SLOT_WIDTH 6 /* AIF1TX_CHAN5_START_SLOT - [5:0] */ - -/* - * R783 (0x30F) - AIF1RX Channel 0 Configuration - */ -#define WM8996_AIF1RX_CHAN0_DAT_INV 0x8000 /* AIF1RX_CHAN0_DAT_INV */ -#define WM8996_AIF1RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN0_DAT_INV */ -#define WM8996_AIF1RX_CHAN0_DAT_INV_SHIFT 15 /* AIF1RX_CHAN0_DAT_INV */ -#define WM8996_AIF1RX_CHAN0_DAT_INV_WIDTH 1 /* AIF1RX_CHAN0_DAT_INV */ -#define WM8996_AIF1RX_CHAN0_SPACING_MASK 0x7E00 /* AIF1RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN0_SPACING_SHIFT 9 /* AIF1RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN0_SPACING_WIDTH 6 /* AIF1RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN0_SLOTS_SHIFT 6 /* AIF1RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN0_SLOTS_WIDTH 3 /* AIF1RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN0_START_SLOT_MASK 0x003F /* AIF1RX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN0_START_SLOT_SHIFT 0 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN0_START_SLOT_WIDTH 6 /* AIF1RX_CHAN0_START_SLOT - [5:0] */ - -/* - * R784 (0x310) - AIF1RX Channel 1 Configuration - */ -#define WM8996_AIF1RX_CHAN1_DAT_INV 0x8000 /* AIF1RX_CHAN1_DAT_INV */ -#define WM8996_AIF1RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN1_DAT_INV */ -#define WM8996_AIF1RX_CHAN1_DAT_INV_SHIFT 15 /* AIF1RX_CHAN1_DAT_INV */ -#define WM8996_AIF1RX_CHAN1_DAT_INV_WIDTH 1 /* AIF1RX_CHAN1_DAT_INV */ -#define WM8996_AIF1RX_CHAN1_SPACING_MASK 0x7E00 /* AIF1RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN1_SPACING_SHIFT 9 /* AIF1RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN1_SPACING_WIDTH 6 /* AIF1RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN1_SLOTS_SHIFT 6 /* AIF1RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN1_SLOTS_WIDTH 3 /* AIF1RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN1_START_SLOT_MASK 0x003F /* AIF1RX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN1_START_SLOT_SHIFT 0 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN1_START_SLOT_WIDTH 6 /* AIF1RX_CHAN1_START_SLOT - [5:0] */ - -/* - * R785 (0x311) - AIF1RX Channel 2 Configuration - */ -#define WM8996_AIF1RX_CHAN2_DAT_INV 0x8000 /* AIF1RX_CHAN2_DAT_INV */ -#define WM8996_AIF1RX_CHAN2_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN2_DAT_INV */ -#define WM8996_AIF1RX_CHAN2_DAT_INV_SHIFT 15 /* AIF1RX_CHAN2_DAT_INV */ -#define WM8996_AIF1RX_CHAN2_DAT_INV_WIDTH 1 /* AIF1RX_CHAN2_DAT_INV */ -#define WM8996_AIF1RX_CHAN2_SPACING_MASK 0x7E00 /* AIF1RX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN2_SPACING_SHIFT 9 /* AIF1RX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN2_SPACING_WIDTH 6 /* AIF1RX_CHAN2_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN2_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN2_SLOTS_SHIFT 6 /* AIF1RX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN2_SLOTS_WIDTH 3 /* AIF1RX_CHAN2_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN2_START_SLOT_MASK 0x003F /* AIF1RX_CHAN2_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN2_START_SLOT_SHIFT 0 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN2_START_SLOT_WIDTH 6 /* AIF1RX_CHAN2_START_SLOT - [5:0] */ - -/* - * R786 (0x312) - AIF1RX Channel 3 Configuration - */ -#define WM8996_AIF1RX_CHAN3_DAT_INV 0x8000 /* AIF1RX_CHAN3_DAT_INV */ -#define WM8996_AIF1RX_CHAN3_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN3_DAT_INV */ -#define WM8996_AIF1RX_CHAN3_DAT_INV_SHIFT 15 /* AIF1RX_CHAN3_DAT_INV */ -#define WM8996_AIF1RX_CHAN3_DAT_INV_WIDTH 1 /* AIF1RX_CHAN3_DAT_INV */ -#define WM8996_AIF1RX_CHAN3_SPACING_MASK 0x7E00 /* AIF1RX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN3_SPACING_SHIFT 9 /* AIF1RX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN3_SPACING_WIDTH 6 /* AIF1RX_CHAN3_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN3_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN3_SLOTS_SHIFT 6 /* AIF1RX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN3_SLOTS_WIDTH 3 /* AIF1RX_CHAN3_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN3_START_SLOT_MASK 0x003F /* AIF1RX_CHAN3_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN3_START_SLOT_SHIFT 0 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN3_START_SLOT_WIDTH 6 /* AIF1RX_CHAN3_START_SLOT - [5:0] */ - -/* - * R787 (0x313) - AIF1RX Channel 4 Configuration - */ -#define WM8996_AIF1RX_CHAN4_DAT_INV 0x8000 /* AIF1RX_CHAN4_DAT_INV */ -#define WM8996_AIF1RX_CHAN4_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN4_DAT_INV */ -#define WM8996_AIF1RX_CHAN4_DAT_INV_SHIFT 15 /* AIF1RX_CHAN4_DAT_INV */ -#define WM8996_AIF1RX_CHAN4_DAT_INV_WIDTH 1 /* AIF1RX_CHAN4_DAT_INV */ -#define WM8996_AIF1RX_CHAN4_SPACING_MASK 0x7E00 /* AIF1RX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN4_SPACING_SHIFT 9 /* AIF1RX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN4_SPACING_WIDTH 6 /* AIF1RX_CHAN4_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN4_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN4_SLOTS_SHIFT 6 /* AIF1RX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN4_SLOTS_WIDTH 3 /* AIF1RX_CHAN4_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN4_START_SLOT_MASK 0x003F /* AIF1RX_CHAN4_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN4_START_SLOT_SHIFT 0 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN4_START_SLOT_WIDTH 6 /* AIF1RX_CHAN4_START_SLOT - [5:0] */ - -/* - * R788 (0x314) - AIF1RX Channel 5 Configuration - */ -#define WM8996_AIF1RX_CHAN5_DAT_INV 0x8000 /* AIF1RX_CHAN5_DAT_INV */ -#define WM8996_AIF1RX_CHAN5_DAT_INV_MASK 0x8000 /* AIF1RX_CHAN5_DAT_INV */ -#define WM8996_AIF1RX_CHAN5_DAT_INV_SHIFT 15 /* AIF1RX_CHAN5_DAT_INV */ -#define WM8996_AIF1RX_CHAN5_DAT_INV_WIDTH 1 /* AIF1RX_CHAN5_DAT_INV */ -#define WM8996_AIF1RX_CHAN5_SPACING_MASK 0x7E00 /* AIF1RX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN5_SPACING_SHIFT 9 /* AIF1RX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN5_SPACING_WIDTH 6 /* AIF1RX_CHAN5_SPACING - [14:9] */ -#define WM8996_AIF1RX_CHAN5_SLOTS_MASK 0x01C0 /* AIF1RX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN5_SLOTS_SHIFT 6 /* AIF1RX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN5_SLOTS_WIDTH 3 /* AIF1RX_CHAN5_SLOTS - [8:6] */ -#define WM8996_AIF1RX_CHAN5_START_SLOT_MASK 0x003F /* AIF1RX_CHAN5_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN5_START_SLOT_SHIFT 0 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ -#define WM8996_AIF1RX_CHAN5_START_SLOT_WIDTH 6 /* AIF1RX_CHAN5_START_SLOT - [5:0] */ - -/* - * R789 (0x315) - AIF1RX Mono Configuration - */ -#define WM8996_AIF1RX_CHAN4_MONO_MODE 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ -#define WM8996_AIF1RX_CHAN4_MONO_MODE_MASK 0x0004 /* AIF1RX_CHAN4_MONO_MODE */ -#define WM8996_AIF1RX_CHAN4_MONO_MODE_SHIFT 2 /* AIF1RX_CHAN4_MONO_MODE */ -#define WM8996_AIF1RX_CHAN4_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN4_MONO_MODE */ -#define WM8996_AIF1RX_CHAN2_MONO_MODE 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ -#define WM8996_AIF1RX_CHAN2_MONO_MODE_MASK 0x0002 /* AIF1RX_CHAN2_MONO_MODE */ -#define WM8996_AIF1RX_CHAN2_MONO_MODE_SHIFT 1 /* AIF1RX_CHAN2_MONO_MODE */ -#define WM8996_AIF1RX_CHAN2_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN2_MONO_MODE */ -#define WM8996_AIF1RX_CHAN0_MONO_MODE 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ -#define WM8996_AIF1RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF1RX_CHAN0_MONO_MODE */ -#define WM8996_AIF1RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF1RX_CHAN0_MONO_MODE */ -#define WM8996_AIF1RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF1RX_CHAN0_MONO_MODE */ - -/* - * R794 (0x31A) - AIF1TX Test - */ -#define WM8996_AIF1TX45_DITHER_ENA 0x0004 /* AIF1TX45_DITHER_ENA */ -#define WM8996_AIF1TX45_DITHER_ENA_MASK 0x0004 /* AIF1TX45_DITHER_ENA */ -#define WM8996_AIF1TX45_DITHER_ENA_SHIFT 2 /* AIF1TX45_DITHER_ENA */ -#define WM8996_AIF1TX45_DITHER_ENA_WIDTH 1 /* AIF1TX45_DITHER_ENA */ -#define WM8996_AIF1TX23_DITHER_ENA 0x0002 /* AIF1TX23_DITHER_ENA */ -#define WM8996_AIF1TX23_DITHER_ENA_MASK 0x0002 /* AIF1TX23_DITHER_ENA */ -#define WM8996_AIF1TX23_DITHER_ENA_SHIFT 1 /* AIF1TX23_DITHER_ENA */ -#define WM8996_AIF1TX23_DITHER_ENA_WIDTH 1 /* AIF1TX23_DITHER_ENA */ -#define WM8996_AIF1TX01_DITHER_ENA 0x0001 /* AIF1TX01_DITHER_ENA */ -#define WM8996_AIF1TX01_DITHER_ENA_MASK 0x0001 /* AIF1TX01_DITHER_ENA */ -#define WM8996_AIF1TX01_DITHER_ENA_SHIFT 0 /* AIF1TX01_DITHER_ENA */ -#define WM8996_AIF1TX01_DITHER_ENA_WIDTH 1 /* AIF1TX01_DITHER_ENA */ - -/* - * R800 (0x320) - AIF2 Control - */ -#define WM8996_AIF2_TRI 0x0004 /* AIF2_TRI */ -#define WM8996_AIF2_TRI_MASK 0x0004 /* AIF2_TRI */ -#define WM8996_AIF2_TRI_SHIFT 2 /* AIF2_TRI */ -#define WM8996_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ -#define WM8996_AIF2_FMT_MASK 0x0003 /* AIF2_FMT - [1:0] */ -#define WM8996_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [1:0] */ -#define WM8996_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [1:0] */ - -/* - * R801 (0x321) - AIF2 BCLK - */ -#define WM8996_AIF2_BCLK_INV 0x0400 /* AIF2_BCLK_INV */ -#define WM8996_AIF2_BCLK_INV_MASK 0x0400 /* AIF2_BCLK_INV */ -#define WM8996_AIF2_BCLK_INV_SHIFT 10 /* AIF2_BCLK_INV */ -#define WM8996_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ -#define WM8996_AIF2_BCLK_FRC 0x0200 /* AIF2_BCLK_FRC */ -#define WM8996_AIF2_BCLK_FRC_MASK 0x0200 /* AIF2_BCLK_FRC */ -#define WM8996_AIF2_BCLK_FRC_SHIFT 9 /* AIF2_BCLK_FRC */ -#define WM8996_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */ -#define WM8996_AIF2_BCLK_MSTR 0x0100 /* AIF2_BCLK_MSTR */ -#define WM8996_AIF2_BCLK_MSTR_MASK 0x0100 /* AIF2_BCLK_MSTR */ -#define WM8996_AIF2_BCLK_MSTR_SHIFT 8 /* AIF2_BCLK_MSTR */ -#define WM8996_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */ -#define WM8996_AIF2_BCLK_DIV_MASK 0x000F /* AIF2_BCLK_DIV - [3:0] */ -#define WM8996_AIF2_BCLK_DIV_SHIFT 0 /* AIF2_BCLK_DIV - [3:0] */ -#define WM8996_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [3:0] */ - -/* - * R802 (0x322) - AIF2 TX LRCLK(1) - */ -#define WM8996_AIF2TX_RATE_MASK 0x07FF /* AIF2TX_RATE - [10:0] */ -#define WM8996_AIF2TX_RATE_SHIFT 0 /* AIF2TX_RATE - [10:0] */ -#define WM8996_AIF2TX_RATE_WIDTH 11 /* AIF2TX_RATE - [10:0] */ - -/* - * R803 (0x323) - AIF2 TX LRCLK(2) - */ -#define WM8996_AIF2TX_LRCLK_MODE 0x0008 /* AIF2TX_LRCLK_MODE */ -#define WM8996_AIF2TX_LRCLK_MODE_MASK 0x0008 /* AIF2TX_LRCLK_MODE */ -#define WM8996_AIF2TX_LRCLK_MODE_SHIFT 3 /* AIF2TX_LRCLK_MODE */ -#define WM8996_AIF2TX_LRCLK_MODE_WIDTH 1 /* AIF2TX_LRCLK_MODE */ -#define WM8996_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */ -#define WM8996_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */ -#define WM8996_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */ -#define WM8996_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */ -#define WM8996_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */ -#define WM8996_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */ -#define WM8996_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */ -#define WM8996_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */ -#define WM8996_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */ -#define WM8996_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */ -#define WM8996_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */ -#define WM8996_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */ - -/* - * R804 (0x324) - AIF2 RX LRCLK(1) - */ -#define WM8996_AIF2RX_RATE_MASK 0x07FF /* AIF2RX_RATE - [10:0] */ -#define WM8996_AIF2RX_RATE_SHIFT 0 /* AIF2RX_RATE - [10:0] */ -#define WM8996_AIF2RX_RATE_WIDTH 11 /* AIF2RX_RATE - [10:0] */ - -/* - * R805 (0x325) - AIF2 RX LRCLK(2) - */ -#define WM8996_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */ -#define WM8996_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */ -#define WM8996_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */ -#define WM8996_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */ -#define WM8996_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */ -#define WM8996_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */ -#define WM8996_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */ -#define WM8996_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */ -#define WM8996_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */ -#define WM8996_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */ -#define WM8996_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */ -#define WM8996_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */ - -/* - * R806 (0x326) - AIF2TX Data Configuration (1) - */ -#define WM8996_AIF2TX_WL_MASK 0xFF00 /* AIF2TX_WL - [15:8] */ -#define WM8996_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [15:8] */ -#define WM8996_AIF2TX_WL_WIDTH 8 /* AIF2TX_WL - [15:8] */ -#define WM8996_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */ -#define WM8996_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */ -#define WM8996_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */ - -/* - * R807 (0x327) - AIF2TX Data Configuration (2) - */ -#define WM8996_AIF2TX_DAT_TRI 0x0001 /* AIF2TX_DAT_TRI */ -#define WM8996_AIF2TX_DAT_TRI_MASK 0x0001 /* AIF2TX_DAT_TRI */ -#define WM8996_AIF2TX_DAT_TRI_SHIFT 0 /* AIF2TX_DAT_TRI */ -#define WM8996_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */ - -/* - * R808 (0x328) - AIF2RX Data Configuration - */ -#define WM8996_AIF2RX_WL_MASK 0xFF00 /* AIF2RX_WL - [15:8] */ -#define WM8996_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [15:8] */ -#define WM8996_AIF2RX_WL_WIDTH 8 /* AIF2RX_WL - [15:8] */ -#define WM8996_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */ -#define WM8996_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */ -#define WM8996_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */ - -/* - * R809 (0x329) - AIF2TX Channel 0 Configuration - */ -#define WM8996_AIF2TX_CHAN0_DAT_INV 0x8000 /* AIF2TX_CHAN0_DAT_INV */ -#define WM8996_AIF2TX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN0_DAT_INV */ -#define WM8996_AIF2TX_CHAN0_DAT_INV_SHIFT 15 /* AIF2TX_CHAN0_DAT_INV */ -#define WM8996_AIF2TX_CHAN0_DAT_INV_WIDTH 1 /* AIF2TX_CHAN0_DAT_INV */ -#define WM8996_AIF2TX_CHAN0_SPACING_MASK 0x7E00 /* AIF2TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN0_SPACING_SHIFT 9 /* AIF2TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN0_SPACING_WIDTH 6 /* AIF2TX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN0_SLOTS_SHIFT 6 /* AIF2TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN0_SLOTS_WIDTH 3 /* AIF2TX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN0_START_SLOT_MASK 0x003F /* AIF2TX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF2TX_CHAN0_START_SLOT_SHIFT 0 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF2TX_CHAN0_START_SLOT_WIDTH 6 /* AIF2TX_CHAN0_START_SLOT - [5:0] */ - -/* - * R810 (0x32A) - AIF2TX Channel 1 Configuration - */ -#define WM8996_AIF2TX_CHAN1_DAT_INV 0x8000 /* AIF2TX_CHAN1_DAT_INV */ -#define WM8996_AIF2TX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2TX_CHAN1_DAT_INV */ -#define WM8996_AIF2TX_CHAN1_DAT_INV_SHIFT 15 /* AIF2TX_CHAN1_DAT_INV */ -#define WM8996_AIF2TX_CHAN1_DAT_INV_WIDTH 1 /* AIF2TX_CHAN1_DAT_INV */ -#define WM8996_AIF2TX_CHAN1_SPACING_MASK 0x7E00 /* AIF2TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN1_SPACING_SHIFT 9 /* AIF2TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN1_SPACING_WIDTH 6 /* AIF2TX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2TX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN1_SLOTS_SHIFT 6 /* AIF2TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN1_SLOTS_WIDTH 3 /* AIF2TX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2TX_CHAN1_START_SLOT_MASK 0x003F /* AIF2TX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF2TX_CHAN1_START_SLOT_SHIFT 0 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF2TX_CHAN1_START_SLOT_WIDTH 6 /* AIF2TX_CHAN1_START_SLOT - [5:0] */ - -/* - * R811 (0x32B) - AIF2RX Channel 0 Configuration - */ -#define WM8996_AIF2RX_CHAN0_DAT_INV 0x8000 /* AIF2RX_CHAN0_DAT_INV */ -#define WM8996_AIF2RX_CHAN0_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN0_DAT_INV */ -#define WM8996_AIF2RX_CHAN0_DAT_INV_SHIFT 15 /* AIF2RX_CHAN0_DAT_INV */ -#define WM8996_AIF2RX_CHAN0_DAT_INV_WIDTH 1 /* AIF2RX_CHAN0_DAT_INV */ -#define WM8996_AIF2RX_CHAN0_SPACING_MASK 0x7E00 /* AIF2RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN0_SPACING_SHIFT 9 /* AIF2RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN0_SPACING_WIDTH 6 /* AIF2RX_CHAN0_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN0_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN0_SLOTS_SHIFT 6 /* AIF2RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN0_SLOTS_WIDTH 3 /* AIF2RX_CHAN0_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN0_START_SLOT_MASK 0x003F /* AIF2RX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF2RX_CHAN0_START_SLOT_SHIFT 0 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ -#define WM8996_AIF2RX_CHAN0_START_SLOT_WIDTH 6 /* AIF2RX_CHAN0_START_SLOT - [5:0] */ - -/* - * R812 (0x32C) - AIF2RX Channel 1 Configuration - */ -#define WM8996_AIF2RX_CHAN1_DAT_INV 0x8000 /* AIF2RX_CHAN1_DAT_INV */ -#define WM8996_AIF2RX_CHAN1_DAT_INV_MASK 0x8000 /* AIF2RX_CHAN1_DAT_INV */ -#define WM8996_AIF2RX_CHAN1_DAT_INV_SHIFT 15 /* AIF2RX_CHAN1_DAT_INV */ -#define WM8996_AIF2RX_CHAN1_DAT_INV_WIDTH 1 /* AIF2RX_CHAN1_DAT_INV */ -#define WM8996_AIF2RX_CHAN1_SPACING_MASK 0x7E00 /* AIF2RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN1_SPACING_SHIFT 9 /* AIF2RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN1_SPACING_WIDTH 6 /* AIF2RX_CHAN1_SPACING - [14:9] */ -#define WM8996_AIF2RX_CHAN1_SLOTS_MASK 0x01C0 /* AIF2RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN1_SLOTS_SHIFT 6 /* AIF2RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN1_SLOTS_WIDTH 3 /* AIF2RX_CHAN1_SLOTS - [8:6] */ -#define WM8996_AIF2RX_CHAN1_START_SLOT_MASK 0x003F /* AIF2RX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF2RX_CHAN1_START_SLOT_SHIFT 0 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ -#define WM8996_AIF2RX_CHAN1_START_SLOT_WIDTH 6 /* AIF2RX_CHAN1_START_SLOT - [5:0] */ - -/* - * R813 (0x32D) - AIF2RX Mono Configuration - */ -#define WM8996_AIF2RX_CHAN0_MONO_MODE 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ -#define WM8996_AIF2RX_CHAN0_MONO_MODE_MASK 0x0001 /* AIF2RX_CHAN0_MONO_MODE */ -#define WM8996_AIF2RX_CHAN0_MONO_MODE_SHIFT 0 /* AIF2RX_CHAN0_MONO_MODE */ -#define WM8996_AIF2RX_CHAN0_MONO_MODE_WIDTH 1 /* AIF2RX_CHAN0_MONO_MODE */ - -/* - * R815 (0x32F) - AIF2TX Test - */ -#define WM8996_AIF2TX_DITHER_ENA 0x0001 /* AIF2TX_DITHER_ENA */ -#define WM8996_AIF2TX_DITHER_ENA_MASK 0x0001 /* AIF2TX_DITHER_ENA */ -#define WM8996_AIF2TX_DITHER_ENA_SHIFT 0 /* AIF2TX_DITHER_ENA */ -#define WM8996_AIF2TX_DITHER_ENA_WIDTH 1 /* AIF2TX_DITHER_ENA */ - -/* - * R1024 (0x400) - DSP1 TX Left Volume - */ -#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ -#define WM8996_DSP1TXL_VOL_MASK 0x00FF /* DSP1TXL_VOL - [7:0] */ -#define WM8996_DSP1TXL_VOL_SHIFT 0 /* DSP1TXL_VOL - [7:0] */ -#define WM8996_DSP1TXL_VOL_WIDTH 8 /* DSP1TXL_VOL - [7:0] */ - -/* - * R1025 (0x401) - DSP1 TX Right Volume - */ -#define WM8996_DSP1TX_VU 0x0100 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_MASK 0x0100 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_SHIFT 8 /* DSP1TX_VU */ -#define WM8996_DSP1TX_VU_WIDTH 1 /* DSP1TX_VU */ -#define WM8996_DSP1TXR_VOL_MASK 0x00FF /* DSP1TXR_VOL - [7:0] */ -#define WM8996_DSP1TXR_VOL_SHIFT 0 /* DSP1TXR_VOL - [7:0] */ -#define WM8996_DSP1TXR_VOL_WIDTH 8 /* DSP1TXR_VOL - [7:0] */ - -/* - * R1026 (0x402) - DSP1 RX Left Volume - */ -#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ -#define WM8996_DSP1RXL_VOL_MASK 0x00FF /* DSP1RXL_VOL - [7:0] */ -#define WM8996_DSP1RXL_VOL_SHIFT 0 /* DSP1RXL_VOL - [7:0] */ -#define WM8996_DSP1RXL_VOL_WIDTH 8 /* DSP1RXL_VOL - [7:0] */ - -/* - * R1027 (0x403) - DSP1 RX Right Volume - */ -#define WM8996_DSP1RX_VU 0x0100 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_MASK 0x0100 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_SHIFT 8 /* DSP1RX_VU */ -#define WM8996_DSP1RX_VU_WIDTH 1 /* DSP1RX_VU */ -#define WM8996_DSP1RXR_VOL_MASK 0x00FF /* DSP1RXR_VOL - [7:0] */ -#define WM8996_DSP1RXR_VOL_SHIFT 0 /* DSP1RXR_VOL - [7:0] */ -#define WM8996_DSP1RXR_VOL_WIDTH 8 /* DSP1RXR_VOL - [7:0] */ - -/* - * R1040 (0x410) - DSP1 TX Filters - */ -#define WM8996_DSP1TX_NF 0x2000 /* DSP1TX_NF */ -#define WM8996_DSP1TX_NF_MASK 0x2000 /* DSP1TX_NF */ -#define WM8996_DSP1TX_NF_SHIFT 13 /* DSP1TX_NF */ -#define WM8996_DSP1TX_NF_WIDTH 1 /* DSP1TX_NF */ -#define WM8996_DSP1TXL_HPF 0x1000 /* DSP1TXL_HPF */ -#define WM8996_DSP1TXL_HPF_MASK 0x1000 /* DSP1TXL_HPF */ -#define WM8996_DSP1TXL_HPF_SHIFT 12 /* DSP1TXL_HPF */ -#define WM8996_DSP1TXL_HPF_WIDTH 1 /* DSP1TXL_HPF */ -#define WM8996_DSP1TXR_HPF 0x0800 /* DSP1TXR_HPF */ -#define WM8996_DSP1TXR_HPF_MASK 0x0800 /* DSP1TXR_HPF */ -#define WM8996_DSP1TXR_HPF_SHIFT 11 /* DSP1TXR_HPF */ -#define WM8996_DSP1TXR_HPF_WIDTH 1 /* DSP1TXR_HPF */ -#define WM8996_DSP1TX_HPF_MODE_MASK 0x0018 /* DSP1TX_HPF_MODE - [4:3] */ -#define WM8996_DSP1TX_HPF_MODE_SHIFT 3 /* DSP1TX_HPF_MODE - [4:3] */ -#define WM8996_DSP1TX_HPF_MODE_WIDTH 2 /* DSP1TX_HPF_MODE - [4:3] */ -#define WM8996_DSP1TX_HPF_CUT_MASK 0x0007 /* DSP1TX_HPF_CUT - [2:0] */ -#define WM8996_DSP1TX_HPF_CUT_SHIFT 0 /* DSP1TX_HPF_CUT - [2:0] */ -#define WM8996_DSP1TX_HPF_CUT_WIDTH 3 /* DSP1TX_HPF_CUT - [2:0] */ - -/* - * R1056 (0x420) - DSP1 RX Filters (1) - */ -#define WM8996_DSP1RX_MUTE 0x0200 /* DSP1RX_MUTE */ -#define WM8996_DSP1RX_MUTE_MASK 0x0200 /* DSP1RX_MUTE */ -#define WM8996_DSP1RX_MUTE_SHIFT 9 /* DSP1RX_MUTE */ -#define WM8996_DSP1RX_MUTE_WIDTH 1 /* DSP1RX_MUTE */ -#define WM8996_DSP1RX_MONO 0x0080 /* DSP1RX_MONO */ -#define WM8996_DSP1RX_MONO_MASK 0x0080 /* DSP1RX_MONO */ -#define WM8996_DSP1RX_MONO_SHIFT 7 /* DSP1RX_MONO */ -#define WM8996_DSP1RX_MONO_WIDTH 1 /* DSP1RX_MONO */ -#define WM8996_DSP1RX_MUTERATE 0x0020 /* DSP1RX_MUTERATE */ -#define WM8996_DSP1RX_MUTERATE_MASK 0x0020 /* DSP1RX_MUTERATE */ -#define WM8996_DSP1RX_MUTERATE_SHIFT 5 /* DSP1RX_MUTERATE */ -#define WM8996_DSP1RX_MUTERATE_WIDTH 1 /* DSP1RX_MUTERATE */ -#define WM8996_DSP1RX_UNMUTE_RAMP 0x0010 /* DSP1RX_UNMUTE_RAMP */ -#define WM8996_DSP1RX_UNMUTE_RAMP_MASK 0x0010 /* DSP1RX_UNMUTE_RAMP */ -#define WM8996_DSP1RX_UNMUTE_RAMP_SHIFT 4 /* DSP1RX_UNMUTE_RAMP */ -#define WM8996_DSP1RX_UNMUTE_RAMP_WIDTH 1 /* DSP1RX_UNMUTE_RAMP */ - -/* - * R1057 (0x421) - DSP1 RX Filters (2) - */ -#define WM8996_DSP1RX_3D_GAIN_MASK 0x3E00 /* DSP1RX_3D_GAIN - [13:9] */ -#define WM8996_DSP1RX_3D_GAIN_SHIFT 9 /* DSP1RX_3D_GAIN - [13:9] */ -#define WM8996_DSP1RX_3D_GAIN_WIDTH 5 /* DSP1RX_3D_GAIN - [13:9] */ -#define WM8996_DSP1RX_3D_ENA 0x0100 /* DSP1RX_3D_ENA */ -#define WM8996_DSP1RX_3D_ENA_MASK 0x0100 /* DSP1RX_3D_ENA */ -#define WM8996_DSP1RX_3D_ENA_SHIFT 8 /* DSP1RX_3D_ENA */ -#define WM8996_DSP1RX_3D_ENA_WIDTH 1 /* DSP1RX_3D_ENA */ - -/* - * R1088 (0x440) - DSP1 DRC (1) - */ -#define WM8996_DSP1DRC_SIG_DET_RMS_MASK 0xF800 /* DSP1DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP1DRC_SIG_DET_RMS_SHIFT 11 /* DSP1DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP1DRC_SIG_DET_RMS_WIDTH 5 /* DSP1DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP1DRC_SIG_DET_PK_MASK 0x0600 /* DSP1DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP1DRC_SIG_DET_PK_SHIFT 9 /* DSP1DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP1DRC_SIG_DET_PK_WIDTH 2 /* DSP1DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP1DRC_NG_ENA 0x0100 /* DSP1DRC_NG_ENA */ -#define WM8996_DSP1DRC_NG_ENA_MASK 0x0100 /* DSP1DRC_NG_ENA */ -#define WM8996_DSP1DRC_NG_ENA_SHIFT 8 /* DSP1DRC_NG_ENA */ -#define WM8996_DSP1DRC_NG_ENA_WIDTH 1 /* DSP1DRC_NG_ENA */ -#define WM8996_DSP1DRC_SIG_DET_MODE 0x0080 /* DSP1DRC_SIG_DET_MODE */ -#define WM8996_DSP1DRC_SIG_DET_MODE_MASK 0x0080 /* DSP1DRC_SIG_DET_MODE */ -#define WM8996_DSP1DRC_SIG_DET_MODE_SHIFT 7 /* DSP1DRC_SIG_DET_MODE */ -#define WM8996_DSP1DRC_SIG_DET_MODE_WIDTH 1 /* DSP1DRC_SIG_DET_MODE */ -#define WM8996_DSP1DRC_SIG_DET 0x0040 /* DSP1DRC_SIG_DET */ -#define WM8996_DSP1DRC_SIG_DET_MASK 0x0040 /* DSP1DRC_SIG_DET */ -#define WM8996_DSP1DRC_SIG_DET_SHIFT 6 /* DSP1DRC_SIG_DET */ -#define WM8996_DSP1DRC_SIG_DET_WIDTH 1 /* DSP1DRC_SIG_DET */ -#define WM8996_DSP1DRC_KNEE2_OP_ENA 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ -#define WM8996_DSP1DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP1DRC_KNEE2_OP_ENA */ -#define WM8996_DSP1DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP1DRC_KNEE2_OP_ENA */ -#define WM8996_DSP1DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP1DRC_KNEE2_OP_ENA */ -#define WM8996_DSP1DRC_QR 0x0010 /* DSP1DRC_QR */ -#define WM8996_DSP1DRC_QR_MASK 0x0010 /* DSP1DRC_QR */ -#define WM8996_DSP1DRC_QR_SHIFT 4 /* DSP1DRC_QR */ -#define WM8996_DSP1DRC_QR_WIDTH 1 /* DSP1DRC_QR */ -#define WM8996_DSP1DRC_ANTICLIP 0x0008 /* DSP1DRC_ANTICLIP */ -#define WM8996_DSP1DRC_ANTICLIP_MASK 0x0008 /* DSP1DRC_ANTICLIP */ -#define WM8996_DSP1DRC_ANTICLIP_SHIFT 3 /* DSP1DRC_ANTICLIP */ -#define WM8996_DSP1DRC_ANTICLIP_WIDTH 1 /* DSP1DRC_ANTICLIP */ -#define WM8996_DSP1RX_DRC_ENA 0x0004 /* DSP1RX_DRC_ENA */ -#define WM8996_DSP1RX_DRC_ENA_MASK 0x0004 /* DSP1RX_DRC_ENA */ -#define WM8996_DSP1RX_DRC_ENA_SHIFT 2 /* DSP1RX_DRC_ENA */ -#define WM8996_DSP1RX_DRC_ENA_WIDTH 1 /* DSP1RX_DRC_ENA */ -#define WM8996_DSP1TXL_DRC_ENA 0x0002 /* DSP1TXL_DRC_ENA */ -#define WM8996_DSP1TXL_DRC_ENA_MASK 0x0002 /* DSP1TXL_DRC_ENA */ -#define WM8996_DSP1TXL_DRC_ENA_SHIFT 1 /* DSP1TXL_DRC_ENA */ -#define WM8996_DSP1TXL_DRC_ENA_WIDTH 1 /* DSP1TXL_DRC_ENA */ -#define WM8996_DSP1TXR_DRC_ENA 0x0001 /* DSP1TXR_DRC_ENA */ -#define WM8996_DSP1TXR_DRC_ENA_MASK 0x0001 /* DSP1TXR_DRC_ENA */ -#define WM8996_DSP1TXR_DRC_ENA_SHIFT 0 /* DSP1TXR_DRC_ENA */ -#define WM8996_DSP1TXR_DRC_ENA_WIDTH 1 /* DSP1TXR_DRC_ENA */ - -/* - * R1089 (0x441) - DSP1 DRC (2) - */ -#define WM8996_DSP1DRC_ATK_MASK 0x1E00 /* DSP1DRC_ATK - [12:9] */ -#define WM8996_DSP1DRC_ATK_SHIFT 9 /* DSP1DRC_ATK - [12:9] */ -#define WM8996_DSP1DRC_ATK_WIDTH 4 /* DSP1DRC_ATK - [12:9] */ -#define WM8996_DSP1DRC_DCY_MASK 0x01E0 /* DSP1DRC_DCY - [8:5] */ -#define WM8996_DSP1DRC_DCY_SHIFT 5 /* DSP1DRC_DCY - [8:5] */ -#define WM8996_DSP1DRC_DCY_WIDTH 4 /* DSP1DRC_DCY - [8:5] */ -#define WM8996_DSP1DRC_MINGAIN_MASK 0x001C /* DSP1DRC_MINGAIN - [4:2] */ -#define WM8996_DSP1DRC_MINGAIN_SHIFT 2 /* DSP1DRC_MINGAIN - [4:2] */ -#define WM8996_DSP1DRC_MINGAIN_WIDTH 3 /* DSP1DRC_MINGAIN - [4:2] */ -#define WM8996_DSP1DRC_MAXGAIN_MASK 0x0003 /* DSP1DRC_MAXGAIN - [1:0] */ -#define WM8996_DSP1DRC_MAXGAIN_SHIFT 0 /* DSP1DRC_MAXGAIN - [1:0] */ -#define WM8996_DSP1DRC_MAXGAIN_WIDTH 2 /* DSP1DRC_MAXGAIN - [1:0] */ - -/* - * R1090 (0x442) - DSP1 DRC (3) - */ -#define WM8996_DSP1DRC_NG_MINGAIN_MASK 0xF000 /* DSP1DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP1DRC_NG_MINGAIN_SHIFT 12 /* DSP1DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP1DRC_NG_MINGAIN_WIDTH 4 /* DSP1DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP1DRC_NG_EXP_MASK 0x0C00 /* DSP1DRC_NG_EXP - [11:10] */ -#define WM8996_DSP1DRC_NG_EXP_SHIFT 10 /* DSP1DRC_NG_EXP - [11:10] */ -#define WM8996_DSP1DRC_NG_EXP_WIDTH 2 /* DSP1DRC_NG_EXP - [11:10] */ -#define WM8996_DSP1DRC_QR_THR_MASK 0x0300 /* DSP1DRC_QR_THR - [9:8] */ -#define WM8996_DSP1DRC_QR_THR_SHIFT 8 /* DSP1DRC_QR_THR - [9:8] */ -#define WM8996_DSP1DRC_QR_THR_WIDTH 2 /* DSP1DRC_QR_THR - [9:8] */ -#define WM8996_DSP1DRC_QR_DCY_MASK 0x00C0 /* DSP1DRC_QR_DCY - [7:6] */ -#define WM8996_DSP1DRC_QR_DCY_SHIFT 6 /* DSP1DRC_QR_DCY - [7:6] */ -#define WM8996_DSP1DRC_QR_DCY_WIDTH 2 /* DSP1DRC_QR_DCY - [7:6] */ -#define WM8996_DSP1DRC_HI_COMP_MASK 0x0038 /* DSP1DRC_HI_COMP - [5:3] */ -#define WM8996_DSP1DRC_HI_COMP_SHIFT 3 /* DSP1DRC_HI_COMP - [5:3] */ -#define WM8996_DSP1DRC_HI_COMP_WIDTH 3 /* DSP1DRC_HI_COMP - [5:3] */ -#define WM8996_DSP1DRC_LO_COMP_MASK 0x0007 /* DSP1DRC_LO_COMP - [2:0] */ -#define WM8996_DSP1DRC_LO_COMP_SHIFT 0 /* DSP1DRC_LO_COMP - [2:0] */ -#define WM8996_DSP1DRC_LO_COMP_WIDTH 3 /* DSP1DRC_LO_COMP - [2:0] */ - -/* - * R1091 (0x443) - DSP1 DRC (4) - */ -#define WM8996_DSP1DRC_KNEE_IP_MASK 0x07E0 /* DSP1DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP1DRC_KNEE_IP_SHIFT 5 /* DSP1DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP1DRC_KNEE_IP_WIDTH 6 /* DSP1DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP1DRC_KNEE_OP_MASK 0x001F /* DSP1DRC_KNEE_OP - [4:0] */ -#define WM8996_DSP1DRC_KNEE_OP_SHIFT 0 /* DSP1DRC_KNEE_OP - [4:0] */ -#define WM8996_DSP1DRC_KNEE_OP_WIDTH 5 /* DSP1DRC_KNEE_OP - [4:0] */ - -/* - * R1092 (0x444) - DSP1 DRC (5) - */ -#define WM8996_DSP1DRC_KNEE2_IP_MASK 0x03E0 /* DSP1DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP1DRC_KNEE2_IP_SHIFT 5 /* DSP1DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP1DRC_KNEE2_IP_WIDTH 5 /* DSP1DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP1DRC_KNEE2_OP_MASK 0x001F /* DSP1DRC_KNEE2_OP - [4:0] */ -#define WM8996_DSP1DRC_KNEE2_OP_SHIFT 0 /* DSP1DRC_KNEE2_OP - [4:0] */ -#define WM8996_DSP1DRC_KNEE2_OP_WIDTH 5 /* DSP1DRC_KNEE2_OP - [4:0] */ - -/* - * R1152 (0x480) - DSP1 RX EQ Gains (1) - */ -#define WM8996_DSP1RX_EQ_B1_GAIN_MASK 0xF800 /* DSP1RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B1_GAIN_SHIFT 11 /* DSP1RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B1_GAIN_WIDTH 5 /* DSP1RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP1RX_EQ_B2_GAIN_SHIFT 6 /* DSP1RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP1RX_EQ_B2_GAIN_WIDTH 5 /* DSP1RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP1RX_EQ_B3_GAIN_MASK 0x003E /* DSP1RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP1RX_EQ_B3_GAIN_SHIFT 1 /* DSP1RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP1RX_EQ_B3_GAIN_WIDTH 5 /* DSP1RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP1RX_EQ_ENA 0x0001 /* DSP1RX_EQ_ENA */ -#define WM8996_DSP1RX_EQ_ENA_MASK 0x0001 /* DSP1RX_EQ_ENA */ -#define WM8996_DSP1RX_EQ_ENA_SHIFT 0 /* DSP1RX_EQ_ENA */ -#define WM8996_DSP1RX_EQ_ENA_WIDTH 1 /* DSP1RX_EQ_ENA */ - -/* - * R1153 (0x481) - DSP1 RX EQ Gains (2) - */ -#define WM8996_DSP1RX_EQ_B4_GAIN_MASK 0xF800 /* DSP1RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B4_GAIN_SHIFT 11 /* DSP1RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B4_GAIN_WIDTH 5 /* DSP1RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP1RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP1RX_EQ_B5_GAIN - [10:6] */ -#define WM8996_DSP1RX_EQ_B5_GAIN_SHIFT 6 /* DSP1RX_EQ_B5_GAIN - [10:6] */ -#define WM8996_DSP1RX_EQ_B5_GAIN_WIDTH 5 /* DSP1RX_EQ_B5_GAIN - [10:6] */ - -/* - * R1154 (0x482) - DSP1 RX EQ Band 1 A - */ -#define WM8996_DSP1RX_EQ_B1_A_MASK 0xFFFF /* DSP1RX_EQ_B1_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_A_SHIFT 0 /* DSP1RX_EQ_B1_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_A_WIDTH 16 /* DSP1RX_EQ_B1_A - [15:0] */ - -/* - * R1155 (0x483) - DSP1 RX EQ Band 1 B - */ -#define WM8996_DSP1RX_EQ_B1_B_MASK 0xFFFF /* DSP1RX_EQ_B1_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_B_SHIFT 0 /* DSP1RX_EQ_B1_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_B_WIDTH 16 /* DSP1RX_EQ_B1_B - [15:0] */ - -/* - * R1156 (0x484) - DSP1 RX EQ Band 1 PG - */ -#define WM8996_DSP1RX_EQ_B1_PG_MASK 0xFFFF /* DSP1RX_EQ_B1_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_PG_SHIFT 0 /* DSP1RX_EQ_B1_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B1_PG_WIDTH 16 /* DSP1RX_EQ_B1_PG - [15:0] */ - -/* - * R1157 (0x485) - DSP1 RX EQ Band 2 A - */ -#define WM8996_DSP1RX_EQ_B2_A_MASK 0xFFFF /* DSP1RX_EQ_B2_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_A_SHIFT 0 /* DSP1RX_EQ_B2_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_A_WIDTH 16 /* DSP1RX_EQ_B2_A - [15:0] */ - -/* - * R1158 (0x486) - DSP1 RX EQ Band 2 B - */ -#define WM8996_DSP1RX_EQ_B2_B_MASK 0xFFFF /* DSP1RX_EQ_B2_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_B_SHIFT 0 /* DSP1RX_EQ_B2_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_B_WIDTH 16 /* DSP1RX_EQ_B2_B - [15:0] */ - -/* - * R1159 (0x487) - DSP1 RX EQ Band 2 C - */ -#define WM8996_DSP1RX_EQ_B2_C_MASK 0xFFFF /* DSP1RX_EQ_B2_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_C_SHIFT 0 /* DSP1RX_EQ_B2_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_C_WIDTH 16 /* DSP1RX_EQ_B2_C - [15:0] */ - -/* - * R1160 (0x488) - DSP1 RX EQ Band 2 PG - */ -#define WM8996_DSP1RX_EQ_B2_PG_MASK 0xFFFF /* DSP1RX_EQ_B2_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_PG_SHIFT 0 /* DSP1RX_EQ_B2_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B2_PG_WIDTH 16 /* DSP1RX_EQ_B2_PG - [15:0] */ - -/* - * R1161 (0x489) - DSP1 RX EQ Band 3 A - */ -#define WM8996_DSP1RX_EQ_B3_A_MASK 0xFFFF /* DSP1RX_EQ_B3_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_A_SHIFT 0 /* DSP1RX_EQ_B3_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_A_WIDTH 16 /* DSP1RX_EQ_B3_A - [15:0] */ - -/* - * R1162 (0x48A) - DSP1 RX EQ Band 3 B - */ -#define WM8996_DSP1RX_EQ_B3_B_MASK 0xFFFF /* DSP1RX_EQ_B3_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_B_SHIFT 0 /* DSP1RX_EQ_B3_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_B_WIDTH 16 /* DSP1RX_EQ_B3_B - [15:0] */ - -/* - * R1163 (0x48B) - DSP1 RX EQ Band 3 C - */ -#define WM8996_DSP1RX_EQ_B3_C_MASK 0xFFFF /* DSP1RX_EQ_B3_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_C_SHIFT 0 /* DSP1RX_EQ_B3_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_C_WIDTH 16 /* DSP1RX_EQ_B3_C - [15:0] */ - -/* - * R1164 (0x48C) - DSP1 RX EQ Band 3 PG - */ -#define WM8996_DSP1RX_EQ_B3_PG_MASK 0xFFFF /* DSP1RX_EQ_B3_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_PG_SHIFT 0 /* DSP1RX_EQ_B3_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B3_PG_WIDTH 16 /* DSP1RX_EQ_B3_PG - [15:0] */ - -/* - * R1165 (0x48D) - DSP1 RX EQ Band 4 A - */ -#define WM8996_DSP1RX_EQ_B4_A_MASK 0xFFFF /* DSP1RX_EQ_B4_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_A_SHIFT 0 /* DSP1RX_EQ_B4_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_A_WIDTH 16 /* DSP1RX_EQ_B4_A - [15:0] */ - -/* - * R1166 (0x48E) - DSP1 RX EQ Band 4 B - */ -#define WM8996_DSP1RX_EQ_B4_B_MASK 0xFFFF /* DSP1RX_EQ_B4_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_B_SHIFT 0 /* DSP1RX_EQ_B4_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_B_WIDTH 16 /* DSP1RX_EQ_B4_B - [15:0] */ - -/* - * R1167 (0x48F) - DSP1 RX EQ Band 4 C - */ -#define WM8996_DSP1RX_EQ_B4_C_MASK 0xFFFF /* DSP1RX_EQ_B4_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_C_SHIFT 0 /* DSP1RX_EQ_B4_C - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_C_WIDTH 16 /* DSP1RX_EQ_B4_C - [15:0] */ - -/* - * R1168 (0x490) - DSP1 RX EQ Band 4 PG - */ -#define WM8996_DSP1RX_EQ_B4_PG_MASK 0xFFFF /* DSP1RX_EQ_B4_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_PG_SHIFT 0 /* DSP1RX_EQ_B4_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B4_PG_WIDTH 16 /* DSP1RX_EQ_B4_PG - [15:0] */ - -/* - * R1169 (0x491) - DSP1 RX EQ Band 5 A - */ -#define WM8996_DSP1RX_EQ_B5_A_MASK 0xFFFF /* DSP1RX_EQ_B5_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_A_SHIFT 0 /* DSP1RX_EQ_B5_A - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_A_WIDTH 16 /* DSP1RX_EQ_B5_A - [15:0] */ - -/* - * R1170 (0x492) - DSP1 RX EQ Band 5 B - */ -#define WM8996_DSP1RX_EQ_B5_B_MASK 0xFFFF /* DSP1RX_EQ_B5_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_B_SHIFT 0 /* DSP1RX_EQ_B5_B - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_B_WIDTH 16 /* DSP1RX_EQ_B5_B - [15:0] */ - -/* - * R1171 (0x493) - DSP1 RX EQ Band 5 PG - */ -#define WM8996_DSP1RX_EQ_B5_PG_MASK 0xFFFF /* DSP1RX_EQ_B5_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_PG_SHIFT 0 /* DSP1RX_EQ_B5_PG - [15:0] */ -#define WM8996_DSP1RX_EQ_B5_PG_WIDTH 16 /* DSP1RX_EQ_B5_PG - [15:0] */ - -/* - * R1280 (0x500) - DSP2 TX Left Volume - */ -#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ -#define WM8996_DSP2TXL_VOL_MASK 0x00FF /* DSP2TXL_VOL - [7:0] */ -#define WM8996_DSP2TXL_VOL_SHIFT 0 /* DSP2TXL_VOL - [7:0] */ -#define WM8996_DSP2TXL_VOL_WIDTH 8 /* DSP2TXL_VOL - [7:0] */ - -/* - * R1281 (0x501) - DSP2 TX Right Volume - */ -#define WM8996_DSP2TX_VU 0x0100 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_MASK 0x0100 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_SHIFT 8 /* DSP2TX_VU */ -#define WM8996_DSP2TX_VU_WIDTH 1 /* DSP2TX_VU */ -#define WM8996_DSP2TXR_VOL_MASK 0x00FF /* DSP2TXR_VOL - [7:0] */ -#define WM8996_DSP2TXR_VOL_SHIFT 0 /* DSP2TXR_VOL - [7:0] */ -#define WM8996_DSP2TXR_VOL_WIDTH 8 /* DSP2TXR_VOL - [7:0] */ - -/* - * R1282 (0x502) - DSP2 RX Left Volume - */ -#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ -#define WM8996_DSP2RXL_VOL_MASK 0x00FF /* DSP2RXL_VOL - [7:0] */ -#define WM8996_DSP2RXL_VOL_SHIFT 0 /* DSP2RXL_VOL - [7:0] */ -#define WM8996_DSP2RXL_VOL_WIDTH 8 /* DSP2RXL_VOL - [7:0] */ - -/* - * R1283 (0x503) - DSP2 RX Right Volume - */ -#define WM8996_DSP2RX_VU 0x0100 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_MASK 0x0100 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_SHIFT 8 /* DSP2RX_VU */ -#define WM8996_DSP2RX_VU_WIDTH 1 /* DSP2RX_VU */ -#define WM8996_DSP2RXR_VOL_MASK 0x00FF /* DSP2RXR_VOL - [7:0] */ -#define WM8996_DSP2RXR_VOL_SHIFT 0 /* DSP2RXR_VOL - [7:0] */ -#define WM8996_DSP2RXR_VOL_WIDTH 8 /* DSP2RXR_VOL - [7:0] */ - -/* - * R1296 (0x510) - DSP2 TX Filters - */ -#define WM8996_DSP2TX_NF 0x2000 /* DSP2TX_NF */ -#define WM8996_DSP2TX_NF_MASK 0x2000 /* DSP2TX_NF */ -#define WM8996_DSP2TX_NF_SHIFT 13 /* DSP2TX_NF */ -#define WM8996_DSP2TX_NF_WIDTH 1 /* DSP2TX_NF */ -#define WM8996_DSP2TXL_HPF 0x1000 /* DSP2TXL_HPF */ -#define WM8996_DSP2TXL_HPF_MASK 0x1000 /* DSP2TXL_HPF */ -#define WM8996_DSP2TXL_HPF_SHIFT 12 /* DSP2TXL_HPF */ -#define WM8996_DSP2TXL_HPF_WIDTH 1 /* DSP2TXL_HPF */ -#define WM8996_DSP2TXR_HPF 0x0800 /* DSP2TXR_HPF */ -#define WM8996_DSP2TXR_HPF_MASK 0x0800 /* DSP2TXR_HPF */ -#define WM8996_DSP2TXR_HPF_SHIFT 11 /* DSP2TXR_HPF */ -#define WM8996_DSP2TXR_HPF_WIDTH 1 /* DSP2TXR_HPF */ -#define WM8996_DSP2TX_HPF_MODE_MASK 0x0018 /* DSP2TX_HPF_MODE - [4:3] */ -#define WM8996_DSP2TX_HPF_MODE_SHIFT 3 /* DSP2TX_HPF_MODE - [4:3] */ -#define WM8996_DSP2TX_HPF_MODE_WIDTH 2 /* DSP2TX_HPF_MODE - [4:3] */ -#define WM8996_DSP2TX_HPF_CUT_MASK 0x0007 /* DSP2TX_HPF_CUT - [2:0] */ -#define WM8996_DSP2TX_HPF_CUT_SHIFT 0 /* DSP2TX_HPF_CUT - [2:0] */ -#define WM8996_DSP2TX_HPF_CUT_WIDTH 3 /* DSP2TX_HPF_CUT - [2:0] */ - -/* - * R1312 (0x520) - DSP2 RX Filters (1) - */ -#define WM8996_DSP2RX_MUTE 0x0200 /* DSP2RX_MUTE */ -#define WM8996_DSP2RX_MUTE_MASK 0x0200 /* DSP2RX_MUTE */ -#define WM8996_DSP2RX_MUTE_SHIFT 9 /* DSP2RX_MUTE */ -#define WM8996_DSP2RX_MUTE_WIDTH 1 /* DSP2RX_MUTE */ -#define WM8996_DSP2RX_MONO 0x0080 /* DSP2RX_MONO */ -#define WM8996_DSP2RX_MONO_MASK 0x0080 /* DSP2RX_MONO */ -#define WM8996_DSP2RX_MONO_SHIFT 7 /* DSP2RX_MONO */ -#define WM8996_DSP2RX_MONO_WIDTH 1 /* DSP2RX_MONO */ -#define WM8996_DSP2RX_MUTERATE 0x0020 /* DSP2RX_MUTERATE */ -#define WM8996_DSP2RX_MUTERATE_MASK 0x0020 /* DSP2RX_MUTERATE */ -#define WM8996_DSP2RX_MUTERATE_SHIFT 5 /* DSP2RX_MUTERATE */ -#define WM8996_DSP2RX_MUTERATE_WIDTH 1 /* DSP2RX_MUTERATE */ -#define WM8996_DSP2RX_UNMUTE_RAMP 0x0010 /* DSP2RX_UNMUTE_RAMP */ -#define WM8996_DSP2RX_UNMUTE_RAMP_MASK 0x0010 /* DSP2RX_UNMUTE_RAMP */ -#define WM8996_DSP2RX_UNMUTE_RAMP_SHIFT 4 /* DSP2RX_UNMUTE_RAMP */ -#define WM8996_DSP2RX_UNMUTE_RAMP_WIDTH 1 /* DSP2RX_UNMUTE_RAMP */ - -/* - * R1313 (0x521) - DSP2 RX Filters (2) - */ -#define WM8996_DSP2RX_3D_GAIN_MASK 0x3E00 /* DSP2RX_3D_GAIN - [13:9] */ -#define WM8996_DSP2RX_3D_GAIN_SHIFT 9 /* DSP2RX_3D_GAIN - [13:9] */ -#define WM8996_DSP2RX_3D_GAIN_WIDTH 5 /* DSP2RX_3D_GAIN - [13:9] */ -#define WM8996_DSP2RX_3D_ENA 0x0100 /* DSP2RX_3D_ENA */ -#define WM8996_DSP2RX_3D_ENA_MASK 0x0100 /* DSP2RX_3D_ENA */ -#define WM8996_DSP2RX_3D_ENA_SHIFT 8 /* DSP2RX_3D_ENA */ -#define WM8996_DSP2RX_3D_ENA_WIDTH 1 /* DSP2RX_3D_ENA */ - -/* - * R1344 (0x540) - DSP2 DRC (1) - */ -#define WM8996_DSP2DRC_SIG_DET_RMS_MASK 0xF800 /* DSP2DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP2DRC_SIG_DET_RMS_SHIFT 11 /* DSP2DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP2DRC_SIG_DET_RMS_WIDTH 5 /* DSP2DRC_SIG_DET_RMS - [15:11] */ -#define WM8996_DSP2DRC_SIG_DET_PK_MASK 0x0600 /* DSP2DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP2DRC_SIG_DET_PK_SHIFT 9 /* DSP2DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP2DRC_SIG_DET_PK_WIDTH 2 /* DSP2DRC_SIG_DET_PK - [10:9] */ -#define WM8996_DSP2DRC_NG_ENA 0x0100 /* DSP2DRC_NG_ENA */ -#define WM8996_DSP2DRC_NG_ENA_MASK 0x0100 /* DSP2DRC_NG_ENA */ -#define WM8996_DSP2DRC_NG_ENA_SHIFT 8 /* DSP2DRC_NG_ENA */ -#define WM8996_DSP2DRC_NG_ENA_WIDTH 1 /* DSP2DRC_NG_ENA */ -#define WM8996_DSP2DRC_SIG_DET_MODE 0x0080 /* DSP2DRC_SIG_DET_MODE */ -#define WM8996_DSP2DRC_SIG_DET_MODE_MASK 0x0080 /* DSP2DRC_SIG_DET_MODE */ -#define WM8996_DSP2DRC_SIG_DET_MODE_SHIFT 7 /* DSP2DRC_SIG_DET_MODE */ -#define WM8996_DSP2DRC_SIG_DET_MODE_WIDTH 1 /* DSP2DRC_SIG_DET_MODE */ -#define WM8996_DSP2DRC_SIG_DET 0x0040 /* DSP2DRC_SIG_DET */ -#define WM8996_DSP2DRC_SIG_DET_MASK 0x0040 /* DSP2DRC_SIG_DET */ -#define WM8996_DSP2DRC_SIG_DET_SHIFT 6 /* DSP2DRC_SIG_DET */ -#define WM8996_DSP2DRC_SIG_DET_WIDTH 1 /* DSP2DRC_SIG_DET */ -#define WM8996_DSP2DRC_KNEE2_OP_ENA 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ -#define WM8996_DSP2DRC_KNEE2_OP_ENA_MASK 0x0020 /* DSP2DRC_KNEE2_OP_ENA */ -#define WM8996_DSP2DRC_KNEE2_OP_ENA_SHIFT 5 /* DSP2DRC_KNEE2_OP_ENA */ -#define WM8996_DSP2DRC_KNEE2_OP_ENA_WIDTH 1 /* DSP2DRC_KNEE2_OP_ENA */ -#define WM8996_DSP2DRC_QR 0x0010 /* DSP2DRC_QR */ -#define WM8996_DSP2DRC_QR_MASK 0x0010 /* DSP2DRC_QR */ -#define WM8996_DSP2DRC_QR_SHIFT 4 /* DSP2DRC_QR */ -#define WM8996_DSP2DRC_QR_WIDTH 1 /* DSP2DRC_QR */ -#define WM8996_DSP2DRC_ANTICLIP 0x0008 /* DSP2DRC_ANTICLIP */ -#define WM8996_DSP2DRC_ANTICLIP_MASK 0x0008 /* DSP2DRC_ANTICLIP */ -#define WM8996_DSP2DRC_ANTICLIP_SHIFT 3 /* DSP2DRC_ANTICLIP */ -#define WM8996_DSP2DRC_ANTICLIP_WIDTH 1 /* DSP2DRC_ANTICLIP */ -#define WM8996_DSP2RX_DRC_ENA 0x0004 /* DSP2RX_DRC_ENA */ -#define WM8996_DSP2RX_DRC_ENA_MASK 0x0004 /* DSP2RX_DRC_ENA */ -#define WM8996_DSP2RX_DRC_ENA_SHIFT 2 /* DSP2RX_DRC_ENA */ -#define WM8996_DSP2RX_DRC_ENA_WIDTH 1 /* DSP2RX_DRC_ENA */ -#define WM8996_DSP2TXL_DRC_ENA 0x0002 /* DSP2TXL_DRC_ENA */ -#define WM8996_DSP2TXL_DRC_ENA_MASK 0x0002 /* DSP2TXL_DRC_ENA */ -#define WM8996_DSP2TXL_DRC_ENA_SHIFT 1 /* DSP2TXL_DRC_ENA */ -#define WM8996_DSP2TXL_DRC_ENA_WIDTH 1 /* DSP2TXL_DRC_ENA */ -#define WM8996_DSP2TXR_DRC_ENA 0x0001 /* DSP2TXR_DRC_ENA */ -#define WM8996_DSP2TXR_DRC_ENA_MASK 0x0001 /* DSP2TXR_DRC_ENA */ -#define WM8996_DSP2TXR_DRC_ENA_SHIFT 0 /* DSP2TXR_DRC_ENA */ -#define WM8996_DSP2TXR_DRC_ENA_WIDTH 1 /* DSP2TXR_DRC_ENA */ - -/* - * R1345 (0x541) - DSP2 DRC (2) - */ -#define WM8996_DSP2DRC_ATK_MASK 0x1E00 /* DSP2DRC_ATK - [12:9] */ -#define WM8996_DSP2DRC_ATK_SHIFT 9 /* DSP2DRC_ATK - [12:9] */ -#define WM8996_DSP2DRC_ATK_WIDTH 4 /* DSP2DRC_ATK - [12:9] */ -#define WM8996_DSP2DRC_DCY_MASK 0x01E0 /* DSP2DRC_DCY - [8:5] */ -#define WM8996_DSP2DRC_DCY_SHIFT 5 /* DSP2DRC_DCY - [8:5] */ -#define WM8996_DSP2DRC_DCY_WIDTH 4 /* DSP2DRC_DCY - [8:5] */ -#define WM8996_DSP2DRC_MINGAIN_MASK 0x001C /* DSP2DRC_MINGAIN - [4:2] */ -#define WM8996_DSP2DRC_MINGAIN_SHIFT 2 /* DSP2DRC_MINGAIN - [4:2] */ -#define WM8996_DSP2DRC_MINGAIN_WIDTH 3 /* DSP2DRC_MINGAIN - [4:2] */ -#define WM8996_DSP2DRC_MAXGAIN_MASK 0x0003 /* DSP2DRC_MAXGAIN - [1:0] */ -#define WM8996_DSP2DRC_MAXGAIN_SHIFT 0 /* DSP2DRC_MAXGAIN - [1:0] */ -#define WM8996_DSP2DRC_MAXGAIN_WIDTH 2 /* DSP2DRC_MAXGAIN - [1:0] */ - -/* - * R1346 (0x542) - DSP2 DRC (3) - */ -#define WM8996_DSP2DRC_NG_MINGAIN_MASK 0xF000 /* DSP2DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP2DRC_NG_MINGAIN_SHIFT 12 /* DSP2DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP2DRC_NG_MINGAIN_WIDTH 4 /* DSP2DRC_NG_MINGAIN - [15:12] */ -#define WM8996_DSP2DRC_NG_EXP_MASK 0x0C00 /* DSP2DRC_NG_EXP - [11:10] */ -#define WM8996_DSP2DRC_NG_EXP_SHIFT 10 /* DSP2DRC_NG_EXP - [11:10] */ -#define WM8996_DSP2DRC_NG_EXP_WIDTH 2 /* DSP2DRC_NG_EXP - [11:10] */ -#define WM8996_DSP2DRC_QR_THR_MASK 0x0300 /* DSP2DRC_QR_THR - [9:8] */ -#define WM8996_DSP2DRC_QR_THR_SHIFT 8 /* DSP2DRC_QR_THR - [9:8] */ -#define WM8996_DSP2DRC_QR_THR_WIDTH 2 /* DSP2DRC_QR_THR - [9:8] */ -#define WM8996_DSP2DRC_QR_DCY_MASK 0x00C0 /* DSP2DRC_QR_DCY - [7:6] */ -#define WM8996_DSP2DRC_QR_DCY_SHIFT 6 /* DSP2DRC_QR_DCY - [7:6] */ -#define WM8996_DSP2DRC_QR_DCY_WIDTH 2 /* DSP2DRC_QR_DCY - [7:6] */ -#define WM8996_DSP2DRC_HI_COMP_MASK 0x0038 /* DSP2DRC_HI_COMP - [5:3] */ -#define WM8996_DSP2DRC_HI_COMP_SHIFT 3 /* DSP2DRC_HI_COMP - [5:3] */ -#define WM8996_DSP2DRC_HI_COMP_WIDTH 3 /* DSP2DRC_HI_COMP - [5:3] */ -#define WM8996_DSP2DRC_LO_COMP_MASK 0x0007 /* DSP2DRC_LO_COMP - [2:0] */ -#define WM8996_DSP2DRC_LO_COMP_SHIFT 0 /* DSP2DRC_LO_COMP - [2:0] */ -#define WM8996_DSP2DRC_LO_COMP_WIDTH 3 /* DSP2DRC_LO_COMP - [2:0] */ - -/* - * R1347 (0x543) - DSP2 DRC (4) - */ -#define WM8996_DSP2DRC_KNEE_IP_MASK 0x07E0 /* DSP2DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP2DRC_KNEE_IP_SHIFT 5 /* DSP2DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP2DRC_KNEE_IP_WIDTH 6 /* DSP2DRC_KNEE_IP - [10:5] */ -#define WM8996_DSP2DRC_KNEE_OP_MASK 0x001F /* DSP2DRC_KNEE_OP - [4:0] */ -#define WM8996_DSP2DRC_KNEE_OP_SHIFT 0 /* DSP2DRC_KNEE_OP - [4:0] */ -#define WM8996_DSP2DRC_KNEE_OP_WIDTH 5 /* DSP2DRC_KNEE_OP - [4:0] */ - -/* - * R1348 (0x544) - DSP2 DRC (5) - */ -#define WM8996_DSP2DRC_KNEE2_IP_MASK 0x03E0 /* DSP2DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP2DRC_KNEE2_IP_SHIFT 5 /* DSP2DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP2DRC_KNEE2_IP_WIDTH 5 /* DSP2DRC_KNEE2_IP - [9:5] */ -#define WM8996_DSP2DRC_KNEE2_OP_MASK 0x001F /* DSP2DRC_KNEE2_OP - [4:0] */ -#define WM8996_DSP2DRC_KNEE2_OP_SHIFT 0 /* DSP2DRC_KNEE2_OP - [4:0] */ -#define WM8996_DSP2DRC_KNEE2_OP_WIDTH 5 /* DSP2DRC_KNEE2_OP - [4:0] */ - -/* - * R1408 (0x580) - DSP2 RX EQ Gains (1) - */ -#define WM8996_DSP2RX_EQ_B1_GAIN_MASK 0xF800 /* DSP2RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B1_GAIN_SHIFT 11 /* DSP2RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B1_GAIN_WIDTH 5 /* DSP2RX_EQ_B1_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B2_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP2RX_EQ_B2_GAIN_SHIFT 6 /* DSP2RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP2RX_EQ_B2_GAIN_WIDTH 5 /* DSP2RX_EQ_B2_GAIN - [10:6] */ -#define WM8996_DSP2RX_EQ_B3_GAIN_MASK 0x003E /* DSP2RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP2RX_EQ_B3_GAIN_SHIFT 1 /* DSP2RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP2RX_EQ_B3_GAIN_WIDTH 5 /* DSP2RX_EQ_B3_GAIN - [5:1] */ -#define WM8996_DSP2RX_EQ_ENA 0x0001 /* DSP2RX_EQ_ENA */ -#define WM8996_DSP2RX_EQ_ENA_MASK 0x0001 /* DSP2RX_EQ_ENA */ -#define WM8996_DSP2RX_EQ_ENA_SHIFT 0 /* DSP2RX_EQ_ENA */ -#define WM8996_DSP2RX_EQ_ENA_WIDTH 1 /* DSP2RX_EQ_ENA */ - -/* - * R1409 (0x581) - DSP2 RX EQ Gains (2) - */ -#define WM8996_DSP2RX_EQ_B4_GAIN_MASK 0xF800 /* DSP2RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B4_GAIN_SHIFT 11 /* DSP2RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B4_GAIN_WIDTH 5 /* DSP2RX_EQ_B4_GAIN - [15:11] */ -#define WM8996_DSP2RX_EQ_B5_GAIN_MASK 0x07C0 /* DSP2RX_EQ_B5_GAIN - [10:6] */ -#define WM8996_DSP2RX_EQ_B5_GAIN_SHIFT 6 /* DSP2RX_EQ_B5_GAIN - [10:6] */ -#define WM8996_DSP2RX_EQ_B5_GAIN_WIDTH 5 /* DSP2RX_EQ_B5_GAIN - [10:6] */ - -/* - * R1410 (0x582) - DSP2 RX EQ Band 1 A - */ -#define WM8996_DSP2RX_EQ_B1_A_MASK 0xFFFF /* DSP2RX_EQ_B1_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_A_SHIFT 0 /* DSP2RX_EQ_B1_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_A_WIDTH 16 /* DSP2RX_EQ_B1_A - [15:0] */ - -/* - * R1411 (0x583) - DSP2 RX EQ Band 1 B - */ -#define WM8996_DSP2RX_EQ_B1_B_MASK 0xFFFF /* DSP2RX_EQ_B1_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_B_SHIFT 0 /* DSP2RX_EQ_B1_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_B_WIDTH 16 /* DSP2RX_EQ_B1_B - [15:0] */ - -/* - * R1412 (0x584) - DSP2 RX EQ Band 1 PG - */ -#define WM8996_DSP2RX_EQ_B1_PG_MASK 0xFFFF /* DSP2RX_EQ_B1_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_PG_SHIFT 0 /* DSP2RX_EQ_B1_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B1_PG_WIDTH 16 /* DSP2RX_EQ_B1_PG - [15:0] */ - -/* - * R1413 (0x585) - DSP2 RX EQ Band 2 A - */ -#define WM8996_DSP2RX_EQ_B2_A_MASK 0xFFFF /* DSP2RX_EQ_B2_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_A_SHIFT 0 /* DSP2RX_EQ_B2_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_A_WIDTH 16 /* DSP2RX_EQ_B2_A - [15:0] */ - -/* - * R1414 (0x586) - DSP2 RX EQ Band 2 B - */ -#define WM8996_DSP2RX_EQ_B2_B_MASK 0xFFFF /* DSP2RX_EQ_B2_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_B_SHIFT 0 /* DSP2RX_EQ_B2_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_B_WIDTH 16 /* DSP2RX_EQ_B2_B - [15:0] */ - -/* - * R1415 (0x587) - DSP2 RX EQ Band 2 C - */ -#define WM8996_DSP2RX_EQ_B2_C_MASK 0xFFFF /* DSP2RX_EQ_B2_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_C_SHIFT 0 /* DSP2RX_EQ_B2_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_C_WIDTH 16 /* DSP2RX_EQ_B2_C - [15:0] */ - -/* - * R1416 (0x588) - DSP2 RX EQ Band 2 PG - */ -#define WM8996_DSP2RX_EQ_B2_PG_MASK 0xFFFF /* DSP2RX_EQ_B2_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_PG_SHIFT 0 /* DSP2RX_EQ_B2_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B2_PG_WIDTH 16 /* DSP2RX_EQ_B2_PG - [15:0] */ - -/* - * R1417 (0x589) - DSP2 RX EQ Band 3 A - */ -#define WM8996_DSP2RX_EQ_B3_A_MASK 0xFFFF /* DSP2RX_EQ_B3_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_A_SHIFT 0 /* DSP2RX_EQ_B3_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_A_WIDTH 16 /* DSP2RX_EQ_B3_A - [15:0] */ - -/* - * R1418 (0x58A) - DSP2 RX EQ Band 3 B - */ -#define WM8996_DSP2RX_EQ_B3_B_MASK 0xFFFF /* DSP2RX_EQ_B3_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_B_SHIFT 0 /* DSP2RX_EQ_B3_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_B_WIDTH 16 /* DSP2RX_EQ_B3_B - [15:0] */ - -/* - * R1419 (0x58B) - DSP2 RX EQ Band 3 C - */ -#define WM8996_DSP2RX_EQ_B3_C_MASK 0xFFFF /* DSP2RX_EQ_B3_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_C_SHIFT 0 /* DSP2RX_EQ_B3_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_C_WIDTH 16 /* DSP2RX_EQ_B3_C - [15:0] */ - -/* - * R1420 (0x58C) - DSP2 RX EQ Band 3 PG - */ -#define WM8996_DSP2RX_EQ_B3_PG_MASK 0xFFFF /* DSP2RX_EQ_B3_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_PG_SHIFT 0 /* DSP2RX_EQ_B3_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B3_PG_WIDTH 16 /* DSP2RX_EQ_B3_PG - [15:0] */ - -/* - * R1421 (0x58D) - DSP2 RX EQ Band 4 A - */ -#define WM8996_DSP2RX_EQ_B4_A_MASK 0xFFFF /* DSP2RX_EQ_B4_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_A_SHIFT 0 /* DSP2RX_EQ_B4_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_A_WIDTH 16 /* DSP2RX_EQ_B4_A - [15:0] */ - -/* - * R1422 (0x58E) - DSP2 RX EQ Band 4 B - */ -#define WM8996_DSP2RX_EQ_B4_B_MASK 0xFFFF /* DSP2RX_EQ_B4_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_B_SHIFT 0 /* DSP2RX_EQ_B4_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_B_WIDTH 16 /* DSP2RX_EQ_B4_B - [15:0] */ - -/* - * R1423 (0x58F) - DSP2 RX EQ Band 4 C - */ -#define WM8996_DSP2RX_EQ_B4_C_MASK 0xFFFF /* DSP2RX_EQ_B4_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_C_SHIFT 0 /* DSP2RX_EQ_B4_C - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_C_WIDTH 16 /* DSP2RX_EQ_B4_C - [15:0] */ - -/* - * R1424 (0x590) - DSP2 RX EQ Band 4 PG - */ -#define WM8996_DSP2RX_EQ_B4_PG_MASK 0xFFFF /* DSP2RX_EQ_B4_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_PG_SHIFT 0 /* DSP2RX_EQ_B4_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B4_PG_WIDTH 16 /* DSP2RX_EQ_B4_PG - [15:0] */ - -/* - * R1425 (0x591) - DSP2 RX EQ Band 5 A - */ -#define WM8996_DSP2RX_EQ_B5_A_MASK 0xFFFF /* DSP2RX_EQ_B5_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_A_SHIFT 0 /* DSP2RX_EQ_B5_A - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_A_WIDTH 16 /* DSP2RX_EQ_B5_A - [15:0] */ - -/* - * R1426 (0x592) - DSP2 RX EQ Band 5 B - */ -#define WM8996_DSP2RX_EQ_B5_B_MASK 0xFFFF /* DSP2RX_EQ_B5_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_B_SHIFT 0 /* DSP2RX_EQ_B5_B - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_B_WIDTH 16 /* DSP2RX_EQ_B5_B - [15:0] */ - -/* - * R1427 (0x593) - DSP2 RX EQ Band 5 PG - */ -#define WM8996_DSP2RX_EQ_B5_PG_MASK 0xFFFF /* DSP2RX_EQ_B5_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_PG_SHIFT 0 /* DSP2RX_EQ_B5_PG - [15:0] */ -#define WM8996_DSP2RX_EQ_B5_PG_WIDTH 16 /* DSP2RX_EQ_B5_PG - [15:0] */ - -/* - * R1536 (0x600) - DAC1 Mixer Volumes - */ -#define WM8996_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */ -#define WM8996_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */ -#define WM8996_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */ -#define WM8996_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */ -#define WM8996_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */ -#define WM8996_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */ - -/* - * R1537 (0x601) - DAC1 Left Mixer Routing - */ -#define WM8996_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */ -#define WM8996_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */ -#define WM8996_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */ -#define WM8996_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */ -#define WM8996_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */ -#define WM8996_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */ -#define WM8996_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */ -#define WM8996_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */ -#define WM8996_DSP2RXL_TO_DAC1L 0x0002 /* DSP2RXL_TO_DAC1L */ -#define WM8996_DSP2RXL_TO_DAC1L_MASK 0x0002 /* DSP2RXL_TO_DAC1L */ -#define WM8996_DSP2RXL_TO_DAC1L_SHIFT 1 /* DSP2RXL_TO_DAC1L */ -#define WM8996_DSP2RXL_TO_DAC1L_WIDTH 1 /* DSP2RXL_TO_DAC1L */ -#define WM8996_DSP1RXL_TO_DAC1L 0x0001 /* DSP1RXL_TO_DAC1L */ -#define WM8996_DSP1RXL_TO_DAC1L_MASK 0x0001 /* DSP1RXL_TO_DAC1L */ -#define WM8996_DSP1RXL_TO_DAC1L_SHIFT 0 /* DSP1RXL_TO_DAC1L */ -#define WM8996_DSP1RXL_TO_DAC1L_WIDTH 1 /* DSP1RXL_TO_DAC1L */ - -/* - * R1538 (0x602) - DAC1 Right Mixer Routing - */ -#define WM8996_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */ -#define WM8996_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */ -#define WM8996_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */ -#define WM8996_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */ -#define WM8996_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */ -#define WM8996_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */ -#define WM8996_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */ -#define WM8996_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */ -#define WM8996_DSP2RXR_TO_DAC1R 0x0002 /* DSP2RXR_TO_DAC1R */ -#define WM8996_DSP2RXR_TO_DAC1R_MASK 0x0002 /* DSP2RXR_TO_DAC1R */ -#define WM8996_DSP2RXR_TO_DAC1R_SHIFT 1 /* DSP2RXR_TO_DAC1R */ -#define WM8996_DSP2RXR_TO_DAC1R_WIDTH 1 /* DSP2RXR_TO_DAC1R */ -#define WM8996_DSP1RXR_TO_DAC1R 0x0001 /* DSP1RXR_TO_DAC1R */ -#define WM8996_DSP1RXR_TO_DAC1R_MASK 0x0001 /* DSP1RXR_TO_DAC1R */ -#define WM8996_DSP1RXR_TO_DAC1R_SHIFT 0 /* DSP1RXR_TO_DAC1R */ -#define WM8996_DSP1RXR_TO_DAC1R_WIDTH 1 /* DSP1RXR_TO_DAC1R */ - -/* - * R1539 (0x603) - DAC2 Mixer Volumes - */ -#define WM8996_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */ -#define WM8996_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */ -#define WM8996_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */ -#define WM8996_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */ -#define WM8996_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */ -#define WM8996_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */ - -/* - * R1540 (0x604) - DAC2 Left Mixer Routing - */ -#define WM8996_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */ -#define WM8996_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */ -#define WM8996_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */ -#define WM8996_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */ -#define WM8996_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */ -#define WM8996_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */ -#define WM8996_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */ -#define WM8996_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */ -#define WM8996_DSP2RXL_TO_DAC2L 0x0002 /* DSP2RXL_TO_DAC2L */ -#define WM8996_DSP2RXL_TO_DAC2L_MASK 0x0002 /* DSP2RXL_TO_DAC2L */ -#define WM8996_DSP2RXL_TO_DAC2L_SHIFT 1 /* DSP2RXL_TO_DAC2L */ -#define WM8996_DSP2RXL_TO_DAC2L_WIDTH 1 /* DSP2RXL_TO_DAC2L */ -#define WM8996_DSP1RXL_TO_DAC2L 0x0001 /* DSP1RXL_TO_DAC2L */ -#define WM8996_DSP1RXL_TO_DAC2L_MASK 0x0001 /* DSP1RXL_TO_DAC2L */ -#define WM8996_DSP1RXL_TO_DAC2L_SHIFT 0 /* DSP1RXL_TO_DAC2L */ -#define WM8996_DSP1RXL_TO_DAC2L_WIDTH 1 /* DSP1RXL_TO_DAC2L */ - -/* - * R1541 (0x605) - DAC2 Right Mixer Routing - */ -#define WM8996_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */ -#define WM8996_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */ -#define WM8996_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */ -#define WM8996_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */ -#define WM8996_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */ -#define WM8996_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */ -#define WM8996_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */ -#define WM8996_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */ -#define WM8996_DSP2RXR_TO_DAC2R 0x0002 /* DSP2RXR_TO_DAC2R */ -#define WM8996_DSP2RXR_TO_DAC2R_MASK 0x0002 /* DSP2RXR_TO_DAC2R */ -#define WM8996_DSP2RXR_TO_DAC2R_SHIFT 1 /* DSP2RXR_TO_DAC2R */ -#define WM8996_DSP2RXR_TO_DAC2R_WIDTH 1 /* DSP2RXR_TO_DAC2R */ -#define WM8996_DSP1RXR_TO_DAC2R 0x0001 /* DSP1RXR_TO_DAC2R */ -#define WM8996_DSP1RXR_TO_DAC2R_MASK 0x0001 /* DSP1RXR_TO_DAC2R */ -#define WM8996_DSP1RXR_TO_DAC2R_SHIFT 0 /* DSP1RXR_TO_DAC2R */ -#define WM8996_DSP1RXR_TO_DAC2R_WIDTH 1 /* DSP1RXR_TO_DAC2R */ - -/* - * R1542 (0x606) - DSP1 TX Left Mixer Routing - */ -#define WM8996_ADC1L_TO_DSP1TXL 0x0002 /* ADC1L_TO_DSP1TXL */ -#define WM8996_ADC1L_TO_DSP1TXL_MASK 0x0002 /* ADC1L_TO_DSP1TXL */ -#define WM8996_ADC1L_TO_DSP1TXL_SHIFT 1 /* ADC1L_TO_DSP1TXL */ -#define WM8996_ADC1L_TO_DSP1TXL_WIDTH 1 /* ADC1L_TO_DSP1TXL */ -#define WM8996_DACL_TO_DSP1TXL 0x0001 /* DACL_TO_DSP1TXL */ -#define WM8996_DACL_TO_DSP1TXL_MASK 0x0001 /* DACL_TO_DSP1TXL */ -#define WM8996_DACL_TO_DSP1TXL_SHIFT 0 /* DACL_TO_DSP1TXL */ -#define WM8996_DACL_TO_DSP1TXL_WIDTH 1 /* DACL_TO_DSP1TXL */ - -/* - * R1543 (0x607) - DSP1 TX Right Mixer Routing - */ -#define WM8996_ADC1R_TO_DSP1TXR 0x0002 /* ADC1R_TO_DSP1TXR */ -#define WM8996_ADC1R_TO_DSP1TXR_MASK 0x0002 /* ADC1R_TO_DSP1TXR */ -#define WM8996_ADC1R_TO_DSP1TXR_SHIFT 1 /* ADC1R_TO_DSP1TXR */ -#define WM8996_ADC1R_TO_DSP1TXR_WIDTH 1 /* ADC1R_TO_DSP1TXR */ -#define WM8996_DACR_TO_DSP1TXR 0x0001 /* DACR_TO_DSP1TXR */ -#define WM8996_DACR_TO_DSP1TXR_MASK 0x0001 /* DACR_TO_DSP1TXR */ -#define WM8996_DACR_TO_DSP1TXR_SHIFT 0 /* DACR_TO_DSP1TXR */ -#define WM8996_DACR_TO_DSP1TXR_WIDTH 1 /* DACR_TO_DSP1TXR */ - -/* - * R1544 (0x608) - DSP2 TX Left Mixer Routing - */ -#define WM8996_ADC2L_TO_DSP2TXL 0x0002 /* ADC2L_TO_DSP2TXL */ -#define WM8996_ADC2L_TO_DSP2TXL_MASK 0x0002 /* ADC2L_TO_DSP2TXL */ -#define WM8996_ADC2L_TO_DSP2TXL_SHIFT 1 /* ADC2L_TO_DSP2TXL */ -#define WM8996_ADC2L_TO_DSP2TXL_WIDTH 1 /* ADC2L_TO_DSP2TXL */ -#define WM8996_DACL_TO_DSP2TXL 0x0001 /* DACL_TO_DSP2TXL */ -#define WM8996_DACL_TO_DSP2TXL_MASK 0x0001 /* DACL_TO_DSP2TXL */ -#define WM8996_DACL_TO_DSP2TXL_SHIFT 0 /* DACL_TO_DSP2TXL */ -#define WM8996_DACL_TO_DSP2TXL_WIDTH 1 /* DACL_TO_DSP2TXL */ - -/* - * R1545 (0x609) - DSP2 TX Right Mixer Routing - */ -#define WM8996_ADC2R_TO_DSP2TXR 0x0002 /* ADC2R_TO_DSP2TXR */ -#define WM8996_ADC2R_TO_DSP2TXR_MASK 0x0002 /* ADC2R_TO_DSP2TXR */ -#define WM8996_ADC2R_TO_DSP2TXR_SHIFT 1 /* ADC2R_TO_DSP2TXR */ -#define WM8996_ADC2R_TO_DSP2TXR_WIDTH 1 /* ADC2R_TO_DSP2TXR */ -#define WM8996_DACR_TO_DSP2TXR 0x0001 /* DACR_TO_DSP2TXR */ -#define WM8996_DACR_TO_DSP2TXR_MASK 0x0001 /* DACR_TO_DSP2TXR */ -#define WM8996_DACR_TO_DSP2TXR_SHIFT 0 /* DACR_TO_DSP2TXR */ -#define WM8996_DACR_TO_DSP2TXR_WIDTH 1 /* DACR_TO_DSP2TXR */ - -/* - * R1546 (0x60A) - DSP TX Mixer Select - */ -#define WM8996_DAC_TO_DSPTX_SRC 0x0001 /* DAC_TO_DSPTX_SRC */ -#define WM8996_DAC_TO_DSPTX_SRC_MASK 0x0001 /* DAC_TO_DSPTX_SRC */ -#define WM8996_DAC_TO_DSPTX_SRC_SHIFT 0 /* DAC_TO_DSPTX_SRC */ -#define WM8996_DAC_TO_DSPTX_SRC_WIDTH 1 /* DAC_TO_DSPTX_SRC */ - -/* - * R1552 (0x610) - DAC Softmute - */ -#define WM8996_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */ -#define WM8996_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */ -#define WM8996_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */ -#define WM8996_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */ -#define WM8996_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */ -#define WM8996_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */ -#define WM8996_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */ -#define WM8996_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ - -/* - * R1568 (0x620) - Oversampling - */ -#define WM8996_SPK_OSR128 0x0008 /* SPK_OSR128 */ -#define WM8996_SPK_OSR128_MASK 0x0008 /* SPK_OSR128 */ -#define WM8996_SPK_OSR128_SHIFT 3 /* SPK_OSR128 */ -#define WM8996_SPK_OSR128_WIDTH 1 /* SPK_OSR128 */ -#define WM8996_DMIC_OSR64 0x0004 /* DMIC_OSR64 */ -#define WM8996_DMIC_OSR64_MASK 0x0004 /* DMIC_OSR64 */ -#define WM8996_DMIC_OSR64_SHIFT 2 /* DMIC_OSR64 */ -#define WM8996_DMIC_OSR64_WIDTH 1 /* DMIC_OSR64 */ -#define WM8996_ADC_OSR128 0x0002 /* ADC_OSR128 */ -#define WM8996_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */ -#define WM8996_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */ -#define WM8996_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ -#define WM8996_DAC_OSR128 0x0001 /* DAC_OSR128 */ -#define WM8996_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */ -#define WM8996_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */ -#define WM8996_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ - -/* - * R1569 (0x621) - Sidetone - */ -#define WM8996_ST_LPF 0x1000 /* ST_LPF */ -#define WM8996_ST_LPF_MASK 0x1000 /* ST_LPF */ -#define WM8996_ST_LPF_SHIFT 12 /* ST_LPF */ -#define WM8996_ST_LPF_WIDTH 1 /* ST_LPF */ -#define WM8996_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */ -#define WM8996_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */ -#define WM8996_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */ -#define WM8996_ST_HPF 0x0040 /* ST_HPF */ -#define WM8996_ST_HPF_MASK 0x0040 /* ST_HPF */ -#define WM8996_ST_HPF_SHIFT 6 /* ST_HPF */ -#define WM8996_ST_HPF_WIDTH 1 /* ST_HPF */ -#define WM8996_STR_SEL 0x0002 /* STR_SEL */ -#define WM8996_STR_SEL_MASK 0x0002 /* STR_SEL */ -#define WM8996_STR_SEL_SHIFT 1 /* STR_SEL */ -#define WM8996_STR_SEL_WIDTH 1 /* STR_SEL */ -#define WM8996_STL_SEL 0x0001 /* STL_SEL */ -#define WM8996_STL_SEL_MASK 0x0001 /* STL_SEL */ -#define WM8996_STL_SEL_SHIFT 0 /* STL_SEL */ -#define WM8996_STL_SEL_WIDTH 1 /* STL_SEL */ - -/* - * R1792 (0x700) - GPIO 1 - */ -#define WM8996_GP1_DIR 0x8000 /* GP1_DIR */ -#define WM8996_GP1_DIR_MASK 0x8000 /* GP1_DIR */ -#define WM8996_GP1_DIR_SHIFT 15 /* GP1_DIR */ -#define WM8996_GP1_DIR_WIDTH 1 /* GP1_DIR */ -#define WM8996_GP1_PU 0x4000 /* GP1_PU */ -#define WM8996_GP1_PU_MASK 0x4000 /* GP1_PU */ -#define WM8996_GP1_PU_SHIFT 14 /* GP1_PU */ -#define WM8996_GP1_PU_WIDTH 1 /* GP1_PU */ -#define WM8996_GP1_PD 0x2000 /* GP1_PD */ -#define WM8996_GP1_PD_MASK 0x2000 /* GP1_PD */ -#define WM8996_GP1_PD_SHIFT 13 /* GP1_PD */ -#define WM8996_GP1_PD_WIDTH 1 /* GP1_PD */ -#define WM8996_GP1_POL 0x0400 /* GP1_POL */ -#define WM8996_GP1_POL_MASK 0x0400 /* GP1_POL */ -#define WM8996_GP1_POL_SHIFT 10 /* GP1_POL */ -#define WM8996_GP1_POL_WIDTH 1 /* GP1_POL */ -#define WM8996_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ -#define WM8996_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ -#define WM8996_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ -#define WM8996_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ -#define WM8996_GP1_DB 0x0100 /* GP1_DB */ -#define WM8996_GP1_DB_MASK 0x0100 /* GP1_DB */ -#define WM8996_GP1_DB_SHIFT 8 /* GP1_DB */ -#define WM8996_GP1_DB_WIDTH 1 /* GP1_DB */ -#define WM8996_GP1_LVL 0x0040 /* GP1_LVL */ -#define WM8996_GP1_LVL_MASK 0x0040 /* GP1_LVL */ -#define WM8996_GP1_LVL_SHIFT 6 /* GP1_LVL */ -#define WM8996_GP1_LVL_WIDTH 1 /* GP1_LVL */ -#define WM8996_GP1_FN_MASK 0x000F /* GP1_FN - [3:0] */ -#define WM8996_GP1_FN_SHIFT 0 /* GP1_FN - [3:0] */ -#define WM8996_GP1_FN_WIDTH 4 /* GP1_FN - [3:0] */ - -/* - * R1793 (0x701) - GPIO 2 - */ -#define WM8996_GP2_DIR 0x8000 /* GP2_DIR */ -#define WM8996_GP2_DIR_MASK 0x8000 /* GP2_DIR */ -#define WM8996_GP2_DIR_SHIFT 15 /* GP2_DIR */ -#define WM8996_GP2_DIR_WIDTH 1 /* GP2_DIR */ -#define WM8996_GP2_PU 0x4000 /* GP2_PU */ -#define WM8996_GP2_PU_MASK 0x4000 /* GP2_PU */ -#define WM8996_GP2_PU_SHIFT 14 /* GP2_PU */ -#define WM8996_GP2_PU_WIDTH 1 /* GP2_PU */ -#define WM8996_GP2_PD 0x2000 /* GP2_PD */ -#define WM8996_GP2_PD_MASK 0x2000 /* GP2_PD */ -#define WM8996_GP2_PD_SHIFT 13 /* GP2_PD */ -#define WM8996_GP2_PD_WIDTH 1 /* GP2_PD */ -#define WM8996_GP2_POL 0x0400 /* GP2_POL */ -#define WM8996_GP2_POL_MASK 0x0400 /* GP2_POL */ -#define WM8996_GP2_POL_SHIFT 10 /* GP2_POL */ -#define WM8996_GP2_POL_WIDTH 1 /* GP2_POL */ -#define WM8996_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ -#define WM8996_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ -#define WM8996_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ -#define WM8996_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ -#define WM8996_GP2_DB 0x0100 /* GP2_DB */ -#define WM8996_GP2_DB_MASK 0x0100 /* GP2_DB */ -#define WM8996_GP2_DB_SHIFT 8 /* GP2_DB */ -#define WM8996_GP2_DB_WIDTH 1 /* GP2_DB */ -#define WM8996_GP2_LVL 0x0040 /* GP2_LVL */ -#define WM8996_GP2_LVL_MASK 0x0040 /* GP2_LVL */ -#define WM8996_GP2_LVL_SHIFT 6 /* GP2_LVL */ -#define WM8996_GP2_LVL_WIDTH 1 /* GP2_LVL */ -#define WM8996_GP2_FN_MASK 0x000F /* GP2_FN - [3:0] */ -#define WM8996_GP2_FN_SHIFT 0 /* GP2_FN - [3:0] */ -#define WM8996_GP2_FN_WIDTH 4 /* GP2_FN - [3:0] */ - -/* - * R1794 (0x702) - GPIO 3 - */ -#define WM8996_GP3_DIR 0x8000 /* GP3_DIR */ -#define WM8996_GP3_DIR_MASK 0x8000 /* GP3_DIR */ -#define WM8996_GP3_DIR_SHIFT 15 /* GP3_DIR */ -#define WM8996_GP3_DIR_WIDTH 1 /* GP3_DIR */ -#define WM8996_GP3_PU 0x4000 /* GP3_PU */ -#define WM8996_GP3_PU_MASK 0x4000 /* GP3_PU */ -#define WM8996_GP3_PU_SHIFT 14 /* GP3_PU */ -#define WM8996_GP3_PU_WIDTH 1 /* GP3_PU */ -#define WM8996_GP3_PD 0x2000 /* GP3_PD */ -#define WM8996_GP3_PD_MASK 0x2000 /* GP3_PD */ -#define WM8996_GP3_PD_SHIFT 13 /* GP3_PD */ -#define WM8996_GP3_PD_WIDTH 1 /* GP3_PD */ -#define WM8996_GP3_POL 0x0400 /* GP3_POL */ -#define WM8996_GP3_POL_MASK 0x0400 /* GP3_POL */ -#define WM8996_GP3_POL_SHIFT 10 /* GP3_POL */ -#define WM8996_GP3_POL_WIDTH 1 /* GP3_POL */ -#define WM8996_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ -#define WM8996_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ -#define WM8996_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ -#define WM8996_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ -#define WM8996_GP3_DB 0x0100 /* GP3_DB */ -#define WM8996_GP3_DB_MASK 0x0100 /* GP3_DB */ -#define WM8996_GP3_DB_SHIFT 8 /* GP3_DB */ -#define WM8996_GP3_DB_WIDTH 1 /* GP3_DB */ -#define WM8996_GP3_LVL 0x0040 /* GP3_LVL */ -#define WM8996_GP3_LVL_MASK 0x0040 /* GP3_LVL */ -#define WM8996_GP3_LVL_SHIFT 6 /* GP3_LVL */ -#define WM8996_GP3_LVL_WIDTH 1 /* GP3_LVL */ -#define WM8996_GP3_FN_MASK 0x000F /* GP3_FN - [3:0] */ -#define WM8996_GP3_FN_SHIFT 0 /* GP3_FN - [3:0] */ -#define WM8996_GP3_FN_WIDTH 4 /* GP3_FN - [3:0] */ - -/* - * R1795 (0x703) - GPIO 4 - */ -#define WM8996_GP4_DIR 0x8000 /* GP4_DIR */ -#define WM8996_GP4_DIR_MASK 0x8000 /* GP4_DIR */ -#define WM8996_GP4_DIR_SHIFT 15 /* GP4_DIR */ -#define WM8996_GP4_DIR_WIDTH 1 /* GP4_DIR */ -#define WM8996_GP4_PU 0x4000 /* GP4_PU */ -#define WM8996_GP4_PU_MASK 0x4000 /* GP4_PU */ -#define WM8996_GP4_PU_SHIFT 14 /* GP4_PU */ -#define WM8996_GP4_PU_WIDTH 1 /* GP4_PU */ -#define WM8996_GP4_PD 0x2000 /* GP4_PD */ -#define WM8996_GP4_PD_MASK 0x2000 /* GP4_PD */ -#define WM8996_GP4_PD_SHIFT 13 /* GP4_PD */ -#define WM8996_GP4_PD_WIDTH 1 /* GP4_PD */ -#define WM8996_GP4_POL 0x0400 /* GP4_POL */ -#define WM8996_GP4_POL_MASK 0x0400 /* GP4_POL */ -#define WM8996_GP4_POL_SHIFT 10 /* GP4_POL */ -#define WM8996_GP4_POL_WIDTH 1 /* GP4_POL */ -#define WM8996_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ -#define WM8996_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ -#define WM8996_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ -#define WM8996_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ -#define WM8996_GP4_DB 0x0100 /* GP4_DB */ -#define WM8996_GP4_DB_MASK 0x0100 /* GP4_DB */ -#define WM8996_GP4_DB_SHIFT 8 /* GP4_DB */ -#define WM8996_GP4_DB_WIDTH 1 /* GP4_DB */ -#define WM8996_GP4_LVL 0x0040 /* GP4_LVL */ -#define WM8996_GP4_LVL_MASK 0x0040 /* GP4_LVL */ -#define WM8996_GP4_LVL_SHIFT 6 /* GP4_LVL */ -#define WM8996_GP4_LVL_WIDTH 1 /* GP4_LVL */ -#define WM8996_GP4_FN_MASK 0x000F /* GP4_FN - [3:0] */ -#define WM8996_GP4_FN_SHIFT 0 /* GP4_FN - [3:0] */ -#define WM8996_GP4_FN_WIDTH 4 /* GP4_FN - [3:0] */ - -/* - * R1796 (0x704) - GPIO 5 - */ -#define WM8996_GP5_DIR 0x8000 /* GP5_DIR */ -#define WM8996_GP5_DIR_MASK 0x8000 /* GP5_DIR */ -#define WM8996_GP5_DIR_SHIFT 15 /* GP5_DIR */ -#define WM8996_GP5_DIR_WIDTH 1 /* GP5_DIR */ -#define WM8996_GP5_PU 0x4000 /* GP5_PU */ -#define WM8996_GP5_PU_MASK 0x4000 /* GP5_PU */ -#define WM8996_GP5_PU_SHIFT 14 /* GP5_PU */ -#define WM8996_GP5_PU_WIDTH 1 /* GP5_PU */ -#define WM8996_GP5_PD 0x2000 /* GP5_PD */ -#define WM8996_GP5_PD_MASK 0x2000 /* GP5_PD */ -#define WM8996_GP5_PD_SHIFT 13 /* GP5_PD */ -#define WM8996_GP5_PD_WIDTH 1 /* GP5_PD */ -#define WM8996_GP5_POL 0x0400 /* GP5_POL */ -#define WM8996_GP5_POL_MASK 0x0400 /* GP5_POL */ -#define WM8996_GP5_POL_SHIFT 10 /* GP5_POL */ -#define WM8996_GP5_POL_WIDTH 1 /* GP5_POL */ -#define WM8996_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */ -#define WM8996_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */ -#define WM8996_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */ -#define WM8996_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */ -#define WM8996_GP5_DB 0x0100 /* GP5_DB */ -#define WM8996_GP5_DB_MASK 0x0100 /* GP5_DB */ -#define WM8996_GP5_DB_SHIFT 8 /* GP5_DB */ -#define WM8996_GP5_DB_WIDTH 1 /* GP5_DB */ -#define WM8996_GP5_LVL 0x0040 /* GP5_LVL */ -#define WM8996_GP5_LVL_MASK 0x0040 /* GP5_LVL */ -#define WM8996_GP5_LVL_SHIFT 6 /* GP5_LVL */ -#define WM8996_GP5_LVL_WIDTH 1 /* GP5_LVL */ -#define WM8996_GP5_FN_MASK 0x000F /* GP5_FN - [3:0] */ -#define WM8996_GP5_FN_SHIFT 0 /* GP5_FN - [3:0] */ -#define WM8996_GP5_FN_WIDTH 4 /* GP5_FN - [3:0] */ - -/* - * R1824 (0x720) - Pull Control (1) - */ -#define WM8996_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */ -#define WM8996_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */ -#define WM8996_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */ -#define WM8996_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ -#define WM8996_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */ -#define WM8996_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */ -#define WM8996_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */ -#define WM8996_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ -#define WM8996_MCLK2_PU 0x0200 /* MCLK2_PU */ -#define WM8996_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */ -#define WM8996_MCLK2_PU_SHIFT 9 /* MCLK2_PU */ -#define WM8996_MCLK2_PU_WIDTH 1 /* MCLK2_PU */ -#define WM8996_MCLK2_PD 0x0100 /* MCLK2_PD */ -#define WM8996_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */ -#define WM8996_MCLK2_PD_SHIFT 8 /* MCLK2_PD */ -#define WM8996_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ -#define WM8996_MCLK1_PU 0x0080 /* MCLK1_PU */ -#define WM8996_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */ -#define WM8996_MCLK1_PU_SHIFT 7 /* MCLK1_PU */ -#define WM8996_MCLK1_PU_WIDTH 1 /* MCLK1_PU */ -#define WM8996_MCLK1_PD 0x0040 /* MCLK1_PD */ -#define WM8996_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */ -#define WM8996_MCLK1_PD_SHIFT 6 /* MCLK1_PD */ -#define WM8996_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ -#define WM8996_DACDAT1_PU 0x0020 /* DACDAT1_PU */ -#define WM8996_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */ -#define WM8996_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */ -#define WM8996_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ -#define WM8996_DACDAT1_PD 0x0010 /* DACDAT1_PD */ -#define WM8996_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */ -#define WM8996_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */ -#define WM8996_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ -#define WM8996_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */ -#define WM8996_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */ -#define WM8996_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */ -#define WM8996_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ -#define WM8996_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */ -#define WM8996_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */ -#define WM8996_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */ -#define WM8996_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ -#define WM8996_BCLK1_PU 0x0002 /* BCLK1_PU */ -#define WM8996_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */ -#define WM8996_BCLK1_PU_SHIFT 1 /* BCLK1_PU */ -#define WM8996_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ -#define WM8996_BCLK1_PD 0x0001 /* BCLK1_PD */ -#define WM8996_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */ -#define WM8996_BCLK1_PD_SHIFT 0 /* BCLK1_PD */ -#define WM8996_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ - -/* - * R1825 (0x721) - Pull Control (2) - */ -#define WM8996_LDO1ENA_PD 0x0100 /* LDO1ENA_PD */ -#define WM8996_LDO1ENA_PD_MASK 0x0100 /* LDO1ENA_PD */ -#define WM8996_LDO1ENA_PD_SHIFT 8 /* LDO1ENA_PD */ -#define WM8996_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ -#define WM8996_ADDR_PD 0x0040 /* ADDR_PD */ -#define WM8996_ADDR_PD_MASK 0x0040 /* ADDR_PD */ -#define WM8996_ADDR_PD_SHIFT 6 /* ADDR_PD */ -#define WM8996_ADDR_PD_WIDTH 1 /* ADDR_PD */ -#define WM8996_DACDAT2_PU 0x0020 /* DACDAT2_PU */ -#define WM8996_DACDAT2_PU_MASK 0x0020 /* DACDAT2_PU */ -#define WM8996_DACDAT2_PU_SHIFT 5 /* DACDAT2_PU */ -#define WM8996_DACDAT2_PU_WIDTH 1 /* DACDAT2_PU */ -#define WM8996_DACDAT2_PD 0x0010 /* DACDAT2_PD */ -#define WM8996_DACDAT2_PD_MASK 0x0010 /* DACDAT2_PD */ -#define WM8996_DACDAT2_PD_SHIFT 4 /* DACDAT2_PD */ -#define WM8996_DACDAT2_PD_WIDTH 1 /* DACDAT2_PD */ -#define WM8996_DACLRCLK2_PU 0x0008 /* DACLRCLK2_PU */ -#define WM8996_DACLRCLK2_PU_MASK 0x0008 /* DACLRCLK2_PU */ -#define WM8996_DACLRCLK2_PU_SHIFT 3 /* DACLRCLK2_PU */ -#define WM8996_DACLRCLK2_PU_WIDTH 1 /* DACLRCLK2_PU */ -#define WM8996_DACLRCLK2_PD 0x0004 /* DACLRCLK2_PD */ -#define WM8996_DACLRCLK2_PD_MASK 0x0004 /* DACLRCLK2_PD */ -#define WM8996_DACLRCLK2_PD_SHIFT 2 /* DACLRCLK2_PD */ -#define WM8996_DACLRCLK2_PD_WIDTH 1 /* DACLRCLK2_PD */ -#define WM8996_BCLK2_PU 0x0002 /* BCLK2_PU */ -#define WM8996_BCLK2_PU_MASK 0x0002 /* BCLK2_PU */ -#define WM8996_BCLK2_PU_SHIFT 1 /* BCLK2_PU */ -#define WM8996_BCLK2_PU_WIDTH 1 /* BCLK2_PU */ -#define WM8996_BCLK2_PD 0x0001 /* BCLK2_PD */ -#define WM8996_BCLK2_PD_MASK 0x0001 /* BCLK2_PD */ -#define WM8996_BCLK2_PD_SHIFT 0 /* BCLK2_PD */ -#define WM8996_BCLK2_PD_WIDTH 1 /* BCLK2_PD */ - -/* - * R1840 (0x730) - Interrupt Status 1 - */ -#define WM8996_GP5_EINT 0x0010 /* GP5_EINT */ -#define WM8996_GP5_EINT_MASK 0x0010 /* GP5_EINT */ -#define WM8996_GP5_EINT_SHIFT 4 /* GP5_EINT */ -#define WM8996_GP5_EINT_WIDTH 1 /* GP5_EINT */ -#define WM8996_GP4_EINT 0x0008 /* GP4_EINT */ -#define WM8996_GP4_EINT_MASK 0x0008 /* GP4_EINT */ -#define WM8996_GP4_EINT_SHIFT 3 /* GP4_EINT */ -#define WM8996_GP4_EINT_WIDTH 1 /* GP4_EINT */ -#define WM8996_GP3_EINT 0x0004 /* GP3_EINT */ -#define WM8996_GP3_EINT_MASK 0x0004 /* GP3_EINT */ -#define WM8996_GP3_EINT_SHIFT 2 /* GP3_EINT */ -#define WM8996_GP3_EINT_WIDTH 1 /* GP3_EINT */ -#define WM8996_GP2_EINT 0x0002 /* GP2_EINT */ -#define WM8996_GP2_EINT_MASK 0x0002 /* GP2_EINT */ -#define WM8996_GP2_EINT_SHIFT 1 /* GP2_EINT */ -#define WM8996_GP2_EINT_WIDTH 1 /* GP2_EINT */ -#define WM8996_GP1_EINT 0x0001 /* GP1_EINT */ -#define WM8996_GP1_EINT_MASK 0x0001 /* GP1_EINT */ -#define WM8996_GP1_EINT_SHIFT 0 /* GP1_EINT */ -#define WM8996_GP1_EINT_WIDTH 1 /* GP1_EINT */ - -/* - * R1841 (0x731) - Interrupt Status 2 - */ -#define WM8996_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */ -#define WM8996_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */ -#define WM8996_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */ -#define WM8996_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */ -#define WM8996_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */ -#define WM8996_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */ -#define WM8996_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */ -#define WM8996_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */ -#define WM8996_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */ -#define WM8996_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */ -#define WM8996_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */ -#define WM8996_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */ -#define WM8996_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */ -#define WM8996_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */ -#define WM8996_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */ -#define WM8996_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */ -#define WM8996_DSP2DRC_SIG_DET_EINT 0x0080 /* DSP2DRC_SIG_DET_EINT */ -#define WM8996_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* DSP2DRC_SIG_DET_EINT */ -#define WM8996_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* DSP2DRC_SIG_DET_EINT */ -#define WM8996_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* DSP2DRC_SIG_DET_EINT */ -#define WM8996_DSP1DRC_SIG_DET_EINT 0x0040 /* DSP1DRC_SIG_DET_EINT */ -#define WM8996_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* DSP1DRC_SIG_DET_EINT */ -#define WM8996_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* DSP1DRC_SIG_DET_EINT */ -#define WM8996_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* DSP1DRC_SIG_DET_EINT */ -#define WM8996_FLL_SW_CLK_DONE_EINT 0x0008 /* FLL_SW_CLK_DONE_EINT */ -#define WM8996_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* FLL_SW_CLK_DONE_EINT */ -#define WM8996_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* FLL_SW_CLK_DONE_EINT */ -#define WM8996_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* FLL_SW_CLK_DONE_EINT */ -#define WM8996_FLL_LOCK_EINT 0x0004 /* FLL_LOCK_EINT */ -#define WM8996_FLL_LOCK_EINT_MASK 0x0004 /* FLL_LOCK_EINT */ -#define WM8996_FLL_LOCK_EINT_SHIFT 2 /* FLL_LOCK_EINT */ -#define WM8996_FLL_LOCK_EINT_WIDTH 1 /* FLL_LOCK_EINT */ -#define WM8996_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */ -#define WM8996_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */ -#define WM8996_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */ -#define WM8996_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */ -#define WM8996_MICD_EINT 0x0001 /* MICD_EINT */ -#define WM8996_MICD_EINT_MASK 0x0001 /* MICD_EINT */ -#define WM8996_MICD_EINT_SHIFT 0 /* MICD_EINT */ -#define WM8996_MICD_EINT_WIDTH 1 /* MICD_EINT */ - -/* - * R1842 (0x732) - Interrupt Raw Status 2 - */ -#define WM8996_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */ -#define WM8996_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */ -#define WM8996_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */ -#define WM8996_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */ -#define WM8996_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */ -#define WM8996_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */ -#define WM8996_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */ -#define WM8996_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */ -#define WM8996_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */ -#define WM8996_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */ -#define WM8996_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */ -#define WM8996_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */ -#define WM8996_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */ -#define WM8996_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */ -#define WM8996_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */ -#define WM8996_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */ -#define WM8996_DSP2DRC_SIG_DET_STS 0x0080 /* DSP2DRC_SIG_DET_STS */ -#define WM8996_DSP2DRC_SIG_DET_STS_MASK 0x0080 /* DSP2DRC_SIG_DET_STS */ -#define WM8996_DSP2DRC_SIG_DET_STS_SHIFT 7 /* DSP2DRC_SIG_DET_STS */ -#define WM8996_DSP2DRC_SIG_DET_STS_WIDTH 1 /* DSP2DRC_SIG_DET_STS */ -#define WM8996_DSP1DRC_SIG_DET_STS 0x0040 /* DSP1DRC_SIG_DET_STS */ -#define WM8996_DSP1DRC_SIG_DET_STS_MASK 0x0040 /* DSP1DRC_SIG_DET_STS */ -#define WM8996_DSP1DRC_SIG_DET_STS_SHIFT 6 /* DSP1DRC_SIG_DET_STS */ -#define WM8996_DSP1DRC_SIG_DET_STS_WIDTH 1 /* DSP1DRC_SIG_DET_STS */ -#define WM8996_FLL_LOCK_STS 0x0004 /* FLL_LOCK_STS */ -#define WM8996_FLL_LOCK_STS_MASK 0x0004 /* FLL_LOCK_STS */ -#define WM8996_FLL_LOCK_STS_SHIFT 2 /* FLL_LOCK_STS */ -#define WM8996_FLL_LOCK_STS_WIDTH 1 /* FLL_LOCK_STS */ - -/* - * R1848 (0x738) - Interrupt Status 1 Mask - */ -#define WM8996_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ -#define WM8996_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ -#define WM8996_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ -#define WM8996_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ -#define WM8996_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ -#define WM8996_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ -#define WM8996_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ -#define WM8996_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ -#define WM8996_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ -#define WM8996_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ -#define WM8996_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ -#define WM8996_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ -#define WM8996_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ -#define WM8996_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ -#define WM8996_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ -#define WM8996_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ -#define WM8996_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ -#define WM8996_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ -#define WM8996_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ -#define WM8996_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ - -/* - * R1849 (0x739) - Interrupt Status 2 Mask - */ -#define WM8996_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */ -#define WM8996_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */ -#define WM8996_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */ -#define WM8996_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */ -#define WM8996_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */ -#define WM8996_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */ -#define WM8996_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */ -#define WM8996_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */ -#define WM8996_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */ -#define WM8996_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */ -#define WM8996_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */ -#define WM8996_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */ -#define WM8996_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */ -#define WM8996_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */ -#define WM8996_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */ -#define WM8996_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */ -#define WM8996_IM_DSP2DRC_SIG_DET_EINT 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP2DRC_SIG_DET_EINT_MASK 0x0080 /* IM_DSP2DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP2DRC_SIG_DET_EINT_SHIFT 7 /* IM_DSP2DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP2DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP2DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP1DRC_SIG_DET_EINT 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP1DRC_SIG_DET_EINT_MASK 0x0040 /* IM_DSP1DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP1DRC_SIG_DET_EINT_SHIFT 6 /* IM_DSP1DRC_SIG_DET_EINT */ -#define WM8996_IM_DSP1DRC_SIG_DET_EINT_WIDTH 1 /* IM_DSP1DRC_SIG_DET_EINT */ -#define WM8996_IM_FLL_SW_CLK_DONE_EINT 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ -#define WM8996_IM_FLL_SW_CLK_DONE_EINT_MASK 0x0008 /* IM_FLL_SW_CLK_DONE_EINT */ -#define WM8996_IM_FLL_SW_CLK_DONE_EINT_SHIFT 3 /* IM_FLL_SW_CLK_DONE_EINT */ -#define WM8996_IM_FLL_SW_CLK_DONE_EINT_WIDTH 1 /* IM_FLL_SW_CLK_DONE_EINT */ -#define WM8996_IM_FLL_LOCK_EINT 0x0004 /* IM_FLL_LOCK_EINT */ -#define WM8996_IM_FLL_LOCK_EINT_MASK 0x0004 /* IM_FLL_LOCK_EINT */ -#define WM8996_IM_FLL_LOCK_EINT_SHIFT 2 /* IM_FLL_LOCK_EINT */ -#define WM8996_IM_FLL_LOCK_EINT_WIDTH 1 /* IM_FLL_LOCK_EINT */ -#define WM8996_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */ -#define WM8996_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */ -#define WM8996_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */ -#define WM8996_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */ -#define WM8996_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */ -#define WM8996_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */ -#define WM8996_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */ -#define WM8996_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */ - -/* - * R1856 (0x740) - Interrupt Control - */ -#define WM8996_IM_IRQ 0x0001 /* IM_IRQ */ -#define WM8996_IM_IRQ_MASK 0x0001 /* IM_IRQ */ -#define WM8996_IM_IRQ_SHIFT 0 /* IM_IRQ */ -#define WM8996_IM_IRQ_WIDTH 1 /* IM_IRQ */ - -/* - * R2048 (0x800) - Left PDM Speaker - */ -#define WM8996_SPKL_ENA 0x0010 /* SPKL_ENA */ -#define WM8996_SPKL_ENA_MASK 0x0010 /* SPKL_ENA */ -#define WM8996_SPKL_ENA_SHIFT 4 /* SPKL_ENA */ -#define WM8996_SPKL_ENA_WIDTH 1 /* SPKL_ENA */ -#define WM8996_SPKL_MUTE 0x0008 /* SPKL_MUTE */ -#define WM8996_SPKL_MUTE_MASK 0x0008 /* SPKL_MUTE */ -#define WM8996_SPKL_MUTE_SHIFT 3 /* SPKL_MUTE */ -#define WM8996_SPKL_MUTE_WIDTH 1 /* SPKL_MUTE */ -#define WM8996_SPKL_MUTE_ZC 0x0004 /* SPKL_MUTE_ZC */ -#define WM8996_SPKL_MUTE_ZC_MASK 0x0004 /* SPKL_MUTE_ZC */ -#define WM8996_SPKL_MUTE_ZC_SHIFT 2 /* SPKL_MUTE_ZC */ -#define WM8996_SPKL_MUTE_ZC_WIDTH 1 /* SPKL_MUTE_ZC */ -#define WM8996_SPKL_SRC_MASK 0x0003 /* SPKL_SRC - [1:0] */ -#define WM8996_SPKL_SRC_SHIFT 0 /* SPKL_SRC - [1:0] */ -#define WM8996_SPKL_SRC_WIDTH 2 /* SPKL_SRC - [1:0] */ - -/* - * R2049 (0x801) - Right PDM Speaker - */ -#define WM8996_SPKR_ENA 0x0010 /* SPKR_ENA */ -#define WM8996_SPKR_ENA_MASK 0x0010 /* SPKR_ENA */ -#define WM8996_SPKR_ENA_SHIFT 4 /* SPKR_ENA */ -#define WM8996_SPKR_ENA_WIDTH 1 /* SPKR_ENA */ -#define WM8996_SPKR_MUTE 0x0008 /* SPKR_MUTE */ -#define WM8996_SPKR_MUTE_MASK 0x0008 /* SPKR_MUTE */ -#define WM8996_SPKR_MUTE_SHIFT 3 /* SPKR_MUTE */ -#define WM8996_SPKR_MUTE_WIDTH 1 /* SPKR_MUTE */ -#define WM8996_SPKR_MUTE_ZC 0x0004 /* SPKR_MUTE_ZC */ -#define WM8996_SPKR_MUTE_ZC_MASK 0x0004 /* SPKR_MUTE_ZC */ -#define WM8996_SPKR_MUTE_ZC_SHIFT 2 /* SPKR_MUTE_ZC */ -#define WM8996_SPKR_MUTE_ZC_WIDTH 1 /* SPKR_MUTE_ZC */ -#define WM8996_SPKR_SRC_MASK 0x0003 /* SPKR_SRC - [1:0] */ -#define WM8996_SPKR_SRC_SHIFT 0 /* SPKR_SRC - [1:0] */ -#define WM8996_SPKR_SRC_WIDTH 2 /* SPKR_SRC - [1:0] */ - -/* - * R2050 (0x802) - PDM Speaker Mute Sequence - */ -#define WM8996_SPK_MUTE_ENDIAN 0x0100 /* SPK_MUTE_ENDIAN */ -#define WM8996_SPK_MUTE_ENDIAN_MASK 0x0100 /* SPK_MUTE_ENDIAN */ -#define WM8996_SPK_MUTE_ENDIAN_SHIFT 8 /* SPK_MUTE_ENDIAN */ -#define WM8996_SPK_MUTE_ENDIAN_WIDTH 1 /* SPK_MUTE_ENDIAN */ -#define WM8996_SPK_MUTE_SEQ1_MASK 0x00FF /* SPK_MUTE_SEQ1 - [7:0] */ -#define WM8996_SPK_MUTE_SEQ1_SHIFT 0 /* SPK_MUTE_SEQ1 - [7:0] */ -#define WM8996_SPK_MUTE_SEQ1_WIDTH 8 /* SPK_MUTE_SEQ1 - [7:0] */ - -/* - * R2051 (0x803) - PDM Speaker Volume - */ -#define WM8996_SPKR_VOL_MASK 0x00F0 /* SPKR_VOL - [7:4] */ -#define WM8996_SPKR_VOL_SHIFT 4 /* SPKR_VOL - [7:4] */ -#define WM8996_SPKR_VOL_WIDTH 4 /* SPKR_VOL - [7:4] */ -#define WM8996_SPKL_VOL_MASK 0x000F /* SPKL_VOL - [3:0] */ -#define WM8996_SPKL_VOL_SHIFT 0 /* SPKL_VOL - [3:0] */ -#define WM8996_SPKL_VOL_WIDTH 4 /* SPKL_VOL - [3:0] */ - -#endif diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index e763c54c55dc..4cc2d567f22f 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -440,8 +440,9 @@ static int hp_event(struct snd_soc_dapm_widget *w, reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY; snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg); + /* Smallest supported update interval */ snd_soc_update_bits(codec, WM8993_DC_SERVO_1, - WM8993_DCS_TIMER_PERIOD_01_MASK, 0); + WM8993_DCS_TIMER_PERIOD_01_MASK, 1); calibrate_dc_servo(codec); diff --git a/trunk/sound/soc/samsung/Kconfig b/trunk/sound/soc/samsung/Kconfig index b99091fc34eb..54b0e4b7faf7 100644 --- a/trunk/sound/soc/samsung/Kconfig +++ b/trunk/sound/soc/samsung/Kconfig @@ -183,7 +183,7 @@ config SND_SOC_SPEYSIDE tristate "Audio support for Wolfson Speyside" depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 select SND_SAMSUNG_I2S - select SND_SOC_WM8996 + select SND_SOC_WM8915 select SND_SOC_WM9081 config SND_SOC_SPEYSIDE_WM8962 diff --git a/trunk/sound/soc/samsung/speyside.c b/trunk/sound/soc/samsung/speyside.c index 590e9274b062..d6dee4d02036 100644 --- a/trunk/sound/soc/samsung/speyside.c +++ b/trunk/sound/soc/samsung/speyside.c @@ -14,10 +14,10 @@ #include #include -#include "../codecs/wm8996.h" +#include "../codecs/wm8915.h" #include "../codecs/wm9081.h" -#define WM8996_HPSEL_GPIO 214 +#define WM8915_HPSEL_GPIO 214 static int speyside_set_bias_level(struct snd_soc_card *card, struct snd_soc_dapm_context *dapm, @@ -31,12 +31,12 @@ static int speyside_set_bias_level(struct snd_soc_card *card, switch (level) { case SND_SOC_BIAS_STANDBY: - ret = snd_soc_dai_set_sysclk(codec_dai, WM8996_SYSCLK_MCLK2, + ret = snd_soc_dai_set_sysclk(codec_dai, WM8915_SYSCLK_MCLK2, 32768, SND_SOC_CLOCK_IN); if (ret < 0) return ret; - ret = snd_soc_dai_set_pll(codec_dai, WM8996_FLL_MCLK2, + ret = snd_soc_dai_set_pll(codec_dai, WM8915_FLL_MCLK2, 0, 0, 0); if (ret < 0) { pr_err("Failed to stop FLL\n"); @@ -65,7 +65,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, case SND_SOC_BIAS_PREPARE: if (card->dapm.bias_level == SND_SOC_BIAS_STANDBY) { ret = snd_soc_dai_set_pll(codec_dai, 0, - WM8996_FLL_MCLK2, + WM8915_FLL_MCLK2, 32768, 48000 * 256); if (ret < 0) { pr_err("Failed to start FLL\n"); @@ -73,7 +73,7 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card, } ret = snd_soc_dai_set_sysclk(codec_dai, - WM8996_SYSCLK_FLL, + WM8915_SYSCLK_FLL, 48000 * 256, SND_SOC_CLOCK_IN); if (ret < 0) @@ -149,26 +149,26 @@ static void speyside_set_polarity(struct snd_soc_codec *codec, int polarity) { speyside_jack_polarity = !polarity; - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); + gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity); /* Re-run DAPM to make sure we're using the correct mic bias */ snd_soc_dapm_sync(&codec->dapm); } -static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) +static int speyside_wm8915_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *dai = rtd->codec_dai; struct snd_soc_codec *codec = rtd->codec; int ret; - ret = snd_soc_dai_set_sysclk(dai, WM8996_SYSCLK_MCLK2, 32768, 0); + ret = snd_soc_dai_set_sysclk(dai, WM8915_SYSCLK_MCLK2, 32768, 0); if (ret < 0) return ret; - ret = gpio_request(WM8996_HPSEL_GPIO, "HP_SEL"); + ret = gpio_request(WM8915_HPSEL_GPIO, "HP_SEL"); if (ret != 0) pr_err("Failed to request HP_SEL GPIO: %d\n", ret); - gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); + gpio_direction_output(WM8915_HPSEL_GPIO, speyside_jack_polarity); ret = snd_soc_jack_new(codec, "Headset", SND_JACK_HEADSET | SND_JACK_BTN_0, @@ -182,7 +182,7 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) if (ret) return ret; - wm8996_detect(codec, &speyside_headset, speyside_set_polarity); + wm8915_detect(codec, &speyside_headset, speyside_set_polarity); return 0; } @@ -205,16 +205,16 @@ static struct snd_soc_dai_link speyside_dai[] = { .name = "CPU", .stream_name = "CPU", .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm8996-aif1", + .codec_dai_name = "wm8915-aif1", .platform_name = "samsung-audio", - .codec_name = "wm8996.1-001a", - .init = speyside_wm8996_init, + .codec_name = "wm8915.1-001a", + .init = speyside_wm8915_init, .ops = &speyside_ops, }, { .name = "Baseband", .stream_name = "Baseband", - .cpu_dai_name = "wm8996-aif2", + .cpu_dai_name = "wm8915-aif2", .codec_dai_name = "wm1250-ev1", .codec_name = "wm1250-ev1.1-0027", .ops = &speyside_ops, diff --git a/trunk/sound/soc/txx9/txx9aclc.c b/trunk/sound/soc/txx9/txx9aclc.c index 3de99af8cb82..34aa972669ed 100644 --- a/trunk/sound/soc/txx9/txx9aclc.c +++ b/trunk/sound/soc/txx9/txx9aclc.c @@ -290,7 +290,6 @@ static void txx9aclc_pcm_free_dma_buffers(struct snd_pcm *pcm) static int txx9aclc_pcm_new(struct snd_soc_pcm_runtime *rtd) { - struct snd_card *card = rtd->card->snd_card; struct snd_soc_dai *dai = rtd->cpu_dai; struct snd_pcm *pcm = rtd->pcm; struct platform_device *pdev = to_platform_device(dai->platform->dev); diff --git a/trunk/sound/usb/caiaq/input.c b/trunk/sound/usb/caiaq/input.c index a213813487bd..4432ef7a70a9 100644 --- a/trunk/sound/usb/caiaq/input.c +++ b/trunk/sound/usb/caiaq/input.c @@ -30,7 +30,7 @@ static unsigned short keycode_ak1[] = { KEY_C, KEY_B, KEY_A }; static unsigned short keycode_rk2[] = { KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7 }; static unsigned short keycode_rk3[] = { KEY_1, KEY_2, KEY_3, KEY_4, - KEY_5, KEY_6, KEY_7, KEY_8, KEY_9 }; + KEY_5, KEY_6, KEY_7, KEY_5, KEY_6 }; static unsigned short keycode_kore[] = { KEY_FN_F1, /* "menu" */ diff --git a/trunk/sound/usb/endpoint.c b/trunk/sound/usb/endpoint.c index 7d46e482375d..7c0d21ecd821 100644 --- a/trunk/sound/usb/endpoint.c +++ b/trunk/sound/usb/endpoint.c @@ -352,7 +352,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) continue; } if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || - ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { + ((protocol == UAC_VERSION_2) && (fmt->bLength != 6))) { snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", dev->devnum, iface_no, altno); continue; diff --git a/trunk/sound/usb/mixer.c b/trunk/sound/usb/mixer.c index c04d7c71ac88..c22fa76e363a 100644 --- a/trunk/sound/usb/mixer.c +++ b/trunk/sound/usb/mixer.c @@ -1191,11 +1191,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void if (state->mixer->protocol == UAC_VERSION_1) { csize = hdr->bControlSize; - if (!csize) { - snd_printdd(KERN_ERR "usbaudio: unit %u: " - "invalid bControlSize == 0\n", unitid); - return -EINVAL; - } channels = (hdr->bLength - 7) / csize - 1; bmaControls = hdr->bmaControls; } else { @@ -1939,13 +1934,15 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) struct mixer_build state; int err; const struct usbmix_ctl_map *map; + struct usb_host_interface *hostif; void *p; + hostif = mixer->chip->ctrl_intf; memset(&state, 0, sizeof(state)); state.chip = mixer->chip; state.mixer = mixer; - state.buffer = mixer->hostif->extra; - state.buflen = mixer->hostif->extralen; + state.buffer = hostif->extra; + state.buflen = hostif->extralen; /* check the mapping table */ for (map = usbmix_ctl_maps; map->id; map++) { @@ -1958,8 +1955,7 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) } p = NULL; - while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, - p, UAC_OUTPUT_TERMINAL)) != NULL) { + while ((p = snd_usb_find_csint_desc(hostif->extra, hostif->extralen, p, UAC_OUTPUT_TERMINAL)) != NULL) { if (mixer->protocol == UAC_VERSION_1) { struct uac1_output_terminal_descriptor *desc = p; @@ -2166,15 +2162,17 @@ int snd_usb_mixer_activate(struct usb_mixer_interface *mixer) /* create the handler for the optional status interrupt endpoint */ static int snd_usb_mixer_status_create(struct usb_mixer_interface *mixer) { + struct usb_host_interface *hostif; struct usb_endpoint_descriptor *ep; void *transfer_buffer; int buffer_length; unsigned int epnum; + hostif = mixer->chip->ctrl_intf; /* we need one interrupt input endpoint */ - if (get_iface_desc(mixer->hostif)->bNumEndpoints < 1) + if (get_iface_desc(hostif)->bNumEndpoints < 1) return 0; - ep = get_endpoint(mixer->hostif, 0); + ep = get_endpoint(hostif, 0); if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_int(ep)) return 0; @@ -2204,6 +2202,7 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, }; struct usb_mixer_interface *mixer; struct snd_info_entry *entry; + struct usb_host_interface *host_iface; int err; strcpy(chip->card->mixername, "USB Mixer"); @@ -2220,8 +2219,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif, return -ENOMEM; } - mixer->hostif = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; - switch (get_iface_desc(mixer->hostif)->bInterfaceProtocol) { + host_iface = &usb_ifnum_to_if(chip->dev, ctrlif)->altsetting[0]; + switch (get_iface_desc(host_iface)->bInterfaceProtocol) { case UAC_VERSION_1: default: mixer->protocol = UAC_VERSION_1; diff --git a/trunk/sound/usb/mixer.h b/trunk/sound/usb/mixer.h index 81b2d8a32fb0..ae1a14dcfe82 100644 --- a/trunk/sound/usb/mixer.h +++ b/trunk/sound/usb/mixer.h @@ -3,7 +3,6 @@ struct usb_mixer_interface { struct snd_usb_audio *chip; - struct usb_host_interface *hostif; struct list_head list; unsigned int ignore_ctl_error; struct urb *urb; diff --git a/trunk/sound/usb/quirks-table.h b/trunk/sound/usb/quirks-table.h index 4d4f86552a23..dba0b7f11c54 100644 --- a/trunk/sound/usb/quirks-table.h +++ b/trunk/sound/usb/quirks-table.h @@ -2417,12 +2417,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), .idProduct = 0x1020, }, -/* KeithMcMillen Stringport */ -{ - USB_DEVICE(0x1f38, 0x0001), - .bInterfaceClass = USB_CLASS_AUDIO, -}, - /* Miditech devices */ { USB_DEVICE(0x4752, 0x0011), diff --git a/trunk/sound/usb/quirks.c b/trunk/sound/usb/quirks.c index 81e07d842581..77762c99afbe 100644 --- a/trunk/sound/usb/quirks.c +++ b/trunk/sound/usb/quirks.c @@ -426,7 +426,7 @@ static int snd_usb_cm106_boot_quirk(struct usb_device *dev) */ static int snd_usb_cm6206_boot_quirk(struct usb_device *dev) { - int err = 0, reg; + int err, reg; int val[] = {0x2004, 0x3000, 0xf800, 0x143f, 0x0000, 0x3000}; for (reg = 0; reg < ARRAY_SIZE(val); reg++) { diff --git a/trunk/tools/perf/Makefile b/trunk/tools/perf/Makefile index 3b8f7b80376b..56d62d3fb167 100644 --- a/trunk/tools/perf/Makefile +++ b/trunk/tools/perf/Makefile @@ -181,9 +181,9 @@ strip-libs = $(filter-out -l%,$(1)) $(OUTPUT)python/perf.so: $(PYRF_OBJS) $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ - --quiet build_ext; \ - mkdir -p $(OUTPUT)python && \ - cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ + --quiet build_ext \ + --build-lib='$(OUTPUT)python' \ + --build-temp='$(OUTPUT)python/temp' # # No Perl scripts right now: # @@ -509,13 +509,9 @@ else PYTHON_WORD := $(call shell-wordify,$(PYTHON)) - # python extension build directories - PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/ - PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ - PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/ - export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP - - python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so + python-clean := $(PYTHON_WORD) util/setup.py clean \ + --build-lib='$(OUTPUT)python' \ + --build-temp='$(OUTPUT)python/temp' ifdef NO_LIBPYTHON $(call disable-python) @@ -872,9 +868,6 @@ install: all $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python' $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' -install-python_ext: - $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)' - install-doc: $(MAKE) -C Documentation install @@ -902,7 +895,7 @@ quick-install-html: ### Cleaning rules clean: - $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS) + $(RM) $(OUTPUT){*.o,*/*.o,*/*/*.o,*/*/*/*.o,$(LIB_FILE),perf-archive} $(RM) $(ALL_PROGRAMS) perf $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* $(MAKE) -C Documentation/ clean diff --git a/trunk/tools/perf/builtin-lock.c b/trunk/tools/perf/builtin-lock.c index 899080ace267..9ac05aafd9b2 100644 --- a/trunk/tools/perf/builtin-lock.c +++ b/trunk/tools/perf/builtin-lock.c @@ -942,10 +942,10 @@ static const char *record_args[] = { "-f", "-m", "1024", "-c", "1", - "-e", "lock:lock_acquire", - "-e", "lock:lock_acquired", - "-e", "lock:lock_contended", - "-e", "lock:lock_release", + "-e", "lock:lock_acquire:r", + "-e", "lock:lock_acquired:r", + "-e", "lock:lock_contended:r", + "-e", "lock:lock_release:r", }; static int __cmd_record(int argc, const char **argv) diff --git a/trunk/tools/perf/builtin-record.c b/trunk/tools/perf/builtin-record.c index f6426b496f4a..80dc5b790e47 100644 --- a/trunk/tools/perf/builtin-record.c +++ b/trunk/tools/perf/builtin-record.c @@ -30,6 +30,8 @@ #include #include +#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) + enum write_mode_t { WRITE_FORCE, WRITE_APPEND @@ -436,6 +438,7 @@ static void mmap_read_all(void) static int __cmd_record(int argc, const char **argv) { + int i; struct stat st; int flags; int err; @@ -679,6 +682,7 @@ static int __cmd_record(int argc, const char **argv) for (;;) { int hits = samples; + int thread; mmap_read_all(); @@ -689,8 +693,19 @@ static int __cmd_record(int argc, const char **argv) waking++; } - if (done) - perf_evlist__disable(evsel_list); + if (done) { + for (i = 0; i < evsel_list->cpus->nr; i++) { + struct perf_evsel *pos; + + list_for_each_entry(pos, &evsel_list->entries, node) { + for (thread = 0; + thread < evsel_list->threads->nr; + thread++) + ioctl(FD(pos, i, thread), + PERF_EVENT_IOC_DISABLE); + } + } + } } if (quiet || signr == SIGUSR1) diff --git a/trunk/tools/perf/builtin-report.c b/trunk/tools/perf/builtin-report.c index d7ff277bdb78..f854efda7686 100644 --- a/trunk/tools/perf/builtin-report.c +++ b/trunk/tools/perf/builtin-report.c @@ -162,22 +162,23 @@ static int perf_session__setup_sample_type(struct perf_session *self) { if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { - ui__warning("Selected --sort parent, but no " - "callchain data. Did you call " - "'perf record' without -g?\n"); + fprintf(stderr, "selected --sort parent, but no" + " callchain data. Did you call" + " perf record without -g?\n"); return -EINVAL; } if (symbol_conf.use_callchain) { - ui__warning("Selected -g but no callchain data. Did " - "you call 'perf record' without -g?\n"); + fprintf(stderr, "selected -g but no callchain data." + " Did you call perf record without" + " -g?\n"); return -1; } } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE && !symbol_conf.use_callchain) { symbol_conf.use_callchain = true; if (callchain_register_param(&callchain_param) < 0) { - ui__warning("Can't register callchain " - "params.\n"); + fprintf(stderr, "Can't register callchain" + " params\n"); return -EINVAL; } } diff --git a/trunk/tools/perf/builtin-sched.c b/trunk/tools/perf/builtin-sched.c index 5177964943e7..dcfe8873c9a1 100644 --- a/trunk/tools/perf/builtin-sched.c +++ b/trunk/tools/perf/builtin-sched.c @@ -1637,29 +1637,23 @@ static struct perf_event_ops event_ops = { .ordered_samples = true, }; -static void read_events(bool destroy, struct perf_session **psession) +static int read_events(void) { int err = -EINVAL; struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops); if (session == NULL) - die("No Memory"); + return -ENOMEM; if (perf_session__has_traces(session, "record -R")) { err = perf_session__process_events(session, &event_ops); - if (err) - die("Failed to process events, error %d", err); - nr_events = session->hists.stats.nr_events[0]; nr_lost_events = session->hists.stats.total_lost; nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST]; } - if (destroy) - perf_session__delete(session); - - if (psession) - *psession = session; + perf_session__delete(session); + return err; } static void print_bad_events(void) @@ -1695,10 +1689,9 @@ static void print_bad_events(void) static void __cmd_lat(void) { struct rb_node *next; - struct perf_session *session; setup_pager(); - read_events(false, &session); + read_events(); sort_lat(); printf("\n ---------------------------------------------------------------------------------------------------------------\n"); @@ -1724,7 +1717,6 @@ static void __cmd_lat(void) print_bad_events(); printf("\n"); - perf_session__delete(session); } static struct trace_sched_handler map_ops = { @@ -1739,7 +1731,7 @@ static void __cmd_map(void) max_cpu = sysconf(_SC_NPROCESSORS_CONF); setup_pager(); - read_events(true, NULL); + read_events(); print_bad_events(); } @@ -1752,7 +1744,7 @@ static void __cmd_replay(void) test_calibrations(); - read_events(true, NULL); + read_events(); printf("nr_run_events: %ld\n", nr_run_events); printf("nr_sleep_events: %ld\n", nr_sleep_events); @@ -1777,7 +1769,7 @@ static void __cmd_replay(void) static const char * const sched_usage[] = { - "perf sched [] {record|latency|map|replay|script}", + "perf sched [] {record|latency|map|replay|trace}", NULL }; diff --git a/trunk/tools/perf/util/config.c b/trunk/tools/perf/util/config.c index fe02903f7d0f..e02d78cae70f 100644 --- a/trunk/tools/perf/util/config.c +++ b/trunk/tools/perf/util/config.c @@ -399,6 +399,7 @@ static int perf_config_global(void) int perf_config(config_fn_t fn, void *data) { int ret = 0, found = 0; + char *repo_config = NULL; const char *home = NULL; /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ @@ -413,32 +414,19 @@ int perf_config(config_fn_t fn, void *data) home = getenv("HOME"); if (perf_config_global() && home) { char *user_config = strdup(mkpath("%s/.perfconfig", home)); - struct stat st; - - if (user_config == NULL) { - warning("Not enough memory to process %s/.perfconfig, " - "ignoring it.", home); - goto out; - } - - if (stat(user_config, &st) < 0) - goto out_free; - - if (st.st_uid && (st.st_uid != geteuid())) { - warning("File %s not owned by current user or root, " - "ignoring it.", user_config); - goto out_free; + if (!access(user_config, R_OK)) { + ret += perf_config_from_file(fn, user_config, data); + found += 1; } + free(user_config); + } - if (!st.st_size) - goto out_free; - - ret += perf_config_from_file(fn, user_config, data); + repo_config = perf_pathdup("config"); + if (!access(repo_config, R_OK)) { + ret += perf_config_from_file(fn, repo_config, data); found += 1; -out_free: - free(user_config); } -out: + free(repo_config); if (found == 0) return -1; return ret; diff --git a/trunk/tools/perf/util/evlist.c b/trunk/tools/perf/util/evlist.c index e03e7bc8205e..b021ea9265c3 100644 --- a/trunk/tools/perf/util/evlist.c +++ b/trunk/tools/perf/util/evlist.c @@ -91,19 +91,6 @@ int perf_evlist__add_default(struct perf_evlist *evlist) return 0; } -void perf_evlist__disable(struct perf_evlist *evlist) -{ - int cpu, thread; - struct perf_evsel *pos; - - for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { - list_for_each_entry(pos, &evlist->entries, node) { - for (thread = 0; thread < evlist->threads->nr; thread++) - ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE); - } - } -} - int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) { int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; diff --git a/trunk/tools/perf/util/evlist.h b/trunk/tools/perf/util/evlist.h index ce85ae9ae57a..b2b862374f37 100644 --- a/trunk/tools/perf/util/evlist.h +++ b/trunk/tools/perf/util/evlist.h @@ -53,8 +53,6 @@ int perf_evlist__alloc_mmap(struct perf_evlist *evlist); int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); void perf_evlist__munmap(struct perf_evlist *evlist); -void perf_evlist__disable(struct perf_evlist *evlist); - static inline void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads) diff --git a/trunk/tools/perf/util/header.c b/trunk/tools/perf/util/header.c index d4f3101773db..cb2959a3fb43 100644 --- a/trunk/tools/perf/util/header.c +++ b/trunk/tools/perf/util/header.c @@ -189,8 +189,8 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, const char *name, bool is_kallsyms) { const size_t size = PATH_MAX; - char *realname, *filename = zalloc(size), - *linkname = zalloc(size), *targetname; + char *realname, *filename = malloc(size), + *linkname = malloc(size), *targetname; int len, err = -1; if (is_kallsyms) { @@ -254,8 +254,8 @@ static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) { const size_t size = PATH_MAX; - char *filename = zalloc(size), - *linkname = zalloc(size); + char *filename = malloc(size), + *linkname = malloc(size); int err = -1; if (filename == NULL || linkname == NULL) diff --git a/trunk/tools/perf/util/probe-event.c b/trunk/tools/perf/util/probe-event.c index 1c7bfa5fe0a8..b82d54fa2c56 100644 --- a/trunk/tools/perf/util/probe-event.c +++ b/trunk/tools/perf/util/probe-event.c @@ -1820,15 +1820,11 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev, ret = -ENOMEM; goto error; } - - if (module) { - tev->point.module = strdup(module); - if (tev->point.module == NULL) { - ret = -ENOMEM; - goto error; - } + tev->point.module = strdup(module); + if (tev->point.module == NULL) { + ret = -ENOMEM; + goto error; } - tev->point.offset = pev->point.offset; tev->point.retprobe = pev->point.retprobe; tev->nargs = pev->nargs; diff --git a/trunk/tools/perf/util/python.c b/trunk/tools/perf/util/python.c index cbc8f215d4b7..8e0b5a39d8a7 100644 --- a/trunk/tools/perf/util/python.c +++ b/trunk/tools/perf/util/python.c @@ -187,117 +187,14 @@ static PyTypeObject pyrf_throttle_event__type = { .tp_repr = (reprfunc)pyrf_throttle_event__repr, }; -static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); - -static PyMemberDef pyrf_lost_event__members[] = { - sample_members - member_def(lost_event, id, T_ULONGLONG, "event id"), - member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), - { .name = NULL, }, -}; - -static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) -{ - PyObject *ret; - char *s; - - if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " - "lost: %#" PRIx64 " }", - pevent->event.lost.id, pevent->event.lost.lost) < 0) { - ret = PyErr_NoMemory(); - } else { - ret = PyString_FromString(s); - free(s); - } - return ret; -} - -static PyTypeObject pyrf_lost_event__type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "perf.lost_event", - .tp_basicsize = sizeof(struct pyrf_event), - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_doc = pyrf_lost_event__doc, - .tp_members = pyrf_lost_event__members, - .tp_repr = (reprfunc)pyrf_lost_event__repr, -}; - -static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); - -static PyMemberDef pyrf_read_event__members[] = { - sample_members - member_def(read_event, pid, T_UINT, "event pid"), - member_def(read_event, tid, T_UINT, "event tid"), - { .name = NULL, }, -}; - -static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) -{ - return PyString_FromFormat("{ type: read, pid: %u, tid: %u }", - pevent->event.read.pid, - pevent->event.read.tid); - /* - * FIXME: return the array of read values, - * making this method useful ;-) - */ -} - -static PyTypeObject pyrf_read_event__type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "perf.read_event", - .tp_basicsize = sizeof(struct pyrf_event), - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_doc = pyrf_read_event__doc, - .tp_members = pyrf_read_event__members, - .tp_repr = (reprfunc)pyrf_read_event__repr, -}; - -static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); - -static PyMemberDef pyrf_sample_event__members[] = { - sample_members - member_def(perf_event_header, type, T_UINT, "event type"), - { .name = NULL, }, -}; - -static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) -{ - PyObject *ret; - char *s; - - if (asprintf(&s, "{ type: sample }") < 0) { - ret = PyErr_NoMemory(); - } else { - ret = PyString_FromString(s); - free(s); - } - return ret; -} - -static PyTypeObject pyrf_sample_event__type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "perf.sample_event", - .tp_basicsize = sizeof(struct pyrf_event), - .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, - .tp_doc = pyrf_sample_event__doc, - .tp_members = pyrf_sample_event__members, - .tp_repr = (reprfunc)pyrf_sample_event__repr, -}; - static int pyrf_event__setup_types(void) { int err; pyrf_mmap_event__type.tp_new = pyrf_task_event__type.tp_new = pyrf_comm_event__type.tp_new = - pyrf_lost_event__type.tp_new = - pyrf_read_event__type.tp_new = - pyrf_sample_event__type.tp_new = pyrf_throttle_event__type.tp_new = PyType_GenericNew; err = PyType_Ready(&pyrf_mmap_event__type); - if (err < 0) - goto out; - err = PyType_Ready(&pyrf_lost_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_task_event__type); @@ -309,26 +206,20 @@ static int pyrf_event__setup_types(void) err = PyType_Ready(&pyrf_throttle_event__type); if (err < 0) goto out; - err = PyType_Ready(&pyrf_read_event__type); - if (err < 0) - goto out; - err = PyType_Ready(&pyrf_sample_event__type); - if (err < 0) - goto out; out: return err; } static PyTypeObject *pyrf_event__type[] = { [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, - [PERF_RECORD_LOST] = &pyrf_lost_event__type, + [PERF_RECORD_LOST] = &pyrf_mmap_event__type, [PERF_RECORD_COMM] = &pyrf_comm_event__type, [PERF_RECORD_EXIT] = &pyrf_task_event__type, [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_FORK] = &pyrf_task_event__type, - [PERF_RECORD_READ] = &pyrf_read_event__type, - [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, + [PERF_RECORD_READ] = &pyrf_mmap_event__type, + [PERF_RECORD_SAMPLE] = &pyrf_mmap_event__type, }; static PyObject *pyrf_event__new(union perf_event *event) diff --git a/trunk/tools/perf/util/setup.py b/trunk/tools/perf/util/setup.py index 95d370074928..bbc982f5dd8b 100644 --- a/trunk/tools/perf/util/setup.py +++ b/trunk/tools/perf/util/setup.py @@ -3,27 +3,9 @@ from distutils.core import setup, Extension from os import getenv -from distutils.command.build_ext import build_ext as _build_ext -from distutils.command.install_lib import install_lib as _install_lib - -class build_ext(_build_ext): - def finalize_options(self): - _build_ext.finalize_options(self) - self.build_lib = build_lib - self.build_temp = build_tmp - -class install_lib(_install_lib): - def finalize_options(self): - _install_lib.finalize_options(self) - self.build_dir = build_lib - - cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] cflags += getenv('CFLAGS', '').split() -build_lib = getenv('PYTHON_EXTBUILD_LIB') -build_tmp = getenv('PYTHON_EXTBUILD_TMP') - perf = Extension('perf', sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', @@ -39,5 +21,4 @@ def finalize_options(self): author_email='acme@redhat.com', license='GPLv2', url='http://perf.wiki.kernel.org', - ext_modules=[perf], - cmdclass={'build_ext': build_ext, 'install_lib': install_lib}) + ext_modules=[perf]) diff --git a/trunk/tools/perf/util/symbol.c b/trunk/tools/perf/util/symbol.c index a8b53714542a..eec196329fd9 100644 --- a/trunk/tools/perf/util/symbol.c +++ b/trunk/tools/perf/util/symbol.c @@ -1504,17 +1504,6 @@ int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) dso->adjust_symbols = 0; if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { - struct stat st; - - if (stat(dso->name, &st) < 0) - return -1; - - if (st.st_uid && (st.st_uid != geteuid())) { - pr_warning("File %s not owned by current user or root, " - "ignoring it.\n", dso->name); - return -1; - } - ret = dso__load_perf_map(dso, map, filter); dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : SYMTAB__NOT_FOUND; diff --git a/trunk/tools/power/x86/turbostat/turbostat.c b/trunk/tools/power/x86/turbostat/turbostat.c index 8b2d37b59c9e..6d8ef4a3a9b5 100644 --- a/trunk/tools/power/x86/turbostat/turbostat.c +++ b/trunk/tools/power/x86/turbostat/turbostat.c @@ -128,34 +128,34 @@ unsigned long long get_msr(int cpu, off_t offset) void print_header(void) { if (show_pkg) - fprintf(stderr, "pk"); + fprintf(stderr, "pkg "); if (show_core) - fprintf(stderr, " cr"); + fprintf(stderr, "core"); if (show_cpu) fprintf(stderr, " CPU"); if (do_nhm_cstates) - fprintf(stderr, " %%c0 "); + fprintf(stderr, " %%c0 "); if (has_aperf) - fprintf(stderr, " GHz"); + fprintf(stderr, " GHz"); fprintf(stderr, " TSC"); if (do_nhm_cstates) - fprintf(stderr, " %%c1"); + fprintf(stderr, " %%c1 "); if (do_nhm_cstates) - fprintf(stderr, " %%c3"); + fprintf(stderr, " %%c3 "); if (do_nhm_cstates) - fprintf(stderr, " %%c6"); + fprintf(stderr, " %%c6 "); if (do_snb_cstates) - fprintf(stderr, " %%c7"); + fprintf(stderr, " %%c7 "); if (do_snb_cstates) - fprintf(stderr, " %%pc2"); + fprintf(stderr, " %%pc2 "); if (do_nhm_cstates) - fprintf(stderr, " %%pc3"); + fprintf(stderr, " %%pc3 "); if (do_nhm_cstates) - fprintf(stderr, " %%pc6"); + fprintf(stderr, " %%pc6 "); if (do_snb_cstates) - fprintf(stderr, " %%pc7"); + fprintf(stderr, " %%pc7 "); if (extra_msr_offset) - fprintf(stderr, " MSR 0x%x ", extra_msr_offset); + fprintf(stderr, " MSR 0x%x ", extra_msr_offset); putc('\n', stderr); } @@ -194,14 +194,14 @@ void print_cnt(struct counters *p) /* topology columns, print blanks on 1st (average) line */ if (p == cnt_average) { if (show_pkg) - fprintf(stderr, " "); + fprintf(stderr, " "); if (show_core) fprintf(stderr, " "); if (show_cpu) fprintf(stderr, " "); } else { if (show_pkg) - fprintf(stderr, "%d", p->pkg); + fprintf(stderr, "%4d", p->pkg); if (show_core) fprintf(stderr, "%4d", p->core); if (show_cpu) @@ -241,22 +241,22 @@ void print_cnt(struct counters *p) if (!skip_c1) fprintf(stderr, "%7.2f", 100.0 * p->c1/p->tsc); else - fprintf(stderr, " ****"); + fprintf(stderr, " ****"); } if (do_nhm_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->c3/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->c3/p->tsc); if (do_nhm_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->c6/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->c6/p->tsc); if (do_snb_cstates) - fprintf(stderr, " %6.2f", 100.0 * p->c7/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->c7/p->tsc); if (do_snb_cstates) - fprintf(stderr, " %5.2f", 100.0 * p->pc2/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->pc2/p->tsc); if (do_nhm_cstates) - fprintf(stderr, " %5.2f", 100.0 * p->pc3/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->pc3/p->tsc); if (do_nhm_cstates) - fprintf(stderr, " %5.2f", 100.0 * p->pc6/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->pc6/p->tsc); if (do_snb_cstates) - fprintf(stderr, " %5.2f", 100.0 * p->pc7/p->tsc); + fprintf(stderr, "%7.2f", 100.0 * p->pc7/p->tsc); if (extra_msr_offset) fprintf(stderr, " 0x%016llx", p->extra_msr); putc('\n', stderr); diff --git a/trunk/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c b/trunk/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c index 33c5c7ee148f..2618ef2ba31f 100644 --- a/trunk/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c +++ b/trunk/tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c @@ -137,6 +137,7 @@ void cmdline(int argc, char **argv) void validate_cpuid(void) { unsigned int eax, ebx, ecx, edx, max_level; + char brand[16]; unsigned int fms, family, model, stepping; eax = ebx = ecx = edx = 0; @@ -159,8 +160,8 @@ void validate_cpuid(void) model += ((fms >> 16) & 0xf) << 4; if (verbose > 1) - printf("CPUID %d levels family:model:stepping " - "0x%x:%x:%x (%d:%d:%d)\n", max_level, + printf("CPUID %s %d levels family:model:stepping " + "0x%x:%x:%x (%d:%d:%d)\n", brand, max_level, family, model, stepping, family, model, stepping); if (!(edx & (1 << 5))) {